From 247d2f17874dba0cb7ce86040d306e91f15ab9b0 Mon Sep 17 00:00:00 2001 From: Saranya Jena Date: Sun, 15 Dec 2024 12:00:35 +0530 Subject: [PATCH 01/10] Added installation manifest for 3.14.0 (#4993) * added installation manifest for 3.14.0 Signed-off-by: Saranya-jena * added installation manifest for 3.14.0 Signed-off-by: Saranya-jena --------- Signed-off-by: Saranya-jena --- .../docs/3.14.0/litmus-getting-started.yaml | 414 ++ mkdocs/docs/3.14.0/litmus-installation.yaml | 447 ++ mkdocs/docs/3.14.0/litmus-portal-crds.yml | 3596 +++++++++++++++++ .../docs/3.14.0/litmus-without-resources.yaml | 420 ++ 4 files changed, 4877 insertions(+) create mode 100644 mkdocs/docs/3.14.0/litmus-getting-started.yaml create mode 100644 mkdocs/docs/3.14.0/litmus-installation.yaml create mode 100644 mkdocs/docs/3.14.0/litmus-portal-crds.yml create mode 100644 mkdocs/docs/3.14.0/litmus-without-resources.yaml diff --git a/mkdocs/docs/3.14.0/litmus-getting-started.yaml b/mkdocs/docs/3.14.0/litmus-getting-started.yaml new file mode 100644 index 00000000000..830fa08d7cf --- /dev/null +++ b/mkdocs/docs/3.14.0/litmus-getting-started.yaml @@ -0,0 +1,414 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: litmus-portal-admin-secret +stringData: + DB_USER: "root" + DB_PASSWORD: "1234" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmus-portal-admin-config +data: + DB_SERVER: mongodb://my-release-mongodb-0.my-release-mongodb-headless:27017,my-release-mongodb-1.my-release-mongodb-headless:27017,my-release-mongodb-2.my-release-mongodb-headless:27017/admin + VERSION: "3.14.0" + SKIP_SSL_VERIFY: "false" + # Configurations if you are using dex for OAuth + DEX_ENABLED: "false" + OIDC_ISSUER: "http://:32000" + DEX_OAUTH_CALLBACK_URL: "http://:8080/auth/dex/callback" + DEX_OAUTH_CLIENT_ID: "LitmusPortalAuthBackend" + DEX_OAUTH_CLIENT_SECRET: "ZXhhbXBsZS1hcHAtc2VjcmV0" + OAuthJwtSecret: "litmus-oauth@123" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmusportal-frontend-nginx-configuration +data: + nginx.conf: | + pid /tmp/nginx.pid; + + events { + worker_connections 1024; + } + + http { + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + + include /etc/nginx/mime.types; + + gzip on; + gzip_disable "msie6"; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + server { + listen 8185 default_server; + root /opt/chaos; + + location /health { + return 200; + } + + location / { + proxy_http_version 1.1; + add_header Cache-Control "no-cache"; + try_files $uri /index.html; + autoindex on; + } + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location /auth/ { + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "http://litmusportal-auth-server-service:9003/"; + } + + location /api/ { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "http://litmusportal-server-service:9002/"; + } + } + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-frontend + labels: + component: litmusportal-frontend +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-frontend + template: + metadata: + labels: + component: litmusportal-frontend + spec: + automountServiceAccountToken: false + containers: + - name: litmusportal-frontend + image: litmuschaos/litmusportal-frontend:3.14.0 + # securityContext: + # runAsUser: 2000 + # allowPrivilegeEscalation: false + # runAsNonRoot: true + imagePullPolicy: Always + ports: + - containerPort: 8185 + resources: + requests: + memory: "250Mi" + cpu: "125m" + ephemeral-storage: "500Mi" + limits: + memory: "512Mi" + cpu: "550m" + ephemeral-storage: "1Gi" + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + volumes: + - name: nginx-config + configMap: + name: litmusportal-frontend-nginx-configuration +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-frontend-service +spec: + type: NodePort + ports: + - name: http + port: 9091 + targetPort: 8185 + selector: + component: litmusportal-frontend +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-server + labels: + component: litmusportal-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-server + template: + metadata: + labels: + component: litmusportal-server + spec: + automountServiceAccountToken: false + volumes: + - name: gitops-storage + emptyDir: {} + - name: hub-storage + emptyDir: {} + containers: + - name: graphql-server + image: litmuschaos/litmusportal-server:3.14.0 + volumeMounts: + - mountPath: /tmp/ + name: gitops-storage + - mountPath: /tmp/version + name: hub-storage + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + # if self-signed certificate are used pass the base64 tls certificate, to allow agents to use tls for communication + - name: TLS_CERT_B64 + value: "" + - name: ENABLE_GQL_INTROSPECTION + value: "false" + - name: INFRA_DEPLOYMENTS + value: '["app=chaos-exporter", "name=chaos-operator", "app=workflow-controller", "app=event-tracker"]' + - name: CHAOS_CENTER_UI_ENDPOINT + value: "" + - name: SUBSCRIBER_IMAGE + value: "litmuschaos/litmusportal-subscriber:3.14.0" + - name: EVENT_TRACKER_IMAGE + value: "litmuschaos/litmusportal-event-tracker:3.14.0" + - name: ARGO_WORKFLOW_CONTROLLER_IMAGE + value: "litmuschaos/workflow-controller:v3.3.1" + - name: ARGO_WORKFLOW_EXECUTOR_IMAGE + value: "litmuschaos/argoexec:v3.3.1" + - name: LITMUS_CHAOS_OPERATOR_IMAGE + value: "litmuschaos/chaos-operator:3.14.0" + - name: LITMUS_CHAOS_RUNNER_IMAGE + value: "litmuschaos/chaos-runner:3.14.0" + - name: LITMUS_CHAOS_EXPORTER_IMAGE + value: "litmuschaos/chaos-exporter:3.14.0" + - name: CONTAINER_RUNTIME_EXECUTOR + value: "k8sapi" + - name: DEFAULT_HUB_BRANCH_NAME + value: "v3.14.x" + - name: LITMUS_AUTH_GRPC_ENDPOINT + value: "litmusportal-auth-server-service" + - name: LITMUS_AUTH_GRPC_PORT + value: "3030" + - name: WORKFLOW_HELPER_IMAGE_VERSION + value: "3.14.0" + - name: REMOTE_HUB_MAX_SIZE + value: "5000000" + - name: INFRA_COMPATIBLE_VERSIONS + value: '["3.14.0"]' + - name: ALLOWED_ORIGINS + value: ".*" #eg: ^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)? + - name: ENABLE_INTERNAL_TLS + value: "false" + - name: TLS_CERT_PATH + value: "" + - name: TLS_KEY_PATH + value: "" + - name: CA_CERT_TLS_PATH + value: "" + - name: REST_PORT + value: "8080" + - name: GRPC_PORT + value: "8000" + ports: + - containerPort: 8080 + - containerPort: 8000 + imagePullPolicy: Always + resources: + requests: + memory: "250Mi" + cpu: "225m" + ephemeral-storage: "500Mi" + limits: + memory: "712Mi" + cpu: "550m" + ephemeral-storage: "1Gi" +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-server + namespace: litmus + labels: + component: litmusportal-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-server-service +spec: + type: NodePort + ports: + - name: graphql-server + port: 9002 + targetPort: 8080 + - name: graphql-rpc-server + port: 8000 + targetPort: 8000 + selector: + component: litmusportal-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-auth-server + labels: + component: litmusportal-auth-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-auth-server + template: + metadata: + labels: + component: litmusportal-auth-server + spec: + automountServiceAccountToken: false + containers: + - name: auth-server + image: litmuschaos/litmusportal-auth-server:3.14.0 + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + - name: STRICT_PASSWORD_POLICY + value: "false" + - name: ADMIN_USERNAME + value: "admin" + - name: ADMIN_PASSWORD + value: "litmus" + - name: LITMUS_GQL_GRPC_ENDPOINT + value: "litmusportal-server-service" + - name: LITMUS_GQL_GRPC_PORT + value: "8000" + - name: ALLOWED_ORIGINS + value: ".*" #eg: ^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)? + - name: ENABLE_INTERNAL_TLS + value: "false" + - name: TLS_CERT_PATH + value: "" + - name: TLS_KEY_PATH + value: "" + - name: CA_CERT_TLS_PATH + value: "" + - name: REST_PORT + value: "3000" + - name: GRPC_PORT + value: "3030" + ports: + - containerPort: 3000 + - containerPort: 3030 + imagePullPolicy: Always + resources: + requests: + memory: "250Mi" + cpu: "125m" + ephemeral-storage: "500Mi" + limits: + memory: "712Mi" + cpu: "550m" + ephemeral-storage: "1Gi" +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-auth-server + namespace: litmus + labels: + component: litmusportal-auth-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-auth-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend + - from: + - podSelector: + matchLabels: + component: litmusportal-server +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-auth-server-service +spec: + type: NodePort + ports: + - name: auth-server + port: 9003 + targetPort: 3000 + - name: auth-rpc-server + port: 3030 + targetPort: 3030 + selector: + component: litmusportal-auth-server \ No newline at end of file diff --git a/mkdocs/docs/3.14.0/litmus-installation.yaml b/mkdocs/docs/3.14.0/litmus-installation.yaml new file mode 100644 index 00000000000..a431143fa45 --- /dev/null +++ b/mkdocs/docs/3.14.0/litmus-installation.yaml @@ -0,0 +1,447 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: litmus-portal-admin-secret +stringData: + DB_USER: "root" + DB_PASSWORD: "1234" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmus-portal-admin-config +data: + DB_SERVER: mongodb://my-release-mongodb-0.my-release-mongodb-headless:27017,my-release-mongodb-1.my-release-mongodb-headless:27017,my-release-mongodb-2.my-release-mongodb-headless:27017/admin + VERSION: "3.14.0" + SKIP_SSL_VERIFY: "false" + # Configurations if you are using dex for OAuth + DEX_ENABLED: "false" + OIDC_ISSUER: "http://:32000" + DEX_OAUTH_CALLBACK_URL: "http://:8080/auth/dex/callback" + DEX_OAUTH_CLIENT_ID: "LitmusPortalAuthBackend" + DEX_OAUTH_CLIENT_SECRET: "ZXhhbXBsZS1hcHAtc2VjcmV0" + OAuthJwtSecret: "litmus-oauth@123" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmusportal-frontend-nginx-configuration +data: + nginx.conf: | + pid /tmp/nginx.pid; + + events { + worker_connections 1024; + } + + http { + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + + include /etc/nginx/mime.types; + + gzip on; + gzip_disable "msie6"; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + server { + listen 8185 ssl; + ssl_certificate /etc/tls/tls.crt; + ssl_certificate_key /etc/tls/tls.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_client_certificate /etc/tls/ca.crt; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + root /opt/chaos; + + location /health { + return 200; + } + + location / { + proxy_http_version 1.1; + add_header Cache-Control "no-cache"; + try_files $uri /index.html; + autoindex on; + } + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location /auth/ { + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "https://litmusportal-auth-server-service:9005/"; + proxy_ssl_certificate /etc/tls/tls.crt; + proxy_ssl_certificate_key /etc/tls/tls.key; + } + + location /api/ { + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "https://litmusportal-server-service:9004/"; + proxy_ssl_certificate /etc/tls/tls.crt; + proxy_ssl_certificate_key /etc/tls/tls.key; + } + } + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-frontend + labels: + component: litmusportal-frontend +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-frontend + template: + metadata: + labels: + component: litmusportal-frontend + spec: + automountServiceAccountToken: false + containers: + - name: litmusportal-frontend + image: litmuschaos/litmusportal-frontend:3.14.0 + # securityContext: + # runAsUser: 2000 + # allowPrivilegeEscalation: false + # runAsNonRoot: true + imagePullPolicy: Always + ports: + - containerPort: 8185 + resources: + requests: + memory: "250Mi" + cpu: "125m" + ephemeral-storage: "500Mi" + limits: + memory: "512Mi" + cpu: "550m" + ephemeral-storage: "1Gi" + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - mountPath: /etc/tls + name: tls-secret + volumes: + - name: nginx-config + configMap: + name: litmusportal-frontend-nginx-configuration + - name: tls-secret + secret: + secretName: tls-secret +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-frontend-service +spec: + type: NodePort + ports: + - name: http + port: 9091 + targetPort: 8185 + selector: + component: litmusportal-frontend +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-server + labels: + component: litmusportal-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-server + template: + metadata: + labels: + component: litmusportal-server + spec: + automountServiceAccountToken: false + volumes: + - name: gitops-storage + emptyDir: {} + - name: hub-storage + emptyDir: {} + - name: tls-secret + secret: + secretName: tls-secret + containers: + - name: graphql-server + image: litmuschaos/litmusportal-server:3.14.0 + volumeMounts: + - mountPath: /tmp/ + name: gitops-storage + - mountPath: /tmp/version + name: hub-storage + - mountPath: /etc/tls + name: tls-secret + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + # if self-signed certificate are used pass the base64 tls certificate, to allow agents to use tls for communication + - name: TLS_CERT_B64 + value: "" + - name: ENABLE_GQL_INTROSPECTION + value: "false" + - name: INFRA_DEPLOYMENTS + value: '["app=chaos-exporter", "name=chaos-operator", "app=workflow-controller", "app=event-tracker"]' + - name: CHAOS_CENTER_UI_ENDPOINT + value: "" + - name: SUBSCRIBER_IMAGE + value: "litmuschaos/litmusportal-subscriber:3.14.0" + - name: EVENT_TRACKER_IMAGE + value: "litmuschaos/litmusportal-event-tracker:3.14.0" + - name: ARGO_WORKFLOW_CONTROLLER_IMAGE + value: "litmuschaos/workflow-controller:v3.3.1" + - name: ARGO_WORKFLOW_EXECUTOR_IMAGE + value: "litmuschaos/argoexec:v3.3.1" + - name: LITMUS_CHAOS_OPERATOR_IMAGE + value: "litmuschaos/chaos-operator:3.14.0" + - name: LITMUS_CHAOS_RUNNER_IMAGE + value: "litmuschaos/chaos-runner:3.14.0" + - name: LITMUS_CHAOS_EXPORTER_IMAGE + value: "litmuschaos/chaos-exporter:3.14.0" + - name: CONTAINER_RUNTIME_EXECUTOR + value: "k8sapi" + - name: DEFAULT_HUB_BRANCH_NAME + value: "v3.14.x" + - name: LITMUS_AUTH_GRPC_ENDPOINT + value: "litmusportal-auth-server-service" + - name: LITMUS_AUTH_GRPC_PORT + value: "3030" + - name: WORKFLOW_HELPER_IMAGE_VERSION + value: "3.14.0" + - name: REMOTE_HUB_MAX_SIZE + value: "5000000" + - name: INFRA_COMPATIBLE_VERSIONS + value: '["3.14.0"]' + - name: ALLOWED_ORIGINS + value: "^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)?" + - name: ENABLE_INTERNAL_TLS + value: "true" + - name: TLS_CERT_PATH + value: "/etc/tls/tls.crt" + - name: TLS_KEY_PATH + value: "/etc/tls/tls.key" + - name: CA_CERT_TLS_PATH + value: "/etc/tls/ca.crt" + - name: REST_PORT + value: "8081" + - name: GRPC_PORT + value: "8001" + ports: + - containerPort: 8081 + - containerPort: 8001 + imagePullPolicy: Always + resources: + requests: + memory: "250Mi" + cpu: "225m" + ephemeral-storage: "500Mi" + limits: + memory: "712Mi" + cpu: "550m" + ephemeral-storage: "1Gi" +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-server + namespace: litmus + labels: + component: litmusportal-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-server-service +spec: + type: NodePort + ports: + - name: graphql-server-https + port: 9004 + targetPort: 8081 + - name: graphql-rpc-server-https + port: 8001 + targetPort: 8001 + selector: + component: litmusportal-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-auth-server + labels: + component: litmusportal-auth-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-auth-server + template: + metadata: + labels: + component: litmusportal-auth-server + spec: + volumes: + - name: tls-secret + secret: + secretName: tls-secret + automountServiceAccountToken: false + containers: + - name: auth-server + volumeMounts: + - mountPath: /etc/tls + name: tls-secret + image: litmuschaos/litmusportal-auth-server:3.14.0 + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + - name: STRICT_PASSWORD_POLICY + value: "false" + - name: ADMIN_USERNAME + value: "admin" + - name: ADMIN_PASSWORD + value: "litmus" + - name: LITMUS_GQL_GRPC_ENDPOINT + value: "litmusportal-server-service" + - name: LITMUS_GQL_GRPC_PORT + value: "8000" + - name: ALLOWED_ORIGINS + value: "^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)?" #ip needs to added here + - name: ENABLE_INTERNAL_TLS + value: "true" + - name: TLS_CERT_PATH + value: "/etc/tls/tls.crt" + - name: TLS_KEY_PATH + value: "/etc/tls/ctls.key" + - name: CA_CERT_TLS_PATH + value: "/etc/tls/ca.crt" + - name: REST_PORT + value: "3001" + - name: GRPC_PORT + value: "3031" + ports: + - containerPort: 3001 + - containerPort: 3031 + imagePullPolicy: Always + resources: + requests: + memory: "250Mi" + cpu: "125m" + ephemeral-storage: "500Mi" + limits: + memory: "712Mi" + cpu: "550m" + ephemeral-storage: "1Gi" +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-auth-server + namespace: litmus + labels: + component: litmusportal-auth-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-auth-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend + - from: + - podSelector: + matchLabels: + component: litmusportal-server +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-auth-server-service +spec: + type: NodePort + ports: + - name: auth-server-https + port: 9005 + targetPort: 3001 + - name: auth-rpc-server-https + port: 3031 + targetPort: 3031 + selector: + component: litmusportal-auth-server diff --git a/mkdocs/docs/3.14.0/litmus-portal-crds.yml b/mkdocs/docs/3.14.0/litmus-portal-crds.yml new file mode 100644 index 00000000000..0dba567b892 --- /dev/null +++ b/mkdocs/docs/3.14.0/litmus-portal-crds.yml @@ -0,0 +1,3596 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterworkflowtemplates.argoproj.io +spec: + group: argoproj.io + names: + kind: ClusterWorkflowTemplate + listKind: ClusterWorkflowTemplateList + plural: clusterworkflowtemplates + shortNames: + - clusterwftmpl + - cwft + singular: clusterworkflowtemplate + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: cronworkflows.argoproj.io +spec: + group: argoproj.io + names: + kind: CronWorkflow + listKind: CronWorkflowList + plural: cronworkflows + shortNames: + - cwf + - cronwf + singular: cronworkflow + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflows.argoproj.io +spec: + group: argoproj.io + names: + kind: Workflow + listKind: WorkflowList + plural: workflows + shortNames: + - wf + singular: workflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Status of the workflow + jsonPath: .status.phase + name: Status + type: string + - description: When the workflow was started + format: date-time + jsonPath: .status.startedAt + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtasksets.argoproj.io +spec: + group: argoproj.io + names: + kind: WorkflowTaskSet + listKind: WorkflowTaskSetList + plural: workflowtasksets + shortNames: + - wfts + singular: workflowtaskset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtemplates.argoproj.io +spec: + group: argoproj.io + names: + kind: WorkflowTemplate + listKind: WorkflowTemplateList + plural: workflowtemplates + shortNames: + - wftmpl + singular: workflowtemplate + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtaskresults.argoproj.io +spec: + group: argoproj.io + names: + kind: WorkflowTaskResult + listKind: WorkflowTaskResultList + plural: workflowtaskresults + singular: workflowtaskresult + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + message: + type: string + metadata: + type: object + outputs: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + securityToken: + type: string + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + exitCode: + type: string + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + result: + type: string + type: object + phase: + type: string + progress: + type: string + required: + - metadata + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosengines.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosEngine + listKind: ChaosEngineList + plural: chaosengines + singular: chaosengine + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + jobCleanUpPolicy: + type: string + pattern: ^(delete|retain)$ + # alternate ways to do this in case of complex pattern matches + #oneOf: + # - pattern: '^delete$' + # - pattern: '^retain$' + defaultHealthCheck: + type: boolean + appinfo: + type: object + properties: + appkind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + applabel: + type: string + appns: + type: string + selectors: + type: object + properties: + pods: + items: + properties: + names: + type: string + namespace: + type: string + required: + - names + - namespace + type: object + type: array + workloads: + items: + properties: + kind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + labels: + type: string + names: + type: string + namespace: + type: string + oneOf: + - required: [ names ] + - required: [ labels ] + required: + - kind + - namespace + type: object + type: array + oneOf: + - required: [ pods ] + - required: [ workloads ] + auxiliaryAppInfo: + type: string + engineState: + type: string + pattern: ^(active|stop)$ + chaosServiceAccount: + type: string + terminationGracePeriodSeconds: + type: integer + components: + type: object + properties: + sidecar: + type: array + items: + type: object + properties: + env: + description: ENV contains ENV passed to the sidecar container + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a double + $$, ie: $$(VAR_NAME). Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: EnvFrom for the sidecar container + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + secrets: + items: + properties: + mountPath: + type: string + name: + type: string + required: + - mountPath + - name + type: object + type: array + runner: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + image: + type: string + type: + type: string + pattern: ^(go)$ + runnerAnnotations: + type: object + runnerLabels: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + value: + type: string + minLength: 1 + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + experiments: + type: array + items: + type: object + properties: + name: + type: string + spec: + type: object + properties: + probe: + type: array + items: + type: object + required: + - name + - type + - mode + - runProperties + properties: + name: + type: string + type: + type: string + minLength: 1 + pattern: ^(k8sProbe|httpProbe|cmdProbe|promProbe|sloProbe)$ + k8sProbe/inputs: + type: object + required: + - version + - resource + - operation + properties: + group: + type: string + version: + type: string + resource: + type: string + namespace: + type: string + resourceNames: + type: string + fieldSelector: + type: string + labelSelector: + type: string + operation: + type: string + pattern: ^(present|absent|create|delete)$ + minLength: 1 + cmdProbe/inputs: + type: object + required: + - command + - comparator + properties: + command: + type: string + minLength: 1 + comparator: + type: object + required: + - type + - criteria + - value + properties: + type: + type: string + minLength: 1 + pattern: ^(int|float|string)$ + criteria: + type: string + value: + type: string + source: + description: The external pod where we have to run the + probe commands. It will run the commands inside the experiment pod itself(inline mode) if source contains a nil value + required: + - image + properties: + annotations: + additionalProperties: + type: string + description: Annotations for the source pod + type: object + args: + description: Args for the source pod + items: + type: string + type: array + command: + description: Command for the source pod + items: + type: string + type: array + env: + description: ENVList contains ENV passed to + the source pod + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container + and any service environment variables. + If a variable cannot be resolved, the + reference in the input string will be + unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, + regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment + variable's value. Cannot be used if + value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the + pod: supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + description: Specifies the output + format of the exposed resources, + defaults to "1" + type: string + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + hostNetwork: + description: HostNetwork define the hostNetwork + of the external pod it supports boolean values + and default value is false + type: boolean + inheritInputs: + description: InheritInputs define to inherit experiment + details in probe pod it supports boolean values + and default value is false. + type: boolean + image: + description: Image for the source pod + type: string + imagePullPolicy: + description: ImagePullPolicy for the source pod + type: string + imagePullSecrets: + description: ImagePullSecrets for source pod + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same + namespace. + properties: + name: + description: 'Name of the referent' + type: string + type: object + type: array + labels: + additionalProperties: + type: string + description: Labels for the source pod + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector for the source pod + type: object + privileged: + description: Privileged for the source pod + type: boolean + volumeMount: + description: VolumesMount for the source pod + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container + at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines + how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is + used. This field is beta in 1.10. + type: string + name: + description: This must match the Name + of a Volume. + type: string + readOnly: + description: Mounted read-only if true, + read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: Path within the volume from + which the container's volume should + be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the + volume from which the container's volume + should be mounted. Behaves similarly + to SubPath but environment variable + references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and + SubPath are mutually exclusive. This + field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes for the source pod + items: + description: Volume represents a named volume + in a pod that may be accessed by any container + in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents + an AWS Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force + and set the ReadOnly property in + VolumeMounts to "true". If omitted, + the default is "false". More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent + disk resource in AWS (Amazon EBS + volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure + Data Disk mount on the host and bind + mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: The Name of the data + disk in the blob storage + type: string + diskURI: + description: The URI the data disk + in the blob storage + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'Expected values Shared: + multiple blob disks per storage + account Dedicated: single blob + disk per storage account Managed: + azure managed data disk (only in + managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure + File Service mount on the host and bind + mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that + contains Azure Storage Account Name + and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph + FS mount on the host that shares a pod's + lifetime + properties: + monitors: + description: 'Required: Monitors is + a collection of Ceph monitors More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the + mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile + is the path to key ring for User, + default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef + is reference to the authentication + secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'Optional: User is the + rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder + volume attached and mounted on kubelets + host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to + a secret object containing parameters + used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify + the volume in cinder. More info: + https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced ConfigMap will + be projected into the volume as + a file whose name is the key and + content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the ConfigMap, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) + represents storage that is handled by + an external CSI driver (Alpha feature). + properties: + driver: + description: Driver is the name of + the CSI driver that handles this + volume. Consult with your admin + for the correct name as registered + in the cluster. + type: string + fsType: + description: Filesystem type to mount. + Ex. "ext4", "xfs", "ntfs". If not + provided, the empty value is passed + to the associated CSI driver which + will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef + is a reference to the secret object + containing sensitive information + to pass to the CSI driver to complete + the CSI NodePublishVolume and NodeUnpublishVolume + calls. This field is optional, and may + be empty if no secret is required. + If the secret object contains more + than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: Specifies a read-only + configuration for the volume. Defaults + to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores + driver-specific properties that + are passed to the CSI driver. Consult + your driver's documentation for + supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward + API about the pod that should populate + this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + description: Specifies the + output format of the exposed + resources, defaults to + "1" + type: string + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary + directory that shares a pod''s lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage + medium should back this directory. + The default is "" which means to + use the node''s default medium. + Must be an empty string (default) + or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + description: 'Total amount of local + storage required for this EmptyDir + volume. The size limit is also applicable + for memory medium. The maximum usage + on memory medium EmptyDir would + be the minimum value between the + SizeLimit specified here and the + sum of memory limits of all containers + in a pod. The default is nil which + means that the limit is undefined. + More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + type: string + type: object + fc: + description: FC represents a Fibre Channel + resource that is attached to a kubelet's + host machine and then exposed to the + pod. + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + lun: + description: 'Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume + world wide identifiers (wwids) Either + wwids or combination of targetWWNs + and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic + volume resource that is provisioned/attached + using an exec based plugin. + properties: + driver: + description: Driver is the name of + the driver to use for this volume. + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". The default + filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command + options if any.' + type: object + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef + is reference to the secret object + containing sensitive information + to pass to the plugin scripts. This + may be empty if no secret object + is specified. If the secret object + contains more than one secret, all + secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker + volume attached to a kubelet's host + machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored + as metadata -> name on the dataset + for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. + This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents + a GCE Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty). More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD + resource in GCE. Used to identify + the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git + repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To + provision a container with a git repo, + mount an EmptyDir into an InitContainer + that clones the repo using git, then + mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. + Must not contain or start with '..'. If + '.' is supplied, the volume directory + will be the git repository. Otherwise, + if specified, the volume will contain + the git repository in the subdirectory + with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs + mount on the host that shares a pod''s + lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the + endpoint name that details Glusterfs + topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs + volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force + the Glusterfs volume to be mounted + with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing + file or directory on the host machine + that is directly exposed to the container. + This is generally used for system agents + or other privileged things that are + allowed to see the host machine. Most + containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + ### TODO(jonesdl) We need to restrict + who can use host directory mounts and + who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory + on the host. If the path is a symlink, + it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume + Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI + Disk resource that is attached to a + kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator + Name. If initiatorName is specified + with iscsiInterface simultaneously, + new iSCSI interface : will be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: iSCSI Interface Name + that uses an iSCSI transport. Defaults + to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. + The portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. + The Portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be + a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount + on the host that shares a pod''s lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported + by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force + the NFS export to be mounted with + read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname + or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource + represents a reference to a PersistentVolumeClaim + in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name + of a PersistentVolumeClaim in the + same namespace as the pod using + this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly + setting in VolumeMounts. Default + false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents + a portworx volume attached and mounted + on kubelets host machine + properties: + fsType: + description: FSType represents the + filesystem type to mount Must be + a filesystem type supported by the + host operating system. Ex. "ext4", + "xfs". Implicitly inferred to be + "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: Mode bits to use on created + files by default. Must be a value + between 0 and 0777. Directories + within the path are not affected + by this setting. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may + be projected along with other + supported volume types + properties: + configMap: + description: information about + the configMap data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced ConfigMap will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + ConfigMap, the volume + setup will error unless + it is marked optional. + Paths must be relative + and may not contain the + '..' path or start with + '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the ConfigMap or its keys + must be defined + type: boolean + type: object + downwardAPI: + description: information about + the downwardAPI data to project + properties: + items: + description: Items is a + list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information + to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field + of the pod: only + annotations, labels, + name and namespace + are supported.' + properties: + apiVersion: + description: Version + of the schema + the FieldPath + is written in + terms of, defaults + to "v1". + type: string + fieldPath: + description: Path + of the field + to select in + the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the + file to be created. + Must not be absolute + or contain the ''..'' + path. Must be utf-8 + encoded. The first + item of the relative + path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects + a resource of the + container: only + resources limits + and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container + name: required + for volumes, + optional for + env vars' + type: string + divisor: + description: Specifies + the output format + of the exposed + resources, defaults + to "1" + type: string + resource: + description: 'Required: + resource to + select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about + the secret data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced Secret will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + Secret, the volume setup + will error unless it is + marked optional. Paths + must be relative and may + not contain the '..' path + or start with '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the Secret or its key + must be defined + type: boolean + type: object + serviceAccountToken: + description: information about + the serviceAccountToken data + to project + properties: + audience: + description: Audience is + the intended audience + of the token. A recipient + of a token must identify + itself with an identifier + specified in the audience + of the token, and otherwise + should reject the token. + The audience defaults + to the identifier of the + apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds + is the requested duration + of validity of the service + account token. As the + token approaches expiration, + the kubelet volume plugin + will proactively rotate + the service account token. + The kubelet will start + trying to rotate the token + if the token is older + than 80 percent of its + time to live or if the + token is older than 24 + hours.Defaults to 1 hour + and must be at least 10 + minutes. + format: int64 + type: integer + path: + description: Path is the + path relative to the mount + point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + description: Quobyte represents a Quobyte + mount on the host that shares a pod's + lifetime + properties: + group: + description: Group to map volume access + to Default is no group + type: string + readOnly: + description: ReadOnly here will force + the Quobyte volume to be mounted + with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a + single or multiple Quobyte Registry + services specified as a string as + host:port pair (multiple entries + are separated with commas) which + acts as the central registry for + volumes + type: string + tenant: + description: Tenant owning the given + Quobyte volume in the Backend Used + with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access + to Defaults to serivceaccount user + type: string + volume: + description: Volume is a string that + references an already created Quobyte + volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block + Device mount on the host that shares + a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + image: + description: 'The rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path + to key ring for RBDUser. Default + is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph + monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. + Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of + the authentication secret for RBDUser. + If provided overrides keyring. Default + is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'The rados user name. + Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO + persistent volume attached and mounted + on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Default is + "xfs". + type: string + gateway: + description: The host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO + Protection Domain for the configured + storage. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references + to the secret for ScaleIO user and + other sensitive information. If + this is not provided, Login operation + will fail. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable + SSL communication with Gateway, + default false + type: boolean + storageMode: + description: Indicates whether the + storage for a volume should be ThickProvisioned + or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: The name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: The name of a volume + already created in the ScaleIO system + that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret + that should populate this volume. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced Secret will be + projected into the volume as a file + whose name is the key and content + is the value. If specified, the + listed keys will be projected into + the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the Secret, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'Name of the secret in + the pod''s namespace to use. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the + secret to use for obtaining the + StorageOS API credentials. If not + specified, default values will be + attempted. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable + name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies + the scope of the volume within StorageOS. If + no namespace is specified then the + Pod's namespace will be used. This + allows the Kubernetes name scoping + to be mirrored within StorageOS + for tighter integration. Set VolumeName + to any name to override the default + behaviour. Set to "default" if you + are not using namespaces within + StorageOS. Namespaces that do not + pre-exist within StorageOS will + be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents + a vSphere volume attached and mounted + on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: Storage Policy Based + Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: Path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + httpProbe/inputs: + type: object + required: + - url + - method + properties: + url: + type: string + minLength: 1 + insecureSkipVerify: + type: boolean + method: + type: object + minProperties: 1 + properties: + get: + type: object + required: + - criteria + - responseCode + properties: + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + post: + type: object + required: + - criteria + - responseCode + properties: + contentType: + type: string + minLength: 1 + body: + type: string + bodyPath: + type: string + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + promProbe/inputs: + type: object + required: + - endpoint + - comparator + properties: + endpoint: + type: string + query: + type: string + queryPath: + type: string + comparator: + type: object + required: + - criteria + - value + properties: + criteria: + type: string + value: + type: string + runProperties: + type: object + minProperties: 2 + required: + - probeTimeout + - interval + properties: + evaluationTimeout: + type: string + probeTimeout: + type: string + interval: + type: string + retry: + type: integer + attempt: + type: integer + probePollingInterval: + type: string + initialDelaySeconds: + type: integer + initialDelay: + type: string + stopOnFailure: + type: boolean + sloProbe/inputs: + description: inputs needed for the SLO probe + required: + - platformEndpoint + - sloIdentifier + - sloSourceMetadata + - comparator + properties: + comparator: + description: Comparator check for the correctness + of the probe output + required: + - criteria + - value + properties: + criteria: + description: Criteria for matching data it + supports >=, <=, ==, >, <, != for int and + float it supports equal, notEqual, contains + for string + type: string + type: + description: Type of data it can be int, float, + string + type: string + value: + description: Value contains relative value + for criteria + type: string + type: object + evaluationWindow: + description: EvaluationWindow is the time period + for which the metrics will be evaluated + properties: + evaluationEndTime: + description: End time of evaluation + type: integer + evaluationStartTime: + description: Start time of evaluation + type: integer + type: object + platformEndpoint: + description: PlatformEndpoint for the monitoring + service endpoint + type: string + insecureSkipVerify: + description: InsecureSkipVerify flag to skip certificate + checks + type: boolean + sloIdentifier: + description: SLOIdentifier for fetching the details + of the SLO + type: string + sloSourceMetadata: + description: SLOSourceMetadata consists of required + metadata details to fetch metric data + required: + - apiTokenSecret + - scope + properties: + apiTokenSecret: + description: APITokenSecret for authenticating + with the platform service + type: string + scope: + description: Scope required for fetching details + required: + - accountIdentifier + - orgIdentifier + - projectIdentifier + properties: + accountIdentifier: + description: AccountIdentifier for account + ID + type: string + orgIdentifier: + description: OrgIdentifier for organization + ID + type: string + projectIdentifier: + description: ProjectIdentifier for project + ID + type: string + type: object + type: object + type: object + mode: + type: string + pattern: ^(SOT|EOT|Edge|Continuous|OnChaos)$ + minLength: 1 + data: + type: string + components: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + statusCheckTimeouts: + type: object + properties: + delay: + type: integer + timeout: + type: integer + nodeSelector: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + experimentImage: + type: string + env: + type: array + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, spec.nodeName, + spec.serviceAccountName, status.hostIP, + status.podIP.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + configMaps: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + secrets: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + experimentAnnotations: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + + status: + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: {} + conversion: + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosexperiments.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosExperiment + listKind: ChaosExperimentList + plural: chaosexperiments + singular: chaosexperiment + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + description: + type: object + additionalProperties: + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + x-kubernetes-preserve-unknown-fields: true + type: object + spec: + type: object + properties: + definition: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + args: + type: array + items: + type: string + command: + type: array + items: + type: string + env: + type: array + items: + type: object + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, spec.nodeName, + spec.serviceAccountName, status.hostIP, + status.podIP.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + image: + type: string + imagePullPolicy: + type: string + labels: + type: object + additionalProperties: + type: string + scope: + type: string + pattern: ^(Namespaced|Cluster)$ + permissions: + type: array + items: + type: object + minProperties: 3 + required: + - apiGroups + - resources + - verbs + properties: + apiGroups: + type: array + items: + type: string + resources: + type: array + items: + type: string + verbs: + type: array + items: + type: string + resourceNames: + type: array + items: + type: string + nonResourceURLs: + type: array + items: + type: string + configMaps: + type: array + items: + type: object + minProperties: 2 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + secrets: + type: array + items: + type: object + minProperties: 2 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + hostFileVolumes: + type: array + items: + type: object + minProperties: 3 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + nodePath: + type: string + allowEmptyValue: false + minLength: 1 + securityContext: + x-kubernetes-preserve-unknown-fields: true + type: object + hostPID: + type: boolean + + served: true + storage: true + subresources: {} + conversion: + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosresults.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosResult + listKind: ChaosResultList + plural: chaosresults + singular: chaosresult + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + x-kubernetes-preserve-unknown-fields: true + type: object + status: + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: {} + conversion: + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: eventtrackerpolicies.eventtracker.litmuschaos.io +spec: + group: eventtracker.litmuschaos.io + names: + kind: EventTrackerPolicy + listKind: EventTrackerPolicyList + plural: eventtrackerpolicies + singular: eventtrackerpolicy + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: EventTrackerPolicy is the Schema for the eventtrackerpolicies + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: EventTrackerPolicySpec defines the desired state of EventTrackerPolicy + properties: + condition_type: + type: string + conditions: + items: + properties: + key: + type: string + operator: + type: string + value: + type: string + type: object + type: array + type: object + statuses: + items: + description: EventTrackerPolicyStatus defines the observed state of + EventTrackerPolicy + properties: + is_triggered: + type: string + resource: + type: string + resource_name: + type: string + result: + type: string + time_stamp: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state + of cluster Important: Run "make" to regenerate code after modifying + this file' + type: string + workflow_id: + type: string + type: object + type: array + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/mkdocs/docs/3.14.0/litmus-without-resources.yaml b/mkdocs/docs/3.14.0/litmus-without-resources.yaml new file mode 100644 index 00000000000..66f0f4e8b85 --- /dev/null +++ b/mkdocs/docs/3.14.0/litmus-without-resources.yaml @@ -0,0 +1,420 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: litmus-portal-admin-secret +stringData: + DB_USER: "root" + DB_PASSWORD: "1234" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmus-portal-admin-config +data: + DB_SERVER: mongodb://my-release-mongodb-0.my-release-mongodb-headless:27017,my-release-mongodb-1.my-release-mongodb-headless:27017,my-release-mongodb-2.my-release-mongodb-headless:27017/admin + VERSION: "3.14.0" + SKIP_SSL_VERIFY: "false" + # Configurations if you are using dex for OAuth + DEX_ENABLED: "false" + OIDC_ISSUER: "http://:32000" + DEX_OAUTH_CALLBACK_URL: "http://:8080/auth/dex/callback" + DEX_OAUTH_CLIENT_ID: "LitmusPortalAuthBackend" + DEX_OAUTH_CLIENT_SECRET: "ZXhhbXBsZS1hcHAtc2VjcmV0" + OAuthJwtSecret: "litmus-oauth@123" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: litmusportal-frontend-nginx-configuration +data: + nginx.conf: | + pid /tmp/nginx.pid; + + events { + worker_connections 1024; + } + + http { + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + + include /etc/nginx/mime.types; + + gzip on; + gzip_disable "msie6"; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + server { + listen 8185 ssl; + ssl_certificate /etc/tls/tls.crt; + ssl_certificate_key /etc/tls/tls.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_client_certificate /etc/tls/ca.crt; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + root /opt/chaos; + + location /health { + return 200; + } + + location / { + proxy_http_version 1.1; + add_header Cache-Control "no-cache"; + try_files $uri /index.html; + autoindex on; + } + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location /auth/ { + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "https://litmusportal-auth-server-service:9005/"; + proxy_ssl_certificate /etc/tls/tls.crt; + proxy_ssl_certificate_key /etc/tls/tls.key; + } + + location /api/ { + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass "https://litmusportal-server-service:9004/"; + proxy_ssl_certificate /etc/tls/tls.crt; + proxy_ssl_certificate_key /etc/tls/tls.key; + } + } + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-frontend + labels: + component: litmusportal-frontend +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-frontend + template: + metadata: + labels: + component: litmusportal-frontend + spec: + automountServiceAccountToken: false + containers: + - name: litmusportal-frontend + image: litmuschaos/litmusportal-frontend:3.14.0 + # securityContext: + # runAsUser: 2000 + # allowPrivilegeEscalation: false + # runAsNonRoot: true + imagePullPolicy: Always + ports: + - containerPort: 8185 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - mountPath: /etc/tls + name: tls-secret + volumes: + - name: nginx-config + configMap: + name: litmusportal-frontend-nginx-configuration + - name: tls-secret + secret: + secretName: tls-secret +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-frontend-service +spec: + type: NodePort + ports: + - name: http + port: 9091 + targetPort: 8185 + selector: + component: litmusportal-frontend +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-server + labels: + component: litmusportal-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-server + template: + metadata: + labels: + component: litmusportal-server + spec: + automountServiceAccountToken: false + volumes: + - name: gitops-storage + emptyDir: {} + - name: hub-storage + emptyDir: {} + - name: tls-secret + secret: + secretName: tls-secret + containers: + - name: graphql-server + image: litmuschaos/litmusportal-server:3.14.0 + volumeMounts: + - mountPath: /tmp/ + name: gitops-storage + - mountPath: /tmp/version + name: hub-storage + - mountPath: /etc/tls + name: tls-secret + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + # if self-signed certificate are used pass the base64 tls certificate, to allow agents to use tls for communication + - name: TLS_CERT_B64 + value: "" + - name: ENABLE_GQL_INTROSPECTION + value: "false" + - name: INFRA_DEPLOYMENTS + value: '["app=chaos-exporter", "name=chaos-operator", "app=workflow-controller", "app=event-tracker"]' + - name: CHAOS_CENTER_UI_ENDPOINT + value: "" + - name: SUBSCRIBER_IMAGE + value: "litmuschaos/litmusportal-subscriber:3.14.0" + - name: EVENT_TRACKER_IMAGE + value: "litmuschaos/litmusportal-event-tracker:3.14.0" + - name: ARGO_WORKFLOW_CONTROLLER_IMAGE + value: "litmuschaos/workflow-controller:v3.3.1" + - name: ARGO_WORKFLOW_EXECUTOR_IMAGE + value: "litmuschaos/argoexec:v3.3.1" + - name: LITMUS_CHAOS_OPERATOR_IMAGE + value: "litmuschaos/chaos-operator:3.14.0" + - name: LITMUS_CHAOS_RUNNER_IMAGE + value: "litmuschaos/chaos-runner:3.14.0" + - name: LITMUS_CHAOS_EXPORTER_IMAGE + value: "litmuschaos/chaos-exporter:3.14.0" + - name: CONTAINER_RUNTIME_EXECUTOR + value: "k8sapi" + - name: DEFAULT_HUB_BRANCH_NAME + value: "v3.14.x" + - name: LITMUS_AUTH_GRPC_ENDPOINT + value: "litmusportal-auth-server-service" + - name: LITMUS_AUTH_GRPC_PORT + value: "3030" + - name: WORKFLOW_HELPER_IMAGE_VERSION + value: "3.14.0" + - name: REMOTE_HUB_MAX_SIZE + value: "5000000" + - name: INFRA_COMPATIBLE_VERSIONS + value: '["3.14.0"]' + - name: ALLOWED_ORIGINS + value: ".*" #eg: ^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)? + - name: ENABLE_INTERNAL_TLS + value: "true" + - name: TLS_CERT_PATH + value: "/etc/tls/tls.crt" + - name: TLS_KEY_PATH + value: "/etc/tls/tls.key" + - name: CA_CERT_TLS_PATH + value: "/etc/tls/ca.crt" + - name: REST_PORT + value: "8081" + - name: GRPC_PORT + value: "8001" + ports: + - containerPort: 8081 + - containerPort: 8001 + imagePullPolicy: Always +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-server + namespace: litmus + labels: + component: litmusportal-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-server-service +spec: + type: NodePort + ports: + - name: graphql-server-https + port: 9004 + targetPort: 8081 + - name: graphql-rpc-server-https + port: 8001 + targetPort: 8001 + selector: + component: litmusportal-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: litmusportal-auth-server + labels: + component: litmusportal-auth-server +spec: + replicas: 1 + selector: + matchLabels: + component: litmusportal-auth-server + template: + metadata: + labels: + component: litmusportal-auth-server + spec: + volumes: + - name: tls-secret + secret: + secretName: tls-secret + automountServiceAccountToken: false + containers: + - name: auth-server + volumeMounts: + - mountPath: /etc/tls + name: tls-secret + image: litmuschaos/litmusportal-auth-server:3.14.0 + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + envFrom: + - configMapRef: + name: litmus-portal-admin-config + - secretRef: + name: litmus-portal-admin-secret + env: + - name: STRICT_PASSWORD_POLICY + value: "false" + - name: ADMIN_USERNAME + value: "admin" + - name: ADMIN_PASSWORD + value: "litmus" + - name: LITMUS_GQL_GRPC_ENDPOINT + value: "litmusportal-server-service" + - name: LITMUS_GQL_GRPC_PORT + value: "8000" + - name: ALLOWED_ORIGINS + value: "^(http://|https://|)litmuschaos.io(:[0-9]+|)?,^(http://|https://|)litmusportal-server-service(:[0-9]+|)?" #ip needs to added here + - name: ENABLE_INTERNAL_TLS + value: "true" + - name: TLS_CERT_PATH + value: "/etc/tls/tls.crt" + - name: TLS_KEY_PATH + value: "/etc/tls/ctls.key" + - name: CA_CERT_TLS_PATH + value: "/etc/tls/ca.crt" + - name: REST_PORT + value: "3001" + - name: GRPC_PORT + value: "3031" + ports: + - containerPort: 3001 + - containerPort: 3031 + imagePullPolicy: Always +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: litmusportal-auth-server + namespace: litmus + labels: + component: litmusportal-auth-server +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + component: litmusportal-auth-server + ingress: + - from: + - podSelector: + matchLabels: + component: litmusportal-frontend + - from: + - podSelector: + matchLabels: + component: litmusportal-server +--- +apiVersion: v1 +kind: Service +metadata: + name: litmusportal-auth-server-service +spec: + type: NodePort + ports: + - name: auth-server-https + port: 9005 + targetPort: 3001 + - name: auth-rpc-server-https + port: 3031 + targetPort: 3031 + selector: + component: litmusportal-auth-server From 89d7f242fffeb9e51ced181dc588a0ce5ad67a23 Mon Sep 17 00:00:00 2001 From: Shubham Chaudhary Date: Tue, 17 Dec 2024 11:15:43 +0530 Subject: [PATCH 02/10] chore(3.14.0): Add the installation manifest for 3.14.0 version (#4995) Signed-off-by: Shubham Chaudhary --- mkdocs/docs/chaos-scheduler-v3.14.0.yaml | 2750 +++++++++++++++ .../litmus-namespaced-operator.yaml | 14 +- .../litmus-namespaced-scheduler.yaml | 2 +- .../litmus-ns-experiment-rbac.yaml | 6 +- .../litmus-ns-rbac.yaml | 6 +- mkdocs/docs/litmus-operator-v3.14.0.yaml | 3004 +++++++++++++++++ 6 files changed, 5768 insertions(+), 14 deletions(-) create mode 100644 mkdocs/docs/chaos-scheduler-v3.14.0.yaml create mode 100644 mkdocs/docs/litmus-operator-v3.14.0.yaml diff --git a/mkdocs/docs/chaos-scheduler-v3.14.0.yaml b/mkdocs/docs/chaos-scheduler-v3.14.0.yaml new file mode 100644 index 00000000000..84c38ffc321 --- /dev/null +++ b/mkdocs/docs/chaos-scheduler-v3.14.0.yaml @@ -0,0 +1,2750 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: litmus +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: scheduler + namespace: litmus + labels: + name: scheduler +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: scheduler + labels: + name: scheduler +rules: +- apiGroups: [""] + resources: ["pods","events", "configmaps","services"] + verbs: ["create","get","list","delete","update","patch"] +- apiGroups: ["apps"] + resources: ["replicasets","deployments"] + verbs: ["get","list"] +- apiGroups: ["litmuschaos.io"] + resources: ["chaosengines","chaosschedules"] + verbs: ["get","create","update","patch","delete","list","watch","deletecollection"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: scheduler + labels: + name: scheduler +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: scheduler +subjects: +- kind: ServiceAccount + name: scheduler + namespace: litmus +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: chaos-scheduler + namespace: litmus +spec: + replicas: 1 + selector: + matchLabels: + name: chaos-scheduler + template: + metadata: + labels: + name: chaos-scheduler + spec: + serviceAccountName: scheduler + containers: + - name: chaos-scheduler + image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-scheduler:3.14.0 + command: + - chaos-scheduler + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "chaos-scheduler" +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosschedules.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosSchedule + listKind: ChaosScheduleList + plural: chaosschedules + singular: chaosschedule + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + engineTemplateSpec: + type: object + properties: + jobCleanUpPolicy: + type: string + pattern: ^(delete|retain)$ + # alternate ways to do this in case of complex pattern matches + #oneOf: + # - pattern: '^delete$' + # - pattern: '^retain$' + defaultHealthCheck: + type: boolean + appinfo: + type: object + properties: + appkind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + applabel: + type: string + appns: + type: string + selectors: + type: object + properties: + pods: + items: + properties: + names: + type: string + namespace: + type: string + required: + - names + - namespace + type: object + type: array + workloads: + items: + properties: + kind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + labels: + type: string + names: + type: string + namespace: + type: string + oneOf: + - required: [ names ] + - required: [ labels ] + required: + - kind + - namespace + type: object + type: array + oneOf: + - required: [ pods ] + - required: [ workloads ] + auxiliaryAppInfo: + type: string + engineState: + type: string + pattern: ^(active|stop)$ + chaosServiceAccount: + type: string + terminationGracePeriodSeconds: + type: integer + components: + type: object + properties: + sidecar: + type: array + items: + type: object + properties: + env: + description: ENV contains ENV passed to the sidecar container + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a double + $$, ie: $$(VAR_NAME). Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: EnvFrom for the sidecar container + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + secrets: + items: + properties: + mountPath: + type: string + name: + type: string + required: + - mountPath + - name + type: object + type: array + runner: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + image: + type: string + type: + type: string + pattern: ^(go)$ + runnerAnnotations: + type: object + runnerLabels: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + value: + type: string + minLength: 1 + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + experiments: + type: array + items: + type: object + properties: + name: + type: string + spec: + type: object + properties: + probe: + type: array + items: + type: object + required: + - name + - type + - mode + - runProperties + properties: + name: + type: string + type: + type: string + minLength: 1 + pattern: ^(k8sProbe|httpProbe|cmdProbe|promProbe|sloProbe)$ + k8sProbe/inputs: + type: object + required: + - version + - resource + - operation + properties: + group: + type: string + version: + type: string + resource: + type: string + namespace: + type: string + resourceNames: + type: string + fieldSelector: + type: string + labelSelector: + type: string + operation: + type: string + pattern: ^(present|absent|create|delete)$ + minLength: 1 + cmdProbe/inputs: + type: object + required: + - command + - comparator + properties: + command: + type: string + minLength: 1 + comparator: + type: object + required: + - type + - criteria + - value + properties: + type: + type: string + minLength: 1 + pattern: ^(int|float|string)$ + criteria: + type: string + value: + type: string + source: + description: The external pod where we have to run the + probe commands. It will run the commands inside the experiment pod itself(inline mode) if source contains a nil value + required: + - image + properties: + annotations: + additionalProperties: + type: string + description: Annotations for the source pod + type: object + args: + description: Args for the source pod + items: + type: string + type: array + command: + description: Command for the source pod + items: + type: string + type: array + env: + description: ENVList contains ENV passed to + the source pod + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container + and any service environment variables. + If a variable cannot be resolved, the + reference in the input string will be + unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, + regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment + variable's value. Cannot be used if + value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the + pod: supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + description: Specifies the output + format of the exposed resources, + defaults to "1" + type: string + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + hostNetwork: + description: HostNetwork define the hostNetwork + of the external pod it supports boolean values + and default value is false + type: boolean + inheritInputs: + description: InheritInputs define to inherit experiment + details in probe pod it supports boolean values + and default value is false. + type: boolean + image: + description: Image for the source pod + type: string + imagePullPolicy: + description: ImagePullPolicy for the source pod + type: string + imagePullSecrets: + description: ImagePullSecrets for source pod + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same + namespace. + properties: + name: + description: 'Name of the referent' + type: string + type: object + type: array + labels: + additionalProperties: + type: string + description: Labels for the source pod + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector for the source pod + type: object + tolerations: + description: Tolerations for the source pod + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + privileged: + description: Privileged for the source pod + type: boolean + volumeMount: + description: VolumesMount for the source pod + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container + at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines + how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is + used. This field is beta in 1.10. + type: string + name: + description: This must match the Name + of a Volume. + type: string + readOnly: + description: Mounted read-only if true, + read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: Path within the volume from + which the container's volume should + be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the + volume from which the container's volume + should be mounted. Behaves similarly + to SubPath but environment variable + references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and + SubPath are mutually exclusive. This + field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes for the source pod + items: + description: Volume represents a named volume + in a pod that may be accessed by any container + in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents + an AWS Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force + and set the ReadOnly property in + VolumeMounts to "true". If omitted, + the default is "false". More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent + disk resource in AWS (Amazon EBS + volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure + Data Disk mount on the host and bind + mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: The Name of the data + disk in the blob storage + type: string + diskURI: + description: The URI the data disk + in the blob storage + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'Expected values Shared: + multiple blob disks per storage + account Dedicated: single blob + disk per storage account Managed: + azure managed data disk (only in + managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure + File Service mount on the host and bind + mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that + contains Azure Storage Account Name + and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph + FS mount on the host that shares a pod's + lifetime + properties: + monitors: + description: 'Required: Monitors is + a collection of Ceph monitors More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the + mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile + is the path to key ring for User, + default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef + is reference to the authentication + secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'Optional: User is the + rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder + volume attached and mounted on kubelets + host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to + a secret object containing parameters + used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify + the volume in cinder. More info: + https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced ConfigMap will + be projected into the volume as + a file whose name is the key and + content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the ConfigMap, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) + represents storage that is handled by + an external CSI driver (Alpha feature). + properties: + driver: + description: Driver is the name of + the CSI driver that handles this + volume. Consult with your admin + for the correct name as registered + in the cluster. + type: string + fsType: + description: Filesystem type to mount. + Ex. "ext4", "xfs", "ntfs". If not + provided, the empty value is passed + to the associated CSI driver which + will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef + is a reference to the secret object + containing sensitive information + to pass to the CSI driver to complete + the CSI NodePublishVolume and NodeUnpublishVolume + calls. This field is optional, and may + be empty if no secret is required. + If the secret object contains more + than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: Specifies a read-only + configuration for the volume. Defaults + to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores + driver-specific properties that + are passed to the CSI driver. Consult + your driver's documentation for + supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward + API about the pod that should populate + this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + description: Specifies the + output format of the exposed + resources, defaults to + "1" + type: string + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary + directory that shares a pod''s lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage + medium should back this directory. + The default is "" which means to + use the node''s default medium. + Must be an empty string (default) + or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + description: 'Total amount of local + storage required for this EmptyDir + volume. The size limit is also applicable + for memory medium. The maximum usage + on memory medium EmptyDir would + be the minimum value between the + SizeLimit specified here and the + sum of memory limits of all containers + in a pod. The default is nil which + means that the limit is undefined. + More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + type: string + type: object + fc: + description: FC represents a Fibre Channel + resource that is attached to a kubelet's + host machine and then exposed to the + pod. + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + lun: + description: 'Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume + world wide identifiers (wwids) Either + wwids or combination of targetWWNs + and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic + volume resource that is provisioned/attached + using an exec based plugin. + properties: + driver: + description: Driver is the name of + the driver to use for this volume. + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". The default + filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command + options if any.' + type: object + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef + is reference to the secret object + containing sensitive information + to pass to the plugin scripts. This + may be empty if no secret object + is specified. If the secret object + contains more than one secret, all + secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker + volume attached to a kubelet's host + machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored + as metadata -> name on the dataset + for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. + This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents + a GCE Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty). More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD + resource in GCE. Used to identify + the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git + repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To + provision a container with a git repo, + mount an EmptyDir into an InitContainer + that clones the repo using git, then + mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. + Must not contain or start with '..'. If + '.' is supplied, the volume directory + will be the git repository. Otherwise, + if specified, the volume will contain + the git repository in the subdirectory + with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs + mount on the host that shares a pod''s + lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the + endpoint name that details Glusterfs + topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs + volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force + the Glusterfs volume to be mounted + with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing + file or directory on the host machine + that is directly exposed to the container. + This is generally used for system agents + or other privileged things that are + allowed to see the host machine. Most + containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict + who can use host directory mounts and + who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory + on the host. If the path is a symlink, + it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume + Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI + Disk resource that is attached to a + kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator + Name. If initiatorName is specified + with iscsiInterface simultaneously, + new iSCSI interface : will be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: iSCSI Interface Name + that uses an iSCSI transport. Defaults + to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. + The portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. + The Portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be + a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount + on the host that shares a pod''s lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported + by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force + the NFS export to be mounted with + read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname + or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource + represents a reference to a PersistentVolumeClaim + in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name + of a PersistentVolumeClaim in the + same namespace as the pod using + this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly + setting in VolumeMounts. Default + false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents + a portworx volume attached and mounted + on kubelets host machine + properties: + fsType: + description: FSType represents the + filesystem type to mount Must be + a filesystem type supported by the + host operating system. Ex. "ext4", + "xfs". Implicitly inferred to be + "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: Mode bits to use on created + files by default. Must be a value + between 0 and 0777. Directories + within the path are not affected + by this setting. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may + be projected along with other + supported volume types + properties: + configMap: + description: information about + the configMap data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced ConfigMap will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + ConfigMap, the volume + setup will error unless + it is marked optional. + Paths must be relative + and may not contain the + '..' path or start with + '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the ConfigMap or its keys + must be defined + type: boolean + type: object + downwardAPI: + description: information about + the downwardAPI data to project + properties: + items: + description: Items is a + list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information + to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field + of the pod: only + annotations, labels, + name and namespace + are supported.' + properties: + apiVersion: + description: Version + of the schema + the FieldPath + is written in + terms of, defaults + to "v1". + type: string + fieldPath: + description: Path + of the field + to select in + the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the + file to be created. + Must not be absolute + or contain the ''..'' + path. Must be utf-8 + encoded. The first + item of the relative + path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects + a resource of the + container: only + resources limits + and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container + name: required + for volumes, + optional for + env vars' + type: string + divisor: + description: Specifies + the output format + of the exposed + resources, defaults + to "1" + type: string + resource: + description: 'Required: + resource to + select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about + the secret data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced Secret will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + Secret, the volume setup + will error unless it is + marked optional. Paths + must be relative and may + not contain the '..' path + or start with '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the Secret or its key + must be defined + type: boolean + type: object + serviceAccountToken: + description: information about + the serviceAccountToken data + to project + properties: + audience: + description: Audience is + the intended audience + of the token. A recipient + of a token must identify + itself with an identifier + specified in the audience + of the token, and otherwise + should reject the token. + The audience defaults + to the identifier of the + apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds + is the requested duration + of validity of the service + account token. As the + token approaches expiration, + the kubelet volume plugin + will proactively rotate + the service account token. + The kubelet will start + trying to rotate the token + if the token is older + than 80 percent of its + time to live or if the + token is older than 24 + hours.Defaults to 1 hour + and must be at least 10 + minutes. + format: int64 + type: integer + path: + description: Path is the + path relative to the mount + point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + description: Quobyte represents a Quobyte + mount on the host that shares a pod's + lifetime + properties: + group: + description: Group to map volume access + to Default is no group + type: string + readOnly: + description: ReadOnly here will force + the Quobyte volume to be mounted + with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a + single or multiple Quobyte Registry + services specified as a string as + host:port pair (multiple entries + are separated with commas) which + acts as the central registry for + volumes + type: string + tenant: + description: Tenant owning the given + Quobyte volume in the Backend Used + with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access + to Defaults to serivceaccount user + type: string + volume: + description: Volume is a string that + references an already created Quobyte + volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block + Device mount on the host that shares + a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + image: + description: 'The rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path + to key ring for RBDUser. Default + is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph + monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. + Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of + the authentication secret for RBDUser. + If provided overrides keyring. Default + is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'The rados user name. + Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO + persistent volume attached and mounted + on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Default is + "xfs". + type: string + gateway: + description: The host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO + Protection Domain for the configured + storage. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references + to the secret for ScaleIO user and + other sensitive information. If + this is not provided, Login operation + will fail. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable + SSL communication with Gateway, + default false + type: boolean + storageMode: + description: Indicates whether the + storage for a volume should be ThickProvisioned + or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: The name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: The name of a volume + already created in the ScaleIO system + that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret + that should populate this volume. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced Secret will be + projected into the volume as a file + whose name is the key and content + is the value. If specified, the + listed keys will be projected into + the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the Secret, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'Name of the secret in + the pod''s namespace to use. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the + secret to use for obtaining the + StorageOS API credentials. If not + specified, default values will be + attempted. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable + name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies + the scope of the volume within StorageOS. If + no namespace is specified then the + Pod's namespace will be used. This + allows the Kubernetes name scoping + to be mirrored within StorageOS + for tighter integration. Set VolumeName + to any name to override the default + behaviour. Set to "default" if you + are not using namespaces within + StorageOS. Namespaces that do not + pre-exist within StorageOS will + be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents + a vSphere volume attached and mounted + on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: Storage Policy Based + Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: Path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + httpProbe/inputs: + type: object + required: + - url + - method + properties: + url: + type: string + minLength: 1 + insecureSkipVerify: + type: boolean + method: + type: object + minProperties: 1 + properties: + get: + type: object + required: + - criteria + - responseCode + properties: + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + post: + type: object + required: + - criteria + - responseCode + properties: + contentType: + type: string + minLength: 1 + body: + type: string + bodyPath: + type: string + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + promProbe/inputs: + type: object + required: + - endpoint + - comparator + properties: + endpoint: + type: string + query: + type: string + queryPath: + type: string + comparator: + type: object + required: + - criteria + - value + properties: + criteria: + type: string + value: + type: string + runProperties: + type: object + minProperties: 2 + required: + - probeTimeout + - interval + properties: + evaluationTimeout: + type: string + probeTimeout: + type: string + interval: + type: string + retry: + type: integer + attempt: + type: integer + probePollingInterval: + type: string + initialDelaySeconds: + type: integer + initialDelay: + type: string + verbosity: + type: string + stopOnFailure: + type: boolean + sloProbe/inputs: + description: inputs needed for the SLO probe + required: + - platformEndpoint + - sloIdentifier + - sloSourceMetadata + - comparator + properties: + comparator: + description: Comparator check for the correctness + of the probe output + required: + - criteria + - value + properties: + criteria: + description: Criteria for matching data it + supports >=, <=, ==, >, <, != for int and + float it supports equal, notEqual, contains + for string + type: string + type: + description: Type of data it can be int, float, + string + type: string + value: + description: Value contains relative value + for criteria + type: string + type: object + evaluationWindow: + description: EvaluationWindow is the time period + for which the metrics will be evaluated + properties: + evaluationEndTime: + description: End time of evaluation + type: integer + evaluationStartTime: + description: Start time of evaluation + type: integer + type: object + platformEndpoint: + description: PlatformEndpoint for the monitoring + service endpoint + type: string + insecureSkipVerify: + description: InsecureSkipVerify flag to skip certificate + checks + type: boolean + sloIdentifier: + description: SLOIdentifier for fetching the details + of the SLO + type: string + sloSourceMetadata: + description: SLOSourceMetadata consists of required + metadata details to fetch metric data + required: + - apiTokenSecret + - scope + properties: + apiTokenSecret: + description: APITokenSecret for authenticating + with the platform service + type: string + scope: + description: Scope required for fetching details + required: + - accountIdentifier + - orgIdentifier + - projectIdentifier + properties: + accountIdentifier: + description: AccountIdentifier for account + ID + type: string + orgIdentifier: + description: OrgIdentifier for organization + ID + type: string + projectIdentifier: + description: ProjectIdentifier for project + ID + type: string + type: object + type: object + type: object + mode: + type: string + pattern: ^(SOT|EOT|Edge|Continuous|OnChaos)$ + minLength: 1 + data: + type: string + components: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + statusCheckTimeouts: + type: object + properties: + delay: + type: integer + timeout: + type: integer + nodeSelector: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + experimentImage: + type: string + env: + type: array + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, spec.nodeName, + spec.serviceAccountName, status.hostIP, + status.podIP.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + configMaps: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + secrets: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + experimentAnnotations: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + concurrencyPolicy: + type: string + scheduleState: + type: string + schedule: + oneOf: + - required: + - now + - required: + - once + - required: + - repeat + properties: + now: + type: boolean + once: + properties: + executionTime: + format: date-time + type: string + type: object + repeat: + properties: + timeRange: + properties: + endTime: + format: date-time + type: string + startTime: + format: date-time + type: string + type: object + workHours: + properties: + includedHours: + type: string + type: object + required: + - includedHours + workDays: + properties: + includedDays: + pattern: ((Mon|Tue|Wed|Thu|Fri|Sat|Sun)(,))*(Mon|Tue|Wed|Thu|Fri|Sat|Sun) + type: string + type: object + required: + - includedDays + properties: + properties: + minChaosInterval: + properties: + hour: + properties: + everyNthHour: + type: integer + minuteOfTheHour: + type: integer + type: object + minute: + properties: + everyNthMinute: + type: integer + type: object + type: object + minProperties: 1 + maxProperties: 1 + random: + type: boolean + type: object + required: + - minChaosInterval + type: object + required: + - properties + type: object + status: + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: {} + conversion: + strategy: None diff --git a/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-operator.yaml b/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-operator.yaml index 73886cd3369..9e6125e84ec 100644 --- a/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-operator.yaml +++ b/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-operator.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-serviceaccount app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-role app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -59,7 +59,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-rolebinding app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -81,7 +81,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -97,7 +97,7 @@ spec: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -106,13 +106,13 @@ spec: serviceAccountName: litmus containers: - name: chaos-operator - image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-operator:3.13.0 + image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-operator:3.14.0 command: - chaos-operator imagePullPolicy: Always env: - name: CHAOS_RUNNER_IMAGE - value: "litmuschaos.docker.scarf.sh/litmuschaos/chaos-runner:3.13.0" + value: "litmuschaos.docker.scarf.sh/litmuschaos/chaos-runner:3.14.0" - name: WATCH_NAMESPACE valueFrom: fieldRef: diff --git a/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-scheduler.yaml b/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-scheduler.yaml index a63ff9539fb..5cefe6ef13a 100644 --- a/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-scheduler.yaml +++ b/mkdocs/docs/litmus-namespaced-scope/litmus-namespaced-scheduler.yaml @@ -16,7 +16,7 @@ spec: containers: - name: chaos-scheduler # Replace this with the built image name - image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-scheduler:3.13.0 + image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-scheduler:3.14.0 command: - chaos-scheduler imagePullPolicy: IfNotPresent diff --git a/mkdocs/docs/litmus-namespaced-scope/litmus-ns-experiment-rbac.yaml b/mkdocs/docs/litmus-namespaced-scope/litmus-ns-experiment-rbac.yaml index cd7b81d0beb..e8633da7950 100644 --- a/mkdocs/docs/litmus-namespaced-scope/litmus-ns-experiment-rbac.yaml +++ b/mkdocs/docs/litmus-namespaced-scope/litmus-ns-experiment-rbac.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-serviceaccount app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-role app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -59,7 +59,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-rolebinding app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl diff --git a/mkdocs/docs/litmus-namespaced-scope/litmus-ns-rbac.yaml b/mkdocs/docs/litmus-namespaced-scope/litmus-ns-rbac.yaml index db76c69f3c6..d3c19d84ec3 100644 --- a/mkdocs/docs/litmus-namespaced-scope/litmus-ns-rbac.yaml +++ b/mkdocs/docs/litmus-namespaced-scope/litmus-ns-rbac.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-serviceaccount app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-role app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl @@ -62,7 +62,7 @@ metadata: app.kubernetes.io/name: litmus # provide unique instance-id if applicable # app.kubernetes.io/instance: litmus-abcxzy - app.kubernetes.io/version: v3.13.0 + app.kubernetes.io/version: v3.14.0 app.kubernetes.io/component: operator-rolebinding app.kubernetes.io/part-of: litmus app.kubernetes.io/managed-by: kubectl diff --git a/mkdocs/docs/litmus-operator-v3.14.0.yaml b/mkdocs/docs/litmus-operator-v3.14.0.yaml new file mode 100644 index 00000000000..79942077f2e --- /dev/null +++ b/mkdocs/docs/litmus-operator-v3.14.0.yaml @@ -0,0 +1,3004 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: litmus +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: litmus + namespace: litmus + labels: + app.kubernetes.io/name: litmus + # provide unique instance-id if applicable + # app.kubernetes.io/instance: litmus-abcxzy + app.kubernetes.io/version: v3.14.0 + app.kubernetes.io/component: operator-serviceaccount + app.kubernetes.io/part-of: litmus + app.kubernetes.io/managed-by: kubectl + name: litmus +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: litmus + labels: + app.kubernetes.io/name: litmus + # provide unique instance-id if applicable + # app.kubernetes.io/instance: litmus-abcxzy + app.kubernetes.io/version: v3.14.0 + app.kubernetes.io/component: operator-clusterrole + app.kubernetes.io/part-of: litmus + app.kubernetes.io/managed-by: kubectl + name: litmus +rules: + # ******************************************************************* + # Permissions needed for creation and discovery of chaos component + # ******************************************************************* + +# for checking app parent resources if they are eligible chaos candidates +- apiGroups: [""] + resources: ["replicationcontrollers"] + verbs: ["get","list"] + +# for checking app parent resources if they are eligible chaos candidates +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get","list"] + +# for checking (openshift) app parent resources if they are eligible chaos candidates +- apiGroups: ["apps.openshift.io"] + resources: ["deploymentconfigs"] + verbs: ["get","list"] + +# for operator to perform asset discovery of available resources on the cluster which can be picked as a target for chaos +- apiGroups: ["apps"] + resources: ["deployments", "daemonsets", "replicasets", "statefulsets"] + verbs: ["get","list"] + +# for operator to perform asset discovery of experiment jobs +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get","list"] + +# for checking (argo) app parent resources if they are eligible chaos candidates +- apiGroups: ["argoproj.io"] + resources: ["rollouts"] + verbs: ["get","list"] + +# for creating and monitoring the chaos-runner pods +- apiGroups: [""] + resources: ["pods","events"] + verbs: ["get","create","update","patch","delete","list","watch","deletecollection"] + +# for operator to create or get the service for mertics +- apiGroups: [""] + resources: ["services"] + verbs: ["create","update","get","list","watch","delete"] + +# for operator to create and manage configmap to handle race condition +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create","update","get","list","watch","delete"] + +# for operator to perform removal of experiment jobs +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["delete","deletecollection"] + +# for creation, status polling and deletion of litmus chaos resources used within an experiment +- apiGroups: ["litmuschaos.io"] + resources: ["chaosengines","chaosexperiments","chaosresults"] + verbs: ["get","create","update","patch","delete","list","watch","deletecollection"] + +# for validation of existance of chaosresult crd +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["list","get"] + +# for managing litmus resource deletion +- apiGroups: ["litmuschaos.io"] + resources: ["chaosengines/finalizers"] + verbs: ["update"] + +# for leader election in case of multireplica +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get","create","list","update","delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: litmus + labels: + app.kubernetes.io/name: litmus + # provide unique instance-id if applicable + # app.kubernetes.io/instance: litmus-abcxzy + app.kubernetes.io/version: v3.14.0 + app.kubernetes.io/component: operator-clusterrolebinding + app.kubernetes.io/part-of: litmus + app.kubernetes.io/managed-by: kubectl + name: litmus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: litmus +subjects: +- kind: ServiceAccount + name: litmus + namespace: litmus +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: litmus + # provide unique instance-id if applicable + # app.kubernetes.io/instance: litmus-abcxzy + app.kubernetes.io/version: v3.14.0 + app.kubernetes.io/component: operator + app.kubernetes.io/part-of: litmus + app.kubernetes.io/managed-by: kubectl + name: litmus + name: chaos-operator-ce + namespace: litmus +spec: + replicas: 1 + selector: + matchLabels: + name: chaos-operator + template: + metadata: + labels: + app.kubernetes.io/name: litmus + # provide unique instance-id if applicable + # app.kubernetes.io/instance: litmus-abcxzy + app.kubernetes.io/version: v3.14.0 + app.kubernetes.io/component: operator + app.kubernetes.io/part-of: litmus + app.kubernetes.io/managed-by: kubectl + name: chaos-operator + spec: + serviceAccountName: litmus + containers: + - name: chaos-operator + image: litmuschaos.docker.scarf.sh/litmuschaos/chaos-operator:3.14.0 + command: + - chaos-operator + args: + - -leader-elect=true + imagePullPolicy: Always + env: + - name: CHAOS_RUNNER_IMAGE + value: "litmuschaos.docker.scarf.sh/litmuschaos/chaos-runner:3.14.0" + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPERATOR_NAME + value: "chaos-operator" +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosengines.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosEngine + listKind: ChaosEngineList + plural: chaosengines + singular: chaosengine + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + jobCleanUpPolicy: + type: string + pattern: ^(delete|retain)$ + # alternate ways to do this in case of complex pattern matches + #oneOf: + # - pattern: '^delete$' + # - pattern: '^retain$' + defaultHealthCheck: + type: boolean + appinfo: + type: object + properties: + appkind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + applabel: + type: string + appns: + type: string + selectors: + type: object + properties: + pods: + items: + properties: + names: + type: string + namespace: + type: string + required: + - names + - namespace + type: object + type: array + workloads: + items: + properties: + kind: + type: string + pattern: ^(^$|deployment|statefulset|daemonset|deploymentconfig|rollout)$ + labels: + type: string + names: + type: string + namespace: + type: string + oneOf: + - required: [ names ] + - required: [ labels ] + required: + - kind + - namespace + type: object + type: array + oneOf: + - required: [ pods ] + - required: [ workloads ] + auxiliaryAppInfo: + type: string + engineState: + type: string + pattern: ^(active|stop)$ + chaosServiceAccount: + type: string + terminationGracePeriodSeconds: + type: integer + components: + type: object + properties: + sidecar: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + properties: + env: + description: ENV contains ENV passed to the sidecar container + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a double + $$, ie: $$(VAR_NAME). Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: EnvFrom for the sidecar container + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + secrets: + items: + properties: + mountPath: + type: string + name: + type: string + required: + - mountPath + - name + type: object + type: array + runner: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + image: + type: string + type: + type: string + pattern: ^(go)$ + runnerAnnotations: + type: object + runnerLabels: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + value: + type: string + minLength: 1 + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + experiments: + type: array + items: + type: object + properties: + name: + type: string + spec: + type: object + properties: + probe: + type: array + items: + type: object + required: + - name + - type + - mode + - runProperties + properties: + name: + type: string + type: + type: string + minLength: 1 + pattern: ^(k8sProbe|httpProbe|cmdProbe|promProbe)$ + k8sProbe/inputs: + type: object + required: + - version + - resource + - operation + properties: + group: + type: string + version: + type: string + resource: + type: string + namespace: + type: string + resourceNames: + type: string + fieldSelector: + type: string + labelSelector: + type: string + operation: + type: string + pattern: ^(present|absent|create|delete)$ + minLength: 1 + cmdProbe/inputs: + type: object + required: + - command + - comparator + properties: + command: + type: string + minLength: 1 + comparator: + type: object + required: + - type + - criteria + - value + properties: + type: + type: string + minLength: 1 + pattern: ^(int|float|string)$ + criteria: + type: string + value: + type: string + source: + description: The external pod where we have to run the + probe commands. It will run the commands inside the experiment pod itself(inline mode) if source contains a nil value + required: + - image + properties: + annotations: + additionalProperties: + type: string + description: Annotations for the source pod + type: object + args: + description: Args for the source pod + items: + type: string + type: array + command: + description: Command for the source pod + items: + type: string + type: array + env: + description: ENVList contains ENV passed to + the source pod + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container + and any service environment variables. + If a variable cannot be resolved, the + reference in the input string will be + unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, + regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment + variable's value. Cannot be used if + value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the + pod: supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + description: Specifies the output + format of the exposed resources, + defaults to "1" + type: string + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + hostNetwork: + description: HostNetwork define the hostNetwork + of the external pod it supports boolean values + and default value is false + type: boolean + inheritInputs: + description: InheritInputs define to inherit experiment + details in probe pod it supports boolean values + and default value is false. + type: boolean + image: + description: Image for the source pod + type: string + imagePullPolicy: + description: ImagePullPolicy for the source pod + type: string + imagePullSecrets: + description: ImagePullSecrets for source pod + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same + namespace. + properties: + name: + description: 'Name of the referent' + type: string + type: object + type: array + labels: + additionalProperties: + type: string + description: Labels for the source pod + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector for the source pod + type: object + tolerations: + description: Tolerations for the source pod + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + privileged: + description: Privileged for the source pod + type: boolean + volumeMount: + description: VolumesMount for the source pod + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container + at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines + how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is + used. This field is beta in 1.10. + type: string + name: + description: This must match the Name + of a Volume. + type: string + readOnly: + description: Mounted read-only if true, + read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: Path within the volume from + which the container's volume should + be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the + volume from which the container's volume + should be mounted. Behaves similarly + to SubPath but environment variable + references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and + SubPath are mutually exclusive. This + field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes for the source pod + items: + description: Volume represents a named volume + in a pod that may be accessed by any container + in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents + an AWS Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force + and set the ReadOnly property in + VolumeMounts to "true". If omitted, + the default is "false". More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent + disk resource in AWS (Amazon EBS + volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure + Data Disk mount on the host and bind + mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: The Name of the data + disk in the blob storage + type: string + diskURI: + description: The URI the data disk + in the blob storage + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'Expected values Shared: + multiple blob disks per storage + account Dedicated: single blob + disk per storage account Managed: + azure managed data disk (only in + managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure + File Service mount on the host and bind + mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that + contains Azure Storage Account Name + and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph + FS mount on the host that shares a pod's + lifetime + properties: + monitors: + description: 'Required: Monitors is + a collection of Ceph monitors More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the + mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile + is the path to key ring for User, + default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef + is reference to the authentication + secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'Optional: User is the + rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder + volume attached and mounted on kubelets + host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to + a secret object containing parameters + used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify + the volume in cinder. More info: + https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced ConfigMap will + be projected into the volume as + a file whose name is the key and + content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the ConfigMap, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) + represents storage that is handled by + an external CSI driver (Alpha feature). + properties: + driver: + description: Driver is the name of + the CSI driver that handles this + volume. Consult with your admin + for the correct name as registered + in the cluster. + type: string + fsType: + description: Filesystem type to mount. + Ex. "ext4", "xfs", "ntfs". If not + provided, the empty value is passed + to the associated CSI driver which + will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef + is a reference to the secret object + containing sensitive information + to pass to the CSI driver to complete + the CSI NodePublishVolume and NodeUnpublishVolume + calls. This field is optional, and may + be empty if no secret is required. + If the secret object contains more + than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: Specifies a read-only + configuration for the volume. Defaults + to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores + driver-specific properties that + are passed to the CSI driver. Consult + your driver's documentation for + supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward + API about the pod that should populate + this volume + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + description: Specifies the + output format of the exposed + resources, defaults to + "1" + type: string + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary + directory that shares a pod''s lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage + medium should back this directory. + The default is "" which means to + use the node''s default medium. + Must be an empty string (default) + or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + description: 'Total amount of local + storage required for this EmptyDir + volume. The size limit is also applicable + for memory medium. The maximum usage + on memory medium EmptyDir would + be the minimum value between the + SizeLimit specified here and the + sum of memory limits of all containers + in a pod. The default is nil which + means that the limit is undefined. + More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + type: string + type: object + fc: + description: FC represents a Fibre Channel + resource that is attached to a kubelet's + host machine and then exposed to the + pod. + properties: + fsType: + description: 'Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + lun: + description: 'Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume + world wide identifiers (wwids) Either + wwids or combination of targetWWNs + and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic + volume resource that is provisioned/attached + using an exec based plugin. + properties: + driver: + description: Driver is the name of + the driver to use for this volume. + type: string + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". The default + filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command + options if any.' + type: object + readOnly: + description: 'Optional: Defaults to + false (read/write). ReadOnly here + will force the ReadOnly setting + in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef + is reference to the secret object + containing sensitive information + to pass to the plugin scripts. This + may be empty if no secret object + is specified. If the secret object + contains more than one secret, all + secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker + volume attached to a kubelet's host + machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored + as metadata -> name on the dataset + for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. + This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents + a GCE Disk resource that is attached + to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + partition: + description: 'The partition in the + volume that you want to mount. If + omitted, the default is to mount + by volume name. Examples: For volume + /dev/sda1, you specify the partition + as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can + leave the property empty). More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD + resource in GCE. Used to identify + the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git + repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To + provision a container with a git repo, + mount an EmptyDir into an InitContainer + that clones the repo using git, then + mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. + Must not contain or start with '..'. If + '.' is supplied, the volume directory + will be the git repository. Otherwise, + if specified, the volume will contain + the git repository in the subdirectory + with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs + mount on the host that shares a pod''s + lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the + endpoint name that details Glusterfs + topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs + volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force + the Glusterfs volume to be mounted + with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing + file or directory on the host machine + that is directly exposed to the container. + This is generally used for system agents + or other privileged things that are + allowed to see the host machine. Most + containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict + who can use host directory mounts and + who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory + on the host. If the path is a symlink, + it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume + Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI + Disk resource that is attached to a + kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator + Name. If initiatorName is specified + with iscsiInterface simultaneously, + new iSCSI interface : will be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: iSCSI Interface Name + that uses an iSCSI transport. Defaults + to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. + The portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. + The Portal is either an IP or ip_addr:port + if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be + a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount + on the host that shares a pod''s lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported + by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force + the NFS export to be mounted with + read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname + or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource + represents a reference to a PersistentVolumeClaim + in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name + of a PersistentVolumeClaim in the + same namespace as the pod using + this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly + setting in VolumeMounts. Default + false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents + a portworx volume attached and mounted + on kubelets host machine + properties: + fsType: + description: FSType represents the + filesystem type to mount Must be + a filesystem type supported by the + host operating system. Ex. "ext4", + "xfs". Implicitly inferred to be + "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: Mode bits to use on created + files by default. Must be a value + between 0 and 0777. Directories + within the path are not affected + by this setting. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may + be projected along with other + supported volume types + properties: + configMap: + description: information about + the configMap data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced ConfigMap will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + ConfigMap, the volume + setup will error unless + it is marked optional. + Paths must be relative + and may not contain the + '..' path or start with + '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the ConfigMap or its keys + must be defined + type: boolean + type: object + downwardAPI: + description: information about + the downwardAPI data to project + properties: + items: + description: Items is a + list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information + to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field + of the pod: only + annotations, labels, + name and namespace + are supported.' + properties: + apiVersion: + description: Version + of the schema + the FieldPath + is written in + terms of, defaults + to "v1". + type: string + fieldPath: + description: Path + of the field + to select in + the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the + file to be created. + Must not be absolute + or contain the ''..'' + path. Must be utf-8 + encoded. The first + item of the relative + path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects + a resource of the + container: only + resources limits + and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container + name: required + for volumes, + optional for + env vars' + type: string + divisor: + description: Specifies + the output format + of the exposed + resources, defaults + to "1" + type: string + resource: + description: 'Required: + resource to + select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about + the secret data to project + properties: + items: + description: If unspecified, + each key-value pair in + the Data field of the + referenced Secret will + be projected into the + volume as a file whose + name is the key and content + is the value. If specified, + the listed keys will be + projected into the specified + paths, and unlisted keys + will not be present. If + a key is specified which + is not present in the + Secret, the volume setup + will error unless it is + marked optional. Paths + must be relative and may + not contain the '..' path + or start with '..'. + items: + description: Maps a string + key to a path within + a volume. + properties: + key: + description: The key + to project. + type: string + mode: + description: 'Optional: + mode bits to use + on this file, must + be a value between + 0 and 0777. If not + specified, the volume + defaultMode will + be used. This might + be in conflict with + other options that + affect the file + mode, like fsGroup, + and the result can + be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative + path of the file + to map the key to. + May not be an absolute + path. May not contain + the path element + '..'. May not start + with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the + referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful + fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether + the Secret or its key + must be defined + type: boolean + type: object + serviceAccountToken: + description: information about + the serviceAccountToken data + to project + properties: + audience: + description: Audience is + the intended audience + of the token. A recipient + of a token must identify + itself with an identifier + specified in the audience + of the token, and otherwise + should reject the token. + The audience defaults + to the identifier of the + apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds + is the requested duration + of validity of the service + account token. As the + token approaches expiration, + the kubelet volume plugin + will proactively rotate + the service account token. + The kubelet will start + trying to rotate the token + if the token is older + than 80 percent of its + time to live or if the + token is older than 24 + hours.Defaults to 1 hour + and must be at least 10 + minutes. + format: int64 + type: integer + path: + description: Path is the + path relative to the mount + point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + description: Quobyte represents a Quobyte + mount on the host that shares a pod's + lifetime + properties: + group: + description: Group to map volume access + to Default is no group + type: string + readOnly: + description: ReadOnly here will force + the Quobyte volume to be mounted + with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a + single or multiple Quobyte Registry + services specified as a string as + host:port pair (multiple entries + are separated with commas) which + acts as the central registry for + volumes + type: string + tenant: + description: Tenant owning the given + Quobyte volume in the Backend Used + with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access + to Defaults to serivceaccount user + type: string + volume: + description: Volume is a string that + references an already created Quobyte + volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block + Device mount on the host that shares + a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the + volume that you want to mount. Tip: + Ensure that the filesystem type + is supported by the host operating + system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be + "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in + the filesystem from compromising + the machine' + type: string + image: + description: 'The rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path + to key ring for RBDUser. Default + is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph + monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. + Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force + the ReadOnly setting in VolumeMounts. + Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of + the authentication secret for RBDUser. + If provided overrides keyring. Default + is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + user: + description: 'The rados user name. + Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO + persistent volume attached and mounted + on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Default is + "xfs". + type: string + gateway: + description: The host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO + Protection Domain for the configured + storage. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references + to the secret for ScaleIO user and + other sensitive information. If + this is not provided, Login operation + will fail. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable + SSL communication with Gateway, + default false + type: boolean + storageMode: + description: Indicates whether the + storage for a volume should be ThickProvisioned + or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: The name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: The name of a volume + already created in the ScaleIO system + that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret + that should populate this volume. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits + to use on created files by default. + Must be a value between 0 and 0777. + Defaults to 0644. Directories within + the path are not affected by this + setting. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the + result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced Secret will be + projected into the volume as a file + whose name is the key and content + is the value. If specified, the + listed keys will be projected into + the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the Secret, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'Name of the secret in + the pod''s namespace to use. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly + setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the + secret to use for obtaining the + StorageOS API credentials. If not + specified, default values will be + attempted. + properties: + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable + name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies + the scope of the volume within StorageOS. If + no namespace is specified then the + Pod's namespace will be used. This + allows the Kubernetes name scoping + to be mirrored within StorageOS + for tighter integration. Set VolumeName + to any name to override the default + behaviour. Set to "default" if you + are not using namespaces within + StorageOS. Namespaces that do not + pre-exist within StorageOS will + be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents + a vSphere volume attached and mounted + on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. + Must be a filesystem type supported + by the host operating system. Ex. + "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: Storage Policy Based + Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: Path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + httpProbe/inputs: + type: object + required: + - url + - method + properties: + url: + type: string + minLength: 1 + insecureSkipVerify: + type: boolean + method: + type: object + minProperties: 1 + properties: + get: + type: object + required: + - criteria + - responseCode + properties: + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + post: + type: object + required: + - criteria + - responseCode + properties: + contentType: + type: string + minLength: 1 + body: + type: string + bodyPath: + type: string + criteria: + type: string + minLength: 1 + responseCode: + type: string + minLength: 1 + promProbe/inputs: + type: object + required: + - endpoint + - comparator + properties: + endpoint: + type: string + query: + type: string + queryPath: + type: string + comparator: + type: object + required: + - criteria + - value + properties: + criteria: + type: string + value: + type: string + runProperties: + type: object + minProperties: 2 + required: + - probeTimeout + - interval + properties: + probeTimeout: + type: string + interval: + type: string + retry: + type: integer + attempt: + type: integer + probePollingInterval: + type: string + initialDelay: + type: string + verbosity: + type: string + initialDelaySeconds: + type: integer + stopOnFailure: + type: boolean + mode: + type: string + pattern: ^(SOT|EOT|Edge|Continuous|OnChaos)$ + minLength: 1 + data: + type: string + components: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + statusCheckTimeouts: + type: object + properties: + delay: + type: integer + timeout: + type: integer + nodeSelector: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + experimentImage: + type: string + env: + type: array + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, spec.nodeName, + spec.serviceAccountName, status.hostIP, + status.podIP.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + configMaps: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + secrets: + type: array + items: + type: object + properties: + name: + type: string + mountPath: + type: string + experimentAnnotations: + type: object + additionalProperties: + type: string + properties: + key: + type: string + minLength: 1 + allowEmptyValue: false + value: + type: string + minLength: 1 + allowEmptyValue: false + tolerations: + description: Pod's tolerations. + items: + description: The pod with this Toleration tolerates any taint matches the using the matching operator . + properties: + effect: + description: Effect to match. Empty means all effects. + type: string + key: + description: Taint key the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists. + type: string + operator: + description: Operators are Exists or Equal. Defaults to Equal. + type: string + tolerationSeconds: + description: Period of time the toleration tolerates the taint. + format: int64 + type: integer + value: + description: If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + + status: + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: {} + conversion: + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosexperiments.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosExperiment + listKind: ChaosExperimentList + plural: chaosexperiments + singular: chaosexperiment + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + description: + type: object + additionalProperties: + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + x-kubernetes-preserve-unknown-fields: true + type: object + spec: + type: object + properties: + definition: + x-kubernetes-preserve-unknown-fields: true + type: object + properties: + args: + type: array + items: + type: string + command: + type: array + items: + type: string + env: + type: array + items: + type: object + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, spec.nodeName, + spec.serviceAccountName, status.hostIP, + status.podIP.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + image: + type: string + imagePullPolicy: + type: string + labels: + type: object + additionalProperties: + type: string + scope: + type: string + pattern: ^(Namespaced|Cluster)$ + permissions: + type: array + items: + type: object + minProperties: 3 + required: + - apiGroups + - resources + - verbs + properties: + apiGroups: + type: array + items: + type: string + resources: + type: array + items: + type: string + verbs: + type: array + items: + type: string + resourceNames: + type: array + items: + type: string + nonResourceURLs: + type: array + items: + type: string + configMaps: + type: array + items: + type: object + minProperties: 2 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + secrets: + type: array + items: + type: object + minProperties: 2 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + hostFileVolumes: + type: array + items: + type: object + minProperties: 3 + properties: + name: + type: string + allowEmptyValue: false + minLength: 1 + mountPath: + type: string + allowEmptyValue: false + minLength: 1 + nodePath: + type: string + allowEmptyValue: false + minLength: 1 + securityContext: + x-kubernetes-preserve-unknown-fields: true + type: object + hostPID: + type: boolean + + served: true + storage: true + subresources: {} + conversion: + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaosresults.litmuschaos.io +spec: + group: litmuschaos.io + names: + kind: ChaosResult + listKind: ChaosResultList + plural: chaosresults + singular: chaosresult + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + x-kubernetes-preserve-unknown-fields: true + type: object + status: + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: {} + conversion: + strategy: None \ No newline at end of file From ac30fbb0fc2b0159e417d07ea6337c2d2e2acaed Mon Sep 17 00:00:00 2001 From: Sayan Mondal Date: Fri, 20 Dec 2024 11:51:05 +0530 Subject: [PATCH 03/10] chore: Adding Pokerbaazi as adopters (#4958) Signed-off-by: Sayan Mondal --- ADOPTERS.md | 1 + adopters/organizations/pokerbaazi.md | 32 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 adopters/organizations/pokerbaazi.md diff --git a/ADOPTERS.md b/ADOPTERS.md index b689879fe0a..1f1bda7f18a 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -31,6 +31,7 @@ The companies listed here conform to [CNCF's definition of end-users](https://gi | [Delivery Hero](https://www.deliveryhero.com/) | Enhancing Resiliency of Our Services | [Our Story](https://github.com/litmuschaos/litmus/issues/2191#issuecomment-1997465958) | | [Wingie Enuygun Company](https://www.wingie.com/) | Chaos Engineering for an Online Travel and Finance Platform | [Our Story](https://github.com/litmuschaos/litmus/issues/2191#issuecomment-2331265698) | | [EmiratesNBD](https://www.emiratesnbd.com) | Chaos Engineering for Government Owned Bank | [Our Story](adopters/organizations/emirates-nbd.md) | +| [PokerBaazi](https://www.pokerbaazi.com/) | Chaos Engineering for Online Gaming | [Our Story](adopters/organizations/pokerbaazi.md) | ### Cloud-Native Vendors diff --git a/adopters/organizations/pokerbaazi.md b/adopters/organizations/pokerbaazi.md new file mode 100644 index 00000000000..820579263fc --- /dev/null +++ b/adopters/organizations/pokerbaazi.md @@ -0,0 +1,32 @@ +## PokerBaazi + +[PokerBaazi](https://www.pokerbaazi.com/) is India's biggest online poker platform providing an unparalleled world-class experience. Home Grown and 8 years of calling it our own, today, we have a strong and loyal user base of 40 LAC+ Indians. + +### **Applications/Workloads or Infra that are being subjected to chaos by Litmus.** + +At PokerBaazi, we leverage Litmus Chaos to subject critical components of our infrastructure to controlled chaos experiments. These include: + +- Microservices Infrastructure: Our backend is designed as a microservices architecture, running on Kubernetes. We conduct experiments on inter-service communication, API latencies, and service resilience during node failures or resource constraints. +- Load Balancers and Networking: We simulate disruptions in networking, such as packet drops or DNS failures, to ensure our applications maintain connectivity and continue serving users. +- Application Workloads: High-demand applications like our gaming engine and payment/promotions api's are put under stress to evaluate their fault tolerance and recovery mechanisms during peak loads or unexpected outages. + +### **Why do we use Litmus.** + +We chose Litmus Chaos for several compelling reasons: + +- Kubernetes-Native Integration: Since our infrastructure is heavily Kubernetes-based, Litmus seamlessly integrates with our stack, making it a natural fit. +- Ease of Use and Open-Source: Litmus offers a user-friendly interface along with robust documentation, allowing our teams to adopt it quickly without steep learning curves. +- Custom Experiment Support: The ability to create tailored chaos experiments aligned with our specific workloads ensures we can target critical failure scenarios unique to our ecosystem. +- Community Support and Scalability: Being an open-source project with an active community, Litmus evolves rapidly, allowing us to leverage the latest chaos engineering methodologies and tools. + +Litmus has been instrumental in identifying hidden weaknesses in our system, such as unexpected dependencies or cascading failures. This has enabled us to proactively address potential issues, enhance system resilience, and meet our uptime commitments. + +### **Where are we using Litmus.** + +We use Litmus Chaos in various environments to ensure robust testing at every stage of development: + +- Development: Initial chaos experiments are conducted in isolated dev environments to identify basic resilience issues and ensure service fault tolerance during early-stage development. +- Staging/Pre-Production: In staging, we run more comprehensive chaos scenarios simulating real-world failures, such as pod crashes, resource exhaustion, or external API downtime, to ensure the production-like environment is resilient. +- Production: Selected, low-risk chaos experiments are conducted in production under strict supervision to verify real-time system robustness and validate SLAs in live conditions. + +Litmus Chaos has transformed our approach to building and maintaining a highly resilient gaming platform, allowing us to deliver exceptional user experiences while preparing for the unexpected. From a14282a62ab0b1c703552faf98566653d23a1f41 Mon Sep 17 00:00:00 2001 From: DongYoung Kim Date: Fri, 20 Dec 2024 15:22:49 +0900 Subject: [PATCH 04/10] Proposal: Load testing with locust (#4955) Signed-off-by: DongYoung Kim --- proposals/images/locust-fault-scenario.png | Bin 0 -> 223565 bytes proposals/locust-load-test.md | 65 +++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 proposals/images/locust-fault-scenario.png create mode 100644 proposals/locust-load-test.md diff --git a/proposals/images/locust-fault-scenario.png b/proposals/images/locust-fault-scenario.png new file mode 100644 index 0000000000000000000000000000000000000000..0fba4287016324bbce06d2f8f77a3ed545e74aec GIT binary patch literal 223565 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 >af^eTGs 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 G-v0p+lBF8} literal 0 HcmV?d00001 diff --git a/proposals/locust-load-test.md b/proposals/locust-load-test.md new file mode 100644 index 00000000000..70890248491 --- /dev/null +++ b/proposals/locust-load-test.md @@ -0,0 +1,65 @@ +| title | authors | creation-date | last-updated | +|-------|------------------------------------------|---------------|--------------| +| Adding a New Chaos Fault - Load Testing with locust | [@kwx4957](https://github.com/kwx4957) | 2024-11-21 | 2024-11-21 | + +# Adding a New Chaos Fault - Load Testing with locust + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) + - [Use Cases](#use-cases) + - [Implementation Details](#implementation-details) +- [Risks and Mitigations](#risks-and-mitigations) +- [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) +- [Drawbacks](#drawbacks) +- [Alternatives](#alternatives) +- [References](#references) + +## Summary +[locust](https://locust.io/) is an open-source load testing. LitmuChaos already supports k6 load testing, but only for the JavaScript language. On the other hand, locust supports writing scripts for Python code, giving users a wider choice. + +## Motivation +Locust is a load testing tool that supports Python code. It supports various [protocols (HTTP, GRPC)](https://docs.locust.io/en/stable/testing-other-systems.html +) and [plugins](https://github.com/SvenskaSpel/locust-plugins?tab=readme-ov-file#users +). Having a wide range of choices when it comes to choosing a load test will help users a lot. + + +### Goals + +- Adding a 'locust' Chaos Fault to [Litmus ChaosHub](https://hub.litmuschaos.io/) +- Fixing [litmus-go](https://github.com/litmuschaos/litmus-go) and [chaos-charts](https://github.com/litmuschaos/chaos-charts) codes + +### Non-Goals + +## Proposal + +### Use Cases + +Detail the things that people will be able to do if this is `implemented`. + +#### Use case 1 + +### Implementation Details + +This is a Locust Chaos Fault Scenario. + +![locust-fault-scenario](./images/locust-fault-scenario.png) + +1. Add scenario to the litmus-go repository +2. Add a new Chaos Fault to the Litmus ChaosHub + +## Risks and Mitigations + +We need to grant proper RBAC permissions to the runner container. Granting override permissions may affect other systems. + +## Upgrade / Downgrade Strategy + +## Drawbacks + +## Alternatives + +## References + +- [locust](https://locust.io/) \ No newline at end of file From 5866d72253cf8b2155a0e61c7e12f187d6061e39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:56:50 +0530 Subject: [PATCH 05/10] chore(deps): Bump nanoid from 3.3.7 to 3.3.8 in /chaoscenter/web (#4992) Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8. - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8) --- updated-dependencies: - dependency-name: nanoid dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- chaoscenter/web/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chaoscenter/web/yarn.lock b/chaoscenter/web/yarn.lock index d757c6859af..92c36367070 100644 --- a/chaoscenter/web/yarn.lock +++ b/chaoscenter/web/yarn.lock @@ -6261,9 +6261,9 @@ nanoclone@^0.2.1: integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== natural-compare-lite@^1.4.0: version "1.4.0" From b970fce669b80815a380ab1ee287e43723123705 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:57:32 +0530 Subject: [PATCH 06/10] chore(deps): Bump cross-spawn from 7.0.3 to 7.0.6 in /chaoscenter/web (#4957) Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- chaoscenter/web/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chaoscenter/web/yarn.lock b/chaoscenter/web/yarn.lock index 92c36367070..ad44c0abe52 100644 --- a/chaoscenter/web/yarn.lock +++ b/chaoscenter/web/yarn.lock @@ -3159,9 +3159,9 @@ cronstrue@^2.10.0: integrity sha512-WCCaKuuzjZJl/xTaJiK2KB2lhHqAz+cTAHgSiZQc/pNnF2XUSZX0FBfxAG0qa9CogToNoQw7pEBJExc77QnFBQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" From 4fcec60d82a77edaadee433f3838894641bd3903 Mon Sep 17 00:00:00 2001 From: Namkyu Park <53862866+namkyu1999@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:30:16 +0900 Subject: [PATCH 07/10] chore: update base image because of the CVE-2024-3596 (#4964) Signed-off-by: namkyu1999 --- chaoscenter/authentication/Dockerfile | 2 +- chaoscenter/event-tracker/Dockerfile | 2 +- chaoscenter/graphql/server/Dockerfile | 2 +- chaoscenter/subscriber/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/chaoscenter/authentication/Dockerfile b/chaoscenter/authentication/Dockerfile index fa6db11dab0..c074a9bdf04 100644 --- a/chaoscenter/authentication/Dockerfile +++ b/chaoscenter/authentication/Dockerfile @@ -16,7 +16,7 @@ RUN CGO_ENABLED=0 go build -o /output/server -v ./api/ # Packaging stage # Use RedHat UBI minimal image as base -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.4 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5 LABEL maintainer="LitmusChaos" diff --git a/chaoscenter/event-tracker/Dockerfile b/chaoscenter/event-tracker/Dockerfile index b6cee80d97d..bee216f4929 100644 --- a/chaoscenter/event-tracker/Dockerfile +++ b/chaoscenter/event-tracker/Dockerfile @@ -17,7 +17,7 @@ RUN CGO_ENABLED=0 go build -o /output/event-tracker -v # Packaging stage # Use RedHat UBI minimal image as base -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.4 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5 LABEL maintainer="LitmusChaos" diff --git a/chaoscenter/graphql/server/Dockerfile b/chaoscenter/graphql/server/Dockerfile index 7497d22c7e5..0c356be4a62 100644 --- a/chaoscenter/graphql/server/Dockerfile +++ b/chaoscenter/graphql/server/Dockerfile @@ -17,7 +17,7 @@ RUN CGO_ENABLED=0 go build -o /output/server -v # DEPLOY STAGE # Use Red Hat UBI minimal image as base -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.4 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5 LABEL maintainer="LitmusChaos" diff --git a/chaoscenter/subscriber/Dockerfile b/chaoscenter/subscriber/Dockerfile index 17b71c3527a..20753cfe238 100644 --- a/chaoscenter/subscriber/Dockerfile +++ b/chaoscenter/subscriber/Dockerfile @@ -17,7 +17,7 @@ RUN CGO_ENABLED=0 go build -o /output/subscriber -v # Packaging stage # Use RedHat UBI minimal image as base -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.4 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5 LABEL maintainer="LitmusChaos" From b6d18ce1641dc59436140c8652cd67e47e93a2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Kylberg?= <47784470+bjoky@users.noreply.github.com> Date: Fri, 20 Dec 2024 07:30:40 +0100 Subject: [PATCH 08/10] JVM fault injection proposal (#4977) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Kylberg <47784470+bjoky@users.noreply.github.com> Co-authored-by: Saranya Jena --- proposals/jvm-fault-injection.md | 105 +++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 proposals/jvm-fault-injection.md diff --git a/proposals/jvm-fault-injection.md b/proposals/jvm-fault-injection.md new file mode 100644 index 00000000000..c4ac89e54b6 --- /dev/null +++ b/proposals/jvm-fault-injection.md @@ -0,0 +1,105 @@ +| title | authors | creation-date | last-updated | +|-------|------------------------------------------|---------------|--------------| +| JVM fault injection | [@bjoky](https://github.com/bjoky) | 2024-12-05 | 2024-12-05 | + +# JVM Fault Injection + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) + - [Use Cases](#use-cases) + - [Implementation Details](#implementation-details) +- [Risks and Mitigations](#risks-and-mitigations) +- [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) +- [Drawbacks](#drawbacks) +- [Alternatives](#alternatives) +- [References](#references) + +## Summary + +This is a proposal to add a new type of fault to Litmus that can be used to perform experiments on a Java Virtual Machine (JVM). The proposed two faults, to begin with, are a CPU hog and a memory hog. + +## Motivation + +Java applications run in a virtual machine. They may behave in upredictable ways with high CPU or memory consumption, which may be different from only high CPU or memory usage in the container it is running. For example, high memory consumption of the JVM can trigger the garbage collection mechanisms. + +This makes it interesting to be able to run experiments in Litmus that targets applications running in a JVM. + +### Goals + +The JVM fault injection should support two different faults: CPU hog/consumption and memory hog/consumption. + +Target Java versions will be 17 and above. + +### Non-Goals + +The first version of this JVM fault injection will not support anything other than CPU and memory consumption. + +It will for example not use Byteman (see [Alternatives](#alternatives)) or any other tools that could inject any type change or error in the JVM. This could be expanded on in the future. + +## Proposal + +### Use Cases + +#### Use case 1 - Memory consumption + +The memory consumption fault will make it possible to consume memory in iterations. + +It will be possible to tune the experiment for amount of memory allocated for each iteration, how long to wait between iterations and how long the total duration will be. + +It will also be possible the configure if the experiment should keep the references to the allocated memory for the total duration of the experiment. If references are kept, it will not be possible for the JVM to garbage collection the memory, which means that the memory will fill up gradually, until an OutOfMemoryError exception is thrown or the experiment ends. After the duration of the experiment, all references will be freed up for garabage collection. + +#### Use case 2 CPU consumption + +The CPU consumption fault will make it possible to run CPU intensive operations for a duration of time. + +It will be possible to tune the experiment for the number of threads that will run in parallell and for how long the total duration will be. + +The operation used to consume CPU will be a Fibonacci number calculation. + +### Implementation Details + +The JVM fault injection will use the Java Instrumentation API. Using that it will run a Java agent that can alter the existing byte code loaded into the JVM in runtime. + +In the case of the memory consumption fault, it will start one thread for that. In the case of the cpu consumption fault, it will start a number of threads, depending on how the experiment was tuned. + +The Java agent will be initiated through a Litmus helper, using the litmus-go image. The image will need to include the jar file with the agent, but should be able to use the Java runtime of the target container to initiate the agent. + +If the experiment is stopped or interrupted, there must be a way to stop any ongoing agent threads in the target JVMs. + +The implementation will be done in several phases, rather than everything at once, so that each step can be properly reviewed. This is a rough outline of the phases: + +##### Phase 1 +The first phase will be to add the Java agent code to the litmus-go repository. + +#### Phase 2 +The second phase will be to build the Java code as part of the litmus-go build, and include it in the image. + +#### Phase 3 +The third phase will be to add the new fault to the litmus-go library and the command call to start the agent. This should include being able to lookup runtime IDs such as process, group and user IDs that are necessary to inject the agent. + +#### Phase 4 +The fourth phase will be to make the faults available, add to chaos-charts and what else is needed to be able to select it in the Chaos Studio. + +## Risks and Mitigations + +## Upgrade / Downgrade Strategy + +## Drawbacks + +## Alternatives + +An alternative to this would be to use something like [Byteman](https://byteman.jboss.org/). Byteman is also running as an agent using the Java instrumentation API. The difference is that it allows the user to make any type of change to JVM. This means that it supports other types of use cases than fault injection, such as monitoring and tracing, that may be outside the scope of chaos engineering. + +This means that it brings more complexity and a higher threshold to begin using it. It might be overkill for just the simple use cases outlined above. + +I think Byteman can be intersting in the long run. And I imagine this JVM Fault Injection could be enhanced in the future to use Byteman instead or Byteman could be added as an additional fault. + +## References + +- [Java instrumentation API](https://docs.oracle.com/en/java/javase/21/docs/api/java.instrument/java/lang/instrument/Instrumentation.html) +- [Java instrumentation API introduction](https://medium.com/o11y/what-is-java-instrumentation-why-is-it-needed-1f9aa467433) +- [Byteman](https://byteman.jboss.org/) +- [Byteman source](https://github.com/bytemanproject/byteman) From 420c4b0a5d2ff0c017f212301fcb0e0ab68c5a99 Mon Sep 17 00:00:00 2001 From: Kursat Aktas Date: Fri, 20 Dec 2024 09:35:11 +0300 Subject: [PATCH 09/10] Introducing LitmusChaos Guru on Gurubase.io (#4943) Signed-off-by: Kursat Aktas Co-authored-by: Saranya Jena --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d675b10c14b..d6890591929 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/3202/badge)](https://www.bestpractices.dev/projects/3202) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Flitmuschaos%2Flitmus.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Flitmuschaos%2Flitmus?ref=badge_shield) [![YouTube Channel](https://img.shields.io/badge/YouTube-Subscribe-red)](https://www.youtube.com/channel/UCa57PMqmz_j0wnteRa9nCaw) +[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20LitmusChaos%20Guru-006BFF)](https://gurubase.io/g/litmuschaos)



#### *Read this in [other languages](translations/TRANSLATIONS.md).* From b74707b6387e5d2db61dbfffa2a70b014f113b80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:05:53 +0530 Subject: [PATCH 10/10] chore(deps): Bump golang.org/x/crypto (#4985) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.23.0 to 0.31.0. - [Commits](https://github.com/golang/crypto/compare/v0.23.0...v0.31.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../upgrade-agents/control-plane/go.mod | 16 +-- .../upgrade-agents/control-plane/go.sum | 122 ++++-------------- 2 files changed, 29 insertions(+), 109 deletions(-) diff --git a/chaoscenter/upgrade-agents/control-plane/go.mod b/chaoscenter/upgrade-agents/control-plane/go.mod index cb37ddf9401..a1d20141af2 100644 --- a/chaoscenter/upgrade-agents/control-plane/go.mod +++ b/chaoscenter/upgrade-agents/control-plane/go.mod @@ -11,30 +11,24 @@ require ( require ( github.com/jessevdk/go-flags v1.5.0 // indirect github.com/montanaflynn/stats v0.7.1 // indirect - golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/term v0.20.0 // indirect + golang.org/x/term v0.27.0 // indirect gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( - github.com/go-stack/stack v1.8.0 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-cmp v0.6.0 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/mongodb/mongo-tools v0.0.0-20240711192303-088725fbaf4b github.com/pkg/errors v0.9.1 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect ) diff --git a/chaoscenter/upgrade-agents/control-plane/go.sum b/chaoscenter/upgrade-agents/control-plane/go.sum index 1d8fb9b2637..2cd6dfa5847 100644 --- a/chaoscenter/upgrade-agents/control-plane/go.sum +++ b/chaoscenter/upgrade-agents/control-plane/go.sum @@ -1,128 +1,75 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= -github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mongodb/mongo-tools v0.0.0-20240711192303-088725fbaf4b h1:39IJuPXnaNCjLk6tMywL0OheXyx7S+BTIgn1LUwSrq8= github.com/mongodb/mongo-tools v0.0.0-20240711192303-088725fbaf4b/go.mod h1:ZqxDY87qeUsPRQ/H8DAOhp4iQA2zQtn2zR/KmLSsA7U= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.7.1 h1:jwqTeEM3x6L9xDXrCxN0Hbg7vdGfPBOTIkr0+/LYZDA= -go.mongodb.org/mongo-driver v1.7.1/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= go.mongodb.org/mongo-driver v1.11.9 h1:JY1e2WLxwNuwdBAPgQxjf4BWweUGP86lF55n89cGZVA= go.mongodb.org/mongo-driver v1.11.9/go.mod h1:P8+TlbZtPFgjUrmnIF41z97iDnSMswJJu6cztZSlCTg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 h1:vpzMC/iZhYFAjJzHU0Cfuq+w1vLLsF2vLkDrPjzKYck= -golang.org/x/exp v0.0.0-20240529005216-23cca8864a10/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -130,66 +77,45 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=