def task_generator(action, selector): log.debug("call task_generator: %s", action) try: service = Prototype.objects.get(bundle=action.prototype.bundle, type='service', name='ZOOKEEPER', version='1.2') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'service ZOOKEEPER not found') try: stop = Action.objects.get(prototype=service, name='stop') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'action stop of service ZOOKEEPER not found') try: start = Action.objects.get(prototype=service, name='start') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'action start of service ZOOKEEPER not found') return ( { 'action': stop, 'selector': selector }, { 'action': start, 'selector': selector }, )
def check_sub(sub_key, sub_type, item): if sub_key not in item: msg = '"{}" sub-field of hostcomponent is required' raise AdcmEx('INVALID_INPUT', msg.format(sub_key)) if not isinstance(item[sub_key], sub_type): msg = '"{}" sub-field of hostcomponent should be "{}"' raise AdcmEx('INVALID_INPUT', msg.format(sub_key, sub_type))
def validate_hc(self, hc): if not hc: raise AdcmEx('INVALID_INPUT', 'hc field is required') if not isinstance(hc, list): raise AdcmEx('INVALID_INPUT', 'hc field should be a list') for item in hc: for key in ('component_id', 'host_id', 'service_id'): if key not in item: msg = '"{}" sub-field is required' raise AdcmEx('INVALID_INPUT', msg.format(key)) return hc
def get_obj_conf(cluster_id, service_id): cluster = check_obj(Cluster, cluster_id) if service_id: co = check_obj(ClusterObject, {'cluster': cluster, 'id': service_id}) obj = co else: obj = cluster if not obj: raise AdcmEx('CONFIG_NOT_FOUND', "this object has no config") if not obj.config: raise AdcmEx('CONFIG_NOT_FOUND', "this object has no config") return obj
def check_hc(cluster, hc_in): # pylint: disable=too-many-branches def check_sub(sub_key, sub_type, item): if sub_key not in item: msg = '"{}" sub-field of hostcomponent is required' raise AdcmEx('INVALID_INPUT', msg.format(sub_key)) if not isinstance(item[sub_key], sub_type): msg = '"{}" sub-field of hostcomponent should be "{}"' raise AdcmEx('INVALID_INPUT', msg.format(sub_key, sub_type)) seen = {} if not isinstance(hc_in, list): raise AdcmEx('INVALID_INPUT', 'hostcomponent should be array') for item in hc_in: for sub_key, sub_type in (('service_id', int), ('host_id', int), ('component_id', int)): check_sub(sub_key, sub_type, item) key = (item.get('service_id', ''), item.get('host_id', ''), item.get('component_id', '')) if key not in seen: seen[key] = 1 else: msg = 'duplicate ({}) in host service list' raise AdcmEx('INVALID_INPUT', msg.format(item)) host_comp_list = [] for item in hc_in: host = Host.obj.get(id=item['host_id']) service = ClusterObject.obj.get(id=item['service_id'], cluster=cluster) comp = ServiceComponent.obj.get(id=item['component_id'], cluster=cluster, service=service) if not host.cluster: msg = f'host #{host.id} {host.fqdn} does not belong to any cluster' raise AdcmEx("FOREIGN_HOST", msg) if host.cluster.id != cluster.id: msg = 'host {} (cluster #{}) does not belong to cluster #{}' raise AdcmEx("FOREIGN_HOST", msg.format(host.fqdn, host.cluster.id, cluster.id)) host_comp_list.append((service, host, comp)) for service in ClusterObject.objects.filter(cluster=cluster): cm.issue.check_component_constraint( service, [i for i in host_comp_list if i[0] == service]) cm.issue.check_component_requires(host_comp_list) cm.issue.check_bound_components(host_comp_list) return host_comp_list
def create(self, validated_data): try: cluster = check_obj(Cluster, self.context.get('cluster_id')) prototype = check_obj(Prototype, validated_data['prototype_id']) return add_service_to_cluster(cluster, prototype) except IntegrityError: raise AdcmEx('SERVICE_CONFLICT') from None
def task_get(action, selector): log.debug("call task: %s", action) try: service = Prototype.objects.get(type='service', name='Simple_service') except Prototype.DoesNotExist: raise AdcmEx('TASK_GET_ERR', 'my error description') from None try: stop = Action.object.get(context='service', context_id=service.id, name='stop') except Prototype.DoesNotExist: raise AdcmEx( 'TASK_GENERATOR_ERROR', 'action stop in service Simple_service not found') from None return {'action': stop, 'selector': selector}
def create_host(host, cluster): """ Creating Host object :param host: Host object in dictionary format :type host: dict :param cluster: Cluster object :type cluster: models.Cluster :return: Host object :rtype: models.Host """ host.pop('provider') provider = HostProvider.objects.get(name=host.pop('provider__name')) try: Host.objects.get(fqdn=host['fqdn']) provider.delete() cluster.delete() raise AdcmEx('HOST_CONFLICT', 'Host fqdn already in use') except Host.DoesNotExist: prototype = get_prototype(bundle_hash=host.pop('bundle_hash'), type='host') ex_id = host.pop('id') config = host.pop('config') new_host = Host.objects.create( prototype=prototype, provider=provider, config=create_config(config), cluster=cluster, **host, ) create_file_from_config(new_host, config) return ex_id, new_host
def load(file_path): """ Loading and creating objects from JSON file :param file_path: Path to JSON file :type file_path: str """ try: with open(file_path, 'r', encoding='utf_8') as f: data = json.load(f) except FileNotFoundError as err: raise AdcmEx('DUMP_LOAD_CLUSTER_ERROR', msg='Loaded file not found') from err check(data) _, cluster = create_cluster(data['cluster']) ex_provider_ids = {} for provider_data in data['providers']: ex_provider_id, provider = create_provider(provider_data) ex_provider_ids[ex_provider_id] = provider ex_host_ids = {} for host_data in data['hosts']: ex_host_id, host = create_host(host_data, cluster) ex_host_ids[ex_host_id] = host ex_service_ids = {} for service_data in data['services']: ex_service_id, service = create_service(service_data, cluster) ex_service_ids[ex_service_id] = service ex_component_ids = {} for component_data in data['components']: ex_component_id, component = create_component( component_data, cluster, ex_service_ids[component_data.pop('service')]) ex_component_ids[ex_component_id] = component for host_component_data in data['host_components']: create_host_component( host_component_data, cluster, ex_host_ids[host_component_data.pop('host')], ex_service_ids[host_component_data.pop('service')], ex_component_ids[host_component_data.pop('component')], ) for group_data in data['groups']: if group_data['model_name'] == 'cluster': obj = cluster elif group_data['model_name'] == 'clusterobject': obj = ex_service_ids[group_data['object_id']] elif group_data['model_name'] == 'servicecomponent': obj = ex_component_ids[group_data['object_id']] elif group_data['model_name'] == 'hostprovider': obj = ex_provider_ids[group_data['object_id']] create_group(group_data, ex_host_ids, obj)
def create(self, validated_data): provider = check_obj(HostProvider, self.context.get('provider_id')) proto = Prototype.obj.get(bundle=provider.prototype.bundle, type='host') try: return cm.api.add_host(proto, provider, validated_data.get('fqdn'), validated_data.get('description', '')) except IntegrityError: raise AdcmEx("HOST_CONFLICT", "duplicate host") from None
def create(self, validated_data): try: return cm.api.add_cluster( validated_data.get('prototype_id'), validated_data.get('name'), validated_data.get('description', ''), ) except IntegrityError: raise AdcmEx("CLUSTER_CONFLICT") from None
def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.description = validated_data.get('description', instance.description) try: instance.save() except IntegrityError: msg = f'cluster with name "{instance.name}" already exists' raise AdcmEx("CLUSTER_CONFLICT", msg) from None return instance
def get(self, request, job_id, log_id): job = JobLog.obj.get(id=job_id) try: log_storage = LogStorage.objects.get(id=log_id, job=job) except LogStorage.DoesNotExist: raise AdcmEx('LOG_NOT_FOUND', f'log {log_id} not found for job {job_id}') from None serializer = self.serializer_class(log_storage, context={'request': request}) return Response(serializer.data)
def create(self, validated_data): try: return cm.api.add_host( validated_data.get('prototype_id'), validated_data.get('provider_id'), validated_data.get('fqdn'), validated_data.get('description', ''), ) except IntegrityError: raise AdcmEx("HOST_CONFLICT", "duplicate host") from None
def from_db_value(self, value, expression, connection): if value is not None: try: return json.loads(value) except json.JSONDecodeError: raise AdcmEx( 'JSON_DB_ERROR', msg=f"Not correct field format '{expression.field.attname}'" ) from None return value
def _get_ansible_content(self, obj): path_file = os.path.join( config.RUN_DIR, f'{obj.job.id}', f'{obj.name}-{obj.type}.{obj.format}' ) try: with open(path_file, 'r', encoding='utf_8') as f: content = f.read() except FileNotFoundError: msg = f'File "{obj.name}-{obj.type}.{obj.format}" not found' raise AdcmEx('LOG_NOT_FOUND', msg) from None return content
def get_page(self, obj, request, context=None): if not context: context = {} context['request'] = request count = obj.count() serializer_class = self.select_serializer(request) if 'fields' in request.query_params or 'distinct' in request.query_params: serializer_class = None try: fields = getlist_from_querydict(request.query_params, 'fields') distinct = int(request.query_params.get('distinct', 0)) if fields and distinct: obj = obj.values(*fields).distinct() elif fields: obj = obj.values(*fields) except (FieldError, ValueError): qp = ','.join([ f'{k}={v}' for k, v in request.query_params.items() if k in ['fields', 'distinct'] ]) msg = f'Bad query params: {qp}' raise AdcmEx('BAD_QUERY_PARAMS', msg=msg) from None page = self.paginate_queryset(obj) if self.is_paged(request): if serializer_class is not None: serializer = serializer_class(page, many=True, context=context) page = serializer.data return self.get_paginated_response(page) if count <= REST_FRAMEWORK['PAGE_SIZE']: if serializer_class is not None: serializer = serializer_class(obj, many=True, context=context) obj = serializer.data return Response(obj) msg = 'Response is too long, use paginated request' raise AdcmEx('TOO_LONG', msg=msg, args=self.get_paged_link())
def run(self, tmp=None, task_vars=None): super().run(tmp, task_vars) if task_vars is not None and 'job' in task_vars or 'id' in task_vars['job']: job_id = task_vars['job']['id'] name = self._task.args.get('name') log_format = self._task.args.get('format') path = self._task.args.get('path') content = self._task.args.get('content') if not name and log_format and (path or content): return { "failed": True, "msg": "name, format and path or content are mandatory args of adcm_custom_log", } try: if path is None: log.debug( 'ansible adcm_custom_log: %s, %s, %s, %s', job_id, name, log_format, content ) log_custom(job_id, name, log_format, content) else: log.debug('ansible adcm_custom_log: %s, %s, %s, %s', job_id, name, log_format, path) slurp_return = self._execute_module( module_name='slurp', module_args={'src': path}, task_vars=task_vars, tmp=tmp ) try: body = base64.standard_b64decode(slurp_return['content']).decode() except Error as error: raise AdcmEx('UNKNOWN_ERROR', msg='Error b64decode for slurp module') from error except UnicodeDecodeError as error: raise AdcmEx( 'UNKNOWN_ERROR', msg='Error UnicodeDecodeError for slurp module' ) from error log_custom(job_id, name, log_format, body) except AdcmEx as e: return {"failed": True, "msg": f"{e.code}: {e.msg}"} return {"failed": False, "changed": False}
def is_valid(self): object_type = self.request.query_params.get('object_type') object_id = self.request.query_params.get('object_id') both_present = all((object_id, object_type)) none_present = not any((object_id, object_type)) if not (both_present or none_present): raise AdcmEx( 'BAD_QUERY_PARAMS', msg= 'Both object_type and object_id params are expected or none of them', ) return super().is_valid()
def check(data): """ Checking cluster load :param data: Data from file :type data: dict """ if settings.ADCM_VERSION != data['ADCM_VERSION']: raise AdcmEx( 'DUMP_LOAD_ADCM_VERSION_ERROR', msg= (f'ADCM versions do not match, dump version: {data["ADCM_VERSION"]},' f' load version: {settings.ADCM_VERSION}'), ) for bundle_hash, bundle in data['bundles'].items(): try: Bundle.objects.get(hash=bundle_hash) except Bundle.DoesNotExist as err: raise AdcmEx( 'DUMP_LOAD_BUNDLE_ERROR', msg=f'Bundle "{bundle["name"]} {bundle["version"]}" not found', ) from err
def task_generator(action, selector): log.debug("call task_generator: %s", action) try: service = Prototype.objects.get(type='service', name='Simple_service', version='new_version') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'service Simple_service not found') from None try: stop = Action.objects.get(context='service', context_id=service.id, name='stop') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'action stop of service ZOOKEEPER not found') from None try: start = Action.objects.get(context='service', context_id=service.id, name='start') except Prototype.DoesNotExist: raise AdcmEx('TASK_GENERATOR_ERROR', 'action start of service ZOOKEEPER not found') from None return ( { 'action': stop, 'selector': selector }, { 'action': start, 'selector': selector }, )
def check_value_unselected_field(cc, nc, gk, spec, obj): """ Check value unselected field :param cc: Current config :param nc: New config :param gk: group_keys from attr :param spec: Config specification :param obj: Parent object (Cluster, Service, Component Provider or Host) """ for k, v in gk.items(): if isinstance(v, Mapping): check_value_unselected_field(cc[k], nc[k], gk[k], spec[k]['fields'], obj) else: is_read_only_list_or_map = ( config_is_ro(obj, k, spec[k]['limits']) and spec[k]['type'] in ['list', 'map'] ) if not is_read_only_list_or_map: if not v and k in cc and k in nc and cc[k] != nc[k]: raise AdcmEx('GROUP_CONFIG_CHANGE_UNSELECTED_FIELD')
def create_cluster(cluster): """ Creating Cluster object :param cluster: Cluster object in dictionary format :type cluster: dict :return: Cluster object :rtype: models.Cluster """ try: Cluster.objects.get(name=cluster['name']) raise AdcmEx('CLUSTER_CONFLICT', 'Cluster with the same name already exist') except Cluster.DoesNotExist: prototype = get_prototype(bundle_hash=cluster.pop('bundle_hash'), type='cluster') ex_id = cluster.pop('id') config = cluster.pop('config') cluster = Cluster.objects.create(prototype=prototype, config=create_config(config), **cluster) create_file_from_config(cluster, config) return ex_id, cluster
def check_host(host, cluster): if host.cluster != cluster: msg = f"Host #{host.id} doesn't belong to cluster #{cluster.id}" raise AdcmEx('FOREIGN_HOST', msg)
def validate_id(self, value): if self.context['group_config'].hosts.filter(id=value.id): raise AdcmEx('GROUP_CONFIG_HOST_EXISTS') return value
def check_object_type(type_name): """Object type checking""" if type_name not in ['cluster', 'service', 'component', 'provider']: raise AdcmEx('GROUP_CONFIG_TYPE_ERROR')
def check_obj(self, kw_req): try: return self.get_queryset().get(**kw_req) except ObjectDoesNotExist: raise AdcmEx(self.error_code) from None