def test_successful_plugin_import_resolver(self):
        self.upload_plugin(TEST_PACKAGE_NAME, TEST_PACKAGE_VERSION,
                           TEST_PACKAGE_YAML_FILE)

        dsl_location = os.path.join(self.get_blueprint_path('mock_blueprint'),
                                    'blueprint_with_plugin_import.yaml')

        tasks.parse_dsl(dsl_location=dsl_location,
                        resources_base_path=self.tmpdir,
                        resolver=self.resolver)
    def test_successful_plugin_import_resolver(self):
        self.upload_plugin(TEST_PACKAGE_NAME,
                           TEST_PACKAGE_VERSION,
                           TEST_PACKAGE_YAML_FILE)

        dsl_location = os.path.join(
            self.get_blueprint_path('mock_blueprint'),
            'blueprint_with_plugin_import.yaml')

        tasks.parse_dsl(dsl_location=dsl_location,
                        resources_base_path=self.tmpdir,
                        resolver=self.resolver)
예제 #3
0
 def publish_blueprint(self, dsl_location, alias_mapping_url,
                       resources_base_url, blueprint_id):
     # TODO: error code if parsing fails (in one of the 2 tasks)
     try:
         plan = tasks.parse_dsl(dsl_location, alias_mapping_url,
                                resources_base_url)
     except Exception, ex:
         raise DslParseException(*ex.args)
 def publish_blueprint(self, dsl_location, alias_mapping_url,
                       resources_base_url, blueprint_id):
     # TODO: error code if parsing fails (in one of the 2 tasks)
     try:
         plan = tasks.parse_dsl(dsl_location, alias_mapping_url,
                                resources_base_url)
     except Exception, ex:
         raise DslParseException(*ex.args)
 def publish_blueprint(self, application_dir, application_file_name,
                       resources_base, blueprint_id):
     application_file = os.path.join(application_dir, application_file_name)
     dsl_location = '{0}{1}'.format(resources_base, application_file)
     try:
         plan = tasks.parse_dsl(dsl_location, resources_base,
                                **self._get_parser_context())
     except Exception, ex:
         raise DslParseException(str(ex))
    def publish_blueprint(self, dsl_location, alias_mapping_url,
                          resources_base_url, blueprint_id=None):
        # TODO: error code if parsing fails (in one of the 2 tasks)
        try:
            plan = tasks.parse_dsl(dsl_location, alias_mapping_url,
                                   resources_base_url)

            with contextlib.closing(urlopen(dsl_location)) as f:
                source = f.read()
        except Exception, ex:
            raise DslParseException(*ex.args)
예제 #7
0
    def stage_deployment_update(self,
                                deployment_id,
                                app_dir,
                                app_blueprint,
                                additional_inputs):
        """Stage a deployment update

        :param app_blueprint:
        :param app_dir:
        :param deployment_id: the deployment id for the update
        :return:
        """

        # enables reverting to original blueprint resources
        deployment = self.sm.get(models.Deployment, deployment_id)
        blueprint_id = deployment.blueprint_id
        file_server_root = config.instance.file_server_root

        blueprint_resource_dir = os.path.join(
            file_server_root,
            'blueprints',
            current_app.config[CURRENT_TENANT_CONFIG].name,
            blueprint_id)
        # The dsl parser expects a URL
        blueprint_resource_dir_url = 'file:{0}'.format(blueprint_resource_dir)

        app_path = os.path.join(file_server_root, app_dir, app_blueprint)

        # parsing the blueprint from here
        try:
            plan = tasks.parse_dsl(
                app_path,
                resources_base_path=file_server_root,
                additional_resources=[blueprint_resource_dir_url],
                **app_context.get_parser_context())

        except parser_exceptions.DSLParsingException as ex:
            raise manager_exceptions.InvalidBlueprintError(
                'Invalid blueprint - {0}'.format(ex))

        # Updating the new inputs with the deployment inputs
        # (overriding old values and adding new ones)
        inputs = copy.deepcopy(deployment.inputs)
        inputs.update(additional_inputs)

        # applying intrinsic functions
        try:
            prepared_plan = tasks.prepare_deployment_plan(plan,
                                                          get_secret_method(),
                                                          inputs=inputs)
        except parser_exceptions.MissingRequiredInputError, e:
            raise manager_exceptions.MissingRequiredDeploymentInputError(
                str(e))
 def publish_blueprint(self,
                       application_dir,
                       application_file_name,
                       resources_base,
                       blueprint_id):
     application_file = os.path.join(application_dir, application_file_name)
     dsl_location = '{0}{1}'.format(resources_base, application_file)
     try:
         plan = tasks.parse_dsl(
             dsl_location, resources_base,
             **self._get_parser_context())
     except Exception, ex:
         raise DslParseException(str(ex))
예제 #9
0
    def stage_deployment_update(self,
                                deployment_id,
                                app_dir,
                                app_blueprint,
                                additional_inputs,
                                new_blueprint_id=None,
                                preview=False,
                                runtime_only_evaluation=False):
        # enables reverting to original blueprint resources
        deployment = self.sm.get(models.Deployment, deployment_id)
        old_blueprint = deployment.blueprint
        file_server_root = config.instance.file_server_root
        blueprint_resource_dir = os.path.join(file_server_root, 'blueprints',
                                              old_blueprint.tenant_name,
                                              old_blueprint.id)
        runtime_only_evaluation = runtime_only_evaluation or \
            deployment.runtime_only_evaluation
        # The dsl parser expects a URL
        blueprint_resource_dir_url = 'file:{0}'.format(blueprint_resource_dir)
        app_path = os.path.join(file_server_root, app_dir, app_blueprint)

        # parsing the blueprint from here
        try:
            plan = tasks.parse_dsl(
                app_path,
                resources_base_path=file_server_root,
                additional_resources=[blueprint_resource_dir_url],
                **app_context.get_parser_context())
        except parser_exceptions.DSLParsingException as ex:
            raise manager_exceptions.InvalidBlueprintError(
                'Invalid blueprint - {0}'.format(ex))

        # Updating the new inputs with the deployment inputs
        # (overriding old values and adding new ones)
        old_inputs = copy.deepcopy(deployment.inputs)
        new_inputs = {
            k: old_inputs[k]
            for k in plan.inputs.keys() if k in old_inputs
        }
        new_inputs.update(additional_inputs)

        # applying intrinsic functions
        try:
            prepared_plan = tasks.prepare_deployment_plan(
                plan,
                get_secret_method,
                inputs=new_inputs,
                runtime_only_evaluation=runtime_only_evaluation)
        except parser_exceptions.MissingRequiredInputError, e:
            raise manager_exceptions.MissingRequiredDeploymentInputError(
                str(e))
    def test_success_with_blueprint_import_resolver(self):
        blueprint_id = 'imported_blueprint'
        self.put_blueprint('mock_blueprint', 'blueprint.yaml', blueprint_id)

        dsl_location = os.path.join(self.get_blueprint_path('mock_blueprint'),
                                    'blueprint_with_blueprint_import.yaml')

        plan = tasks.parse_dsl(dsl_location=dsl_location,
                               resources_base_path=self.tmpdir,
                               resolver=self.resolver)

        nodes = {node["name"] for node in plan[constants.NODES]}

        self.assertEqual(nodes, {"test", "vm", "http_web_server"})
예제 #11
0
    def stage_deployment_update(self,
                                deployment_id,
                                app_dir,
                                app_blueprint,
                                additional_inputs):
        """Stage a deployment update

        :param app_blueprint:
        :param app_dir:
        :param deployment_id: the deployment id for the update
        :return:
        """

        # enables reverting to original blueprint resources
        deployment = self.sm.get_deployment(deployment_id)
        blueprint_id = deployment.blueprint_id

        # enables reverting to original blueprint resources
        file_server_base_url = \
            '{0}/'.format(config.instance().file_server_base_uri)

        blueprint_resource_dir = os.path.join(file_server_base_url,
                                              'blueprints',
                                              blueprint_id)

        app_path = os.path.join(file_server_base_url, app_dir, app_blueprint)

        # parsing the blueprint from here
        try:
            plan = tasks.parse_dsl(
                app_path,
                resources_base_url=file_server_base_url,
                additional_resources=[blueprint_resource_dir],
                **app_context.get_parser_context())

        except parser_exceptions.DSLParsingException as ex:
            raise manager_exceptions.InvalidBlueprintError(
                'Invalid blueprint - {0}'.format(ex))

        # Updating the new inputs with the deployment inputs
        # (overriding old values and adding new ones)
        inputs = copy.deepcopy(deployment.inputs)
        inputs.update(additional_inputs)

        # applying intrinsic functions
        try:
            prepared_plan = tasks.prepare_deployment_plan(plan, inputs=inputs)
        except parser_exceptions.MissingRequiredInputError, e:
            raise manager_exceptions.MissingRequiredDeploymentInputError(
                str(e))
    def test_success_with_blueprint_import_resolver(self):
        blueprint_id = 'imported_blueprint'
        self.put_blueprint('mock_blueprint',
                           'blueprint.yaml', blueprint_id)

        dsl_location = os.path.join(
            self.get_blueprint_path('mock_blueprint'),
            'blueprint_with_blueprint_import.yaml')

        plan = tasks.parse_dsl(dsl_location=dsl_location,
                               resources_base_path=self.tmpdir,
                               resolver=self.resolver)

        nodes = {node["name"] for node in plan[constants.NODES]}

        self.assertEqual(nodes, {"test", "ns--vm", "ns--http_web_server"})
예제 #13
0
def get_parsed_deployment(blueprint, app_dir, app_blueprint):
    file_server_root = config.instance.file_server_root
    blueprint_resource_dir = os.path.join(file_server_root, 'blueprints',
                                          blueprint.tenant_name, blueprint.id)
    # The dsl parser expects a URL
    blueprint_resource_dir_url = 'file:{0}'.format(blueprint_resource_dir)
    app_path = os.path.join(file_server_root, app_dir, app_blueprint)

    try:
        return tasks.parse_dsl(
            app_path,
            resources_base_path=file_server_root,
            additional_resources=[blueprint_resource_dir_url],
            **app_context.get_parser_context())
    except parser_exceptions.DSLParsingException as ex:
        raise manager_exceptions.InvalidBlueprintError(
            'Invalid blueprint - {0}'.format(ex))
예제 #14
0
    def stage_deployment_update(self,
                                deployment_id,
                                app_dir,
                                app_blueprint,
                                additional_inputs,
                                new_blueprint_id=None,
                                preview=False):
        # enables reverting to original blueprint resources
        deployment = self.sm.get(models.Deployment, deployment_id)
        old_blueprint = deployment.blueprint
        file_server_root = config.instance.file_server_root
        blueprint_resource_dir = os.path.join(file_server_root,
                                              'blueprints',
                                              old_blueprint.tenant_name,
                                              old_blueprint.id)
        # The dsl parser expects a URL
        blueprint_resource_dir_url = 'file:{0}'.format(blueprint_resource_dir)
        app_path = os.path.join(file_server_root, app_dir, app_blueprint)

        # parsing the blueprint from here
        try:
            plan = tasks.parse_dsl(
                app_path,
                resources_base_path=file_server_root,
                additional_resources=[blueprint_resource_dir_url],
                **app_context.get_parser_context()
            )
        except parser_exceptions.DSLParsingException as ex:
            raise manager_exceptions.InvalidBlueprintError(
                'Invalid blueprint - {0}'.format(ex))

        # Updating the new inputs with the deployment inputs
        # (overriding old values and adding new ones)
        old_inputs = copy.deepcopy(deployment.inputs)
        new_inputs = {k: old_inputs[k]
                      for k in plan.inputs.keys() if k in old_inputs}
        new_inputs.update(additional_inputs)

        # applying intrinsic functions
        try:
            prepared_plan = tasks.prepare_deployment_plan(plan,
                                                          get_secret_method(),
                                                          inputs=new_inputs)
        except parser_exceptions.MissingRequiredInputError, e:
            raise manager_exceptions.MissingRequiredDeploymentInputError(
                str(e))
예제 #15
0
    def stage_deployment_update(self, deployment_id, app_dir, app_blueprint,
                                additional_inputs):
        """Stage a deployment update

        :param app_blueprint:
        :param app_dir:
        :param deployment_id: the deployment id for the update
        :return:
        """

        # enables reverting to original blueprint resources
        deployment = self.sm.get_deployment(deployment_id)
        blueprint_id = deployment.blueprint_id

        # enables reverting to original blueprint resources
        file_server_base_url = \
            '{0}/'.format(config.instance.file_server_base_uri)

        blueprint_resource_dir = os.path.join(file_server_base_url,
                                              'blueprints', blueprint_id)

        app_path = os.path.join(file_server_base_url, app_dir, app_blueprint)

        # parsing the blueprint from here
        try:
            plan = tasks.parse_dsl(
                app_path,
                resources_base_url=file_server_base_url,
                additional_resources=[blueprint_resource_dir],
                **app_context.get_parser_context())

        except parser_exceptions.DSLParsingException as ex:
            raise manager_exceptions.InvalidBlueprintError(
                'Invalid blueprint - {0}'.format(ex))

        # Updating the new inputs with the deployment inputs
        # (overriding old values and adding new ones)
        inputs = copy.deepcopy(deployment.inputs)
        inputs.update(additional_inputs)

        # applying intrinsic functions
        try:
            prepared_plan = tasks.prepare_deployment_plan(plan, inputs=inputs)
        except parser_exceptions.MissingRequiredInputError, e:
            raise manager_exceptions.MissingRequiredDeploymentInputError(
                str(e))
예제 #16
0
def upload(ctx, **kwargs):

    client = get_rest_client()

    # extract the execution parameters
    blueprint_id = kwargs['blueprint_id']
    app_file_name = kwargs['app_file_name']
    url = kwargs['url']
    file_server_root = kwargs['file_server_root']
    validate_only = kwargs['validate_only']
    labels = kwargs.get('labels')

    # Download the archive, one way or the other
    archive_target_path = tempfile.mkdtemp()
    try:
        if url:
            # download the blueprint archive from URL using requests:
            if not validate_only:
                client.blueprints.update(
                    blueprint_id,
                    update_dict={'state': BlueprintUploadState.UPLOADING})
            with requests.get(url, stream=True, timeout=(5, None)) as resp:
                resp.raise_for_status()
                archive_file_path = os.path.join(archive_target_path,
                                                 os.path.basename(url))
                with open(archive_file_path, 'wb') as f:
                    for chunk in resp.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)

            # Upload the downloaded archive to the manager
            if not validate_only:
                client.blueprints.upload_archive(
                    blueprint_id, archive_path=archive_file_path)

        else:
            # download the blueprint archive using REST
            archive_file_path = client.blueprints.download(
                blueprint_id, output_file=archive_target_path)
    except Exception as e:
        client.blueprints.update(blueprint_id,
                                 update_dict={
                                     'state':
                                     BlueprintUploadState.FAILED_UPLOADING,
                                     'error': str(e),
                                     'error_traceback': traceback.format_exc()
                                 })
        remove(archive_target_path)
        raise

    ctx.logger.info('Blueprint archive uploaded. Extracting...')

    # Extract the archive so we can parse it
    if not validate_only:
        client.blueprints.update(
            blueprint_id,
            update_dict={'state': BlueprintUploadState.EXTRACTING})
    try:
        archive_util.unpack_archive(archive_file_path, archive_target_path)
    except archive_util.UnrecognizedFormat:
        error_msg = 'Blueprint archive is of an unrecognized format. ' \
                    'Supported formats are: ' \
                    '{0}'.format(SUPPORTED_ARCHIVE_TYPES)
        handle_failed_extracting(ctx, client, blueprint_id, error_msg,
                                 archive_target_path)
    except Exception as e:
        handle_failed_extracting(ctx, client, blueprint_id, str(e),
                                 archive_target_path)
    archive_file_list = os.listdir(archive_target_path)
    # ignore the archive file for now
    archive_file_list.remove(os.path.basename(archive_file_path))
    # the other item in the archive dir is the extracted app, which is
    # supposed to consist of one folder in a properly-structured archive
    app_dir = os.path.join(archive_target_path, archive_file_list[0])
    if len(archive_file_list) != 1 or not os.path.isdir(app_dir):
        error_msg = 'Archive must contain exactly 1 directory'
        handle_failed_extracting(ctx, client, blueprint_id, error_msg,
                                 archive_target_path)

    # get actual app file name
    if app_file_name:
        app_file_name = unquote(app_file_name)
        application_file = os.path.join(app_dir, app_file_name)
        if not os.path.isfile(application_file):
            error_msg = '{0} does not exist in the application ' \
                        'directory'.format(app_file_name)
            handle_failed_extracting(ctx, client, blueprint_id, error_msg,
                                     archive_target_path)
    else:
        app_file_name = CONVENTION_APPLICATION_BLUEPRINT_FILE
        application_file = os.path.join(app_dir, app_file_name)
        if not os.path.isfile(application_file):
            error_msg = 'Application directory is missing blueprint.yaml and' \
                        ' application_file_name query parameter was not passed'
            handle_failed_extracting(ctx, client, blueprint_id, error_msg,
                                     archive_target_path)

    ctx.logger.info('Blueprint archive extracted. Parsing...')

    # Parse plan
    if not validate_only:
        client.blueprints.update(
            blueprint_id, update_dict={'state': BlueprintUploadState.PARSING})

    dsl_location = os.path.join(app_dir, app_file_name)

    provider_context = client.manager.get_context()['context']
    try:
        parser_context = extract_parser_context(provider_context,
                                                resolver_parameters={
                                                    'file_server_root':
                                                    file_server_root,
                                                    'client': client
                                                })
    except dsl_parser_utils.ResolverInstantiationError as e:
        ctx.logger.critical(str(e))
        client.blueprints.update(blueprint_id,
                                 update_dict={
                                     'state':
                                     BlueprintUploadState.FAILED_PARSING,
                                     'error': str(e),
                                     'error_traceback': traceback.format_exc()
                                 })
        raise
    try:
        plan = tasks.parse_dsl(dsl_location, file_server_root,
                               **parser_context)
    except (InvalidBlueprintImport, DSLParsingException) as e:
        error_msg = 'Invalid blueprint - {}'.format(e)
        ctx.logger.critical(error_msg)
        client.blueprints.update(blueprint_id,
                                 update_dict={
                                     'state': BlueprintUploadState.INVALID,
                                     'error': error_msg,
                                     'error_traceback': traceback.format_exc()
                                 })
        raise
    except Exception as e:
        error_msg = 'Failed parsing blueprint - {}'.format(e)
        ctx.logger.critical(error_msg)
        client.blueprints.update(blueprint_id,
                                 update_dict={
                                     'state':
                                     BlueprintUploadState.FAILED_PARSING,
                                     'error': error_msg,
                                     'error_traceback': traceback.format_exc()
                                 })
        raise
    finally:
        remove(archive_target_path)

    if validate_only:
        ctx.logger.info('Blueprint validated.')
    else:
        ctx.logger.info('Blueprint parsed. Updating DB with blueprint plan.')

    # Update DB with parsed plan
    update_dict = {
        'plan': plan,
        'main_file_name': app_file_name,
        'state': BlueprintUploadState.UPLOADED,
    }
    if plan.get('description'):
        update_dict['description'] = plan['description']
    if labels:
        update_dict['labels'] = labels
    client.blueprints.update(blueprint_id, update_dict=update_dict)
 def publish_blueprint(self, dsl_location,
                       resources_base_url, blueprint_id):
     try:
         plan = tasks.parse_dsl(dsl_location, resources_base_url)
     except Exception, ex:
         raise DslParseException(str(ex))