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 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 create_master(self, **kargs): env = [ V1EnvVar( name="MY_POD_IP", value_from=V1EnvVarSource(field_ref=V1ObjectFieldSelector( field_path="status.podIP")), ) ] if "envs" in kargs: for key in kargs["envs"]: env.append(V1EnvVar(name=key, value=kargs["envs"][key])) pod = self._create_pod( pod_name=self.get_master_pod_name(), job_name=self.job_name, image_name=self._image_name, command=["python"], resource_requests=kargs["resource_requests"], resource_limits=kargs["resource_limits"], container_args=kargs["args"], pod_priority=kargs["pod_priority"], image_pull_policy=kargs["image_pull_policy"], restart_policy=kargs["restart_policy"], volume=kargs["volume"], owner_pod=None, env=env, ) # Add replica type and index pod.metadata.labels[ELASTICDL_REPLICA_TYPE_KEY] = "master" pod.metadata.labels[ELASTICDL_REPLICA_INDEX_KEY] = "0" self.client.create_namespaced_pod(self.namespace, pod) logger.info("Master launched.")
def setUp(self): super().setUp() self.cluster_dict = getExampleClusterDefinition() self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict) self.name = self.cluster_object.metadata.name self.namespace = self.cluster_object.metadata.namespace self.stateful_set = V1beta1StatefulSet( metadata=self._createMeta(self.name), spec=V1beta1StatefulSetSpec( replicas=3, service_name=self.name, template=V1PodTemplateSpec( metadata=V1ObjectMeta(labels=KubernetesResources. createDefaultLabels(self.name)), spec=V1PodSpec(containers=[ V1Container( name="mongodb", env=[ V1EnvVar(name="POD_IP", value_from=V1EnvVarSource( field_ref=V1ObjectFieldSelector( api_version="v1", field_path="status.podIP"))) ], command=[ "mongod", "--replSet", self.name, "--bind_ip", "0.0.0.0", "--smallfiles", "--noprealloc" ], image="mongo:3.6.4", ports=[ V1ContainerPort(name="mongodb", container_port=27017, protocol="TCP") ], volume_mounts=[ V1VolumeMount(name="mongo-storage", read_only=False, mount_path="/data/db") ], resources=V1ResourceRequirements(limits={ "cpu": "100m", "memory": "64Mi" }, requests={ "cpu": "100m", "memory": "64Mi" })) ])), volume_claim_templates=[ V1PersistentVolumeClaim( metadata=V1ObjectMeta(name="mongo-storage"), spec=V1PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], resources=V1ResourceRequirements( requests={"storage": "30Gi"}))) ], ), )
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 get_kubernetes_environment(self) -> List[V1EnvVar]: kubernetes_env = [ V1EnvVar( name='PAASTA_POD_IP', value_from=V1EnvVarSource(field_ref=V1ObjectFieldSelector( field_path='status.podIP', ), ), ), ] return kubernetes_env
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 append_pod_ip_to_env(env): pod_ip_var = V1EnvVar( name="MY_POD_IP", value_from=V1EnvVarSource(field_ref=V1ObjectFieldSelector( field_path="status.podIP")), ) if env: env.append(pod_ip_var) else: env = [pod_ip_var] return env
def _createStatefulSet(self) -> V1beta1StatefulSet: return V1beta1StatefulSet( metadata=self._createMeta(self.name), spec=V1beta1StatefulSetSpec( replicas=3, service_name=self.name, template=V1PodTemplateSpec( metadata=V1ObjectMeta(labels=KubernetesResources. createDefaultLabels(self.name)), spec=V1PodSpec(containers=[ V1Container( name="mongodb", env=[ V1EnvVar(name="POD_IP", value_from=V1EnvVarSource( field_ref=V1ObjectFieldSelector( api_version="v1", field_path="status.podIP"))) ], command=[ "mongod", "--wiredTigerCacheSizeGB", "0.25", "--replSet", self.name, "--bind_ip", "0.0.0.0", "--smallfiles", "--noprealloc" ], image="mongo:3.6.4", ports=[ V1ContainerPort(name="mongodb", container_port=27017, protocol="TCP") ], volume_mounts=[ V1VolumeMount(name="mongo-storage", read_only=False, mount_path="/data/db") ], resources=self._createResourceLimits()) ])), volume_claim_templates=[ V1PersistentVolumeClaim( metadata=V1ObjectMeta(name="mongo-storage"), spec=V1PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], resources=V1ResourceRequirements( requests={"storage": "30Gi"}))) ], ), )
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", ) ), ), ], ) ], ), ), ), )
def __init__(self) -> None: metadata = V1ObjectMeta(name="environmentd", labels={"app": "environmentd"}) label_selector = V1LabelSelector(match_labels={"app": "environmentd"}) value_from = V1EnvVarSource(field_ref=V1ObjectFieldSelector( field_path="metadata.name")) env = [ V1EnvVar(name="MZ_POD_NAME", value_from=value_from), V1EnvVar(name="AWS_REGION", value="minio"), V1EnvVar(name="AWS_ACCESS_KEY_ID", value="minio"), V1EnvVar(name="AWS_SECRET_ACCESS_KEY", value="minio123"), ] ports = [V1ContainerPort(container_port=5432, name="sql")] volume_mounts = [ V1VolumeMount(name="data", mount_path="/data"), ] s3_endpoint = urllib.parse.quote("http://minio-service.default:9000") container = V1Container( name="environmentd", image=self.image("environmentd"), args=[ "--storaged-image=" + self.image("storaged"), "--computed-image=" + self.image("computed"), "--availability-zone=kind-worker", "--availability-zone=kind-worker2", "--availability-zone=kind-worker3", f"--persist-blob-url=s3://minio:minio123@persist/persist?endpoint={s3_endpoint}®ion=minio", "--orchestrator=kubernetes", "--orchestrator-kubernetes-image-pull-policy=never", "--persist-consensus-url=postgres://[email protected]?options=--search_path=consensus", "--adapter-stash-url=postgres://[email protected]?options=--search_path=catalog", "--storage-stash-url=postgres://[email protected]?options=--search_path=storage", "--unsafe-mode", ], env=env, ports=ports, volume_mounts=volume_mounts, ) pod_spec = V1PodSpec(containers=[container]) template_spec = V1PodTemplateSpec(metadata=metadata, spec=pod_spec) claim_templates = [ V1PersistentVolumeClaim( metadata=V1ObjectMeta(name="data"), spec=V1PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], resources=V1ResourceRequirements( requests={"storage": "1Gi"}), ), ) ] self.stateful_set = V1StatefulSet( api_version="apps/v1", kind="StatefulSet", metadata=metadata, spec=V1StatefulSetSpec( service_name="environmentd", replicas=1, pod_management_policy="Parallel", selector=label_selector, template=template_spec, volume_claim_templates=claim_templates, ), )