def teardown(builder: ChartBuilder): builder.uninstall_chart() while True: if not kubectl_name_dict("configmap"): break info("Terminating...") info("airflow uninstalled")
def test_namespace_doesnt_exist(chart_info): builder = ChartBuilder(chart_info, [], namespace="12345678") with pytest.raises( NamespaceDoesNotExist, match=".*To create namespace on installation, " "use create_namespace=True in the ChartBuilder class.*", ): builder.install_chart()
def test_helm_upgrade(chart_info): builder = ChartBuilder(chart_info, []) with ChartInstallationContext(builder): # Check helm release builder.upgrade_chart() helm_installation = get_helm_installations() assert helm_installation["NAME"][0] == "test" assert helm_installation["REVISION"][0] == "2" assert helm_installation["STATUS"][0] == "deployed" assert helm_installation["NAMESPACE"][0] == "default"
def test_install_local_dependency(): # Create "fake" chart output_directory = Path.cwd() / "tmp" chart_info = ChartInfo("3.2.4", "local-chart", "0.1.0") builder = ChartBuilder(chart_info, [], output_directory=str(output_directory)) builder.generate_chart() # Create chart with local dependency local_dependency = ChartDependency( name=chart_info.name, version=chart_info.version, local_repo_name="local-repo", repository=f"file://{output_directory.resolve()}/{chart_info.name}", is_local=True, ) builder = ChartBuilder( ChartInfo( api_version="3.2.4", name="local-repo-dep-test", version="0.1.0", app_version="v1", dependencies=[local_dependency], ), [], keep_chart=True, ) builder.generate_chart() with ChartInstallationContext(builder): assert builder.is_installed
def test_replication_controller(chart_info, replication_controller): builder = ChartBuilder(chart_info, [replication_controller]) with ChartInstallationContext(builder): replication_info = kubectl_get("replicationcontrollers") assert replication_info["NAME"][0] == "test-replication-controller" assert replication_info["DESIRED"][0] == "1" assert replication_info["CURRENT"][0] == "1"
def test_create_pod_template(chart_info: ChartInfo, pod_template: PodTemplate): builder = ChartBuilder(chart_info, [pod_template]) with ChartInstallationContext(builder): template_info = kubectl_get("podtemplates") assert template_info["NAME"][0] == "test-pod-template" assert template_info["CONTAINERS"][0] == "test-container-0" assert template_info["IMAGES"][0] == "k8s.gcr.io/echoserver:1.4"
def test_endpoints_with_subset(chart_info: ChartInfo, endpoints_with_subset: Endpoints): builder = ChartBuilder(chart_info, [endpoints_with_subset]) with ChartInstallationContext(builder): endpoints_info = get_endpoints_info() assert endpoints_info["NAME"][0] == "test-endpoints" assert endpoints_info["ENDPOINTS"][0] == "10.9.8.7"
def test_certificate_signing_request(chart_info): signing_request = CertificateSigningRequest( ObjectMeta(name="signing-request"), CertificateSigningRequestSpec( "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQV" "FBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFF" "RgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWl" "JTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBG" "d2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SV" "BYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpu" "b1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RV" "F6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01L" "aE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKz" "BERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVM" "QlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQT" "Z1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5" "VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG" "5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdM" "YTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2" "JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1W" "Qzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SV" "FjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo="), ) builder = ChartBuilder( chart_info, [signing_request], ) with ChartInstallationContext(builder): certificate_signing_request_frame = DataFrame( kubectl_get("certificatesigningrequest")) certificate_signing_request_frame = certificate_signing_request_frame[ certificate_signing_request_frame["NAME"] == signing_request.metadata.name].reset_index() assert certificate_signing_request_frame["NAME"][ 0] == "signing-request"
def test_eviction(chart_info): builder = ChartBuilder( chart_info, [Eviction(ObjectMeta(name="test-eviction"), None)], # type: ignore ) with ChartInstallationContext(builder): kubectl_get("eviction")
def test_network_policy( chart_info, name: str, selector: Optional[LabelSelector], egress: Optional[List[NetworkPolicyEgressRule]], ingress: Optional[List[NetworkPolicyIngressRule]], policy_types: Optional[List[str]], ): builder = ChartBuilder( chart_info, [ NetworkPolicy( ObjectMeta(name=name), NetworkPolicySpec(egress, ingress, selector, policy_types), ) ], ) with ChartInstallationContext(builder): network_policy_info = kubectl_get("networkpolicy") assert network_policy_info["NAME"][0] == name expected_selector = "<none>" if isinstance(selector, LabelSelector): match_labels = selector.matchLabels if match_labels is None: raise Exception("Match labels cannot be none in this case") first_key = list(match_labels.keys())[0] expected_selector = f"{first_key}={match_labels[first_key]}" assert network_policy_info["POD-SELECTOR"][0] == expected_selector
def test_controller_revision(chart_info, controller_revision): builder = ChartBuilder(chart_info, [controller_revision]) with ChartInstallationContext(builder): controller_revision_info = kubectl_get("controllerrevisions") assert controller_revision_info["NAME"][ 0] == "test-controller-revision" assert controller_revision_info["REVISION"][0] == "1"
def test_api_resource(chart_info): builder = ChartBuilder( chart_info, [APIResource("test", None, None, None, None, None, None, None, None)], # type: ignore ) with ChartInstallationContext(builder): print(kubectl_get("apiresource"))
def test_values_yaml_output(chart_info: ChartInfo, config_map_value_yaml, values_yaml): template_directory = ChartBuilder( chart_info, [config_map_value_yaml], values=values_yaml, ).generate_chart() with open(template_directory / "ConfigMap-0.yaml") as config_map_file: assert ( config_map_file.read() == """apiVersion: v1 data: my_nested_value: '{{ .Values.my.nested.value }}' my_value: '{{ .Values.my_value }}' kind: ConfigMap metadata: name: test-values """ ) with open(template_directory.parent / "values.yaml") as values_file: assert ( values_file.read() == """my: nested: value: 0 my_value: some_value """ )
def test_deployment( chart_info, test_labels, pod_template_spec, selector, deployment_strategy: Optional[DeploymentStrategy], ): builder = ChartBuilder( chart_info, [ Deployment( metadata=ObjectMeta(name="test-deployment", labels=test_labels), spec=DeploymentSpec( replicas=1, template=pod_template_spec, selector=selector, strategy=deployment_strategy, ), ) ], ) with ChartInstallationContext(builder): deployment_info = kubectl_get("deployments") assert deployment_info["NAME"][0] == "test-deployment" assert deployment_info["READY"][0] == "1/1"
def test_object_meta(chart_info: ChartInfo, object_meta: ObjectMeta): config_map = ConfigMap(object_meta, {"test": "1"},) builder = ChartBuilder(chart_info, [config_map]) with ChartInstallationContext(builder): config_maps = kubectl_get("configmaps") assert config_maps["NAME"][0] == config_map.metadata.name assert config_maps["DATA"][0] == str(len(config_map.data))
def test_replica_set(chart_info, replica_set): builder = ChartBuilder(chart_info, [replica_set]) with ChartInstallationContext(builder): replica_set_info = kubectl_get("replicasets") assert replica_set_info["NAME"][0] == "test-replica-set" assert replica_set_info["DESIRED"][0] == "1" assert replica_set_info["CURRENT"][0] == "1"
def test_chart_installation(config_map): builder = ChartBuilder( ChartInfo( api_version="3.2.4", name="test", version="0.1.0", app_version="v1", maintainers=[ ChartMaintainer("A Name Jr.", "*****@*****.**", "www.example.com") ], ), [config_map], ) assert not builder.is_installed with ChartInstallationContext(builder): # Check helm release helm_installation = get_helm_installations() assert helm_installation["NAME"][0] == "test" assert helm_installation["REVISION"][0] == "1" assert helm_installation["STATUS"][0] == "deployed" assert builder.is_installed config_maps = kubectl_get("configmaps") assert config_maps["NAME"][0] == "test-config-map" assert config_maps["DATA"][0] == "1"
def test_already_installed_error(chart_info, config_map): builder = ChartBuilder( chart_info, [config_map], ) builder.install_chart() with pytest.raises(ChartAlreadyInstalledError): builder.install_chart() builder.uninstall_chart()
def test_chart_w_multiple_dependencies_repo_not_present( grafana_dependency, kube2iam_dependency): builder = ChartBuilder( ChartInfo( api_version="3.2.4", name="test", version="0.1.0", app_version="v1", dependencies=[grafana_dependency, kube2iam_dependency], ), [], ) assert "stable" not in builder.get_helm_repos() with ChartInstallationContext(builder): assert builder.is_installed remove_stable_repo()
def test_empty_persistent_volume_claim(chart_info, empty_persistent_volume_claim): builder = ChartBuilder(chart_info, [empty_persistent_volume_claim]) with ChartInstallationContext(builder): volume_info = kubectl_get("persistentvolumeclaims") assert volume_info["NAME"][0] == "test-persistent-volume-claim" assert volume_info["CAPACITY"][0] == "1" assert volume_info["ACCESS MODES"][0] == modes_expected_value
def test_chart_folder_building(test_deployment1: Deployment): test_folder = Path("tmp") os.makedirs(test_folder, exist_ok=True) builder = ChartBuilder( ChartInfo(api_version="3.2.4", name="test", version="0.1.0"), [test_deployment1, test_deployment1], str(test_folder), ) builder.generate_chart() templates_folder = test_folder / builder.chart_info.name / "templates" for file in os.listdir(templates_folder): with open(templates_folder / Path(file)) as kube_file: assert kube_file.read() == str(test_deployment1) assert re.match(rf"{test_deployment1.kind}-[0-9]+\.yaml", file) shutil.rmtree(test_folder)
def test_secret(chart_info, secret_data: dict): builder = ChartBuilder( chart_info, [Secret(ObjectMeta(name="test-secret"), secret_data)]) with ChartInstallationContext(builder): secret_info = get_secret_info() assert secret_info["NAME"][0] == "test-secret" assert secret_info["DATA"][0] == str( len(secret_data)) if secret_data else "0"
def __init__(self, cleanup: bool = False, chart_info_file: str = None) -> None: """Setup Helm chart details. Arguments: cleanup (bool): cleanup after execution. Defaults to False. chart_info_file (str): description file of a chart. Default to None. """ chart_info = None dependencies = [] super().__init__(cleanup=cleanup) chart_info_path = get_local_dir() / chart_info_file try: with open(chart_info_path, 'r') as stream: chart_info = yaml.safe_load(stream) except IOError as err: msg = f"{chart_info_file} not found." raise EnvironmentPreparationException(msg) from err try: for dependency in chart_info["dependencies"]: dep = ChartDependency( name=dependency["name"], version=dependency["version"], repository=dependency["repository"], local_repo_name=dependency["local_repo_name"], values=dependency["values"]) dependencies.append(dep) self.builder = ChartBuilder( chart_info=ChartInfo( api_version=chart_info["api_version"], name=chart_info["chart_name"], version=chart_info["version"], # SemVer 2 version app_version=chart_info["app_version"], dependencies=dependencies), kubernetes_objects=[], keep_chart=False) except KeyError as err: msg = f"{chart_info_file} does not contain required keys." raise EnvironmentPreparationException(msg) from err
def test_installation_with_value_args(chart_info): builder = ChartBuilder(chart_info, [], namespace="test") with ChartInstallationContext(builder, extra_installation_args={"output": "json"}): helm_installation = get_helm_installations("test") assert helm_installation["NAME"][0] == "test" assert helm_installation["REVISION"][0] == "1" assert helm_installation["STATUS"][0] == "deployed" assert helm_installation["NAMESPACE"][0] == "test"
def test_installation_with_namespace(chart_info): builder = ChartBuilder(chart_info, [], namespace="test") with ChartInstallationContext(builder, timeout=60): # Check helm release helm_installation = get_helm_installations("test") assert helm_installation["NAME"][0] == "test" assert helm_installation["REVISION"][0] == "1" assert helm_installation["STATUS"][0] == "deployed" assert helm_installation["NAMESPACE"][0] == "test"
def test_values_yaml_with_dependencies( config_map_value_yaml, values_yaml, dependency_chart_info ): builder = ChartBuilder( dependency_chart_info, [config_map_value_yaml], values=values_yaml ) with ChartInstallationContext(builder): assert get_config_map_data() == {"my_nested_value": 0, "my_value": "some_value"} assert builder.is_installed
def test_role_binding_to_service_account( chart_info, role, role_binding_to_service_account, empty_service_account ): builder = ChartBuilder( chart_info, [role, role_binding_to_service_account, empty_service_account] ) with ChartInstallationContext(builder): bindings = kubectl_get("rolebinding") assert bindings["NAME"][0] == "test-role-binding" assert bindings["ROLE"][0] == "Role/test-role"
def test_container_probes(chart_info, probe: Probe): pod = get_pod_with_options(readiness_probe=probe) builder = ChartBuilder(chart_info, [pod]) with ChartInstallationContext(builder, expected_status={"1/1"}, status_field="READY"): pod_info = kubectl_get("pods") assert pod_info["NAME"][0] == "test-pod" assert pod_info["READY"][0] == "1/1" assert pod_info["STATUS"][0] == "Running"
def test_cluster_role_binding(chart_info, cluster_role_binding: ClusterRoleBinding): builder = ChartBuilder(chart_info, [cluster_role_binding, CLUSTER_ROLE]) with ChartInstallationContext(builder): cluster_role_binding_info = kubectl_get("clusterrolebinding") info_frame = DataFrame(cluster_role_binding_info) info_frame = info_frame[ info_frame["NAME"] == cluster_role_binding.metadata.name ].reset_index() assert info_frame["NAME"][0] == cluster_role_binding.metadata.name assert info_frame["ROLE"][0] == f"ClusterRole/{CLUSTER_ROLE.metadata.name}"
def test_helm_upgrade_w_dependencies(chart_info, grafana_dependency): builder = ChartBuilder( ChartInfo( api_version="3.2.4", name="test", version="0.1.0", app_version="v1", dependencies=[grafana_dependency], ), [], ) with ChartInstallationContext(builder): builder.upgrade_chart(options={"dependency-update": None}) helm_installation = get_helm_installations() assert helm_installation["NAME"][0] == "test" assert helm_installation["REVISION"][0] == "2" assert helm_installation["STATUS"][0] == "deployed" assert helm_installation["NAMESPACE"][0] == "default" remove_stable_repo()