diff --git a/core/v1/accessory.k b/core/v1/accessory.k new file mode 100644 index 0000000..15e7cb9 --- /dev/null +++ b/core/v1/accessory.k @@ -0,0 +1,5 @@ +schema Accessory(Object): + """ Accessory refers to various runtime capabilities and operational requirements provided by the underlying + infrastructure, such as database, gateway, cache e.g. All specific accessory schema definitions must inherit + the Accessory schema. + """ diff --git a/v1/app_configuration.k b/core/v1/app_configuration.k similarity index 61% rename from v1/app_configuration.k rename to core/v1/app_configuration.k index 50a23c6..d7db252 100644 --- a/v1/app_configuration.k +++ b/core/v1/app_configuration.k @@ -1,34 +1,30 @@ -import v1.workload as wl +import extensions.v1 as extv1 -schema AppConfiguration: +schema AppConfiguration(Object): """ AppConfiguration is a developer-centric definition that describes how to run an Application. This application model builds upon a decade of experience at AntGroup running super large scale internal developer platform, combined with best-of-breed ideas and practices from the community. Attributes ---------- - workload: wl.Service | wl.Job, default is Undefined, required. + workload: Service | Job, default is Undefined, required. Workload defines how to run your application code. Currently supported workload profile includes Service and Job. accessories: {str:any}, default is Undefined, optional. Accessories defines a collection of accessories that will be attached to the workload. - labels: {str:str}, default is Undefined, optional. + extensions: [extv1.KubernetesMetadata], default is Undefined, optional. Labels can be used to attach arbitrary metadata as key-value pairs to resources. - annotations: {str:str}, default is Undefined, optional. - Annotations are key/value pairs that attach arbitrary non-identifying metadata to resources. Examples -------- # Instantiate an App with a long-running service and its image is "nginx:v1" - import kam as ac - import kam.workload as wl - import kam.workload.container as c + import kam.core.v1 as v1 - helloworld : ac.AppConfiguration { - workload: wl.Service { + helloworld : v1.AppConfiguration { + workload: v1.Service { containers: { - "nginx": c.Container { + "nginx": v1.Container { image: "nginx:v1" } } @@ -37,12 +33,10 @@ schema AppConfiguration: """ # Workload defines how to run your application code. - workload: wl.Service | wl.Job + workload: Workload # Accessories defines a collection of accessories that will be attached to the workload. - accessories?: {str:any} + accessories?: {str:Accessory} - ###### Other metadata info # Labels and annotations can be used to attach arbitrary metadata as key-value pairs to resources. - labels?: {str:str} - annotations?: {str:str} \ No newline at end of file + extensions?: [extv1.KubernetesMetadata] \ No newline at end of file diff --git a/core/v1/container.k b/core/v1/container.k new file mode 100644 index 0000000..94dc161 --- /dev/null +++ b/core/v1/container.k @@ -0,0 +1,318 @@ +import regex + +schema Container: + """ Container describes how the Application's tasks are expected to be run. Depending on + the replicas parameter 1 or more containers can be created from each template. + + Attributes + ---------- + image: str, default is Undefined, required. + Image refers to the Docker image name to run for this container. + More info: https://kubernetes.io/docs/concepts/containers/images + command: [str], default is Undefined, optional. + Entrypoint array. Not executed within a shell. + Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker + image's ENTRYPOINT is used if this is not provided. + args: [str], default is Undefined, optional. + Arguments to the entrypoint. + Args will overwrite the CMD value set in the Dockfile, otherwise the Docker + image's CMD is used if this is not provided. + env: {str:str}, default is Undefined, optional. + List of environment variables to set in the container. + The value of the environment variable may be static text or a value from a secret. + workingDir: str, default is Undefined, optional. + The working directory of the running process defined in entrypoint. + Default container runtime will be used if this is not specified. + resources: {str:str}, default is Undefined, optional. + Map of resource requirements the container should run with. + The resources parameter is a dict with the key being the resource name and the value being + the resource value. + files: {str:FileSpec}, default is Undefined, optional. + List of files to create in the container. + The files parameter is a dict with the key being the file name in the container and the value + being the target file specification. + dirs: {str:str}, default is Undefined, optional. + Collection of volumes mount into the container's filesystem. + The dirs parameter is a dict with the key being the folder name in the container and the value + being the referenced volume. + livenessProbe: Probe, default is Undefined, optional. + LivenessProbe indicates if a running process is healthy. + Container will be restarted if the probe fails. + readinessProbe: Probe, default is Undefined, optional. + ReadinessProbe indicates whether an application is available to handle requests. + startupProbe: Probe, default is Undefined, optional. + StartupProbe indicates that the container has started for the first time. + Container will be restarted if the probe fails. + lifecycle: Lifecycle, default is Undefined, optional. + Lifecycle refers to actions that the management system should take in response to container lifecycle events. + + Examples + -------- + import kam.core.v1 as v1 + + web = v1.Container { + image: "nginx:latest" + command: ["/bin/sh", "-c", "echo hi"] + env: { + "name": "value" + } + resources: { + "cpu": "2" + "memory": "4Gi" + } + } + """ + + # Image to run for this container. + image: str + + # Entrypoint array. + # The image's ENTRYPOINT is used if this is not provided. + command?: [str] + # Arguments to the entrypoint. + # The image's CMD is used if this is not provided. + args?: [str] + # Collection of environment variables to set in the container. + # The value of environment variable may be static text or a value from a secret. + env?: {str:str} + # The current working directory of the running process defined in entrypoint. + workingDir?: str + + # Resource requirements for this container. + resources?: {str:str} + + # Files configures one or more files to be created in the container. + files?: {str:FileSpec} + # Dirs configures one or more volumes to be mounted to the specified folder. + dirs?: {str:str} + + # Liveness probe for this container. + # Liveness probe indicates if a running process is healthy. + livenessProbe?: Probe + # Readiness probe for this container. + # Readiness probe indicates whether an application is available to handle requests. + readinessProbe?: Probe + # Startup probe for this container. + # Startup probe indicates that the container has started for the first time. + startupProbe?: Probe + + # Lifecycle configures actions which should be taken response to container lifecycle + # events. + lifecycle?: Lifecycle + + check: + all e in env { + regex.match(e, r"^[-._a-zA-Z][-._a-zA-Z0-9]*$") + } if env, "a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit" + +schema FileSpec: + """ FileSpec defines the target file in a Container. + + Attributes + ---------- + content: str, default is Undefined, optional. + File content in plain text. + contentFrom: str, default is Undefined, optional. + Source for the file content, reference to a secret of configmap value. + mode: str, default is Undefined, optional. + Mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511 + + Examples + -------- + import kam.core.v1 as v1 + + tmpFile = v1.FileSpec { + content: "some file contents" + mode: "0777" + } + """ + + # The content of target file in plain text. + content?: str + + # Source for the file content, might be a reference to a secret value. + contentFrom?: str + + # Mode bits used to set permissions on this file. + # Defaults to 0644. + mode: str = "0644" + + check: + not content or not contentFrom, "content and contentFrom are mutually exclusive" + regex.match(mode, r"^[0-7]{3,4}$"), "valid mode must between 0000 and 0777, both inclusive" + +schema Probe: + """ Probe describes a health check to be performed against a container to determine whether it is + alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup. + + Attributes + ---------- + probeHandler: Exec | Http | Tcp, default is Undefined, required. + The action taken to determine the alive or health of a container + initialDelaySeconds: int, default is Undefined, optional. + The number of seconds before health checking is activated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + timeoutSeconds: int, default is Undefined, optional. + The number of seconds after which the probe times out. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + periodSeconds: int, default is Undefined, optional. + How often (in seconds) to perform the probe. + successThreshold: int, default is Undefined, optional. + Minimum consecutive successes for the probe to be considered successful after having failed. + failureThreshold: int, default is Undefined, optional. + Minimum consecutive failures for the probe to be considered failed after having succeeded. + terminationGracePeriod: int, default is Undefined, optional. + Duration in seconds before terminate gracefully upon probe failure. + + Examples + -------- + import kam.core.v1 as v1 + + probe = v1.Probe { + probeHandler: v1.Http { + path: "/healthz" + } + initialDelaySeconds: 10 + } + """ + + # The action taken to determine the health of a container + probeHandler: Exec | Http | Tcp + + # Number of seconds after the container has started before liveness probes are initiated. + initialDelaySeconds?: int + + # Number of seconds after which the probe times out. + timeoutSeconds?: int + + # How often (in seconds) to perform the probe. + periodSeconds?: int + + # Minimum consecutive successes for the probe to be considered successful after having failed. + successThreshold?: int + + # Minimum consecutive failures for the probe to be considered failed after having succeeded. + failureThreshold?: int + + # Duration in seconds before terminate gracefully upon probe failure. + terminationGracePeriod?: int + + check: + initialDelaySeconds >= 0 if initialDelaySeconds, "initialDelaySeconds must be greater than or equal to 0" + timeoutSeconds >= 0 if timeoutSeconds, "timeoutSeconds must be greater than or equal to 0" + periodSeconds >= 0 if periodSeconds, "periodSeconds must be greater than or equal to 0" + successThreshold >= 0 if successThreshold, "successThreshold must be greater than or equal to 0" + failureThreshold >= 0 if failureThreshold, "failureThreshold must be greater than or equal to 0" + terminationGracePeriod >= 0 if terminationGracePeriod, "terminationGracePeriod must be greater than or equal to 0" + +schema Exec: + """ Exec describes a "run in container" action. + + Attributes + ---------- + command: [str], default is Undefined, required. + The command line to execute inside the container. + + Examples + -------- + import kam.core.v1 as v1 + + execProbe = v1.Exec { + command: ["probe.sh"] + } + """ + + # The command line to execute inside the container. + # Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + command: [str] + + check: + len(command) > 0, "command must be specified" + +schema Http: + """ Http describes an action based on HTTP Get requests. + + Attributes + ---------- + url: str, default is Undefined, required. + The full qualified url to send HTTP requests. + headers: {str:str}, default is Undefined, optional. + Collection of custom headers to set in the request + + Examples + -------- + import kam.core.v1 as v1 + + httpProbe = v1.Http { + url: "http://localhost:80" + headers: { + "X-HEADER": "VALUE" + } + } + """ + + # The full qualified url to send HTTP requests. + url: str + + # Custom headers to set in the request. + headers?: {str:str} + + check: + all header in headers { + regex.match(header, r"^[-A-Za-z0-9]+$") + } if headers, "a valid HTTP header must consist of alphanumeric characters or '-' e.g X-Header-Name" + +schema Tcp: + """ Tcp describes an action based on opening a socket. + + Attributes + ---------- + url: str, default is Undefined, required. + The full qualified url to open a socket. + + Examples + -------- + import kam.core.v1 as v1 + + tcpProbe = v1.Tcp { + url: "tcp://localhost:1234" + } + """ + + # The full qualified url to open a socket. + url: str + +schema Lifecycle: + """ Lifecycle describes actions that the management system should take in response + to container lifecycle events. + + Attributes + ---------- + preStop: p.Exec | p.Http, default is Undefined, optional. + The action to be taken before a container is terminated due to an API request or + management event such as liveness/startup probe failure, preemption, resource contention, etc. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + postStart: p.Exec | p.Http, default is Undefined, optional. + The action to be taken after a container is created. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + + Examples + -------- + import kam.core.v1 as v1 + + lifecycleHook = v1.Lifecycle { + preStop: v1.Exec { + command: ["preStop.sh"] + } + postStart: v1.Http { + url: "http://localhost:80" + } + } + """ + + # The action to be taken before a container is terminated. + preStop?: Exec | Http + + # The action to be taken after a container is created. + postStart?: Exec | Http \ No newline at end of file diff --git a/core/v1/exclusive_accessory.k b/core/v1/exclusive_accessory.k new file mode 100644 index 0000000..c2a239d --- /dev/null +++ b/core/v1/exclusive_accessory.k @@ -0,0 +1,5 @@ +schema ExclusiveAccessory(Accessory): + """ For specific accessory schema definition, if there should be only one instance within AppConfiguration, must + inherit the ExclusiveAccessory schema. + """ + diff --git a/v1/workload/job.k b/core/v1/job.k similarity index 81% rename from v1/workload/job.k rename to core/v1/job.k index d24ae39..9cdc3b5 100644 --- a/v1/workload/job.k +++ b/core/v1/job.k @@ -1,4 +1,4 @@ -schema Job(WorkloadBase): +schema Job(Workload): """ Job is a kind of workload profile that describes how to run your application code. This is typically used for tasks that take from a few seconds to a few days to complete. @@ -11,12 +11,11 @@ schema Job(WorkloadBase): -------- Instantiate a job with busybox image and runs every hour - import kam.workload as wl - import kam.workload.container as c + import kam.core.v1 as v1 - echoJob : wl.Job { + echoJob : v1.Job { containers: { - "busybox": c.Container{ + "busybox": v1.Container{ image: "busybox:1.28" command: ["/bin/sh", "-c", "echo hello"] } @@ -25,6 +24,9 @@ schema Job(WorkloadBase): } """ + # The kind + kind: "job" = "job" + # The scheduling strategy in Cron format. # More info: https://en.wikipedia.org/wiki/Cron. schedule: str diff --git a/core/v1/object.k b/core/v1/object.k new file mode 100644 index 0000000..6e0b348 --- /dev/null +++ b/core/v1/object.k @@ -0,0 +1,17 @@ +schema Object: + """ Object is the root of the schema hierarchy. All top level schema definitions must inherit the Object schema, + which includes fields that all schema definitions must have. + + Attributes + ---------- + kind: str, default is Undefined, required. + Kind is a string value representing the resource this schema represents. + name: str, default is Undefined, required. + Name of the resource this schema represents. + """ + + # Kind is a string value representing the resource this schema represents. + kind: str + + # Name of the resource this schema represents. + name: str diff --git a/v1/workload/secret/secret.k b/core/v1/secret.k similarity index 84% rename from v1/workload/secret/secret.k rename to core/v1/secret.k index f1ff817..e758022 100644 --- a/v1/workload/secret/secret.k +++ b/core/v1/secret.k @@ -16,8 +16,8 @@ schema Secret: Attributes ---------- - type: str, default is Undefined, required. - Type of secret, used to facilitate programmatic handling of secret data. + category: str, default is Undefined, required. + Category of secret, used to facilitate programmatic handling of secret data. params: {str:str}, default is Undefined, optional. Collection of parameters used to facilitate programmatic handling of secret data. data: {str:str}, default is Undefined, optional. @@ -27,10 +27,10 @@ schema Secret: Examples -------- - import kam.workload.secret as sec + import kam.core.v1 as v1 - basicAuth = sec.Secret { - type: "basic" + basicAuth = v1.Secret { + category: "basic" data: { "username": "" "password": "" @@ -38,8 +38,8 @@ schema Secret: } """ - # Types of secrets available to use. - type: "basic" | "token" | "opaque" | "certificate" | "external" + # Categories of secrets available to use. + category: "basic" | "token" | "opaque" | "certificate" | "external" # Params defines extra parameters used to customize secret handling. params?: {str:str} diff --git a/v1/workload/service.k b/core/v1/service.k similarity index 70% rename from v1/workload/service.k rename to core/v1/service.k index 254efd1..403a736 100644 --- a/v1/workload/service.k +++ b/core/v1/service.k @@ -1,4 +1,4 @@ -schema Service(WorkloadBase): +schema Service(Workload): """ Service is a kind of workload profile that describes how to run your application code. This is typically used for long-running web applications that should "never" go down, and handle short-lived latency-sensitive web requests, or events. @@ -10,14 +10,16 @@ schema Service(WorkloadBase): -------- # Instantiate a long-running service and its image is "nginx:v1" - import kam.workload as wl - import kam.workload.container as c + import kam.core.v1 as v1 - nginxSvc : wl.Service { + nginxSvc : v1.Service { containers: { - "nginx": c.Container { + "nginx": v1.Container { image: "nginx:v1" } } } - """ \ No newline at end of file + """ + + # The kind + kind: "service" = "service" \ No newline at end of file diff --git a/v1/workload/common.k b/core/v1/workload.k similarity index 52% rename from v1/workload/common.k rename to core/v1/workload.k index b6629d1..812d392 100644 --- a/v1/workload/common.k +++ b/core/v1/workload.k @@ -1,35 +1,33 @@ -import v1.workload.container as c -import v1.workload.secret as sec - -schema WorkloadBase: - """ WorkloadBase defines set of attributes shared by different workload profile, e.g Service +schema Workload(Object): + """ Workload defines set of attributes shared by different workload profile, e.g Service and Job. You can inherit this Schema to reuse these common attributes. Attributes ---------- - containers: {str:c.Container}, default is Undefined, required. + containers: {str:Container}, default is Undefined, required. Containers defines the templates of containers to be ran. More info: https://kubernetes.io/docs/concepts/containers - secrets: {str:sec.Secret}, default is Undefined, optional. + secrets: {str:Secret}, default is Undefined, optional. Secrets can be used to store small amount of sensitive data e.g. password, token. replicas: int, optional. Number of container replicas based on this configuration that should be ran. labels: {str:str}, default is Undefined, optional. - Labels are key/value pairs that are attached to the workload. + The labels to set on target Kubernetes Workload resource. annotations: {str:str}, default is Undefined, optional. - Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload. + The annotations to set on target Kubernetes Workload resource. """ # The templates of containers to be ran. - containers: {str:c.Container} + containers: {str:Container} # Secrets store small amount of sensitive data e.g. a password, a token, or a key. - secrets?: {str:sec.Secret} + secrets?: {str:Secret} # The number of containers that should be ran. - replicas?: int + replicas?: int - ###### Other metadata info - # Labels and annotations can be used to attach arbitrary metadata as key-value pairs to resources. + # The labels to set on target Kubernetes Workload resource. labels?: {str:str} + + # The annotations to set on target Kubernetes Workload resource. annotations?: {str:str} diff --git a/example/project.yaml b/example/project.yaml deleted file mode 100644 index 66147a5..0000000 --- a/example/project.yaml +++ /dev/null @@ -1 +0,0 @@ -name: example \ No newline at end of file diff --git a/example/dev/kcl.mod b/examples/helloworld/dev/kcl.mod similarity index 100% rename from example/dev/kcl.mod rename to examples/helloworld/dev/kcl.mod diff --git a/example/dev/example.k b/examples/helloworld/dev/main.k similarity index 100% rename from example/dev/example.k rename to examples/helloworld/dev/main.k diff --git a/example/dev/stack.yaml b/examples/helloworld/dev/stack.yaml similarity index 100% rename from example/dev/stack.yaml rename to examples/helloworld/dev/stack.yaml diff --git a/examples/helloworld/project.yaml b/examples/helloworld/project.yaml new file mode 100644 index 0000000..99903ae --- /dev/null +++ b/examples/helloworld/project.yaml @@ -0,0 +1 @@ +name: helloworld \ No newline at end of file diff --git a/extensions/v1/k8s_metadata.k b/extensions/v1/k8s_metadata.k new file mode 100644 index 0000000..713462c --- /dev/null +++ b/extensions/v1/k8s_metadata.k @@ -0,0 +1,32 @@ +schema KubernetesMetadata: + """ KubernetesMetadata extension enables you set Kubernetes metadata such as labels and annotations on all the + Kubernetes resources of your Kusion Application. + + Attributes + ---------- + labels: {str:str}, default is Undefined, optional. + The Kubernetes labels to set on the application and its Kubernetes resources. + annotations: {str:str}, default is Undefined, optional. + The Kubernetes annotations to set on the application and its Kubernetes resources. + + Examples + -------- + Instantiate a KubernetesMetadata extension with custom labels and annotations + + import kam.extensions.v1 as extv1 + + kubeMetadataExt : extv1.KubernetesMetadata { + labels: { + "tier": "frontend" + } + annotations: { + "team": "PE" + } + } + """ + + # The Kubernetes labels to set on the application and its Kubernetes resources. + labels?: {str:str} + + # The Kubernetes annotations to set on the application and its Kubernetes resources. + annotations?: {str:str} \ No newline at end of file diff --git a/v1/workload/container/container.k b/v1/workload/container/container.k deleted file mode 100644 index c81b159..0000000 --- a/v1/workload/container/container.k +++ /dev/null @@ -1,146 +0,0 @@ -import v1.workload.container.probe as p -import v1.workload.container.lifecycle as lc - -import regex - -schema Container: - """ Container describes how the Application's tasks are expected to be run. Depending on - the replicas parameter 1 or more containers can be created from each template. - - Attributes - ---------- - image: str, default is Undefined, required. - Image refers to the Docker image name to run for this container. - More info: https://kubernetes.io/docs/concepts/containers/images - command: [str], default is Undefined, optional. - Entrypoint array. Not executed within a shell. - Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker - image's ENTRYPOINT is used if this is not provided. - args: [str], default is Undefined, optional. - Arguments to the entrypoint. - Args will overwrite the CMD value set in the Dockfile, otherwise the Docker - image's CMD is used if this is not provided. - env: {str:str}, default is Undefined, optional. - List of environment variables to set in the container. - The value of the environment variable may be static text or a value from a secret. - workingDir: str, default is Undefined, optional. - The working directory of the running process defined in entrypoint. - Default container runtime will be used if this is not specified. - resources: {str:str}, default is Undefined, optional. - Map of resource requirements the container should run with. - The resources parameter is a dict with the key being the resource name and the value being - the resource value. - files: {str:FileSpec}, default is Undefined, optional. - List of files to create in the container. - The files parameter is a dict with the key being the file name in the container and the value - being the target file specification. - dirs: {str:str}, default is Undefined, optional. - Collection of volumes mount into the container's filesystem. - The dirs parameter is a dict with the key being the folder name in the container and the value - being the referenced volume. - livenessProbe: p.Probe, default is Undefined, optional. - LivenessProbe indicates if a running process is healthy. - Container will be restarted if the probe fails. - readinessProbe: p.Probe, default is Undefined, optional. - ReadinessProbe indicates whether an application is available to handle requests. - startupProbe: p.Probe, default is Undefined, optional. - StartupProbe indicates that the container has started for the first time. - Container will be restarted if the probe fails. - lifecycle: lc.Lifecycle, default is Undefined, optional. - Lifecycle refers to actions that the management system should take in response to container lifecycle events. - - Examples - -------- - import kam.workload.container as c - - web = c.Container { - image: "nginx:latest" - command: ["/bin/sh", "-c", "echo hi"] - env: { - "name": "value" - } - resources: { - "cpu": "2" - "memory": "4Gi" - } - } - """ - - # Image to run for this container. - image: str - - # Entrypoint array. - # The image's ENTRYPOINT is used if this is not provided. - command?: [str] - # Arguments to the entrypoint. - # The image's CMD is used if this is not provided. - args?: [str] - # Collection of environment variables to set in the container. - # The value of environment variable may be static text or a value from a secret. - env?: {str:str} - # The current working directory of the running process defined in entrypoint. - workingDir?: str - - # Resource requirements for this container. - resources?: {str:str} - - # Files configures one or more files to be created in the container. - files?: {str:FileSpec} - # Dirs configures one or more volumes to be mounted to the specified folder. - dirs?: {str:str} - - # Liveness probe for this container. - # Liveness probe indicates if a running process is healthy. - livenessProbe?: p.Probe - # Readiness probe for this container. - # Readiness probe indicates whether an application is available to handle requests. - readinessProbe?: p.Probe - # Startup probe for this container. - # Startup probe indicates that the container has started for the first time. - startupProbe?: p.Probe - - # Lifecycle configures actions which should be taken response to container lifecycle - # events. - lifecycle?: lc.Lifecycle - - check: - all e in env { - regex.match(e, r"^[-._a-zA-Z][-._a-zA-Z0-9]*$") - } if env, "a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit" - -schema FileSpec: - """ FileSpec defines the target file in a Container. - - Attributes - ---------- - content: str, default is Undefined, optional. - File content in plain text. - contentFrom: str, default is Undefined, optional. - Source for the file content, reference to a secret of configmap value. - mode: str, default is Undefined, optional. - Mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between 0 and 511 - - Examples - -------- - import kam.workload.container as c - - tmpFile = c.FileSpec { - content: "some file contents" - mode: "0777" - } - """ - - # The content of target file in plain text. - content?: str - - # Source for the file content, might be a reference to a secret value. - contentFrom?: str - - # Mode bits used to set permissions on this file. - # Defaults to 0644. - mode: str = "0644" - - check: - not content or not contentFrom, "content and contentFrom are mutually exclusive" - regex.match(mode, r"^[0-7]{3,4}$"), "valid mode must between 0000 and 0777, both inclusive" diff --git a/v1/workload/container/lifecycle/lifecycle.k b/v1/workload/container/lifecycle/lifecycle.k deleted file mode 100644 index f4e6356..0000000 --- a/v1/workload/container/lifecycle/lifecycle.k +++ /dev/null @@ -1,36 +0,0 @@ -import v1.workload.container.probe as p - -schema Lifecycle: - """ Lifecycle describes actions that the management system should take in response - to container lifecycle events. - - Attributes - ---------- - preStop: p.Exec | p.Http, default is Undefined, optional. - The action to be taken before a container is terminated due to an API request or - management event such as liveness/startup probe failure, preemption, resource contention, etc. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - postStart: p.Exec | p.Http, default is Undefined, optional. - The action to be taken after a container is created. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - - Examples - -------- - import kam.workload.container.probe as p - import kam.workload.container.lifecycle as lc - - lifecycleHook = lc.Lifecycle { - preStop: p.Exec { - command: ["preStop.sh"] - } - postStart: p.Http { - url: "http://localhost:80" - } - } - """ - - # The action to be taken before a container is terminated. - preStop?: p.Exec | p.Http - - # The action to be taken after a container is created. - postStart?: p.Exec | p.Http diff --git a/v1/workload/container/probe/probe.k b/v1/workload/container/probe/probe.k deleted file mode 100644 index 70b3ff6..0000000 --- a/v1/workload/container/probe/probe.k +++ /dev/null @@ -1,142 +0,0 @@ -import regex - -schema Probe: - """ Probe describes a health check to be performed against a container to determine whether it is - alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup. - - Attributes - ---------- - probeHandler: Exec | Http | Tcp, default is Undefined, required. - The action taken to determine the alive or health of a container - initialDelaySeconds: int, default is Undefined, optional. - The number of seconds before health checking is activated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - timeoutSeconds: int, default is Undefined, optional. - The number of seconds after which the probe times out. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - periodSeconds: int, default is Undefined, optional. - How often (in seconds) to perform the probe. - successThreshold: int, default is Undefined, optional. - Minimum consecutive successes for the probe to be considered successful after having failed. - failureThreshold: int, default is Undefined, optional. - Minimum consecutive failures for the probe to be considered failed after having succeeded. - terminationGracePeriod: int, default is Undefined, optional. - Duration in seconds before terminate gracefully upon probe failure. - - Examples - -------- - import kam.workload.container.probe as p - - probe = p.Probe { - probeHandler: p.Http { - path: "/healthz" - } - initialDelaySeconds: 10 - } - """ - - # The action taken to determine the health of a container - probeHandler: Exec | Http | Tcp - - # Number of seconds after the container has started before liveness probes are initiated. - initialDelaySeconds?: int - - # Number of seconds after which the probe times out. - timeoutSeconds?: int - - # How often (in seconds) to perform the probe. - periodSeconds?: int - - # Minimum consecutive successes for the probe to be considered successful after having failed. - successThreshold?: int - - # Minimum consecutive failures for the probe to be considered failed after having succeeded. - failureThreshold?: int - - # Duration in seconds before terminate gracefully upon probe failure. - terminationGracePeriod?: int - - check: - initialDelaySeconds >= 0 if initialDelaySeconds, "initialDelaySeconds must be greater than or equal to 0" - timeoutSeconds >= 0 if timeoutSeconds, "timeoutSeconds must be greater than or equal to 0" - periodSeconds >= 0 if periodSeconds, "periodSeconds must be greater than or equal to 0" - successThreshold >= 0 if successThreshold, "successThreshold must be greater than or equal to 0" - failureThreshold >= 0 if failureThreshold, "failureThreshold must be greater than or equal to 0" - terminationGracePeriod >= 0 if terminationGracePeriod, "terminationGracePeriod must be greater than or equal to 0" - -schema Exec: - """ Exec describes a "run in container" action. - - Attributes - ---------- - command: [str], default is Undefined, required. - The command line to execute inside the container. - - Examples - -------- - import kam.workload.container.probe as p - - execProbe = p.Exec { - command: ["probe.sh"] - } - """ - - # The command line to execute inside the container. - # Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - command: [str] - - check: - len(command) > 0, "command must be specified" - -schema Http: - """ Http describes an action based on HTTP Get requests. - - Attributes - ---------- - url: str, default is Undefined, required. - The full qualified url to send HTTP requests. - headers: {str:str}, default is Undefined, optional. - Collection of custom headers to set in the request - - Examples - -------- - import kam.workload.container.probe as p - - httpProbe = p.Http { - url: "http://localhost:80" - headers: { - "X-HEADER": "VALUE" - } - } - """ - - # The full qualified url to send HTTP requests. - url: str - - # Custom headers to set in the request. - headers?: {str:str} - - check: - all header in headers { - regex.match(header, r"^[-A-Za-z0-9]+$") - } if headers, "a valid HTTP header must consist of alphanumeric characters or '-' e.g X-Header-Name" - -schema Tcp: - """ Tcp describes an action based on opening a socket. - - Attributes - ---------- - url: str, default is Undefined, required. - The full qualified url to open a socket. - - Examples - -------- - import kam.workload.container.probe as p - - tcpProbe = p.Tcp { - url: "tcp://localhost:1234" - } - """ - - # The full qualified url to open a socket. - url: str