Added changes whitelists to API

Change-Id: I470caeaf0145ad1f967a9ad71fc4b90908509a44
This commit is contained in:
Dmitry Nikishov 2016-11-15 08:53:20 +00:00
parent be68d28707
commit 79a59c52f0
6 changed files with 196 additions and 6 deletions

View File

@ -168,7 +168,11 @@ class ExternalGit(BaseExtension):
'handler': handlers.GitRepoHandler},
{'uri':
r'/clusters/(?P<env_id>\d+)/git-repos/(?P<obj_id>\d+)/init?$',
'handler': handlers.GitRepoInit}]
'handler': handlers.GitRepoInit},
{'uri': r'/clusters/(?P<env_id>\d+)/changes-whitelist/$',
'handler': handlers.ChangesWhitelistRuleCollectionHandler},
{'uri': r'/clusters/changes-whitelist/(?P<obj_id>\d+)?$',
'handler': handlers.ChangesWhitelistRuleHandler}]
data_pipelines = [
OpenStackConfigPipeline,

View File

@ -11,6 +11,8 @@
# under the License.
from fuel_external_git import json_schema
from fuel_external_git.objects import ChangesWhitelistRule
from fuel_external_git.objects import ChangesWhitelistRuleCollection
from fuel_external_git.objects import GitRepo
from fuel_external_git.objects import GitRepoCollection
@ -30,8 +32,8 @@ REPOS_DIR = '/var/lib/fuel_repos'
class GitRepoValidator(base.BasicValidator):
single_schema = json_schema.single_schema
collection_schema = json_schema.collection_schema
single_schema = json_schema.gitrepo_single_schema
collection_schema = json_schema.gitrepo_collection_schema
_blocked_for_update = (
'env_id',
@ -77,6 +79,44 @@ class GitRepoValidator(base.BasicValidator):
return d
class ChangesWhitelistRuleValidator(base.BasicValidator):
single_schema = json_schema.changeswhitelistrule_single_schema
collection_schema = json_schema.changeswhitelistrule_collection_schema
_blocked_for_update = (
'env_id',
)
@classmethod
def validate_update(self, data, instance):
d = self.validate_json(data)
for k in self._blocked_for_update:
if k in d and getattr(instance, k) != d[k]:
raise errors.InvalidData(
u"Changing '{0}' for white list is prohibited".format(k),
log_message=True
)
return d
# TODO(dnikishov): investigate if there's a more simple way to do this
@classmethod
def validate_one_or_multiple(self, data):
d = self.validate_json(data)
if not isinstance(d, list):
d = [d]
for item in d:
self.validate_schema(item, self.single_schema)
return d
# This is required for inherited handlers to work
@classmethod
def validate_delete(self, *args, **kwargs):
pass
class GitRepoCollectionHandler(CollectionHandler):
collection = GitRepoCollection
validator = GitRepoValidator
@ -157,3 +197,50 @@ class GitRepoInit(BaseHandler):
obj = GitRepo.get_by_cluster_id(obj.env_id)
GitRepo.init(obj)
raise self.http(200, "{}")
class ChangesWhitelistRuleHandler(SingleHandler):
single = ChangesWhitelistRule
validator = ChangesWhitelistRuleValidator
class ChangesWhitelistRuleCollectionHandler(CollectionHandler):
collection = ChangesWhitelistRuleCollection
validator = ChangesWhitelistRuleValidator
@handle_errors
@validate
@serialize
def GET(self, env_id):
""":returns: JSONized REST object.
:http: * 200 (OK)
* 404 (dashboard entry not found in db)
"""
self.get_object_or_404(objects.Cluster, env_id)
rules = self.collection.get_by_env_id(env_id)
return self.collection.to_list(rules)
@handle_errors
@serialize
def POST(self, env_id):
""":returns: JSONized REST object.
:http: * 201 (object successfully created)
* 400 (invalid object data specified)
* 409 (object with such parameters already exists)
"""
data = self.checked_data(
validate_method=self.validator.validate_one_or_multiple
)
for item in data:
item['env_id'] = env_id
new_objs = []
try:
for item in data:
new_objs.append(self.collection.create(item))
except errors.CannotCreate as exc:
raise self.http(400, exc.message)
raise self.http(201, self.collection.to_json(new_objs))

View File

@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
single_schema = {
gitrepo_single_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "GitRepo",
"description": "Serialized GitRepo object",
@ -25,10 +25,30 @@ single_schema = {
}
}
collection_schema = {
gitrepo_collection_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "GitRepo Collection",
"description": "Serialized GitRepo collection",
"type": "object",
"items": single_schema["properties"]
"items": gitrepo_single_schema["properties"]
}
changeswhitelistrule_single_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "ChangesWhitelistRule",
"description": "Serialized ChangesWhitelistRule object",
"type": "object",
"properties": {
"id": {"type": "number"},
"env_id": {"type": "number"},
"rule": {"type": "string"},
}
}
changeswhitelistrule_collection_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "ChangesWhitelistRule Collection",
"description": "Serialized ChangesWhitelistRule collection",
"type": "object",
"items": changeswhitelistrule_single_schema["properties"]
}

View File

@ -0,0 +1,45 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""add whitelist table
Revision ID: 8736ad38ca31
Revises: adb78f70605d
Create Date: 2016-11-07 10:50:38.168018
"""
# revision identifiers, used by Alembic.
revision = '8736ad38ca31'
down_revision = 'adb78f70605d'
branch_labels = None
depends_on = None
from alembic import context
from alembic import op
import sqlalchemy as sa
def upgrade():
table_prefix = context.config.get_main_option('table_prefix')
op.create_table(
table_prefix + 'changes_whitelist',
sa.Column('id', sa.Integer(), nullable=False, primary_key=True),
sa.Column('env_id', sa.Integer(), nullable=False),
sa.Column('rule', sa.String(255),
server_default='', nullable=False)
)
def downgrade():
table_prefix = context.config.get_main_option('table_prefix')
op.drop_table(table_prefix + 'changes_whitelist')

View File

@ -30,3 +30,10 @@ class GitRepo(Base):
user_key = Column(String(255), default='', server_default='',
nullable=False)
manage_master = Column(Boolean(), nullable=False)
class ChangesWhitelistRule(Base):
__tablename__ = 'fuel_external_git_changes_whitelist'
id = Column(Integer, primary_key=True)
env_id = Column(Integer, nullable=False)
rule = Column(String(255), server_default='', nullable=False)

View File

@ -18,6 +18,7 @@ import yaml
from distutils.dir_util import copy_tree
from fuel_external_git import const
from fuel_external_git.models import ChangesWhitelistRule
from fuel_external_git.models import GitRepo
from git import exc
@ -45,6 +46,14 @@ class GitRepoSerializer(BasicSerializer):
)
class ChangesWhitelistRuleSerializer(BasicSerializer):
fields = (
"id",
"env_id",
"rule"
)
class GitRepo(NailgunObject):
model = GitRepo
serializer = GitRepoSerializer
@ -198,3 +207,21 @@ class GitRepo(NailgunObject):
class GitRepoCollection(NailgunCollection):
single = GitRepo
class ChangesWhitelistRule(NailgunObject):
model = ChangesWhitelistRule
serializer = ChangesWhitelistRuleSerializer
class ChangesWhitelistRuleCollection(NailgunCollection):
single = ChangesWhitelistRule
@classmethod
def get_by_env_id(self, env_id):
whitelist = set()
for rule in ChangesWhitelistRuleCollection.all():
if env_id == rule.env_id:
whitelist.add(rule)
return whitelist