Esempio n. 1
0
 def pre_run(self, config: argparse.Namespace) -> None:
     """
     Checks if the required version of helm is installed and if a lock file is present.
     :param config: the config object
     :return: None
     """
     if not self._should_run(config):
         logger.debug(
             "No chart version override requested, skipping dependency update."
         )
         return
     if len(self._detect_chart_lock_files(config)) == 0:
         logger.debug(
             f"No {_chart_lock} or {_requirements_lock} file exists, skipping dependency update."
         )
         return
     self._assert_binary_present_in_path(self._helm_bin)
     run_res = run_and_log([self._helm_bin, "version"],
                           capture_output=True)  # nosec
     version_line = run_res.stdout.splitlines()[0]
     prefix = "version.BuildInfo"
     if version_line.startswith(prefix):
         version_line = version_line[len(prefix):].strip("{}")
     else:
         raise ValidationError(
             self.name, f"Can't parse '{self._helm_bin}' version number.")
     version_entries = version_line.split(",")[0]
     version = version_entries.split(":")[1].strip('"')
     self._assert_version_in_range(self._helm_bin, version,
                                   self._min_helm_version,
                                   self._max_helm_version)
Esempio n. 2
0
    def run(self, config: argparse.Namespace, _: Context) -> None:
        args = [
            self._kubelinter_bin,
            "lint",
            config.chart_dir,
            "--verbose",
        ]

        # adding `--verbose` to the default args due to the kube-linter hiding
        # some problems and thus skipping linting some of the resources.

        if config.kubelinter_config is not None:
            args.append(f"--config={config.kubelinter_config}")
        logger.info("Running kube-linter tool")
        run_res = run_and_log(args, capture_output=True
                              )  # nosec, input params checked above in pre_run
        for line in run_res.stdout.splitlines():
            logger.info(line)
        if run_res.returncode != 0:
            logger.error(
                f"{self._kubelinter_bin} run failed with exit code {run_res.returncode}"
            )
            for line in run_res.stderr.splitlines():
                logger.error(line)
            raise BuildError(self.name, "kube-linter failed")
Esempio n. 3
0
 def pre_run(self, config: argparse.Namespace) -> None:
     """
     Verifies if the required version of `kube-linter` is installed and config options are sane.
     :param config: the config object
     :return: None
     """
     # verify if binary present
     self._assert_binary_present_in_path(self._kubelinter_bin)
     # verify version
     run_res = run_and_log([self._kubelinter_bin, "version"],
                           capture_output=True)  # nosec
     version = run_res.stdout.splitlines()[0]
     self._assert_version_in_range(self._kubelinter_bin, version,
                                   self._min_kubelinter_version,
                                   self._max_kubelinter_version)
     # validate config options
     if config.kubelinter_config is not None and not os.path.isabs(
             config.kubelinter_config):
         config.kubelinter_config = os.path.join(os.getcwd(),
                                                 config.kubelinter_config)
     if config.kubelinter_config is not None and not os.path.isfile(
             config.kubelinter_config):
         raise ValidationError(
             self.name,
             f"Kube-linter config file {config.kubelinter_config} doesn't exist.",
         )
     _default_cfg_path = os.path.join(config.chart_dir,
                                      self._default_kubelinter_cfg_file)
     if not config.kubelinter_config and os.path.isfile(_default_cfg_path):
         config.kubelinter_config = _default_cfg_path
Esempio n. 4
0
 def pre_run(self, config: argparse.Namespace) -> None:
     """
     Verifies if the required version of `ct` is installed and config options are sane.
     :param config: the config object
     :return: None
     """
     # verify if binary present
     self._assert_binary_present_in_path(self._ct_bin)
     # verify version
     run_res = run_and_log([self._ct_bin, "version"],
                           capture_output=True)  # nosec
     version_line = run_res.stdout.splitlines()[0]
     version = version_line.split(":")[1].strip()
     self._assert_version_in_range(self._ct_bin, version,
                                   self._min_ct_version,
                                   self._max_ct_version)
     # validate config options
     if config.ct_config is not None and not os.path.isabs(
             config.ct_config):
         config.ct_config = os.path.join(os.getcwd(), config.ct_config)
     if config.ct_config is not None and not os.path.isfile(
             config.ct_config):
         raise ValidationError(
             self.name,
             f"Chart tool config file {config.ct_config} doesn't exist.",
         )
     # if we're validating a metadata enabled project (for Giant Swarm App Platform),
     # we have to use the modified schema
     if config.generate_metadata:
         full_path = os.path.join(
             os.path.dirname(__file__),
             "..",
             "..",
             "resources",
             "ct_schemas",
             self._metadata_schema,
         )
         logger.info(
             f"Metadata generation was requested, changing default validation schema to '{self._metadata_schema}'"
         )
         config.ct_schema = full_path
     # validate schema path
     if config.ct_schema is not None and not os.path.isabs(
             config.ct_schema):
         config.ct_schema = os.path.join(os.getcwd(), config.ct_schema)
     if config.ct_schema is not None and not os.path.isfile(
             config.ct_schema):
         raise ValidationError(
             self.name,
             f"Chart tool schema file {config.ct_schema} doesn't exist.",
         )
Esempio n. 5
0
 def run(self, config: argparse.Namespace, context: Context) -> None:
     """
     Runs 'helm package' to build the chart.
     :param config: the config object
     :param context: the context object
     :return: None
     """
     args = [
         self._helm_bin,
         "package",
         config.chart_dir,
         "--destination",
         config.destination,
     ]
     logger.info("Building chart with 'helm package'")
     run_res = run_and_log(args, capture_output=True
                           )  # nosec, input params checked above in pre_run
     for line in run_res.stdout.splitlines():
         logger.info(line)
         if line.startswith("Successfully packaged chart and saved it to"):
             full_chart_path = line.split(":")[1].strip()
             full_chart_path = os.path.abspath(full_chart_path)
             # compare our expected chart_file_name with the one returned from helm and fail if differs
             helm_chart_file_name = os.path.basename(full_chart_path)
             if (context_key_chart_file_name in context
                     and helm_chart_file_name !=
                     context[context_key_chart_file_name]):
                 raise BuildError(
                     self.name,
                     f"unexpected chart path '{helm_chart_file_name}' != '{context[context_key_chart_file_name]}'",
                 )
             if context_key_chart_full_path in context and full_chart_path != context[
                     context_key_chart_full_path]:
                 raise BuildError(
                     self.name,
                     f"unexpected helm build result: path reported in output '{full_chart_path}' "
                     f"is not equal to '{context[context_key_chart_full_path]}'",
                 )
     if run_res.returncode != 0:
         logger.error(
             f"{self._helm_bin} run failed with exit code {run_res.returncode}"
         )
         raise BuildError(self.name, "Chart build failed")
Esempio n. 6
0
 def run(self, config: argparse.Namespace, context: Context) -> None:
     """
     Runs 'helm dependencies update' to update or generate a Chart.lock file.
     :param config: the config object
     :param context: the context object
     :return: None
     """
     context[context_key_chart_lock_files_to_restore] = []
     present_lock_files = self._detect_chart_lock_files(config)
     if not self._should_run(config):
         logger.debug(
             "No chart version override requested. Dependency update not required, ending step."
         )
         return
     if len(present_lock_files) == 0:
         logger.debug(
             f"No {_chart_lock} or {_requirements_lock} file exists, skipping dependency update."
         )
         return
     args = []
     for lock_file in present_lock_files:
         logger.debug(f"Saving backup of {lock_file} in {lock_file}.back")
         lock_path = os.path.join(config.chart_dir, lock_file)
         shutil.copy2(lock_path, lock_path + ".back")
         args = [
             self._helm_bin,
             "dependencies",
             "update",
             config.chart_dir,
         ]
         context[context_key_chart_lock_files_to_restore].append(lock_file)
     logger.info(
         f"Updating lockfile(s) with 'helm dependencies update {config.chart_dir}'"
     )
     run_res = run_and_log(args, capture_output=True
                           )  # nosec, input params checked above in pre_run
     if run_res.returncode != 0:
         logger.error(
             f"{self._helm_bin} run failed with exit code {run_res.returncode}"
         )
         raise BuildError(self.name, "Chart dependency update failed")
Esempio n. 7
0
 def pre_run(self, config: argparse.Namespace) -> None:
     """
     Checks if the required version of helm is installed.
     :param config: the config object
     :return: None
     """
     self._assert_binary_present_in_path(self._helm_bin)
     run_res = run_and_log([self._helm_bin, "version"],
                           capture_output=True)  # nosec
     version_line = run_res.stdout.splitlines()[0]
     prefix = "version.BuildInfo"
     if version_line.startswith(prefix):
         version_line = version_line[len(prefix):].strip("{}")
     else:
         raise ValidationError(
             self.name, f"Can't parse '{self._helm_bin}' version number.")
     version_entries = version_line.split(",")[0]
     version = version_entries.split(":")[1].strip('"')
     self._assert_version_in_range(self._helm_bin, version,
                                   self._min_helm_version,
                                   self._max_helm_version)
Esempio n. 8
0
 def run(self, config: argparse.Namespace, _: Context) -> None:
     args = [
         self._ct_bin,
         "lint",
         "--validate-maintainers=false",
         f"--charts={config.chart_dir}",
     ]
     if config.debug:
         args.append("--debug")
     if config.ct_config is not None:
         args.append(f"--config={config.ct_config}")
     if config.ct_schema is not None:
         args.append(f"--chart-yaml-schema={config.ct_schema}")
     logger.info("Running chart tool linting")
     run_res = run_and_log(args, capture_output=True
                           )  # nosec, input params checked above in pre_run
     for line in run_res.stdout.splitlines():
         logger.info(line)
     if run_res.returncode != 0:
         logger.error(
             f"{self._ct_bin} run failed with exit code {run_res.returncode}"
         )
         raise BuildError(self.name, "Linting failed")