class CreateUserSerializer(OneUserSerializer): password = vst_fields.VSTCharField(write_only=True) password2 = vst_fields.VSTCharField(write_only=True, label='Repeat password') class Meta(OneUserSerializer.Meta): fields = list(OneUserSerializer.Meta.fields) + ['password', 'password2'] def run_validation(self, data=serializers.empty): validated_data = super(CreateUserSerializer, self).run_validation(data) if validated_data['password'] != validated_data.pop('password2', None): raise exceptions.ValidationError('Passwords do not match.') return validated_data
class ProjectCreateMasterSerializer(vst_serializers.VSTSerializer): types = list_to_choices(models.Project.repo_handlers.keys()) auth_types = list_to_choices(['NONE', 'KEY', 'PASSWORD']) status = vst_fields.VSTCharField(read_only=True) type = serializers.ChoiceField(choices=types, default='MANUAL', label='Repo type') repository = vst_fields.VSTCharField(default='MANUAL', label='Repo url') repo_auth = serializers.ChoiceField(choices=auth_types, default='NONE', label='Repo auth type', write_only=True) auth_data = vst_fields.DependEnumField(allow_blank=True, write_only=True, default='', field='repo_auth', label='Repo auth data', types={ 'KEY': 'secretfile', 'PASSWORD': '******', 'NONE': 'disabled' }) class Meta: model = models.Project fields = ( 'id', 'name', 'status', 'type', 'repository', 'repo_auth', 'auth_data', ) extra_kwargs = {'name': {'required': True}} def create(self, validated_data): repo_type = validated_data.pop('type') repo_auth_type = validated_data.pop('repo_auth') repo_auth_data = validated_data.pop('auth_data') instance = super(ProjectCreateMasterSerializer, self).create(validated_data) instance.variables.create(key='repo_type', value=repo_type) if repo_auth_type != 'NONE': # nocv key = 'repo_{}'.format(repo_auth_type.lower()) instance.variables.create(key=key, value=repo_auth_data) return instance
class ProjectSerializer(_InventoryOperations): status = vst_fields.VSTCharField(read_only=True) type = vst_fields.VSTCharField(read_only=True) class Meta: model = models.Project fields = ( 'id', 'name', 'type', 'status', ) @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 OnePlaybookSerializer(PlaybookSerializer): playbook = vst_fields.VSTCharField(read_only=True) class Meta: model = models.Task fields = ('id', 'name', 'playbook',)
class InventoryImportSerializer(serializers.Serializer): # pylint: disable=abstract-method inventory_id = vst_fields.RedirectIntegerField(default=None, allow_null=True, read_only=True) name = serializers.CharField(required=True) raw_data = vst_fields.VSTCharField() def create(self, validated_data: Dict) -> Dict: return models.Inventory.import_inventory_from_string(**validated_data) def to_representation(self, instance): return dict(inventory_id=instance.id, name=instance.name, raw_data=getattr(instance, 'raw_data', ''))
class InventoryImportSerializer(DataSerializer): inventory_id = vst_fields.RedirectIntegerField(default=None, allow_null=True) name = serializers.CharField(required=True) raw_data = vst_fields.VSTCharField() @transaction.atomic() def create(self, validated_data: Dict) -> Dict: parser = AnsibleInventoryParser() inv_json = parser.get_inventory_data(validated_data['raw_data']) inventory = models.Inventory.objects.create( name=validated_data['name']) inventory.vars = inv_json['vars'] created_hosts, created_groups = dict(), dict() for host in inv_json['hosts']: inv_host = inventory.hosts.create(name=host['name']) inv_host.vars = host['vars'] created_hosts[inv_host.name] = inv_host for group in inv_json['groups']: children = not len(group['groups']) == 0 inv_group = inventory.groups.create(name=group['name'], children=children) inv_group.vars = group['vars'] created_groups[inv_group.name] = inv_group for group in inv_json['groups']: inv_group = created_groups[group['name']] g_subs = list() if inv_group.children: for name in group['groups']: g_subs.append(created_groups[name]) inv_group.groups.add(*g_subs) else: for name in group['hosts']: g_subs.append(created_hosts[name]) inv_group.hosts.add(*g_subs) inventory.raw_data = validated_data['raw_data'] return inventory def to_representation(self, instance): return dict(inventory_id=instance.id, name=instance.name, raw_data=getattr(instance, 'raw_data', ''))
class InventoryFileImportSerializer(InventoryImportSerializer): name = serializers.CharField(required=True, validators=[path_validator]) raw_data = vst_fields.VSTCharField(read_only=True) def update(self, instance, validated_data: Dict) -> Dict: inventory_path = Path(instance.path) / Path(validated_data['name']) inventory, _ = instance.slave_inventory.get_or_create( name=inventory_path.stem) inventory.variables.update_or_create(key='inventory_extension', value=inventory_path.suffix, hidden=True) inventory.import_inventory_from_string( raw_data=inventory_path.read_text(), master_project=instance, inventory_instance=inventory, **validated_data) return inventory
class ActionResponseSerializer(DataSerializer, EmptySerializer): detail = vst_fields.VSTCharField()
class OneProjectSerializer(ProjectSerializer, _InventoryOperations): repository = vst_fields.VSTCharField(default='MANUAL') owner = UserSerializer(read_only=True) notes = vst_fields.TextareaField(required=False, allow_blank=True) readme_content = vst_fields.HtmlField(read_only=True, label='Information') execute_view_data = vst_serializers.DataSerializer(read_only=True, allow_null=True) class Meta: model = models.Project fields = ( 'id', 'name', 'repository', 'status', 'revision', 'branch', 'owner', 'notes', 'readme_content', 'execute_view_data', ) @transaction.atomic() def sync(self) -> Response: self.instance.start_repo_task("sync") serializer = ActionResponseSerializer(data=dict( detail="Sync with {}.".format(self.instance.repository))) serializer.is_valid(True) return Response(serializer.data, status.HTTP_200_OK) def _get_ansible_serializer(self, kind: str) -> serializers.Serializer: view = self.context['view'] exec_method = getattr(view, 'execute_{}'.format(kind), None) if exec_method is None: # nocv raise Exception('Unknown kind') serializer_class = exec_method.kwargs['serializer_class'] serializer = serializer_class(context=self.context) serializer.project = self.instance return serializer def _execution(self, kind: str, data: Dict, user: User, **kwargs) -> Response: template = data.pop("template", None) inventory = data.get("inventory", None) msg = "Started in the inventory {}.".format( inventory if inventory else 'specified in the project configuration.') if template is not None: init_type = "template" obj_id = template msg = 'Start template [id={}].'.format(template) else: init_type = "project" obj_id = self.instance.id serializer = self._get_ansible_serializer(kind.lower()) data = { k: v for k, v in serializer.to_internal_value(data).items() if k in data.keys() or v } target = data.pop(kind) try: target = str(target) except UnicodeEncodeError: # nocv target = target.encode('utf-8') history_id = self.instance.execute(kind, str(target), initiator=obj_id, initiator_type=init_type, executor=user, **data) rdata = ExecuteResponseSerializer( data=dict(detail=msg, history_id=history_id, executor=user.id)) rdata.is_valid(raise_exception=True) return Response(rdata.data, status.HTTP_201_CREATED) def execute_playbook(self, request) -> Response: return self._execution("playbook", dict(request.data), request.user) def execute_module(self, request) -> Response: return self._execution("module", dict(request.data), request.user)
class ProjectCreateMasterSerializer(vst_serializers.VSTSerializer, _WithPermissionsSerializer): types = models.list_to_choices(models.Project.repo_handlers.keys()) auth_types = ['NONE', 'KEY', 'PASSWORD'] branch_auth_types = { t: "hidden" for t in models.Project.repo_handlers.keys() } branch_auth_types['GIT'] = 'string' branch_types = dict(**branch_auth_types) branch_types['TAR'] = 'string' status = vst_fields.VSTCharField(read_only=True) type = serializers.ChoiceField(choices=types, default='MANUAL', label='Repo type') repository = vst_fields.VSTCharField(default='MANUAL', label='Repo url') repo_auth = vst_fields.DependEnumField(default='NONE', field='type', choices={"GIT": auth_types}, types=branch_auth_types, label='Repo auth type', write_only=True) auth_data = vst_fields.DependEnumField(allow_blank=True, write_only=True, default='', field='repo_auth', label='Repo auth data', types={ 'KEY': 'secretfile', 'PASSWORD': '******', 'NONE': 'hidden' }) branch = vst_fields.DependEnumField( allow_blank=True, required=False, allow_null=True, label='Branch for GIT(branch/tag/SHA) or TAR(subdir)', field='type', types=branch_types) class Meta: model = models.Project fields = ( 'id', 'name', 'status', 'type', 'repository', 'repo_auth', 'auth_data', 'branch', ) extra_kwargs = {'name': {'required': True}} def create(self, validated_data: Dict) -> models.Project: repo_type = validated_data.pop('type') repo_auth_type = validated_data.pop('repo_auth') repo_auth_data = validated_data.pop('auth_data') repo_branch = validated_data.pop('branch', None) instance = super(ProjectCreateMasterSerializer, self).create(validated_data) instance.variables.create(key='repo_type', value=repo_type) if repo_auth_type != 'NONE': # nocv key = 'repo_{}'.format(repo_auth_type.lower()) instance.variables.create(key=key, value=repo_auth_data) if repo_branch: # nocv instance.variables.create(key='repo_branch', value=repo_branch) return instance
class TemplateExecSerializer(DataSerializer): option = vst_fields.VSTCharField( help_text='Option name from template options.', min_length=0, allow_blank=True, required=False)
class OneProjectSerializer(ProjectSerializer, _InventoryOperations): repository = vst_fields.VSTCharField(default='MANUAL') owner = UserSerializer(read_only=True) notes = vst_fields.TextareaField(required=False, allow_blank=True) readme_content = vst_fields.HtmlField(read_only=True, label='Information') execute_view_data = vst_serializers.DataSerializer(read_only=True, allow_null=True) class Meta: model = models.Project fields = ( 'id', 'name', 'repository', 'status', 'revision', 'branch', 'owner', 'notes', 'readme_content', 'execute_view_data', ) @transaction.atomic() def sync(self): self.instance.start_repo_task("sync") serializer = ActionResponseSerializer(data=dict( detail="Sync with {}.".format(self.instance.repository))) serializer.is_valid(True) return Response(serializer.data, status.HTTP_200_OK) def _get_execution_inventory(self, template, inventory, user): if template or inventory is None: return inventory try: inventory = Inventory.objects.get(id=int(inventory)) if not inventory.acl_handler.viewable_by(user): # nocv raise PermissionDenied( "You don't have permission to inventory.") except ValueError: pass return inventory def _execution(self, kind, data, user, **kwargs): template = kwargs.pop("template", None) inventory = self._get_execution_inventory(template, data.pop("inventory", None), user) msg = "Started in the inventory {}.".format( inventory if inventory else 'specified in the project configuration.') if template is not None: init_type = "template" obj_id = template data['template_option'] = kwargs.get('template_option', None) msg = 'Start template [id={}].'.format(template) else: init_type = "project" obj_id = self.instance.id if kind.lower() == 'module': serializer = AnsibleModuleSerializer() elif kind.lower() == 'playbook': serializer = AnsiblePlaybookSerializer() else: # nocv raise Exception('Unknown kind') data = { k: v for k, v in serializer.to_internal_value(data).items() if k in data.keys() or v } history_id = self.instance.execute(kind, str(data.pop(kind)), inventory, initiator=obj_id, initiator_type=init_type, executor=user, **data) rdata = ExecuteResponseSerializer( data=dict(detail=msg, history_id=history_id, executor=user.id)) rdata.is_valid(raise_exception=True) return Response(rdata.data, status.HTTP_201_CREATED) 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)