def test_create_helm_process(rule_runner: RuleRunner) -> None: helm_binary = rule_runner.request(HelmBinary, []) helm_argv = ["foo"] helm_process = HelmProcess( helm_argv, input_digest=EMPTY_DIGEST, description="Test Helm process", extra_immutable_input_digests={"foo_digest": EMPTY_DIGEST}, extra_env={"FOO_ENV": "1"}, output_directories=["foo_out"], cache_scope=ProcessCacheScope.ALWAYS, ) process = rule_runner.request(Process, [helm_process]) assert process.argv == (helm_binary.path, *helm_argv) assert process.description == helm_process.description assert process.level == helm_process.level assert process.input_digest == helm_process.input_digest assert process.immutable_input_digests == FrozenDict({ **helm_binary.immutable_input_digests, **helm_process.extra_immutable_input_digests }) assert process.env == FrozenDict({ **helm_binary.env, **helm_process.extra_env }) assert process.output_directories == helm_process.output_directories assert process.cache_scope == helm_process.cache_scope
def create_process(chart: HelmChart, field_set: HelmLintFieldSet) -> HelmProcess: argv = ["lint", chart.path] strict: bool = field_set.lint_strict.value or helm_subsystem.lint_strict if strict: argv.append("--strict") return HelmProcess( argv, input_digest=chart.snapshot.digest, description=f"Linting chart: {chart.metadata.name}", )
def create_fetch_process(artifact: ResolvedHelmArtifact) -> HelmProcess: return HelmProcess( argv=[ "pull", artifact.name, "--repo", artifact.location_url, "--version", artifact.version, "--destination", download_prefix, "--untar", ], input_digest=empty_download_digest, description= f"Pulling Helm Chart '{artifact.name}' with version {artifact.version}", output_directories=(download_prefix, ), )
def test_install_plugin(rule_runner: RuleRunner) -> None: plugin_ls_process = HelmProcess( argv=["plugin", "ls"], input_digest=EMPTY_DIGEST, description="Verify installation of Helm plugins", ) process_result = rule_runner.request(ProcessResult, [plugin_ls_process]) # The result of the `helm plugin ls` command is a table with a header like # NAME VERSION DESCRIPTION # plugin_name 0.1.0 Some plugin description # # So to build the test expectation we parse that output keeping # the plugin's name and version to be used in the comparison plugin_table_rows = process_result.stdout.decode().splitlines()[1:] loaded_plugins = [(columns[0].strip(), columns[1].strip()) for columns in (re.split(r"\t+", line.rstrip()) for line in plugin_table_rows)] assert loaded_plugins == [(HelmUnitTestSubsystem.plugin_name, HelmUnitTestSubsystem.default_version)]
async def run_helm_package(field_set: HelmPackageFieldSet) -> BuiltPackage: result_dir = "__out" chart, result_digest = await MultiGet( Get(HelmChart, HelmChartRequest(field_set)), Get(Digest, CreateDigest([Directory(result_dir)])), ) input_digest = await Get( Digest, MergeDigests([chart.snapshot.digest, result_digest])) process_output_file = os.path.join(result_dir, _helm_artifact_filename(chart.metadata)) process_result = await Get( ProcessResult, HelmProcess( argv=["package", chart.path, "-d", result_dir], input_digest=input_digest, output_files=(process_output_file, ), description=f"Packaging Helm chart: {field_set.address.spec_path}", ), ) stripped_output_digest = await Get( Digest, RemovePrefix(process_result.output_digest, result_dir)) final_snapshot = await Get( Snapshot, AddPrefix(stripped_output_digest, field_set.output_path.value_or_default(file_ending=None)), ) return BuiltPackage( final_snapshot.digest, artifacts=tuple( BuiltPackageArtifact( file, extra_log_lines=(f"Built Helm chart artifact: {file}", )) for file in final_snapshot.files), )
async def run_helm_unittest( field_set: HelmUnitTestFieldSet, test_subsystem: TestSubsystem, unittest_subsystem: HelmUnitTestSubsystem, ) -> TestResult: direct_dep_targets, transitive_targets = await MultiGet( Get(Targets, DependenciesRequest(field_set.dependencies)), Get( TransitiveTargets, TransitiveTargetsRequest([field_set.address]), ), ) chart_targets = [tgt for tgt in direct_dep_targets if HelmChartFieldSet.is_applicable(tgt)] if len(chart_targets) == 0: raise MissingUnitTestChartDependency(field_set.address) chart, source_files = await MultiGet( Get(HelmChart, HelmChartRequest, HelmChartRequest.from_target(chart_targets[0])), Get( StrippedSourceFiles, SourceFilesRequest( sources_fields=[ field_set.source, *( tgt.get(SourcesField) for tgt in transitive_targets.dependencies if not HelmChartFieldSet.is_applicable(tgt) ), ], for_sources_types=(HelmUnitTestSourceField, ResourceSourceField), enable_codegen=True, ), ), ) prefixed_test_files_digest = await Get( Digest, AddPrefix(source_files.snapshot.digest, chart.path) ) reports_dir = "__reports_dir" reports_file = os.path.join(reports_dir, f"{field_set.address.path_safe_spec}.xml") input_digest = await Get( Digest, MergeDigests([chart.snapshot.digest, prefixed_test_files_digest]) ) # Cache test runs only if they are successful, or not at all if `--test-force`. cache_scope = ( ProcessCacheScope.PER_SESSION if test_subsystem.force else ProcessCacheScope.SUCCESSFUL ) process_result = await Get( FallibleProcessResult, HelmProcess( argv=[ unittest_subsystem.plugin_name, "--helm3", "--output-type", unittest_subsystem.output_type.value, "--output-file", reports_file, chart.path, ], description=f"Running Helm unittest on: {field_set.address}", input_digest=input_digest, cache_scope=cache_scope, output_directories=(reports_dir,), ), ) xml_results = await Get(Snapshot, RemovePrefix(process_result.output_digest, reports_dir)) return TestResult.from_fallible_process_result( process_result, address=field_set.address, output_setting=test_subsystem.output, xml_results=xml_results, )
async def publish_helm_chart( request: PublishHelmChartRequest, helm_subsystem: HelmSubsystem) -> PublishProcesses: remotes = helm_subsystem.remotes() built_artifacts = [ (pkg, artifact, artifact.metadata) for pkg in request.packages for artifact in pkg.artifacts if isinstance(artifact, BuiltHelmArtifact) and artifact.metadata ] registries_to_push = list( remotes.get(*(request.field_set.registries.value or []))) if not registries_to_push: return PublishProcesses([ PublishPackages( names=tuple(metadata.artifact_name for _, _, metadata in built_artifacts), description= f"(by missing `{request.field_set.registries.alias}` on {request.field_set.address})", ) ]) push_repository = (request.field_set.repository.value or helm_subsystem.default_registry_repository) publish_refs = [ registry.package_ref(metadata.artifact_name, repository=push_repository) for _, _, metadata in built_artifacts for registry in registries_to_push ] if request.field_set.skip_push.value: return PublishProcesses([ PublishPackages( names=tuple(publish_refs), description= f"(by `{request.field_set.skip_push.alias}` on {request.field_set.address})", ) ]) processes = await MultiGet( Get( Process, HelmProcess( [ "push", artifact.relpath, registry.repository_ref(push_repository) ], input_digest=pkg.digest, description= f"Pushing Helm chart '{metadata.name}' with version '{metadata.version}' into OCI registry: {registry.address}", ), ) for pkg, artifact, metadata in built_artifacts if artifact.relpath for registry in registries_to_push) interactive_processes = await MultiGet( Get(InteractiveProcess, InteractiveProcessRequest(process)) for process in processes) refs_and_processes = zip(publish_refs, interactive_processes) return PublishProcesses([ PublishPackages(names=(package_ref, ), process=process) for package_ref, process in refs_and_processes ])