Ejemplo n.º 1
0
    def _import_direct_online_template(self, name, running_on_same_folder,
                                       template, standards, python_version):
        """ Create shell based on template downloaded by the direct link """

        template_url = self._remove_prefix(
            template, NewCommandExecutor.REMOTE_TEMPLATE_URL_PREFIX)
        with TempDirContext(name) as temp_dir:
            try:
                repo_path = self.repository_downloader.download_template(
                    temp_dir,
                    template_url,
                    branch=None,
                    is_need_construct=False)
            except VersionRequestException:
                raise click.BadParameter(
                    "Failed to download template from provided direct link {}".
                    format(template_url))

            self._verify_template_standards_compatibility(
                template_path=repo_path, standards=standards)

            extra_content = self._get_template_params(repo_path=repo_path)

            self.template_compiler.compile_template(
                shell_name=name,
                template_path=repo_path,
                extra_context=extra_content,
                running_on_same_folder=running_on_same_folder,
                python_version=python_version)
    def pack(self, path):
        """
        Creates TOSCA based Shell package
        :return:
        """
        shell_package = ShellPackage(path)
        shell_name = shell_package.get_shell_name()
        with TempDirContext(shell_name) as package_path:

            self._copy_tosca_meta(package_path, '')
            tosca_meta = self._read_tosca_meta(path)

            shell_definition_path = tosca_meta['Entry-Definitions']

            self._copy_shell_definition(package_path, '', shell_definition_path)
            self._create_driver('', os.curdir, shell_name)

            with open(shell_definition_path) as shell_definition_file:
                shell_definition = yaml.load(shell_definition_file)

                if 'template_icon' in shell_definition['metadata']:
                    self._copy_artifact(shell_definition['metadata']['template_icon'], package_path)

                for node_type in shell_definition['node_types'].values():
                    if 'artifacts' not in node_type:
                        continue
                    for artifact in node_type['artifacts'].values():
                        self._copy_artifact(artifact['file'], package_path)

            zip_path = self._zip_package(package_path, '', shell_name)

            click.echo(u'Shell package was successfully created: ' + zip_path)
Ejemplo n.º 3
0
    def _import_online_template(self, name, running_on_same_folder, template,
                                version):
        # Create a temp folder for the operation to make sure we delete it after
        with TempDirContext(name) as temp_dir:

            try:
                templates = self.template_retriever.get_templates()
            except SSLError:
                raise click.UsageError(
                    "Cannot retrieve templates list, are you offline?")

            if template not in templates:
                raise click.BadParameter(
                    u'Template {0} does not exist. Supported templates are: {1}'
                    .format(template,
                            self._get_templates_with_comma(templates)))
            template_obj = templates[template]

            try:
                repo_path = self.repository_downloader.download_template(
                    temp_dir, template_obj.repository, version)
            except VersionRequestException:
                raise click.BadParameter(
                    u'{} does not exists or invalid value'.format(version))

            self.template_compiler.compile_template(name, repo_path,
                                                    template_obj.params,
                                                    running_on_same_folder)
Ejemplo n.º 4
0
    def get_templates(self, cs_version, output_dir=None):
        """ Download all templates relevant to provided CloudShell Version
        :param str cs_version: The desired version of the CloudShell
        :param str output_dir: Output directory to download templates
        """

        shellfoundry_config = self.cloudshell_config_reader.read()
        online_mode = shellfoundry_config.online_mode.lower() == "true"
        if online_mode:
            try:
                response = self.template_retriever._get_templates_from_github()
                config = yaml.safe_load(response)
                repos = set(template["repository"] for template in config["templates"])

                if not output_dir:
                    output_dir = os.path.abspath(os.path.curdir)

                archive_name = "shellfoundry_templates_{}".format(cs_version)

                archive_path = os.path.join(output_dir, "{}.zip".format(archive_name))
                if os.path.exists(archive_path):
                    click.confirm(
                        text="Templates archive for CloudShell Version {cs_version} already exists in path {path}."
                             "\nDo you wish to overwrite it?".format(cs_version=cs_version,
                                                                     path=archive_path),
                        abort=True)
                    os.remove(archive_path)

                with TempDirContext(archive_name) as temp_dir:
                    templates_path = temp_dir
                    threads = []
                    errors = []
                    for i, repo in enumerate(repos):
                        template_thread = Thread(name=str(i),
                                                 target=self.download_template,
                                                 args=(repo, cs_version, templates_path,
                                                       shellfoundry_config.github_login,
                                                       shellfoundry_config.github_password, errors))
                        threads.append(template_thread)

                    for thread in threads:
                        thread.start()
                    for thread in threads:
                        thread.join()

                    if errors:
                        raise click.ClickException(errors[0])

                    os.chdir(output_dir)
                    shutil.make_archive(archive_name, "zip", templates_path)

                click.echo(
                    "Downloaded templates for CloudShell {cs_version} to {templates}".format(cs_version=cs_version,
                                                                                             templates=os.path.abspath(
                                                                                                 archive_path)))
            except SSLError:
                raise click.UsageError("Could not retrieve the templates list to download. Are you offline?")
        else:
            click.echo("Please, move shellfoundry to online mode. See, shellfoundry config command")
Ejemplo n.º 5
0
    def _import_online_template(self, name, running_on_same_folder, template,
                                version, standards, python_version):
        """ Create shell based on template downloaded from GitHub by the name """

        # Create a temp folder for the operation to make sure we delete it after
        with TempDirContext(name) as temp_dir:
            try:
                templates = self.template_retriever.get_templates(
                    standards=standards)
            except (SSLError, FatalError):
                raise click.UsageError(
                    "Cannot retrieve templates list, are you offline?")
            except FeatureUnavailable:
                templates = self.template_retriever.get_templates(
                    alternative=ALTERNATIVE_TEMPLATES_PATH,
                    standards=standards)

            templates = {
                template_name: template[0]
                for template_name, template in templates.items()
            }

            if template not in templates:
                raise click.BadParameter(
                    'Template {0} does not exist. '
                    'Supported templates are: {1}'.format(
                        template, self._get_templates_with_comma(templates)))
            template_obj = templates[template]

            if not version and template != self.L1_TEMPLATE:
                version = self._get_template_latest_version(
                    standards, template_obj.standard)

            try:
                repo_path = self.repository_downloader.download_template(
                    temp_dir, template_obj.repository, version)
            except VersionRequestException:
                branches = TemplateVersions(*template_obj.repository.split('/')
                                            [-2:]).get_versions_of_template()
                branches.remove(MASTER_BRANCH_NAME)
                branches_str = ', '.join(branches)
                raise click.BadParameter(
                    'Requested standard version (\'{}\') does not match template version. \n'
                    'Available versions for {}: {}'.format(
                        version, template_obj.name, branches_str))

            self._verify_template_standards_compatibility(
                template_path=repo_path, standards=standards)

            self.template_compiler.compile_template(
                shell_name=name,
                template_path=repo_path,
                extra_context=template_obj.params,
                running_on_same_folder=running_on_same_folder,
                python_version=python_version)
    def pack(self, path):
        """
        Creates TOSCA based Shell package
        :return:
        """

        self._remove_all_pyc(path)
        shell_package = ShellPackage(path)
        shell_name = shell_package.get_shell_name()
        shell_real_name = shell_package.get_name_from_definition()
        with TempDirContext(shell_name) as package_path:
            self._copy_tosca_meta(package_path, "")
            tosca_meta = self._read_tosca_meta(path)

            shell_definition_path = tosca_meta["Entry-Definitions"]

            self._copy_shell_definition(package_path, "",
                                        shell_definition_path)

            with open(shell_definition_path) as shell_definition_file:
                shell_definition = yaml.load(shell_definition_file)

                if "template_icon" in shell_definition["metadata"]:
                    self._copy_artifact(
                        shell_definition["metadata"]["template_icon"],
                        package_path)

                for node_type in shell_definition["node_types"].values():
                    if "artifacts" not in node_type:
                        continue

                    for artifact_name, artifact in node_type[
                            "artifacts"].iteritems():
                        if artifact_name == "driver":
                            self._create_driver(path="",
                                                package_path=os.curdir,
                                                dir_path=self.DRIVER_DIR,
                                                driver_name=os.path.basename(
                                                    artifact["file"]))
                        elif artifact_name == "deployment":
                            self._create_driver(path="",
                                                package_path=os.curdir,
                                                dir_path=self.DEPLOY_DIR,
                                                driver_name=os.path.basename(
                                                    artifact["file"]),
                                                mandatory=False)

                        self._copy_artifact(artifact["file"], package_path)

            zip_path = self._zip_package(package_path, "", shell_real_name)

            click.echo(u"Shell package was successfully created: " + zip_path)
Ejemplo n.º 7
0
    def extend(self, source, attribute_names):
        """ Create a new shell based on an already existing shell
        :param str source: The path to the existing shell. Can be a url or local path
        :param tuple attribute_names: Sequence of attribute names that should be added
        """

        with TempDirContext("Extended_Shell_Temp_Dir") as temp_dir:
            try:
                if self._is_local(source):
                    temp_shell_path = self._copy_local_shell(
                        self._remove_prefix(
                            source,
                            ExtendCommandExecutor.LOCAL_TEMPLATE_URL_PREFIX),
                        temp_dir)
                else:
                    temp_shell_path = self._copy_online_shell(source, temp_dir)
            except VersionRequestException as err:
                raise click.ClickException(err.message)
            except Exception:
                # raise
                raise click.BadParameter(
                    u"Check correctness of entered attributes")

            # Remove shell version from folder name
            shell_path = re.sub(r"-\d+(\.\d+)*/?$", "", temp_shell_path)
            os.rename(temp_shell_path, shell_path)

            if not self.shell_gen_validations.validate_2nd_gen(shell_path):
                raise click.ClickException(u"Invalid second generation Shell.")

            modificator = DefinitionModification(shell_path)
            self._unpack_driver_archive(shell_path, modificator)
            self._remove_quali_signature(shell_path)
            self._change_author(shell_path, modificator)
            self._add_based_on(shell_path, modificator)
            self._add_attributes(shell_path, attribute_names)

            try:
                # pass
                shutil.move(shell_path, os.path.curdir)
            except shutil.Error as err:
                raise click.BadParameter(err.message)

        click.echo("Created shell based on source {}".format(source))
Ejemplo n.º 8
0
    def _generate_driver_data_model(client, cloudshell_config,
                                    destination_path, package_full_path,
                                    shell_filename, shell_name):
        """

        :param client:
        :param cloudshell_config:
        :type cloudshell_config: InstallConfig
        :param destination_path:
        :param package_full_path:
        :param shell_filename:
        :param shell_name:
        :return:
        """
        url = 'http://{0}:{1}/API/ShellDrivers/Generate'.format(
            cloudshell_config.host, cloudshell_config.port)
        token = client.token
        response = post(url,
                        files={
                            path.basename(shell_filename):
                            open(package_full_path, 'rb')
                        },
                        headers={'Authorization': 'Basic ' + token})

        if response.status_code != 200:
            error_message = 'Code generation failed with code {0} and error {1}' \
                .format(response.status_code, response.text)
            click.echo(message=error_message, err=True)
            return

        click.echo('Extracting data model ...')
        with TempDirContext(remove_dir_on_error=False,
                            prefix=shell_name) as temp_dir:
            generated_zip = path.join(temp_dir, shell_filename)
            click.echo('Writing temporary file {0}'.format(generated_zip))
            with open(generated_zip, 'wb') as driver_file:
                driver_file.write(response.content)

            click.echo(
                'Extracting generated code at {0}'.format(destination_path))
            with zipfile.ZipFile(generated_zip) as zf:
                zf.extractall(destination_path)
Ejemplo n.º 9
0
    def _import_online_template(self, name, running_on_same_folder, template, version):
        # Create a temp folder for the operation to make sure we delete it after
        with TempDirContext(name) as temp_dir:
            try:
                standards = self.standards.fetch()
                templates = self.template_retriever.get_templates(standards=standards)
            except (SSLError, FatalError):
                raise click.UsageError("Cannot retrieve templates list, are you offline?")
            except FeatureUnavailable:
                standards = self.standards.fetch(alternative=ALTERNATIVE_STANDARDS_PATH)
                templates = self.template_retriever.get_templates(
                    alternative=ALTERNATIVE_TEMPLATES_PATH, standards=standards)

            if template not in templates:
                raise click.BadParameter(
                    u'Template {0} does not exist. Supported templates are: {1}'.format(template,
                                                                                        self._get_templates_with_comma(
                                                                                            templates)))
            template_obj = templates[template]

            if not version:
                version = self._get_template_latest_version(standards, template_obj.standard)

            try:
                repo_path = self.repository_downloader.download_template(temp_dir, template_obj.repository, version)
            except VersionRequestException:
                branches = TemplateVersions(*template_obj.repository.split('/')[-2:]).get_versions_of_template()
                branches.remove(MASTER_BRANCH_NAME)
                branches_str = ', '.join(branches)
                raise click.BadParameter(
                    u'Requested standard version (\'{}\') does not match '
                    u'template version. \nAvailable versions for {}: {}'
                    .format(version, template_obj.name, branches_str))

            self.template_compiler.compile_template(name, repo_path, template_obj.params,
                                                    running_on_same_folder)