def get_reference_object(self) -> V1Deployment: """Get deployment object for outpost""" # Generate V1ContainerPort objects container_ports = [] for port in self.controller.deployment_ports: container_ports.append( V1ContainerPort( container_port=port.port, name=port.name, protocol=port.protocol.upper(), )) meta = self.get_object_meta(name=self.name) secret_name = f"authentik-outpost-{self.controller.outpost.uuid.hex}-api" image_prefix = CONFIG.y("outposts.docker_image_base") return V1Deployment( metadata=meta, spec=V1DeploymentSpec( replicas=self.outpost.config.kubernetes_replicas, selector=V1LabelSelector(match_labels=self.get_pod_meta()), template=V1PodTemplateSpec( metadata=V1ObjectMeta(labels=self.get_pod_meta()), spec=V1PodSpec(containers=[ V1Container( name=str(self.outpost.type), image= f"{image_prefix}-{self.outpost.type}:{__version__}", ports=container_ports, env=[ V1EnvVar( name="AUTHENTIK_HOST", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=secret_name, key="authentik_host", )), ), V1EnvVar( name="AUTHENTIK_TOKEN", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=secret_name, key="token", )), ), V1EnvVar( name="AUTHENTIK_INSECURE", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=secret_name, key="authentik_host_insecure", )), ), ], ) ]), ), ), )
def test_get_kubernetes_env_vars(): test_env_vars = pmap({ "FAKE_PLAIN_VAR": "not_secret_data", }) test_secret_env_vars = pmap({ "FAKE_SECRET": { "secret_name": "taskns-secret-taskname-some--secret--name", "key": "some_secret_name" }, "FAKE_SHARED_SECRET": { "secret_name": "taskns-secret-underscore-shared-shared--secret-name", "key": "shared_secret-name" }, }) expected_env_vars = [ V1EnvVar(name="FAKE_PLAIN_VAR", value="not_secret_data"), V1EnvVar( name="FAKE_SECRET", value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector( name="taskns-secret-taskname-some--secret--name", key="some_secret_name", optional=False, ), ), ), V1EnvVar( name="FAKE_SHARED_SECRET", value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector( name="taskns-secret-underscore-shared-shared--secret-name", key="shared_secret-name", optional=False, ), ), ), ] env_vars = get_kubernetes_env_vars( environment=test_env_vars, secret_environment=test_secret_env_vars, ) assert sorted(expected_env_vars, key=lambda x: x.name) == sorted(env_vars, key=lambda x: x.name) test_dupe_env_vars = test_env_vars.set("FAKE_SECRET", "SECRET(not_secret_data)") env_vars = get_kubernetes_env_vars( environment=test_dupe_env_vars, secret_environment=test_secret_env_vars, ) assert sorted(expected_env_vars, key=lambda x: x.name) == sorted(env_vars, key=lambda x: x.name)
def custom_artifact_location(secret_name: str = "mlpipeline-minio-artifact", tag: str = '1.31.0', namespace: str = "kubeflow", bucket: str = "mlpipeline"): # configures artifact location pipeline_artifact_location = dsl.ArtifactLocation.s3( bucket=bucket, endpoint="minio-service.%s:9000" % namespace, # parameterize minio-service endpoint insecure=True, access_key_secret=V1SecretKeySelector(name=secret_name, key="accesskey"), secret_key_secret={ "name": secret_name, "key": "secretkey" }, # accepts dict also ) # set pipeline level artifact location dsl.get_pipeline_conf().set_artifact_location(pipeline_artifact_location) # artifacts in this op are stored to endpoint `minio-service.<namespace>:9000` op = dsl.ContainerOp(name="foo", image="busybox:%s" % tag, command=['sh', '-c', 'echo hello > /tmp/output.txt'], file_outputs={'output': '/tmp/output.txt'})
def get_kubernetes_env_vars( environment: PMap[str, str], secret_environment: PMap[str, 'SecretEnvSource'], ) -> List[V1EnvVar]: """ Given a dict of environment variables, transform them into the corresponding Kubernetes representation. This function will replace any secret placeholders with the value of the actual secret. """ env_vars = [ V1EnvVar(name=key, value=value) for key, value in environment.items() if key not in secret_environment.keys() ] secret_env_vars = [ V1EnvVar( name=key, value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector( name=value["secret_name"], key=value["key"], optional=False, ), ), ) for key, value in secret_environment.items() ] return env_vars + secret_env_vars
def create_pod_mapping(self, name, data, secret=False): result = [] for item in data: env_var = V1EnvVar(name=item['name']) if secret: ref = V1SecretKeySelector(item['name'], name) env_var.value_from = V1EnvVarSource(secret_key_ref=ref) else: ref = V1ConfigMapKeySelector(item['name'], name) env_var.value_from = V1EnvVarSource(config_map_key_ref=ref) result.append(kubernetes.client.ApiClient().sanitize_for_serialization(env_var)) #We need to sanitize the V1EnvVar to be able to serialize it later return result
def custom_artifact_location( tag: str, namespace: str = "kubeflow", bucket: str = "mybucket" ): # configures artifact location pipeline_artifact_location = dsl.ArtifactLocation.s3( bucket=bucket, endpoint="minio-service.%s:9000" % namespace, # parameterize minio-service endpoint insecure=True, access_key_secret=V1SecretKeySelector(name="minio", key="accesskey"), secret_key_secret={"name": "minio", "key": "secretkey"}, # accepts dict also ) # set pipeline level artifact location dsl.get_pipeline_conf().set_artifact_location(pipeline_artifact_location) # artifacts in this op are stored to endpoint `minio-service.<namespace>:9000` op = dsl.ContainerOp(name="foo", image="busybox:%s" % tag)
def _parse_env_from(value_from: dict) -> V1EnvVarSource: """Parses an environment value dict into an EnvVarSource""" source = value_from.get('source', '').lower() if source == 'secret': return V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=value_from['name'], key=value_from['key'], ), ) elif source == 'configmap': return V1EnvVarSource( config_map_key_ref=V1ConfigMapKeySelector( name=value_from['name'], key=value_from['key'], ), ) else: raise ValueError(f'Unsupported environment source "{source}"')
def test_secret_key_ref(self): service_account = self.cluster_object.spec.backups.gcs.service_account expected = V1ServiceAccountRef(secret_key_ref=V1SecretKeySelector( name="storage-serviceaccount", key="json")) self.assertEqual(expected, service_account)
def _get_container(self, command: str, config_map_volume_names: list = None) -> V1Container: """Get the K8s container object to be used by by a PodSpec. :param command: The command to run in the container. :return: The V1Container object definition to run the command. """ if self.use_https: protocol = "https" else: protocol = "http" config_map_mounts = [] if config_map_volume_names: for map_number, map_volume in enumerate(config_map_volume_names): mount_dir = self.config_map_path + f"/{map_number}" config_map_mounts.append( V1VolumeMount(name=map_volume, mount_path=mount_dir) ) env_setup_ca1 = "mkdir -p /root/.mc/certs/CAs; " # The find command doesn't exist by default in the minio container env_setup_ca2 = f"cp {self.config_map_path}/*/* /root/.mc/certs/CAs/; " env_setup_ca = env_setup_ca1 + env_setup_ca2 else: env_setup_ca = "" env_setup1 = f"export MC_HOST_{self.s3_alias}={protocol}://${{S3_ACCESSKEY}}:${{S3_SECRETKEY}}@" env_setup2 = f"{self.s3_host}:{self.s3_port}; " container_setup = env_setup_ca + env_setup1 + env_setup2 container = V1Container( name="netapp-dataops-s3mc-container", image=self.image, env=[ V1EnvVar( name="S3_ACCESSKEY", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.credentials_secret_name, key="access_key" ) ) ), V1EnvVar( name="S3_SECRETKEY", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.credentials_secret_name, key="secret_key" ) ) ), ], command=["/bin/bash"], args=["-c", container_setup + command], volume_mounts=[ V1VolumeMount(mount_path=self.data_volume_path, name=self.data_volume_name) ] + config_map_mounts, resources=self._get_resource_requirements() ) return container
def get_reference_object(self) -> V1Deployment: """Get deployment object for outpost""" # Generate V1ContainerPort objects container_ports = [] for port in self.controller.deployment_ports: container_ports.append( V1ContainerPort( container_port=port.inner_port or port.port, name=port.name, protocol=port.protocol.upper(), ) ) meta = self.get_object_meta(name=self.name) image_name = self.controller.get_container_image() image_pull_secrets = self.outpost.config.kubernetes_image_pull_secrets version = get_full_version() return V1Deployment( metadata=meta, spec=V1DeploymentSpec( replicas=self.outpost.config.kubernetes_replicas, selector=V1LabelSelector(match_labels=self.get_pod_meta()), template=V1PodTemplateSpec( metadata=V1ObjectMeta( labels=self.get_pod_meta( **{ # Support istio-specific labels, but also use the standard k8s # recommendations "app.kubernetes.io/version": version, "app": "authentik-outpost", "version": version, } ) ), spec=V1PodSpec( image_pull_secrets=[ V1ObjectReference(name=secret) for secret in image_pull_secrets ], containers=[ V1Container( name=str(self.outpost.type), image=image_name, ports=container_ports, env=[ V1EnvVar( name="AUTHENTIK_HOST", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.name, key="authentik_host", ) ), ), V1EnvVar( name="AUTHENTIK_HOST_BROWSER", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.name, key="authentik_host_browser", ) ), ), V1EnvVar( name="AUTHENTIK_TOKEN", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.name, key="token", ) ), ), V1EnvVar( name="AUTHENTIK_INSECURE", value_from=V1EnvVarSource( secret_key_ref=V1SecretKeySelector( name=self.name, key="authentik_host_insecure", ) ), ), ], ) ], ), ), ), )