예제 #1
0
def get_fqn_for_name(namespaces, name):
    """Analyze name for namespace reference.

    If namespaces are used - return a full name
    :param namespaces: content of 'Namespaces' section of muranoPL class
    :param name: name that should be checked
    :returns: generated name according to namespaces
    """
    values = name.split(':')
    if len(values) == 1:
        if '=' in namespaces:
            return namespaces['='] + '.' + values[0]
        return values[0]
    if len(values) > 2:
        raise exceptions.CommandError(
            "Error in class definition: Wrong usage of ':' is "
            "reserved for namespace referencing and could "
            "be used only once "
            "for each name")
    if not namespaces:
        raise exceptions.CommandError("Error in {0} class definition: "
                                      "'Namespaces' section is missed")

    result = namespaces.get(values[0])
    if not result:
        raise exceptions.CommandError(
            "Error in class definition: namespaces "
            "reference is not correct at the 'Extends'"
            " section")
    return result + '.' + values[1]
예제 #2
0
def do_package_create(mc, args):
    """Create an application package."""
    if args.template and args.classes_dir:
        raise exceptions.CommandError(
            "Provide --template for a HOT-based package, OR"
            " --classes-dir for a MuranoPL-based package")
    if not args.template and not args.classes_dir:
        raise exceptions.CommandError(
            "Provide --template for a HOT-based package, OR at least"
            " --classes-dir for a MuranoPL-based package")
    directory_path = None
    try:
        archive_name = args.output if args.output else None
        if args.template:
            directory_path = hot_package.prepare_package(args)
            if not archive_name:
                archive_name = os.path.basename(args.template)
                archive_name = os.path.splitext(archive_name)[0] + ".zip"
        else:
            directory_path = mpl_package.prepare_package(args)
            if not archive_name:
                archive_name = tempfile.mkstemp(prefix="murano_",
                                                dir=os.getcwd())[1] + ".zip"

        _make_archive(archive_name, directory_path)
        print("Application package is available at " +
              os.path.abspath(archive_name))
    finally:
        if directory_path:
            shutil.rmtree(directory_path)
예제 #3
0
def update_args(args):
    """Add and update arguments if possible.

    Some parameters are not required and would be guessed
    from muranoPL classes: thus, if class extends system application class
    fully qualified and require names could be calculated.
    Also, in that case type of a package could be set to 'Application'.
    """

    classes = {}
    extends_from_application = False
    for root, dirs, files in os.walk(args.classes_dir):
        for class_file in files:
            class_file_path = os.path.join(root, class_file)
            try:
                with open(class_file_path) as f:
                    content = yaml.load(f, utils.YaqlYamlLoader)

                if not content.get('Name'):
                    raise exceptions.CommandError(
                        "Error in class definition: 'Name' "
                        "section is required")
                class_name = get_fqn_for_name(content.get('Namespaces'),
                                              content['Name'])
                if root == args.classes_dir:
                    relative_path = class_file
                else:
                    relative_path = os.path.join(
                        root.replace(args.classes_dir, "")[1:], class_file)
                classes[class_name] = relative_path

                extends_from_application = check_derived_from_application(
                    content, extends_from_application)
                if extends_from_application:
                    if not args.type:
                        args.type = 'Application'
                    if not args.name:
                        args.name = class_name.split('.')[-1]
                    if not args.full_name:
                        args.full_name = class_name

            except yaml.YAMLError:
                raise exceptions.CommandError(
                    "MuranoPL class {0} should be"
                    " a valid yaml file".format(class_file_path))
            except IOError:
                raise exceptions.CommandError(
                    "Could not open file {0}".format(class_file_path))
    if not classes:
        raise exceptions.CommandError("Application should have "
                                      "at least one class")
    args.classes = classes
    return args
예제 #4
0
def do_app_show(mc, args):
    """List applications, added to specified environment.
    """
    if args.path == '/':
        apps = mc.services.list(args.id)
        formatters = {
            'id': lambda x: getattr(x, '?')['id'],
            'type': lambda x: getattr(x, '?')['type']
        }
        field_labels = ['Id', 'Name', 'Type']
        fields = ['id', 'name', 'type']
        utils.print_list(apps, fields, field_labels, formatters=formatters)
    else:
        if not args.path.startswith('/'):
            args.path = '/' + args.path
        app = mc.services.get(args.id, args.path)

        # If app with specified path is not found, it is empty.
        if hasattr(app, '?'):
            formatters = {}
            for key in app.to_dict().keys():
                formatters[key] = utils.json_formatter
            utils.print_dict(app.to_dict(), formatters)
        else:
            raise exceptions.CommandError("Could not find application at path"
                                          " %s" % args.path)
예제 #5
0
    def take_action(self, parsed_args):
        LOG.debug("take_action({0})".format(parsed_args))
        client = self.app.client_manager.application_catalog

        abandon = getattr(parsed_args, 'abandon', False)
        failure_count = 0
        for environment_id in parsed_args.id:
            try:
                environment = murano_utils.find_resource(
                    client.environments, environment_id)
                client.environments.delete(environment.id, abandon)
            except exceptions.NotFound:
                failure_count += 1
                print("Failed to delete '{0}'; environment not found".format(
                    environment_id))

        if failure_count == len(parsed_args.id):
            raise exceptions.CommandError("Unable to find and delete any of "
                                          "the specified environments.")

        data = client.environments.list()

        columns = ('id', 'name', 'status', 'created', 'updated')
        column_headers = [c.capitalize() for c in columns]

        return (column_headers,
                list(utils.get_item_properties(
                    s,
                    columns,
                ) for s in data))
예제 #6
0
def do_package_show(mc, args):
    """Display details for a package."""
    try:
        package = mc.packages.get(args.id)
    except common_exceptions.HTTPNotFound:
        raise exceptions.CommandError("Package %s not found" % args.id)
    else:
        to_display = dict(id=package.id,
                          type=package.type,
                          owner_id=package.owner_id,
                          name=package.name,
                          fully_qualified_name=package.fully_qualified_name,
                          is_public=package.is_public,
                          enabled=package.enabled,
                          class_definitions=", ".join(
                              package.class_definitions),
                          categories=", ".join(package.categories),
                          tags=", ".join(package.tags),
                          description=package.description)
        formatters = {
            'class_definitions': utils.text_wrap_formatter,
            'categories': utils.text_wrap_formatter,
            'tags': utils.text_wrap_formatter,
            'description': utils.text_wrap_formatter,
        }
        utils.print_dict(to_display, formatters)
예제 #7
0
    def take_action(self, parsed_args):
        LOG.debug("take_action({0})".format(parsed_args))
        client = self.app.client_manager.application_catalog

        arguments = {}
        for argument in parsed_args.arguments or []:
            if '=' not in argument:
                raise exceptions.CommandError(
                    "Argument should be in form of KEY=VALUE. Found: "
                    "{0}".format(argument))
            key, value = argument.split('=', 1)
            try:
                value = json.loads(value)
            except ValueError:
                # treat value as a string if it doesn't load as json
                pass

            arguments[key] = value

        request_body = {
            "className": parsed_args.class_name,
            "methodName": parsed_args.method_name,
            "packageName": parsed_args.package_name or None,
            "classVersion": parsed_args.class_version or '=0',
            "parameters": arguments
        }

        print("Waiting for result...")
        result = client.static_actions.call(request_body).get_result()
        return ["Static action result"], [result]
예제 #8
0
    def take_action(self, parsed_args):
        LOG.debug("take_action({0})".format(parsed_args))
        client = self.app.client_manager.application_catalog

        failure_count = 0
        for category_id in parsed_args.id:
            try:
                client.categories.delete(category_id)
            except Exception:
                failure_count += 1
                print("Failed to delete '{0}'; category not found".format(
                    category_id))
        if failure_count == len(parsed_args.id):
            raise exceptions.CommandError("Unable to find and delete any of "
                                          "the specified categories.")
        data = client.categories.list()

        fields = ["id", "name"]
        field_labels = ["ID", "Name"]

        return (field_labels,
                list(utils.get_item_properties(
                    s,
                    fields,
                ) for s in data))
예제 #9
0
    def _discover_auth_versions(self, session, auth_url):
        # discover the API versions the server is supporting base on the
        # given URL
        v2_auth_url = None
        v3_auth_url = None
        try:
            ks_discover = discover.Discover(session=session, auth_url=auth_url)
            v2_auth_url = ks_discover.url_for('2.0')
            v3_auth_url = ks_discover.url_for('3.0')
        except ks_exc.ClientException as e:
            # Identity service may not support discover API version.
            # Lets trying to figure out the API version from the original URL.
            url_parts = urlparse.urlparse(auth_url)
            (scheme, netloc, path, params, query, fragment) = url_parts
            path = path.lower()
            if path.startswith('/v3'):
                v3_auth_url = auth_url
            elif path.startswith('/v2'):
                v2_auth_url = auth_url
            else:
                # not enough information to determine the auth version
                msg = ('Unable to determine the Keystone version '
                       'to authenticate with using the given '
                       'auth_url. Identity service may not support API '
                       'version discovery. Please provide a versioned '
                       'auth_url instead. error=%s') % (e)
                raise exc.CommandError(msg)

        return (v2_auth_url, v3_auth_url)
예제 #10
0
def prepare_package(args):
    """Compose required files for murano application package.

    :param args: list of command line arguments
    :returns: absolute path to directory with prepared files
    """
    manifest = generate_manifest(args)

    temp_dir = tempfile.mkdtemp()
    manifest_file = os.path.join(temp_dir, 'manifest.yaml')
    template_file = os.path.join(temp_dir, 'template.yaml')

    if args.resources_dir:
        if not os.path.isdir(args.resources_dir):
            raise exceptions.CommandError(
                "'--resources-dir' parameter should be a directory")
        resource_directory = os.path.join(temp_dir, 'Resources')
        shutil.copytree(args.resources_dir, resource_directory)

    logo_file = os.path.join(temp_dir, 'logo.png')
    if not args.logo:
        shutil.copyfile(muranoclient.get_resource('heat_logo.png'), logo_file)
    else:
        if os.path.isfile(args.logo):
            shutil.copyfile(args.logo, logo_file)

    with open(manifest_file, 'w') as f:
        f.write(yaml.dump(manifest, default_flow_style=False))
    shutil.copyfile(args.template, template_file)

    return temp_dir
예제 #11
0
def generate_manifest(args):
    """Generates application manifest file.
    If some parameters are missed - they we be generated automatically.
    :param args:

    :returns: dictionary, contains manifest file data

    """
    if not os.path.isfile(args.template):
        raise exceptions.CommandError("Template '{0}' doesn`t exist".format(
            args.template))
    filename = os.path.basename(args.template)
    if not args.name:
        args.name = os.path.splitext(filename)[0]
    if not args.full_name:
        prefix = 'io.murano.apps.generated'
        normalized_name = args.name.replace('_', ' ').replace('-', ' ')
        normalized_name = normalized_name.title().replace(' ', '')
        args.full_name = '{0}.{1}'.format(prefix, normalized_name)
    try:
        with open(args.template, 'rb') as heat_file:
            yaml_content = yaml.load(heat_file)
            if not args.description:
                args.description = yaml_content.get(
                    'description',
                    'Heat-defined application for a template "{0}"'.format(
                        filename))
    except yaml.YAMLError:
        raise exceptions.CommandError(
            "Heat template, represented by --'template' parameter"
            " should be a valid yaml file")
    if not args.author:
        args.author = args.os_username
    if not args.tags:
        args.tags = ['Heat-generated']

    manifest = {
        'Format': 'Heat.HOT/1.0',
        'Type': 'Application',
        'FullName': args.full_name,
        'Name': args.name,
        'Description': args.description,
        'Author': args.author,
        'Tags': args.tags
    }
    return manifest
예제 #12
0
def prepare_package(args):
    """Prepare for application package

    Prepare all files and directories for that application package.
    Generates manifest file and all required parameters for that.

    :param args: list of command line arguments
    :returns: absolute path to directory with prepared files
    """
    if args.type and args.type not in ['Application', 'Library']:
        raise exceptions.CommandError(
            "--type should be set to 'Application' or 'Library'")

    manifest = generate_manifest(args)
    if args.type == 'Application':
        if not args.ui:
            raise exceptions.CommandError("'--ui' is required parameter")
        if not os.path.exists(args.ui) or not os.path.isfile(args.ui):
            raise exceptions.CommandError(
                "{0} is not a file or doesn`t exist".format(args.ui))

    temp_dir = tempfile.mkdtemp()
    manifest_file = os.path.join(temp_dir, 'manifest.yaml')
    classes_directory = os.path.join(temp_dir, 'Classes')
    resource_directory = os.path.join(temp_dir, 'Resources')

    with open(manifest_file, 'w') as f:
        f.write(yaml.dump(manifest, default_flow_style=False))

    logo_file = os.path.join(temp_dir, 'logo.png')
    if not args.logo or (args.logo and not os.path.isfile(args.logo)):
        shutil.copyfile(muranoclient.get_resource('mpl_logo.png'), logo_file)
    else:
        shutil.copyfile(args.logo, logo_file)

    shutil.copytree(args.classes_dir, classes_directory)
    if args.resources_dir:
        if not os.path.isdir(args.resources_dir):
            raise exceptions.CommandError(
                "'--resources-dir' parameter should be a directory")
        shutil.copytree(args.resources_dir, resource_directory)
    if args.ui:
        ui_directory = os.path.join(temp_dir, 'UI')
        os.mkdir(ui_directory)
        shutil.copyfile(args.ui, os.path.join(ui_directory, 'ui.yaml'))
    return temp_dir
예제 #13
0
def do_environment_rename(mc, args):
    """Rename an environment."""
    try:
        environment = utils.find_resource(mc.environments, args.id)
        environment = mc.environments.update(environment.id, args.name)
    except exceptions.NotFound:
        raise exceptions.CommandError("Environment %s not found" % args.id)
    else:
        _print_environment_list([environment])
예제 #14
0
def do_package_delete(mc, args):
    """Delete a package."""
    failure_count = 0
    for package_id in args.id:
        try:
            mc.packages.delete(package_id)
            print("Deleted package  '{0}'".format(package_id))
        except exceptions.NotFound:
            raise exceptions.CommandError("Package %s not found" % package_id)
            failure_count += 1
            print(
                "Failed to delete '{0}'; package not found".format(package_id))

    if failure_count == len(args.id):
        raise exceptions.CommandError("Unable to find and delete any of the "
                                      "specified packages.")
    else:
        do_package_list(mc)
예제 #15
0
def _handle_package_exists(mc, data, package, exists_action):
    name = package.manifest['FullName']
    version = package.manifest.get('Version', '0')
    while True:
        print("Importing package {0}".format(name))
        try:
            return mc.packages.create(data, {name: package.file()})
        except common_exceptions.HTTPConflict:
            print(
                "Importing package {0} failed. Package with the same"
                " name/classes is already registered.".format(name))
            allowed_results = ['s', 'u', 'a']
            res = exists_action
            if not res:
                while True:
                    print("What do you want to do? (s)kip, (u)pdate, (a)bort")
                    res = six.moves.input()
                    if res in allowed_results:
                        break
            if res == 's':
                print("Skipping.")
                return None
            elif res == 'a':
                print("Exiting.")
                sys.exit()
            elif res == 'u':
                pkgs = list(
                    mc.packages.filter(fqn=name, version=version, owned=True))
                if not pkgs:
                    msg = (
                        "Got a conflict response, but could not find the "
                        "package '{0}' in the current tenant.\nThis probably "
                        "means the conflicting package is in another tenant.\n"
                        "Please delete it manually.").format(name)
                    raise exceptions.CommandError(msg)
                elif len(pkgs) > 1:
                    msg = (
                        "Got {0} packages with name '{1}'.\nI do not trust "
                        "myself, please delete the package manually.").format(
                            len(pkgs), name)
                    raise exceptions.CommandError(msg)
                print("Deleting package {0}({1})".format(name, pkgs[0].id))
                mc.packages.delete(pkgs[0].id)
                continue
예제 #16
0
 def do_help(self, args):
     """Display help about this program or one of its subcommands."""
     if getattr(args, 'command', None):
         if args.command in self.subcommands:
             self.subcommands[args.command].print_help()
         else:
             msg = "'%s' is not a valid subcommand"
             raise exc.CommandError(msg % args.command)
     else:
         self.parser.print_help()
예제 #17
0
def do_package_download(mc, args):
    """Download a package to a filename or stdout."""
    def download_to_fh(package_id, fh):
        fh.write(mc.packages.download(package_id))

    try:
        if args.filename:
            with open(args.filename, 'wb') as fh:
                download_to_fh(args.id, fh)
                print("Package downloaded to %s" % args.filename)
        elif not sys.stdout.isatty():
            download_to_fh(args.id, sys.stdout)
        else:
            msg = ('No stdout redirection or local file specified for '
                   'downloaded package. Please specify a local file to save '
                   'downloaded package or redirect output to another source.')
            raise exceptions.CommandError(msg)
    except common_exceptions.HTTPNotFound:
        raise exceptions.CommandError("Package %s not found" % args.id)
예제 #18
0
def do_deployment_list(mc, args):
    """List deployments for an environment."""
    try:
        environment = utils.find_resource(mc.environments, args.id)
        deployments = mc.deployments.list(environment.id)
    except exceptions.NotFound:
        raise exceptions.CommandError("Environment %s not found" % args.id)
    else:
        field_labels = ["ID", "State", "Created", "Updated", "Finished"]
        fields = ["id", "state", "created", "updated", "finished"]
        utils.print_list(deployments, fields, field_labels, sortby=0)
예제 #19
0
    def _get_keystone_auth(self, session, auth_url, **kwargs):
        auth_token = kwargs.pop('auth_token', None)
        if auth_token:
            return token.Token(
                auth_url,
                auth_token,
                project_id=kwargs.pop('project_id'),
                project_name=kwargs.pop('project_name'),
                project_domain_id=kwargs.pop('project_domain_id'),
                project_domain_name=kwargs.pop('project_domain_name'))

        # NOTE(starodubcevna): this is a workaround for the bug:
        # https://bugs.launchpad.net/python-openstackclient/+bug/1447704
        # Change that fix this error in keystoneclient was abandoned,
        # so we should use workaround until we move to keystoneauth.
        # The idea of the code came from glanceclient.

        (v2_auth_url, v3_auth_url) = self._discover_auth_versions(
            session=session,
            auth_url=auth_url)

        if v3_auth_url:
            # NOTE(starodubcevna): set user_domain_id and project_domain_id
            # to default as it done in other projects.
            return password.Password(auth_url,
                                     username=kwargs.pop('username'),
                                     user_id=kwargs.pop('user_id'),
                                     password=kwargs.pop('password'),
                                     user_domain_id=kwargs.pop(
                                         'user_domain_id') or 'default',
                                     user_domain_name=kwargs.pop(
                                         'user_domain_name'),
                                     project_id=kwargs.pop('project_id'),
                                     project_name=kwargs.pop('project_name'),
                                     project_domain_id=kwargs.pop(
                                         'project_domain_id') or 'default')
        elif v2_auth_url:
            return password.Password(auth_url,
                                     username=kwargs.pop('username'),
                                     user_id=kwargs.pop('user_id'),
                                     password=kwargs.pop('password'),
                                     project_id=kwargs.pop('project_id'),
                                     project_name=kwargs.pop('project_name'))
        else:
            # if we get here it means domain information is provided
            # (caller meant to use Keystone V3) but the auth url is
            # actually Keystone V2. Obviously we can't authenticate a V3
            # user using V2.
            exc.CommandError("Credential and auth_url mismatch. The given "
                             "auth_url is using Keystone V2 endpoint, which "
                             "may not able to handle Keystone V3 credentials. "
                             "Please provide a correct Keystone V3 auth_url.")
예제 #20
0
def do_env_template_create_env(mc, args):
    """Create a new environment from template."""
    try:
        template = mc.env_templates.create_env(args.id, args.name)
    except common_exceptions.HTTPNotFound:
        raise exceptions.CommandError("Environment template %s not found" %
                                      args.id)
    else:
        formatters = {
            "environment_id": utils.text_wrap_formatter,
            "session_id": utils.text_wrap_formatter
        }
        utils.print_dict(template.to_dict(), formatters=formatters)
예제 #21
0
def do_category_delete(mc, args):
    """Delete a category."""
    failure_count = 0
    for category_id in args.id:
        try:
            mc.categories.delete(category_id)
        except common_exceptions.HTTPNotFound:
            failure_count += 1
            print("Failed to delete '{0}'; category not found".format(
                category_id))
    if failure_count == len(args.id):
        raise exceptions.CommandError("Unable to find and delete any of the "
                                      "specified categories.")
    do_category_list(mc)
예제 #22
0
def do_bundle_save(mc, args):
    """Save a bundle.

    This will download a bundle of packages with all dependencies
    to specified path. If path doesn't exist it will be created.
    """

    bundle = args.filename
    base_url = args.murano_repo_url

    if args.path:
        if not os.path.exists(args.path):
            os.makedirs(args.path)
        dst = args.path
    else:
        dst = os.getcwd()

    total_reqs = collections.OrderedDict()

    if os.path.isfile(bundle):
        _file = bundle
    else:
        print(
            "Bundle file '{0}' does not exist, attempting to download".format(
                bundle))
        _file = utils.to_url(
            bundle,
            base_url=base_url,
            path='bundles/',
            extension='.bundle',
        )
    try:
        bundle_file = utils.Bundle.from_file(_file)
    except Exception as e:
        msg = "Failed to create bundle for {0}, reason: {1}".format(bundle, e)
        raise exceptions.CommandError(msg)

    for package in bundle_file.packages(base_url=base_url):
        requirements = package.requirements(base_url=base_url)
        total_reqs.update(requirements)

    no_images = getattr(args, 'no_images', False)

    _handle_save_packages(total_reqs, dst, base_url, no_images)

    try:
        bundle_file.save(dst, binary=False)
        print("Bundle file {0} has been successfully saved".format(bundle))
    except Exception as e:
        print("Error {0} occurred while saving bundle {1}".format(e, bundle))
예제 #23
0
def do_env_template_delete(mc, args):
    """Delete an environment template."""
    failure_count = 0
    for env_template_id in args.id:
        try:
            mc.env_templates.delete(env_template_id)
        except common_exceptions.HTTPNotFound:
            failure_count += 1
            mns = "Failed to delete '{0}'; environment template not found".\
                format(env_template_id)

    if failure_count == len(args.id):
        raise exceptions.CommandError(mns)
    do_env_template_list(mc)
예제 #24
0
def generate_manifest(args):
    """Generates application manifest file.

    If some parameters are missed - they we be generated automatically.
    :param args:
    :returns: dictionary, contains manifest file data
    """
    if not os.path.isdir(args.classes_dir):
        raise exceptions.CommandError(
            "'--classes-dir' parameter should be a directory")
    args = update_args(args)
    if not args.type:
        raise exceptions.CommandError(
            "Too few arguments: --type and --full-name is required")

    if not args.author:
        args.author = args.os_username
    if not args.description:
        args.description = "Description for the application is not provided"

    if not args.full_name:
        raise exceptions.CommandError("Please, provide --full-name parameter")

    manifest = {
        'Format': 'MuranoPL/1.0',
        'Type': args.type,
        'FullName': args.full_name,
        'Name': args.name,
        'Description': args.description,
        'Author': args.author,
        'Classes': args.classes
    }

    if args.tags:
        manifest['Tags'] = args.tags
    return manifest
예제 #25
0
def do_env_template_show(mc, args):
    """Display environment template details."""
    try:
        env_template = mc.env_templates.get(args.id)
    except common_exceptions.HTTPNotFound:
        raise exceptions.CommandError("Environment template %s not found" %
                                      args.id)
    else:
        formatters = {
            "id": utils.text_wrap_formatter,
            "created": utils.text_wrap_formatter,
            "name": utils.text_wrap_formatter,
            "tenant_id": utils.text_wrap_formatter,
            "services": utils.json_formatter,
        }
        utils.print_dict(env_template.to_dict(), formatters=formatters)
예제 #26
0
def do_environment_delete(mc, args):
    """Delete an environment."""
    abandon = getattr(args, 'abandon', False)
    failure_count = 0
    for environment_id in args.id:
        try:
            environment = utils.find_resource(mc.environments, environment_id)
            mc.environments.delete(environment.id, abandon)
        except exceptions.NotFound:
            failure_count += 1
            print("Failed to delete '{0}'; environment not found".format(
                environment_id))
    if failure_count == len(args.id):
        raise exceptions.CommandError("Unable to find and delete any of the "
                                      "specified environments.")
    do_environment_list(mc)
예제 #27
0
def check_derived_from_application(content, extends_from_application):
    """Look up for system 'io.murano.Application' class in extends section"""
    if content.get('Extends'):
        extends = content['Extends']
        if not isinstance(extends, list):
            extends = [extends]

        for name in extends:
            parent_class_name = get_fqn_for_name(content.get('Namespaces'),
                                                 name)
            if parent_class_name == 'io.murano.Application':
                if not extends_from_application:
                    return True
                else:
                    raise exceptions.CommandError(
                        "Murano package should have only one class"
                        " extends 'io.murano.Application' class")
    return False
예제 #28
0
def do_environment_action_call(mc, args):
    """Call action `ACTION` in environment `ID`.

    Returns id of an asynchronous task, that executes the action.
    Actions can only be called on a `deployed` environment.
    To view actions available in a given environment use `environment-show`
    command.
    """
    arguments = {}
    for argument in args.arguments or []:
        if '=' not in argument:
            raise exceptions.CommandError(
                "Argument should be in form of KEY=VALUE. Found: {0}".format(
                    argument))
        k, v = argument.split('=', 1)
        arguments[k] = v
    task_id = mc.actions.call(args.id, args.action_id, arguments=arguments)
    print("Created task, id: {0}".format(task_id))
예제 #29
0
def do_env_template_clone(mc, args):
    """Create a new template, cloned from template."""
    try:
        env_template = mc.env_templates.clone(args.id, args.name)
    except common_exceptions.HTTPNotFound:
        raise exceptions.CommandError("Environment template %s not found" %
                                      args.id)
    else:
        formatters = {
            "id": utils.text_wrap_formatter,
            "created": utils.text_wrap_formatter,
            "updated": utils.text_wrap_formatter,
            "version": utils.text_wrap_formatter,
            "name": utils.text_wrap_formatter,
            "tenant_id": utils.text_wrap_formatter,
            "is_public": utils.text_wrap_formatter,
            "services": utils.json_formatter,
        }
        utils.print_dict(env_template.to_dict(), formatters=formatters)
예제 #30
0
def do_environment_show(mc, args):
    """Display environment details."""
    try:
        environment = utils.find_resource(mc.environments,
                                          args.id,
                                          session_id=args.session_id)
    except exceptions.NotFound:
        raise exceptions.CommandError("Environment %s not found" % args.id)
    else:
        if getattr(args, 'only_apps', False):
            print(utils.json_formatter(environment.services))
        else:
            formatters = {
                "id": utils.text_wrap_formatter,
                "created": utils.text_wrap_formatter,
                "name": utils.text_wrap_formatter,
                "tenant_id": utils.text_wrap_formatter,
                "services": utils.json_formatter,
            }
            utils.print_dict(environment.to_dict(), formatters=formatters)