class TemplateSerializer(_WithVariablesSerializer): data = DictField(required=True, write_only=True) options = DictField(write_only=True) options_list = DictField(read_only=True) class Meta: model = models.Template fields = ( 'id', 'name', 'kind', 'data', 'options', 'options_list', ) def get_vars(self, representation): try: return representation['data']['vars'] except KeyError: return None def set_opts_vars(self, rep, hidden_vars): if not rep.get('vars', None): return rep var = rep['vars'] for mask_key in hidden_vars: if mask_key in var.keys(): var[mask_key] = "[~~ENCRYPTED~~]" return rep def repr_options(self, instance, data, hidden_vars): hv = hidden_vars hv = instance.HIDDEN_VARS if hv is None else hv for name, rep in data.get('options', {}).items(): data['options'][name] = self.set_opts_vars(rep, hv) def to_representation(self, instance): data = OrderedDict() if instance.kind in ["Task", "PeriodicTask", "Module"]: hidden_vars = models.PeriodicTask.HIDDEN_VARS data = super(TemplateSerializer, self).to_representation( instance, hidden_vars=hidden_vars ) self.repr_options(instance, data, hidden_vars) elif instance.kind in ["Host", "Group"]: data = super(TemplateSerializer, self).to_representation( instance, hidden_vars=models.Inventory.HIDDEN_VARS ) return data
class OnePeriodictaskSerializer(PeriodictaskSerializer): vars = DictField(required=False) class Meta: model = models.PeriodicTask fields = ( 'id', 'name', 'type', 'schedule', 'mode', 'kind', 'project', 'inventory', 'save_result', 'enabled', 'vars', 'url', ) def execute(self): inventory = self.instance.inventory history_id = self.instance.execute(sync=False) rdata = dict(detail="Started at inventory {}.".format(inventory), history_id=history_id) return APIRespone(rdata, 201)
class OneGroupSerializer(GroupSerializer, _InventoryOperations): vars = DictField(required=False) hosts = HostSerializer(read_only=True, many=True) groups = GroupSerializer(read_only=True, many=True) owner = UserSerializer(read_only=True) class Meta: model = models.Group fields = ( 'id', 'name', 'hosts', "groups", 'vars', 'children', 'owner', 'url', ) class ValidationException(rest_exceptions.ValidationError): status_code = 409 def hosts_operations(self, method, data): if self.instance.children: raise self.ValidationException("Group is children.") return super(OneGroupSerializer, self).hosts_operations(method, data) def groups_operations(self, method, data): if not self.instance.children: raise self.ValidationException("Group is not children.") return super(OneGroupSerializer, self).groups_operations(method, data)
class PeriodictaskSerializer(_WithVariablesSerializer): vars = DictField(required=False, write_only=True) schedule = serializers.CharField(allow_blank=True) inventory = serializers.CharField() class Meta: model = models.PeriodicTask fields = ( 'id', 'name', 'type', 'schedule', 'mode', 'kind', 'project', 'inventory', 'save_result', 'enabled', 'vars', 'url', ) @transaction.atomic def permissions(self, request): # noce raise main_exceptions.NotApplicable("See project permissions.") def owner(self, request): # noce raise main_exceptions.NotApplicable("See project owner.")
class InventorySerializer(_WithVariablesSerializer): vars = DictField(required=False, write_only=True) class Meta: model = models.Inventory fields = ( 'id', 'name', 'vars', 'url', )
class TeamSerializer(_WithPermissionsSerializer): users_list = DictField(required=False, write_only=True) class Meta: model = models.UserGroup fields = ( 'id', "name", "users_list", 'url', )
class HostSerializer(_WithVariablesSerializer): vars = DictField(required=False, write_only=True) class Meta: model = models.Host fields = ( 'id', 'name', 'type', 'vars', 'url', )
class GroupSerializer(_WithVariablesSerializer): vars = DictField(required=False, write_only=True) class Meta: model = models.Group fields = ( 'id', 'name', 'vars', 'children', 'url', )
class OneTemplateSerializer(TemplateSerializer): data = DictField(required=True) owner = UserSerializer(read_only=True) options = DictField(required=False) options_list = DictField(read_only=True) class Meta: model = models.Template fields = ( 'id', 'name', 'kind', 'owner', 'data', 'options', 'options_list', ) def execute(self, request): serializer = OneProjectSerializer(self.instance.project) return self.instance.execute( serializer, request.user, request.data.get('option', None) )
class OneHostSerializer(HostSerializer): owner = UserSerializer(read_only=True) vars = DictField(required=False) class Meta: model = models.Host fields = ( 'id', 'name', 'type', 'vars', 'owner', 'url', )
class OneTeamSerializer(TeamSerializer): users = UserSerializer(many=True, required=False) users_list = DictField(required=False) owner = UserSerializer(read_only=True) class Meta: model = models.UserGroup fields = ( 'id', "name", "users", "users_list", "owner", 'url', )
class OneInventorySerializer(InventorySerializer, _InventoryOperations): vars = DictField(required=False) all_hosts = HostSerializer(read_only=True, many=True) hosts = HostSerializer(read_only=True, many=True, source="hosts_list") groups = GroupSerializer(read_only=True, many=True, source="groups_list") owner = UserSerializer(read_only=True) class Meta: model = models.Inventory fields = ( 'id', 'name', 'hosts', 'all_hosts', "groups", 'vars', 'owner', 'url', )
class ProjectSerializer(_InventoryOperations): status = serializers.CharField(read_only=True) type = serializers.CharField(read_only=True) vars = DictField(required=False, write_only=True) class Meta: model = models.Project fields = ( 'id', 'name', 'status', 'type', 'vars', 'url', ) @transaction.atomic def _do_with_vars(self, *args, **kw): instance = super(ProjectSerializer, self)._do_with_vars(*args, **kw) return instance if instance.repo_class else None
class OneProjectSerializer(ProjectSerializer, _InventoryOperations): vars = DictField(required=False) hosts = HostSerializer(read_only=True, many=True) groups = GroupSerializer(read_only=True, many=True) inventories = InventorySerializer(read_only=True, many=True) owner = UserSerializer(read_only=True) class Meta: model = models.Project fields = ( 'id', 'name', 'status', 'repository', 'hosts', "groups", 'inventories', 'vars', 'owner', 'revision', 'branch', 'url', ) def inventories_operations(self, method, data): return self.get_operation(method, data, attr="inventories") @transaction.atomic() def sync(self): self.instance.start_repo_task("sync") data = dict(detail="Sync with {}.".format(self.instance.repository)) return APIResponse(data, 200) def _execution(self, kind, data, user): """ :param kind: playbook/module/script :param data: là data POST lên {"playbook":"testing.yml","script_remote_path":"/tmp/ping.sh","lang":"bash","limit":"pj-blog2","inventory":"2"} :param user: là object user, chạy theo permission :return: """ inventory = data.pop("inventory") try: # get object inventory from model inventory = Inventory.objects.get(id=int(inventory)) if not inventory.viewable_by(user): # nocv raise PermissionDenied( "You don't have permission to inventory.") except ValueError: pass # goi exec function cua model # kind: playbook/module/script # str(data.pop(kind))=*args: lấy giá trị trong data kind xóa giá trị đó trong data "playbook":"testing.yml" history_id = self.instance.execute(kind, str(data.pop(kind)), inventory, initiator=user.id, **data) rdata = dict(detail="Started at inventory {}.".format(inventory), history_id=history_id) return APIResponse(rdata, 201) def execute_playbook(self, request): return self._execution("playbook", dict(request.data), request.user) def execute_module(self, request): return self._execution("module", dict(request.data), request.user) #################################### AUTH: DONGVT ####################################### # serialize chạy ansible python client api def _execution_api(self, kind, user, data): """ :param kind: playbook/module/script :param user: là object user, chạy theo permission :param data: là data POST lên {"list-hosts":"","inventory":"1","module":"shell","group":"groupapi","args":"ifconfig"} :return: """ # lấy inventory từ request post lên inventory = data.pop("inventory") try: # get object inventory from model inventory = Inventory.objects.get(id=int(inventory)) # check permisioon if not inventory.viewable_by(user): # nocv raise PermissionDenied( "You don't have permission to inventory.") except ValueError: pass extra = { "data": data, "inventory": inventory, "sync": False, "user": user } #goi exec function cua model #kind: playbook/module/script #str(data.pop(kind))=*args: lấy giá trị trong data kind xóa giá trị đó trong data "playbook":"testing.yml" history_id = self.instance.execute_api(kind=kind, **extra) rdata = dict(detail="Started at inventory {}.".format(inventory), history_id=history_id) return APIResponse(rdata, 201) # chạy private function def execute_module_api(self, request): return self._execution_api("moduleapi", request.user, dict(request.data)) def execute_script(self, request): """ data request post len phai theo format :param request.data: {"id":"<id script>","script_remote_path": "/tmp/ping.sh","limit":"pj-blog2","inventory":"2"} xủ lý lấy thông tin để tạo request.data output xủ lý { "extra-vars":"name=testing script=/mto_automation/polemarch/projects/1/ping.sh script_remote_path=/tmp/ping.sh lang=bash","limit":"pj-blog2","playbook":"init.yml","inventory":"2"} :return: về phương thức private _execution """ data = {} try: script_id = dict(request.data)["id"] # get object script from model scriptobj = Script.objects.get(id=int(script_id)) except: raise main_exceptions.PMException("{id} not in correct") data["extra-vars"] = "name=" + scriptobj.name + " script=" + scriptobj.script + " script_remote_path=" + dict(request.data)["script_remote_path"] + \ " lang=" + scriptobj.lang data["limit"] = request.data["limit"] data["inventory"] = request.data["inventory"] data["playbook"] = "init.yml" # tra ve phuong thuc private execut kind, data, user return self._execution("playbook", dict(data), request.user)