def put(self, blueprint_id, **kwargs):
     """
     Upload a blueprint (id specified)
     """
     rest_utils.validate_inputs({'blueprint_id': blueprint_id})
     visibility = rest_utils.get_visibility_parameter(
         optional=True,
         is_argument=True,
         valid_values=VisibilityState.STATES)
     # Fail fast if trying to upload a duplicate blueprint
     current_tenant = request.headers.get('tenant')
     if visibility == VisibilityState.GLOBAL:
         existing_duplicates = get_storage_manager().list(
             models.Blueprint, filters={'id': blueprint_id})
         if existing_duplicates:
             raise IllegalActionError(
                 "Can't set or create the resource `{0}`, it's visibility "
                 "can't be global because it also exists in other "
                 "tenants".format(blueprint_id))
     else:
         existing_duplicates = get_storage_manager().list(models.Blueprint,
                                                          filters={
                                                              'id':
                                                              blueprint_id,
                                                              'tenant_name':
                                                              current_tenant
                                                          })
         if existing_duplicates:
             raise ConflictError(
                 'blueprint with id={0} already exists on tenant {1} or '
                 'with global visibility'.format(blueprint_id,
                                                 current_tenant))
     return UploadedBlueprintsManager().\
         receive_uploaded_data(data_id=blueprint_id,
                               visibility=visibility)
Exemple #2
0
    def put(self, blueprint_id, **kwargs):
        """
        Upload a blueprint (id specified)
        """
        rest_utils.validate_inputs({'blueprint_id': blueprint_id})
        args = get_args_and_verify_arguments([
            Argument('async_upload', type=boolean, default=False),
            Argument('labels')
        ])
        async_upload = args.async_upload
        visibility = rest_utils.get_visibility_parameter(
            optional=True,
            is_argument=True,
            valid_values=VisibilityState.STATES)
        labels = self._get_labels_from_args(args)
        # Fail fast if trying to upload a duplicate blueprint.
        # Allow overriding an existing blueprint which failed to upload
        current_tenant = request.headers.get('tenant')
        override_failed = False

        if visibility == VisibilityState.GLOBAL:
            existing_duplicates = get_storage_manager().list(
                models.Blueprint, filters={'id': blueprint_id})
            if existing_duplicates:
                if existing_duplicates[0].state in \
                        BlueprintUploadState.FAILED_STATES:
                    override_failed = True
                else:
                    raise IllegalActionError(
                        "Can't set or create the resource `{0}`, it's "
                        "visibility can't be global because it also exists in "
                        "other tenants".format(blueprint_id))
        else:
            existing_duplicates = get_storage_manager().list(models.Blueprint,
                                                             filters={
                                                                 'id':
                                                                 blueprint_id,
                                                                 'tenant_name':
                                                                 current_tenant
                                                             })
            if existing_duplicates:
                if existing_duplicates[0].state in \
                        BlueprintUploadState.FAILED_STATES:
                    override_failed = True
                else:
                    raise ConflictError(
                        'blueprint with id={0} already exists on tenant {1} '
                        'or with global visibility'.format(
                            blueprint_id, current_tenant))
        response = UploadedBlueprintsManager().\
            receive_uploaded_data(data_id=blueprint_id,
                                  visibility=visibility,
                                  override_failed=override_failed,
                                  labels=labels)
        if not async_upload:
            sm = get_storage_manager()
            blueprint, _ = response
            response = rest_utils.get_uploaded_blueprint(sm, blueprint)
        return response
Exemple #3
0
 def patch(self, key):
     """
     Update an existing secret
     """
     rest_utils.validate_inputs({'key': key})
     if not request.json:
         raise IllegalActionError('Update a secret request must include at '
                                  'least one parameter to update')
     secret = get_storage_manager().get(models.Secret, key)
     self._validate_secret_modification_permitted(secret)
     self._update_is_hidden_value(secret)
     self._update_visibility(secret)
     self._update_value(secret)
     secret.updated_at = utils.get_formatted_timestamp()
     return get_storage_manager().update(secret)
 def _validate_plugins_update_state(plugins_update):
     if plugins_update.state != STATES.EXECUTING_WORKFLOW:
         raise IllegalActionError("Cannot finalize plugins update {0}, "
                                  "it's not in the {1} state.".format(
                                      plugins_update.id,
                                      STATES.EXECUTING_WORKFLOW))
Exemple #5
0
    def patch(self, blueprint_id, **kwargs):
        """
        Update a blueprint.

        Used for updating the blueprint's state (and error) while uploading,
        and updating the blueprint's other attributes upon a successful upload.
        This method is for internal use only.
        """
        if not request.json:
            raise IllegalActionError('Update a blueprint request must include '
                                     'at least one parameter to update')

        request_schema = {
            'plan': {
                'type': dict,
                'optional': True
            },
            'description': {
                'type': text_type,
                'optional': True
            },
            'main_file_name': {
                'type': text_type,
                'optional': True
            },
            'visibility': {
                'type': text_type,
                'optional': True
            },
            'state': {
                'type': text_type,
                'optional': True
            },
            'error': {
                'type': text_type,
                'optional': True
            },
            'error_traceback': {
                'type': text_type,
                'optional': True
            },
            'labels': {
                'type': list,
                'optional': True
            }
        }
        request_dict = rest_utils.get_json_and_verify_params(request_schema)

        invalid_params = set(request_dict.keys()) - set(request_schema.keys())
        if invalid_params:
            raise BadParametersError("Unknown parameters: {}".format(
                ','.join(invalid_params)))
        sm = get_storage_manager()
        rm = get_resource_manager()
        blueprint = sm.get(models.Blueprint, blueprint_id)

        # if finished blueprint validation - cleanup DB entry
        # and uploaded blueprints folder
        if blueprint.state == BlueprintUploadState.VALIDATING:
            uploaded_blueprint_path = join(
                config.instance.file_server_root,
                FILE_SERVER_UPLOADED_BLUEPRINTS_FOLDER, blueprint.tenant.name,
                blueprint.id)
            remove(uploaded_blueprint_path)
            sm.delete(blueprint)
            return blueprint

        # set blueprint visibility
        visibility = request_dict.get('visibility')
        if visibility:
            if visibility not in VisibilityState.STATES:
                raise BadParametersError(
                    "Invalid visibility: `{0}`. Valid visibility's values "
                    "are: {1}".format(visibility, VisibilityState.STATES))
            blueprint.visibility = visibility

        # set other blueprint attributes.
        if 'plan' in request_dict:
            blueprint.plan = request_dict['plan']
        if 'description' in request_dict:
            blueprint.description = request_dict['description']
        if 'main_file_name' in request_dict:
            blueprint.main_file_name = request_dict['main_file_name']
        provided_labels = request_dict.get('labels')

        if request_dict.get('plan'):
            dsl_labels = request_dict['plan'].get('labels', {})
            csys_obj_parents = dsl_labels.get('csys-obj-parent')
            if csys_obj_parents:
                dep_parents = csys_obj_parents['values']
                missing_parents = rm.get_missing_deployment_parents(
                    dep_parents)
                if missing_parents:
                    raise DeploymentParentNotFound(
                        'Blueprint {0}: is referencing deployments'
                        ' using label `csys-obj-parent` that does not exist, '
                        'make sure that deployment(s) {1} exist before '
                        'creating blueprint'.format(blueprint.id,
                                                    ','.join(missing_parents)))
        # set blueprint state
        state = request_dict.get('state')
        if state:
            if state not in BlueprintUploadState.STATES:
                raise BadParametersError(
                    "Invalid state: `{0}`. Valid blueprint state values are: "
                    "{1}".format(state, BlueprintUploadState.STATES))
            if (state != BlueprintUploadState.UPLOADED
                    and provided_labels is not None):
                raise ConflictError(
                    'Blueprint labels can be created only if the provided '
                    'blueprint state is {0}'.format(
                        BlueprintUploadState.UPLOADED))

            blueprint.state = state
            blueprint.error = request_dict.get('error')
            blueprint.error_traceback = request_dict.get('error_traceback')

            # On finalizing the blueprint upload, extract archive to file
            # server
            if state == BlueprintUploadState.UPLOADED:
                UploadedBlueprintsManager(). \
                    extract_blueprint_archive_to_file_server(
                        blueprint_id=blueprint_id,
                        tenant=blueprint.tenant.name)
                _create_blueprint_labels(blueprint, provided_labels)

            # If failed for any reason, cleanup the blueprint archive from
            # server
            elif state in BlueprintUploadState.FAILED_STATES:
                UploadedBlueprintsManager(). \
                    cleanup_blueprint_archive_from_file_server(
                        blueprint_id=blueprint_id,
                        tenant=blueprint.tenant.name)
        else:  # Updating the blueprint not as part of the upload process
            if provided_labels is not None:
                if blueprint.state != BlueprintUploadState.UPLOADED:
                    raise ConflictError(
                        'Blueprint labels can only be updated if the blueprint'
                        ' was uploaded successfully')

                rm = get_resource_manager()
                labels_list = rest_utils.get_labels_list(provided_labels)
                rm.update_resource_labels(models.BlueprintLabel, blueprint,
                                          labels_list)

        blueprint.updated_at = get_formatted_timestamp()
        return sm.update(blueprint)