From 18d4ad5934254de36b3a558beeba022dd3b7d325 Mon Sep 17 00:00:00 2001 From: Dennis Nguyen Date: Tue, 15 Aug 2023 08:23:46 -0700 Subject: [PATCH 1/4] add support for rollouts --- API.md | 4 +- .../crd/bases/crd.argoproj.io_rollouts.yaml | 3630 +++++++++++++++++ ...rds.wizardofoz.co_execaccesstemplates.yaml | 1 + ...crds.wizardofoz.co_podaccesstemplates.yaml | 137 +- config/rbac/role.yaml | 8 + examples/rollout.yaml | 31 + go.mod | 5 +- go.sum | 10 +- .../cross_version_object_reference.go | 4 +- .../api/v1alpha1/pod_spec_mutation_config.go | 2 - .../create_access_resources_test.go | 147 +- .../builders/podaccessbuilder/suite_test.go | 4 + internal/builders/podaccessbuilder/types.go | 1 + .../utils/get_pod_template_from_controller.go | 17 +- internal/builders/utils/get_rollout.go | 29 + .../builders/utils/get_selector_labels.go | 11 + internal/cmd/manager/main.go | 2 + .../templatecontroller/controller.go | 1 + 18 files changed, 3970 insertions(+), 74 deletions(-) create mode 100644 config/crd/bases/crd.argoproj.io_rollouts.yaml create mode 100644 examples/rollout.yaml create mode 100644 internal/builders/utils/get_rollout.go diff --git a/API.md b/API.md index 90e60f52..be9b8ef4 100644 --- a/API.md +++ b/API.md @@ -1096,9 +1096,7 @@ that should be applied. The primary use case is in the PodAccessTemplate, where controller (Deployment, DaemonSet, StatefulSet) can be used as the reference for the PodSpec that is launched for the user. However, the operator may want to make modifications to the PodSpec at launch time (eg, change the entrypoint command or arguments).

-

TODO: Add podAnnotations -TODO: Add podLabels -TODO: Add affinity

+

TODO: Add affinity

diff --git a/config/crd/bases/crd.argoproj.io_rollouts.yaml b/config/crd/bases/crd.argoproj.io_rollouts.yaml new file mode 100644 index 00000000..21bb5d70 --- /dev/null +++ b/config/crd/bases/crd.argoproj.io_rollouts.yaml @@ -0,0 +1,3630 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.1 + name: rollouts.argoproj.io +spec: + group: argoproj.io + names: + kind: Rollout + listKind: RolloutList + plural: rollouts + shortNames: + - ro + singular: rollout + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Number of desired pods + jsonPath: .spec.replicas + name: Desired + type: integer + - description: Total number of non-terminated pods targeted by this rollout + jsonPath: .status.replicas + name: Current + type: integer + - description: Total number of non-terminated pods targeted by this rollout that + have the desired template spec + jsonPath: .status.updatedReplicas + name: Up-to-date + type: integer + - description: Total number of available pods (ready for at least minReadySeconds) + targeted by this rollout + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + analysis: + properties: + successfulRunHistoryLimit: + format: int32 + type: integer + unsuccessfulRunHistoryLimit: + format: int32 + type: integer + type: object + minReadySeconds: + format: int32 + type: integer + paused: + type: boolean + progressDeadlineAbort: + type: boolean + progressDeadlineSeconds: + format: int32 + type: integer + replicas: + format: int32 + type: integer + restartAt: + format: date-time + type: string + revisionHistoryLimit: + format: int32 + type: integer + rollbackWindow: + properties: + revisions: + format: int32 + type: integer + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + properties: + blueGreen: + properties: + abortScaleDownDelaySeconds: + format: int32 + type: integer + activeMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + activeService: + type: string + antiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + properties: + weight: + format: int32 + type: integer + required: + - weight + type: object + requiredDuringSchedulingIgnoredDuringExecution: + type: object + type: object + autoPromotionEnabled: + type: boolean + autoPromotionSeconds: + format: int32 + type: integer + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + postPromotionAnalysis: + properties: + analysisRunMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + prePromotionAnalysis: + properties: + analysisRunMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + previewMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + previewReplicaCount: + format: int32 + type: integer + previewService: + type: string + scaleDownDelayRevisionLimit: + format: int32 + type: integer + scaleDownDelaySeconds: + format: int32 + type: integer + required: + - activeService + type: object + canary: + properties: + abortScaleDownDelaySeconds: + format: int32 + type: integer + analysis: + properties: + analysisRunMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + startingStep: + format: int32 + type: integer + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + antiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + properties: + weight: + format: int32 + type: integer + required: + - weight + type: object + requiredDuringSchedulingIgnoredDuringExecution: + type: object + type: object + canaryMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + canaryService: + type: string + dynamicStableScale: + type: boolean + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minPodsPerReplicaSet: + format: int32 + type: integer + pingPong: + properties: + pingService: + type: string + pongService: + type: string + required: + - pingService + - pongService + type: object + scaleDownDelayRevisionLimit: + format: int32 + type: integer + scaleDownDelaySeconds: + format: int32 + type: integer + stableMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + stableService: + type: string + steps: + items: + properties: + analysis: + properties: + analysisRunMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + experiment: + properties: + analyses: + items: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + clusterScope: + type: boolean + name: + type: string + requiredForCompletion: + type: boolean + templateName: + type: string + required: + - name + - templateName + type: object + type: array + duration: + type: string + templates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + replicas: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + service: + properties: + name: + type: string + type: object + specRef: + type: string + weight: + format: int32 + type: integer + required: + - name + - specRef + type: object + type: array + required: + - templates + type: object + pause: + properties: + duration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + setCanaryScale: + properties: + matchTrafficWeight: + type: boolean + replicas: + format: int32 + type: integer + weight: + format: int32 + type: integer + type: object + setHeaderRoute: + properties: + match: + items: + properties: + headerName: + type: string + headerValue: + properties: + exact: + type: string + prefix: + type: string + regex: + type: string + type: object + required: + - headerName + - headerValue + type: object + type: array + name: + type: string + type: object + setMirrorRoute: + properties: + match: + items: + properties: + headers: + additionalProperties: + properties: + exact: + type: string + prefix: + type: string + regex: + type: string + type: object + type: object + method: + properties: + exact: + type: string + prefix: + type: string + regex: + type: string + type: object + path: + properties: + exact: + type: string + prefix: + type: string + regex: + type: string + type: object + type: object + type: array + name: + type: string + percentage: + format: int32 + type: integer + required: + - name + type: object + setWeight: + format: int32 + type: integer + type: object + type: array + trafficRouting: + properties: + alb: + properties: + annotationPrefix: + type: string + ingress: + type: string + ingresses: + items: + type: string + type: array + rootService: + type: string + servicePort: + format: int32 + type: integer + stickinessConfig: + properties: + durationSeconds: + format: int64 + type: integer + enabled: + type: boolean + required: + - durationSeconds + - enabled + type: object + required: + - servicePort + type: object + ambassador: + properties: + mappings: + items: + type: string + type: array + required: + - mappings + type: object + apisix: + properties: + route: + properties: + name: + type: string + rules: + items: + type: string + type: array + required: + - name + type: object + type: object + appMesh: + properties: + virtualNodeGroup: + properties: + canaryVirtualNodeRef: + properties: + name: + type: string + required: + - name + type: object + stableVirtualNodeRef: + properties: + name: + type: string + required: + - name + type: object + required: + - canaryVirtualNodeRef + - stableVirtualNodeRef + type: object + virtualService: + properties: + name: + type: string + routes: + items: + type: string + type: array + required: + - name + type: object + type: object + istio: + properties: + destinationRule: + properties: + canarySubsetName: + type: string + name: + type: string + stableSubsetName: + type: string + required: + - canarySubsetName + - name + - stableSubsetName + type: object + virtualService: + properties: + name: + type: string + routes: + items: + type: string + type: array + tcpRoutes: + items: + properties: + port: + format: int64 + type: integer + type: object + type: array + tlsRoutes: + items: + properties: + port: + format: int64 + type: integer + sniHosts: + items: + type: string + type: array + type: object + type: array + required: + - name + type: object + virtualServices: + items: + properties: + name: + type: string + routes: + items: + type: string + type: array + tcpRoutes: + items: + properties: + port: + format: int64 + type: integer + type: object + type: array + tlsRoutes: + items: + properties: + port: + format: int64 + type: integer + sniHosts: + items: + type: string + type: array + type: object + type: array + required: + - name + type: object + type: array + type: object + managedRoutes: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + nginx: + properties: + additionalIngressAnnotations: + additionalProperties: + type: string + type: object + annotationPrefix: + type: string + stableIngress: + type: string + stableIngresses: + items: + type: string + type: array + type: object + plugins: + type: object + x-kubernetes-preserve-unknown-fields: true + smi: + properties: + rootService: + type: string + trafficSplitName: + type: string + type: object + traefik: + properties: + weightedTraefikServiceName: + type: string + required: + - weightedTraefikServiceName + type: object + type: object + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + required: + - containers + type: object + type: object + workloadRef: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + type: object + type: object + status: + properties: + HPAReplicas: + format: int32 + type: integer + abort: + type: boolean + abortedAt: + format: date-time + type: string + alb: + properties: + canaryTargetGroup: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + ingress: + type: string + loadBalancer: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + stableTargetGroup: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + type: object + albs: + items: + properties: + canaryTargetGroup: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + ingress: + type: string + loadBalancer: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + stableTargetGroup: + properties: + arn: + type: string + fullName: + type: string + name: + type: string + required: + - arn + - name + type: object + type: object + type: array + availableReplicas: + format: int32 + type: integer + blueGreen: + properties: + activeSelector: + type: string + postPromotionAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + prePromotionAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + previewSelector: + type: string + scaleUpPreviewCheckPoint: + type: boolean + type: object + canary: + properties: + currentBackgroundAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + currentExperiment: + type: string + currentStepAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + stablePingPong: + type: string + weights: + properties: + additional: + items: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + type: array + canary: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + stable: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + verified: + type: boolean + required: + - canary + - stable + type: object + type: object + collisionCount: + format: int32 + type: integer + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + lastUpdateTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - lastTransitionTime + - lastUpdateTime + - message + - reason + - status + - type + type: object + type: array + controllerPause: + type: boolean + currentPodHash: + type: string + currentStepHash: + type: string + currentStepIndex: + format: int32 + type: integer + message: + type: string + observedGeneration: + type: string + pauseConditions: + items: + properties: + reason: + type: string + startTime: + format: date-time + type: string + required: + - reason + - startTime + type: object + type: array + phase: + type: string + promoteFull: + type: boolean + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + restartedAt: + format: date-time + type: string + selector: + type: string + stableRS: + type: string + updatedReplicas: + format: int32 + type: integer + workloadObservedGeneration: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.HPAReplicas + status: {} \ No newline at end of file diff --git a/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml b/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml index 95b3b02c..31d847a6 100644 --- a/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml +++ b/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml @@ -93,6 +93,7 @@ spec: - Deployment - DaemonSet - StatefulSet + - Rollout type: string name: description: Defines the "metadata.Name" of the target resource. diff --git a/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml b/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml index 64d2c44a..180746ec 100644 --- a/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml +++ b/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml @@ -350,6 +350,7 @@ spec: - Deployment - DaemonSet - StatefulSet + - Rollout type: string name: description: Defines the "metadata.Name" of the target resource. @@ -2118,6 +2119,27 @@ spec: value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -2242,7 +2264,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -2275,15 +2298,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -3468,6 +3487,12 @@ spec: value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: Restart policy for the container to manage + the restart behavior of each container within a pod. This + may only be set for init containers. You cannot set this + field on ephemeral containers. + type: string securityContext: description: 'Optional: SecurityContext defines the security options the ephemeral container should be run with. If @@ -3592,7 +3617,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -3625,15 +3651,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -4851,6 +4873,27 @@ spec: value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -4975,7 +5018,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -5008,15 +5052,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -5431,18 +5471,13 @@ spec: as this pod. \n The template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also - be deleted. The name of the ResourceClaim will be - -, where - is the PodResourceClaim.Name. Pod validation will - reject the pod if the concatenated name is not valid - for a ResourceClaim (e.g. too long). \n An existing - ResourceClaim with that name that is not owned by - the pod will not be used for the pod to avoid using - an unrelated resource by mistake. Scheduling and pod - startup are then blocked until the unrelated ResourceClaim - is removed. \n This field is immutable and no changes - will be made to the corresponding ResourceClaim by - the control plane after creating the ResourceClaim." + be deleted. The pod name and resource name, along + with a generated component, will be used to form a + unique name for the ResourceClaim, which will be recorded + in pod.status.resourceClaimStatuses. \n This field + is immutable and no changes will be made to the corresponding + ResourceClaim by the control plane after creating + the ResourceClaim." type: string type: object required: @@ -5585,7 +5620,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -5650,15 +5686,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index f68c656c..7dafe13f 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -34,6 +34,14 @@ rules: - get - list - watch +- apiGroups: + - argoproj.io + resources: + - rollouts + verbs: + - get + - list + - watch - apiGroups: - crds.wizardofoz.co resources: diff --git a/examples/rollout.yaml b/examples/rollout.yaml new file mode 100644 index 00000000..2931cc87 --- /dev/null +++ b/examples/rollout.yaml @@ -0,0 +1,31 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: rollouts-demo +spec: + replicas: 5 + strategy: + canary: + steps: + - setWeight: 20 + - pause: {duration: 1} + revisionHistoryLimit: 2 + selector: + matchLabels: + app: rollouts-demo + template: + metadata: + labels: + app: rollouts-demo + spec: + containers: + - name: rollouts-demo + image: nginx:latest + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + requests: + memory: 32Mi + cpu: 5m diff --git a/go.mod b/go.mod index 80258590..e582663e 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/diranged/oz go 1.20 require ( + github.com/argoproj/argo-rollouts v1.5.1 github.com/fatih/color v1.15.0 github.com/go-logr/logr v1.2.4 github.com/ivanpirog/coloredcobra v1.0.1 @@ -34,14 +35,14 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/btree v1.0.1 // indirect + github.com/google/btree v1.1.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect diff --git a/go.sum b/go.sum index 830ff211..8d4b87d5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/argoproj/argo-rollouts v1.5.1 h1:P1C6oIWn6fwtPvB3u04NQlUGIv8cq/aJvUkbwciuWYo= +github.com/argoproj/argo-rollouts v1.5.1/go.mod h1:OaOf+oZawsss6fy+9WEDy4IaSbwuRteBj1X2QiVfqdA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -64,8 +66,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -86,8 +88,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= diff --git a/internal/api/v1alpha1/cross_version_object_reference.go b/internal/api/v1alpha1/cross_version_object_reference.go index 69991984..89800f96 100644 --- a/internal/api/v1alpha1/cross_version_object_reference.go +++ b/internal/api/v1alpha1/cross_version_object_reference.go @@ -22,7 +22,7 @@ type CrossVersionObjectReference struct { // Defines the "Kind" of resource being referred to. // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum=Deployment;DaemonSet;StatefulSet + // +kubebuilder:validation:Enum=Deployment;DaemonSet;StatefulSet;Rollout Kind ControllerKind `json:"kind"` // Defines the "metadata.Name" of the target resource. @@ -68,7 +68,7 @@ func (r *CrossVersionObjectReference) GetGroupVersionKind() schema.GroupVersionK } } -// GetObject returns a generic unstrucutred resource that points to the desired API object. Because +// GetObject returns a generic unstructured resource that points to the desired API object. Because // this is unstructured (for now), you can really only use this to get metadata back from the API // about the resource. // diff --git a/internal/api/v1alpha1/pod_spec_mutation_config.go b/internal/api/v1alpha1/pod_spec_mutation_config.go index 6a2f503a..f9fd8599 100644 --- a/internal/api/v1alpha1/pod_spec_mutation_config.go +++ b/internal/api/v1alpha1/pod_spec_mutation_config.go @@ -24,8 +24,6 @@ const ( // that is launched for the user. However, the operator may want to make modifications to the // PodSpec at launch time (eg, change the entrypoint command or arguments). // -// TODO: Add podAnnotations -// TODO: Add podLabels // TODO: Add affinity type PodTemplateSpecMutationConfig struct { // DefaultContainerName allows the operator to define which container is considered the default diff --git a/internal/builders/podaccessbuilder/create_access_resources_test.go b/internal/builders/podaccessbuilder/create_access_resources_test.go index 6f53bcdc..d2e331be 100644 --- a/internal/builders/podaccessbuilder/create_access_resources_test.go +++ b/internal/builders/podaccessbuilder/create_access_resources_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -22,12 +23,15 @@ import ( var _ = Describe("RequestReconciler", Ordered, func() { Context("CreateAccessResources()", func() { var ( - ctx = context.Background() - ns *corev1.Namespace - deployment *appsv1.Deployment - request *v1alpha1.PodAccessRequest - template *v1alpha1.PodAccessTemplate - builder = PodAccessBuilder{} + ctx = context.Background() + ns *corev1.Namespace + deployment *appsv1.Deployment + request *v1alpha1.PodAccessRequest + rolloutRequest *v1alpha1.PodAccessRequest + template *v1alpha1.PodAccessTemplate + rolloutTemplate *v1alpha1.PodAccessTemplate + builder = PodAccessBuilder{} + rollout *rolloutsv1alpha1.Rollout ) BeforeAll(func() { @@ -72,6 +76,38 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, deployment) Expect(err).To(Not(HaveOccurred())) + By("Creating a Rollout to reference for the test") + rollout = &rolloutsv1alpha1.Rollout{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rollout-test", + Namespace: ns.Name, + }, + Spec: rolloutsv1alpha1.RolloutSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testLabel": "testValue", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "testLabel": "testValue", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test", + Image: "nginx:latest", + }, + }, + }, + }, + }, + } + err = k8sClient.Create(ctx, rollout) + Expect(err).To(Not(HaveOccurred())) + By("Should have an PodAccessTemplate to test against") cpuReq, _ := resource.ParseQuantity("1") template = &v1alpha1.PodAccessTemplate{ @@ -108,6 +144,41 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, template) Expect(err).ToNot(HaveOccurred()) + By("Should have an rollout PodAccessTemplate to test against") + rolloutTemplate = &v1alpha1.PodAccessTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: utils.RandomString(8), + Namespace: ns.GetName(), + }, + Spec: v1alpha1.PodAccessTemplateSpec{ + AccessConfig: v1alpha1.AccessConfig{ + AllowedGroups: []string{"testGroupA"}, + DefaultDuration: "1h", + MaxDuration: "2h", + }, + ControllerTargetRef: &v1alpha1.CrossVersionObjectReference{ + APIVersion: "argoproj.io/v1alpha1", + Kind: "Rollout", + Name: rollout.Name, + }, + ControllerTargetMutationConfig: &v1alpha1.PodTemplateSpecMutationConfig{ + DefaultContainerName: "test", + Command: &[]string{"/bin/sleep"}, + Args: &[]string{"100"}, + Env: []corev1.EnvVar{ + {Name: "FOO", Value: "BAR"}, + }, + Resources: corev1.ResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + "cpu": cpuReq, + }, + }, + }, + }, + } + err = k8sClient.Create(ctx, rolloutTemplate) + Expect(err).ToNot(HaveOccurred()) + By("Should have an PodAccessRequest built to test against") request = &v1alpha1.PodAccessRequest{ ObjectMeta: metav1.ObjectMeta{ @@ -120,6 +191,19 @@ var _ = Describe("RequestReconciler", Ordered, func() { } err = k8sClient.Create(ctx, request) Expect(err).ToNot(HaveOccurred()) + + // verify podaccess request with Rollout + rolloutRequest = &v1alpha1.PodAccessRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: "createaccessresource-rollout-test", + Namespace: ns.GetName(), + }, + Spec: v1alpha1.PodAccessRequestSpec{ + TemplateName: rolloutTemplate.GetName(), + }, + } + err = k8sClient.Create(ctx, rolloutRequest) + Expect(err).ToNot(HaveOccurred()) }) AfterAll(func() { @@ -178,5 +262,56 @@ var _ = Describe("RequestReconciler", Ordered, func() { Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) }) + + It("CreateAccessResources() should succeed with Rollout", func() { + rolloutRequest.Status.PodName = "" + + // Execute + ret, err := builder.CreateAccessResources(ctx, k8sClient, rolloutRequest, rolloutTemplate) + + // VERIFY: No error returned + Expect(err).ToNot(HaveOccurred()) + + // VERIFY: Proper status string returned + Expect(ret).To(MatchRegexp(fmt.Sprintf( + "Success. Pod %s-.*, Role %s-.*, RoleBinding %s.* created", + rolloutRequest.GetName(), + rolloutRequest.GetName(), + rolloutRequest.GetName(), + ))) + + // VERIFY: Pod Created as expected + foundPod := &corev1.Pod{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundPod) + Expect(err).ToNot(HaveOccurred()) + Expect(foundPod.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundPod.Spec.Containers[0].Command[0]).To(Equal("/bin/sleep")) + Expect(foundPod.Spec.Containers[0].Args[0]).To(Equal("100")) + + // VERIFY: Role Created as expected + foundRole := &rbacv1.Role{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundRole) + Expect(err).ToNot(HaveOccurred()) + Expect(foundRole.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundRole.Rules[0].ResourceNames[0]).To(Equal(foundPod.GetName())) + Expect(foundRole.Rules[1].ResourceNames[0]).To(Equal(foundPod.GetName())) + + // VERIFY: RoleBinding Created as expected + foundRoleBinding := &rbacv1.RoleBinding{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundRoleBinding) + Expect(err).ToNot(HaveOccurred()) + Expect(foundRoleBinding.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) + Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) + }) }) }) diff --git a/internal/builders/podaccessbuilder/suite_test.go b/internal/builders/podaccessbuilder/suite_test.go index be23a77d..38feee27 100644 --- a/internal/builders/podaccessbuilder/suite_test.go +++ b/internal/builders/podaccessbuilder/suite_test.go @@ -20,6 +20,7 @@ import ( "path/filepath" "testing" + rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/zap/zapcore" @@ -73,6 +74,9 @@ var _ = BeforeSuite(func() { err = crdsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = rolloutsv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + //+kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) diff --git a/internal/builders/podaccessbuilder/types.go b/internal/builders/podaccessbuilder/types.go index bd8e3931..85b44388 100644 --- a/internal/builders/podaccessbuilder/types.go +++ b/internal/builders/podaccessbuilder/types.go @@ -14,6 +14,7 @@ import ( //+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles,verbs=get;list;watch;create;update;patch;delete;bind;escalate //+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=argoproj.io,resources=rollouts,verbs=get;list;watch // defaultReadyWaitTime is the default time in which we wait for resources to // become Ready in the AccessResourcesAreReady() method. diff --git a/internal/builders/utils/get_pod_template_from_controller.go b/internal/builders/utils/get_pod_template_from_controller.go index 9ea05999..db288033 100644 --- a/internal/builders/utils/get_pod_template_from_controller.go +++ b/internal/builders/utils/get_pod_template_from_controller.go @@ -2,7 +2,7 @@ package utils import ( "context" - "errors" + "fmt" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -12,7 +12,9 @@ import ( ) // GetPodTemplateFromController will return a PodTemplate resource from an -// understood controller type (Deployment, DaemonSet or StatefulSet). +// understood controller type (Deployment, DaemonSet, Rollout, or StatefulSet). +// +// revive:disable:cyclomatic func GetPodTemplateFromController( ctx context.Context, client client.Client, @@ -36,6 +38,15 @@ func GetPodTemplateFromController( } return *controller.Spec.Template.DeepCopy(), nil + case "Rollout": + controller, err := getRollout(ctx, client, targetController) + if err != nil { + log.Error(err, "Failed to find target Rollout") + return corev1.PodTemplateSpec{}, err + } + + return *controller.Spec.Template.DeepCopy(), nil + case "DaemonSet": controller, err := getDaemonSet(ctx, client, targetController) if err != nil { @@ -53,6 +64,6 @@ func GetPodTemplateFromController( return *controller.Spec.Template.DeepCopy(), nil default: - return corev1.PodTemplateSpec{}, errors.New("invalid input") + return corev1.PodTemplateSpec{}, fmt.Errorf("invalid input %s", kind) } } diff --git a/internal/builders/utils/get_rollout.go b/internal/builders/utils/get_rollout.go new file mode 100644 index 00000000..09807448 --- /dev/null +++ b/internal/builders/utils/get_rollout.go @@ -0,0 +1,29 @@ +package utils + +import ( + "context" + + rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// getRollout returns a Rollout given the supplied generic client.Object resource +// +// Returns: +// +// v1alpha1.Rollout: A populated Rollout object +// error: Any error that may have occurred +func getRollout( + ctx context.Context, + client client.Client, + obj client.Object, +) (*rolloutsv1alpha1.Rollout, error) { + found := &rolloutsv1alpha1.Rollout{} + err := client.Get(ctx, types.NamespacedName{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + }, found) + + return found, err +} diff --git a/internal/builders/utils/get_selector_labels.go b/internal/builders/utils/get_selector_labels.go index 03600183..226ebdd9 100644 --- a/internal/builders/utils/get_selector_labels.go +++ b/internal/builders/utils/get_selector_labels.go @@ -18,6 +18,7 @@ import ( // - Deployment // - DaemonSet // - StatefulSet +// - Rollout // // https://medium.com/coding-kubernetes/using-k8s-label-selectors-in-go-the-right-way-733cde7e8630 // @@ -25,6 +26,8 @@ import ( // // - labels.Selector: A populated labels.Selector which can be used when searching for Pods // - error +// +// revive:disable:cyclomatic func GetSelectorLabels( ctx context.Context, client client.Client, @@ -48,6 +51,14 @@ func GetSelectorLabels( } return metav1.LabelSelectorAsSelector(controller.Spec.Selector) + case "Rollout": + controller, err := getRollout(ctx, client, targetController) + if err != nil { + log.Error(err, "Failed to find target Rollout") + return nil, err + } + return metav1.LabelSelectorAsSelector(controller.Spec.Selector) + case "DaemonSet": controller, err := getDaemonSet(ctx, client, targetController) if err != nil { diff --git a/internal/cmd/manager/main.go b/internal/cmd/manager/main.go index b93c63da..7f5230c7 100644 --- a/internal/cmd/manager/main.go +++ b/internal/cmd/manager/main.go @@ -23,6 +23,7 @@ import ( "os" "time" + rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -56,6 +57,7 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(rolloutsv1alpha1.AddToScheme(scheme)) utilruntime.Must(crdsv1alpha1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme diff --git a/internal/controllers/templatecontroller/controller.go b/internal/controllers/templatecontroller/controller.go index 115dc0f5..f0658abf 100644 --- a/internal/controllers/templatecontroller/controller.go +++ b/internal/controllers/templatecontroller/controller.go @@ -24,6 +24,7 @@ import ( //+kubebuilder:rbac:groups=crds.wizardofoz.co,resources=podaccesstemplates/finalizers,verbs=update //+kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;statefulsets,verbs=get;list;watch +//+kubebuilder:rbac:groups=argoproj.io,resources=rollouts,verbs=get;list;watch // Reconcile is a high level entrypoint triggered by Watches on particular // Custom Resources within the cluster. This wrapper handles a few common From 11e9b55c2a2434ede6f601e1683cc32da5ea7686 Mon Sep 17 00:00:00 2001 From: Dennis Nguyen Date: Wed, 16 Aug 2023 21:53:55 -0700 Subject: [PATCH 2/4] update --- .../crd/bases/crd.argoproj.io_rollouts.yaml | 3630 ----------------- ...rds.wizardofoz.co_execaccesstemplates.yaml | 3 + ...crds.wizardofoz.co_podaccesstemplates.yaml | 3 + .../cross_version_object_reference.go | 1 + .../create_access_resources_test.go | 147 +- 5 files changed, 13 insertions(+), 3771 deletions(-) delete mode 100644 config/crd/bases/crd.argoproj.io_rollouts.yaml diff --git a/config/crd/bases/crd.argoproj.io_rollouts.yaml b/config/crd/bases/crd.argoproj.io_rollouts.yaml deleted file mode 100644 index 21bb5d70..00000000 --- a/config/crd/bases/crd.argoproj.io_rollouts.yaml +++ /dev/null @@ -1,3630 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.12.1 - name: rollouts.argoproj.io -spec: - group: argoproj.io - names: - kind: Rollout - listKind: RolloutList - plural: rollouts - shortNames: - - ro - singular: rollout - preserveUnknownFields: false - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Number of desired pods - jsonPath: .spec.replicas - name: Desired - type: integer - - description: Total number of non-terminated pods targeted by this rollout - jsonPath: .status.replicas - name: Current - type: integer - - description: Total number of non-terminated pods targeted by this rollout that - have the desired template spec - jsonPath: .status.updatedReplicas - name: Up-to-date - type: integer - - description: Total number of available pods (ready for at least minReadySeconds) - targeted by this rollout - jsonPath: .status.availableReplicas - name: Available - type: integer - - description: Time since resource was created - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - analysis: - properties: - successfulRunHistoryLimit: - format: int32 - type: integer - unsuccessfulRunHistoryLimit: - format: int32 - type: integer - type: object - minReadySeconds: - format: int32 - type: integer - paused: - type: boolean - progressDeadlineAbort: - type: boolean - progressDeadlineSeconds: - format: int32 - type: integer - replicas: - format: int32 - type: integer - restartAt: - format: date-time - type: string - revisionHistoryLimit: - format: int32 - type: integer - rollbackWindow: - properties: - revisions: - format: int32 - type: integer - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - strategy: - properties: - blueGreen: - properties: - abortScaleDownDelaySeconds: - format: int32 - type: integer - activeMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - activeService: - type: string - antiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - properties: - weight: - format: int32 - type: integer - required: - - weight - type: object - requiredDuringSchedulingIgnoredDuringExecution: - type: object - type: object - autoPromotionEnabled: - type: boolean - autoPromotionSeconds: - format: int32 - type: integer - maxUnavailable: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - postPromotionAnalysis: - properties: - analysisRunMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - args: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - fieldRef: - properties: - fieldPath: - type: string - required: - - fieldPath - type: object - podTemplateHashValue: - type: string - type: object - required: - - name - type: object - type: array - dryRun: - items: - properties: - metricName: - type: string - required: - - metricName - type: object - type: array - measurementRetention: - items: - properties: - limit: - format: int32 - type: integer - metricName: - type: string - required: - - limit - - metricName - type: object - type: array - templates: - items: - properties: - clusterScope: - type: boolean - templateName: - type: string - type: object - type: array - type: object - prePromotionAnalysis: - properties: - analysisRunMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - args: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - fieldRef: - properties: - fieldPath: - type: string - required: - - fieldPath - type: object - podTemplateHashValue: - type: string - type: object - required: - - name - type: object - type: array - dryRun: - items: - properties: - metricName: - type: string - required: - - metricName - type: object - type: array - measurementRetention: - items: - properties: - limit: - format: int32 - type: integer - metricName: - type: string - required: - - limit - - metricName - type: object - type: array - templates: - items: - properties: - clusterScope: - type: boolean - templateName: - type: string - type: object - type: array - type: object - previewMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - previewReplicaCount: - format: int32 - type: integer - previewService: - type: string - scaleDownDelayRevisionLimit: - format: int32 - type: integer - scaleDownDelaySeconds: - format: int32 - type: integer - required: - - activeService - type: object - canary: - properties: - abortScaleDownDelaySeconds: - format: int32 - type: integer - analysis: - properties: - analysisRunMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - args: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - fieldRef: - properties: - fieldPath: - type: string - required: - - fieldPath - type: object - podTemplateHashValue: - type: string - type: object - required: - - name - type: object - type: array - dryRun: - items: - properties: - metricName: - type: string - required: - - metricName - type: object - type: array - measurementRetention: - items: - properties: - limit: - format: int32 - type: integer - metricName: - type: string - required: - - limit - - metricName - type: object - type: array - startingStep: - format: int32 - type: integer - templates: - items: - properties: - clusterScope: - type: boolean - templateName: - type: string - type: object - type: array - type: object - antiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - properties: - weight: - format: int32 - type: integer - required: - - weight - type: object - requiredDuringSchedulingIgnoredDuringExecution: - type: object - type: object - canaryMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - canaryService: - type: string - dynamicStableScale: - type: boolean - maxSurge: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - minPodsPerReplicaSet: - format: int32 - type: integer - pingPong: - properties: - pingService: - type: string - pongService: - type: string - required: - - pingService - - pongService - type: object - scaleDownDelayRevisionLimit: - format: int32 - type: integer - scaleDownDelaySeconds: - format: int32 - type: integer - stableMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - stableService: - type: string - steps: - items: - properties: - analysis: - properties: - analysisRunMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - args: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - fieldRef: - properties: - fieldPath: - type: string - required: - - fieldPath - type: object - podTemplateHashValue: - type: string - type: object - required: - - name - type: object - type: array - dryRun: - items: - properties: - metricName: - type: string - required: - - metricName - type: object - type: array - measurementRetention: - items: - properties: - limit: - format: int32 - type: integer - metricName: - type: string - required: - - limit - - metricName - type: object - type: array - templates: - items: - properties: - clusterScope: - type: boolean - templateName: - type: string - type: object - type: array - type: object - experiment: - properties: - analyses: - items: - properties: - args: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - fieldRef: - properties: - fieldPath: - type: string - required: - - fieldPath - type: object - podTemplateHashValue: - type: string - type: object - required: - - name - type: object - type: array - clusterScope: - type: boolean - name: - type: string - requiredForCompletion: - type: boolean - templateName: - type: string - required: - - name - - templateName - type: object - type: array - duration: - type: string - templates: - items: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - name: - type: string - replicas: - format: int32 - type: integer - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - service: - properties: - name: - type: string - type: object - specRef: - type: string - weight: - format: int32 - type: integer - required: - - name - - specRef - type: object - type: array - required: - - templates - type: object - pause: - properties: - duration: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - type: object - setCanaryScale: - properties: - matchTrafficWeight: - type: boolean - replicas: - format: int32 - type: integer - weight: - format: int32 - type: integer - type: object - setHeaderRoute: - properties: - match: - items: - properties: - headerName: - type: string - headerValue: - properties: - exact: - type: string - prefix: - type: string - regex: - type: string - type: object - required: - - headerName - - headerValue - type: object - type: array - name: - type: string - type: object - setMirrorRoute: - properties: - match: - items: - properties: - headers: - additionalProperties: - properties: - exact: - type: string - prefix: - type: string - regex: - type: string - type: object - type: object - method: - properties: - exact: - type: string - prefix: - type: string - regex: - type: string - type: object - path: - properties: - exact: - type: string - prefix: - type: string - regex: - type: string - type: object - type: object - type: array - name: - type: string - percentage: - format: int32 - type: integer - required: - - name - type: object - setWeight: - format: int32 - type: integer - type: object - type: array - trafficRouting: - properties: - alb: - properties: - annotationPrefix: - type: string - ingress: - type: string - ingresses: - items: - type: string - type: array - rootService: - type: string - servicePort: - format: int32 - type: integer - stickinessConfig: - properties: - durationSeconds: - format: int64 - type: integer - enabled: - type: boolean - required: - - durationSeconds - - enabled - type: object - required: - - servicePort - type: object - ambassador: - properties: - mappings: - items: - type: string - type: array - required: - - mappings - type: object - apisix: - properties: - route: - properties: - name: - type: string - rules: - items: - type: string - type: array - required: - - name - type: object - type: object - appMesh: - properties: - virtualNodeGroup: - properties: - canaryVirtualNodeRef: - properties: - name: - type: string - required: - - name - type: object - stableVirtualNodeRef: - properties: - name: - type: string - required: - - name - type: object - required: - - canaryVirtualNodeRef - - stableVirtualNodeRef - type: object - virtualService: - properties: - name: - type: string - routes: - items: - type: string - type: array - required: - - name - type: object - type: object - istio: - properties: - destinationRule: - properties: - canarySubsetName: - type: string - name: - type: string - stableSubsetName: - type: string - required: - - canarySubsetName - - name - - stableSubsetName - type: object - virtualService: - properties: - name: - type: string - routes: - items: - type: string - type: array - tcpRoutes: - items: - properties: - port: - format: int64 - type: integer - type: object - type: array - tlsRoutes: - items: - properties: - port: - format: int64 - type: integer - sniHosts: - items: - type: string - type: array - type: object - type: array - required: - - name - type: object - virtualServices: - items: - properties: - name: - type: string - routes: - items: - type: string - type: array - tcpRoutes: - items: - properties: - port: - format: int64 - type: integer - type: object - type: array - tlsRoutes: - items: - properties: - port: - format: int64 - type: integer - sniHosts: - items: - type: string - type: array - type: object - type: array - required: - - name - type: object - type: array - type: object - managedRoutes: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - nginx: - properties: - additionalIngressAnnotations: - additionalProperties: - type: string - type: object - annotationPrefix: - type: string - stableIngress: - type: string - stableIngresses: - items: - type: string - type: array - type: object - plugins: - type: object - x-kubernetes-preserve-unknown-fields: true - smi: - properties: - rootService: - type: string - trafficSplitName: - type: string - type: object - traefik: - properties: - weightedTraefikServiceName: - type: string - required: - - weightedTraefikServiceName - type: object - type: object - type: object - type: object - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - type: boolean - containers: - items: - properties: - args: - items: - type: string - type: array - command: - items: - type: string - type: array - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - limits: - x-kubernetes-preserve-unknown-fields: true - requests: - x-kubernetes-preserve-unknown-fields: true - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - type: string - required: - - name - type: object - type: array - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - enableServiceLinks: - type: boolean - ephemeralContainers: - items: - properties: - args: - items: - type: string - type: array - command: - items: - type: string - type: array - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - limits: - x-kubernetes-preserve-unknown-fields: true - requests: - x-kubernetes-preserve-unknown-fields: true - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - targetContainerName: - type: string - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - type: string - required: - - name - type: object - type: array - hostAliases: - items: - properties: - hostnames: - items: - type: string - type: array - ip: - type: string - type: object - type: array - hostIPC: - type: boolean - hostNetwork: - type: boolean - hostPID: - type: boolean - hostUsers: - type: boolean - hostname: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - type: array - initContainers: - items: - properties: - args: - items: - type: string - type: array - command: - items: - type: string - type: array - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - limits: - x-kubernetes-preserve-unknown-fields: true - requests: - x-kubernetes-preserve-unknown-fields: true - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - type: string - required: - - name - type: object - type: array - nodeName: - type: string - nodeSelector: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic - os: - properties: - name: - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - preemptionPolicy: - type: string - priority: - format: int32 - type: integer - priorityClassName: - type: string - readinessGates: - items: - properties: - conditionType: - type: string - required: - - conditionType - type: object - type: array - restartPolicy: - type: string - runtimeClassName: - type: string - schedulerName: - type: string - securityContext: - properties: - fsGroup: - format: int64 - type: integer - fsGroupChangePolicy: - type: string - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - supplementalGroups: - items: - format: int64 - type: integer - type: array - sysctls: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - serviceAccount: - type: string - serviceAccountName: - type: string - setHostnameAsFQDN: - type: boolean - shareProcessNamespace: - type: boolean - subdomain: - type: string - terminationGracePeriodSeconds: - format: int64 - type: integer - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - items: - x-kubernetes-preserve-unknown-fields: true - type: array - required: - - containers - type: object - type: object - workloadRef: - properties: - apiVersion: - type: string - kind: - type: string - name: - type: string - type: object - type: object - status: - properties: - HPAReplicas: - format: int32 - type: integer - abort: - type: boolean - abortedAt: - format: date-time - type: string - alb: - properties: - canaryTargetGroup: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - ingress: - type: string - loadBalancer: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - stableTargetGroup: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - type: object - albs: - items: - properties: - canaryTargetGroup: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - ingress: - type: string - loadBalancer: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - stableTargetGroup: - properties: - arn: - type: string - fullName: - type: string - name: - type: string - required: - - arn - - name - type: object - type: object - type: array - availableReplicas: - format: int32 - type: integer - blueGreen: - properties: - activeSelector: - type: string - postPromotionAnalysisRunStatus: - properties: - message: - type: string - name: - type: string - status: - type: string - required: - - name - - status - type: object - prePromotionAnalysisRunStatus: - properties: - message: - type: string - name: - type: string - status: - type: string - required: - - name - - status - type: object - previewSelector: - type: string - scaleUpPreviewCheckPoint: - type: boolean - type: object - canary: - properties: - currentBackgroundAnalysisRunStatus: - properties: - message: - type: string - name: - type: string - status: - type: string - required: - - name - - status - type: object - currentExperiment: - type: string - currentStepAnalysisRunStatus: - properties: - message: - type: string - name: - type: string - status: - type: string - required: - - name - - status - type: object - stablePingPong: - type: string - weights: - properties: - additional: - items: - properties: - podTemplateHash: - type: string - serviceName: - type: string - weight: - format: int32 - type: integer - required: - - weight - type: object - type: array - canary: - properties: - podTemplateHash: - type: string - serviceName: - type: string - weight: - format: int32 - type: integer - required: - - weight - type: object - stable: - properties: - podTemplateHash: - type: string - serviceName: - type: string - weight: - format: int32 - type: integer - required: - - weight - type: object - verified: - type: boolean - required: - - canary - - stable - type: object - type: object - collisionCount: - format: int32 - type: integer - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - lastUpdateTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - lastTransitionTime - - lastUpdateTime - - message - - reason - - status - - type - type: object - type: array - controllerPause: - type: boolean - currentPodHash: - type: string - currentStepHash: - type: string - currentStepIndex: - format: int32 - type: integer - message: - type: string - observedGeneration: - type: string - pauseConditions: - items: - properties: - reason: - type: string - startTime: - format: date-time - type: string - required: - - reason - - startTime - type: object - type: array - phase: - type: string - promoteFull: - type: boolean - readyReplicas: - format: int32 - type: integer - replicas: - format: int32 - type: integer - restartedAt: - format: date-time - type: string - selector: - type: string - stableRS: - type: string - updatedReplicas: - format: int32 - type: integer - workloadObservedGeneration: - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - scale: - labelSelectorPath: .status.selector - specReplicasPath: .spec.replicas - statusReplicasPath: .status.HPAReplicas - status: {} \ No newline at end of file diff --git a/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml b/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml index 31d847a6..2f0d6bb1 100644 --- a/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml +++ b/config/crd/bases/crds.wizardofoz.co_execaccesstemplates.yaml @@ -86,6 +86,9 @@ spec: description: "Defines the \"APIVersion\" of the resource being referred to. Eg, \"apps/v1\". \n TODO: Figure out how to regex validate that it has a \"/\" in it" + enum: + - apps/v1 + - argoproj.io/v1alpha1 type: string kind: description: Defines the "Kind" of resource being referred to. diff --git a/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml b/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml index 180746ec..5f11bd34 100644 --- a/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml +++ b/config/crd/bases/crds.wizardofoz.co_podaccesstemplates.yaml @@ -343,6 +343,9 @@ spec: description: "Defines the \"APIVersion\" of the resource being referred to. Eg, \"apps/v1\". \n TODO: Figure out how to regex validate that it has a \"/\" in it" + enum: + - apps/v1 + - argoproj.io/v1alpha1 type: string kind: description: Defines the "Kind" of resource being referred to. diff --git a/internal/api/v1alpha1/cross_version_object_reference.go b/internal/api/v1alpha1/cross_version_object_reference.go index 89800f96..21fab7e7 100644 --- a/internal/api/v1alpha1/cross_version_object_reference.go +++ b/internal/api/v1alpha1/cross_version_object_reference.go @@ -18,6 +18,7 @@ type CrossVersionObjectReference struct { // TODO: Figure out how to regex validate that it has a "/" in it // // +kubebuilder:validation:Required + // +kubebuilder:validation:Enum=apps/v1;argoproj.io/v1alpha1 APIVersion string `json:"apiVersion"` // Defines the "Kind" of resource being referred to. diff --git a/internal/builders/podaccessbuilder/create_access_resources_test.go b/internal/builders/podaccessbuilder/create_access_resources_test.go index d2e331be..6f53bcdc 100644 --- a/internal/builders/podaccessbuilder/create_access_resources_test.go +++ b/internal/builders/podaccessbuilder/create_access_resources_test.go @@ -7,7 +7,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -23,15 +22,12 @@ import ( var _ = Describe("RequestReconciler", Ordered, func() { Context("CreateAccessResources()", func() { var ( - ctx = context.Background() - ns *corev1.Namespace - deployment *appsv1.Deployment - request *v1alpha1.PodAccessRequest - rolloutRequest *v1alpha1.PodAccessRequest - template *v1alpha1.PodAccessTemplate - rolloutTemplate *v1alpha1.PodAccessTemplate - builder = PodAccessBuilder{} - rollout *rolloutsv1alpha1.Rollout + ctx = context.Background() + ns *corev1.Namespace + deployment *appsv1.Deployment + request *v1alpha1.PodAccessRequest + template *v1alpha1.PodAccessTemplate + builder = PodAccessBuilder{} ) BeforeAll(func() { @@ -76,38 +72,6 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, deployment) Expect(err).To(Not(HaveOccurred())) - By("Creating a Rollout to reference for the test") - rollout = &rolloutsv1alpha1.Rollout{ - ObjectMeta: metav1.ObjectMeta{ - Name: "rollout-test", - Namespace: ns.Name, - }, - Spec: rolloutsv1alpha1.RolloutSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "testLabel": "testValue", - }, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "testLabel": "testValue", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "test", - Image: "nginx:latest", - }, - }, - }, - }, - }, - } - err = k8sClient.Create(ctx, rollout) - Expect(err).To(Not(HaveOccurred())) - By("Should have an PodAccessTemplate to test against") cpuReq, _ := resource.ParseQuantity("1") template = &v1alpha1.PodAccessTemplate{ @@ -144,41 +108,6 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, template) Expect(err).ToNot(HaveOccurred()) - By("Should have an rollout PodAccessTemplate to test against") - rolloutTemplate = &v1alpha1.PodAccessTemplate{ - ObjectMeta: metav1.ObjectMeta{ - Name: utils.RandomString(8), - Namespace: ns.GetName(), - }, - Spec: v1alpha1.PodAccessTemplateSpec{ - AccessConfig: v1alpha1.AccessConfig{ - AllowedGroups: []string{"testGroupA"}, - DefaultDuration: "1h", - MaxDuration: "2h", - }, - ControllerTargetRef: &v1alpha1.CrossVersionObjectReference{ - APIVersion: "argoproj.io/v1alpha1", - Kind: "Rollout", - Name: rollout.Name, - }, - ControllerTargetMutationConfig: &v1alpha1.PodTemplateSpecMutationConfig{ - DefaultContainerName: "test", - Command: &[]string{"/bin/sleep"}, - Args: &[]string{"100"}, - Env: []corev1.EnvVar{ - {Name: "FOO", Value: "BAR"}, - }, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{ - "cpu": cpuReq, - }, - }, - }, - }, - } - err = k8sClient.Create(ctx, rolloutTemplate) - Expect(err).ToNot(HaveOccurred()) - By("Should have an PodAccessRequest built to test against") request = &v1alpha1.PodAccessRequest{ ObjectMeta: metav1.ObjectMeta{ @@ -191,19 +120,6 @@ var _ = Describe("RequestReconciler", Ordered, func() { } err = k8sClient.Create(ctx, request) Expect(err).ToNot(HaveOccurred()) - - // verify podaccess request with Rollout - rolloutRequest = &v1alpha1.PodAccessRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: "createaccessresource-rollout-test", - Namespace: ns.GetName(), - }, - Spec: v1alpha1.PodAccessRequestSpec{ - TemplateName: rolloutTemplate.GetName(), - }, - } - err = k8sClient.Create(ctx, rolloutRequest) - Expect(err).ToNot(HaveOccurred()) }) AfterAll(func() { @@ -262,56 +178,5 @@ var _ = Describe("RequestReconciler", Ordered, func() { Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) }) - - It("CreateAccessResources() should succeed with Rollout", func() { - rolloutRequest.Status.PodName = "" - - // Execute - ret, err := builder.CreateAccessResources(ctx, k8sClient, rolloutRequest, rolloutTemplate) - - // VERIFY: No error returned - Expect(err).ToNot(HaveOccurred()) - - // VERIFY: Proper status string returned - Expect(ret).To(MatchRegexp(fmt.Sprintf( - "Success. Pod %s-.*, Role %s-.*, RoleBinding %s.* created", - rolloutRequest.GetName(), - rolloutRequest.GetName(), - rolloutRequest.GetName(), - ))) - - // VERIFY: Pod Created as expected - foundPod := &corev1.Pod{} - err = k8sClient.Get(ctx, types.NamespacedName{ - Name: bldutil.GenerateResourceName(rolloutRequest), - Namespace: ns.GetName(), - }, foundPod) - Expect(err).ToNot(HaveOccurred()) - Expect(foundPod.GetOwnerReferences()).ToNot(BeNil()) - Expect(foundPod.Spec.Containers[0].Command[0]).To(Equal("/bin/sleep")) - Expect(foundPod.Spec.Containers[0].Args[0]).To(Equal("100")) - - // VERIFY: Role Created as expected - foundRole := &rbacv1.Role{} - err = k8sClient.Get(ctx, types.NamespacedName{ - Name: bldutil.GenerateResourceName(rolloutRequest), - Namespace: ns.GetName(), - }, foundRole) - Expect(err).ToNot(HaveOccurred()) - Expect(foundRole.GetOwnerReferences()).ToNot(BeNil()) - Expect(foundRole.Rules[0].ResourceNames[0]).To(Equal(foundPod.GetName())) - Expect(foundRole.Rules[1].ResourceNames[0]).To(Equal(foundPod.GetName())) - - // VERIFY: RoleBinding Created as expected - foundRoleBinding := &rbacv1.RoleBinding{} - err = k8sClient.Get(ctx, types.NamespacedName{ - Name: bldutil.GenerateResourceName(rolloutRequest), - Namespace: ns.GetName(), - }, foundRoleBinding) - Expect(err).ToNot(HaveOccurred()) - Expect(foundRoleBinding.GetOwnerReferences()).ToNot(BeNil()) - Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) - Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) - }) }) }) From 7e19a25943f946a6d2c4e3cc00714314d4809fd3 Mon Sep 17 00:00:00 2001 From: Dennis Nguyen Date: Thu, 17 Aug 2023 22:03:43 -0700 Subject: [PATCH 3/4] inject rollout crd into test cluster --- Makefile | 1 + .../create_access_resources_test.go | 146 +++++++++++++++++- .../builders/podaccessbuilder/suite_test.go | 20 ++- 3 files changed, 157 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index d5bb774a..496c928a 100644 --- a/Makefile +++ b/Makefile @@ -101,6 +101,7 @@ vet: ## Run go vet against code. .PHONY: test test: manifests generate envtest ## Run tests. + go mod download KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test -v $(shell go list ./... | grep -v 'e2e') -coverprofile cover.out -covermode=atomic -race ##@ Build diff --git a/internal/builders/podaccessbuilder/create_access_resources_test.go b/internal/builders/podaccessbuilder/create_access_resources_test.go index 6f53bcdc..1088b4cf 100644 --- a/internal/builders/podaccessbuilder/create_access_resources_test.go +++ b/internal/builders/podaccessbuilder/create_access_resources_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -22,12 +23,14 @@ import ( var _ = Describe("RequestReconciler", Ordered, func() { Context("CreateAccessResources()", func() { var ( - ctx = context.Background() - ns *corev1.Namespace - deployment *appsv1.Deployment - request *v1alpha1.PodAccessRequest - template *v1alpha1.PodAccessTemplate - builder = PodAccessBuilder{} + ctx = context.Background() + ns *corev1.Namespace + deployment *appsv1.Deployment + request *v1alpha1.PodAccessRequest + rolloutRequest *v1alpha1.PodAccessRequest + template *v1alpha1.PodAccessTemplate + rolloutTemplate *v1alpha1.PodAccessTemplate + builder = PodAccessBuilder{} ) BeforeAll(func() { @@ -72,6 +75,39 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, deployment) Expect(err).To(Not(HaveOccurred())) + By("Creating a Rollout to reference for the test") + rollout := &rolloutsv1alpha1.Rollout{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rollout-test", + Namespace: ns.Name, + }, + Spec: rolloutsv1alpha1.RolloutSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testLabel": "testValue", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "testLabel": "testValue", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test", + Image: "nginx:latest", + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, rollout) + Expect(err).To(Not(HaveOccurred())) + By("Should have an PodAccessTemplate to test against") cpuReq, _ := resource.ParseQuantity("1") template = &v1alpha1.PodAccessTemplate{ @@ -108,6 +144,40 @@ var _ = Describe("RequestReconciler", Ordered, func() { err = k8sClient.Create(ctx, template) Expect(err).ToNot(HaveOccurred()) + rolloutTemplate = &v1alpha1.PodAccessTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: utils.RandomString(8), + Namespace: ns.GetName(), + }, + Spec: v1alpha1.PodAccessTemplateSpec{ + AccessConfig: v1alpha1.AccessConfig{ + AllowedGroups: []string{"testGroupA"}, + DefaultDuration: "1h", + MaxDuration: "2h", + }, + ControllerTargetRef: &v1alpha1.CrossVersionObjectReference{ + APIVersion: "argoproj.io/v1alpha1", + Kind: "Rollout", + Name: "rollout-test", + }, + ControllerTargetMutationConfig: &v1alpha1.PodTemplateSpecMutationConfig{ + DefaultContainerName: "test", + Command: &[]string{"/bin/sleep"}, + Args: &[]string{"100"}, + Env: []corev1.EnvVar{ + {Name: "FOO", Value: "BAR"}, + }, + Resources: corev1.ResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + "cpu": cpuReq, + }, + }, + }, + }, + } + err = k8sClient.Create(ctx, rolloutTemplate) + Expect(err).ToNot(HaveOccurred()) + By("Should have an PodAccessRequest built to test against") request = &v1alpha1.PodAccessRequest{ ObjectMeta: metav1.ObjectMeta{ @@ -120,6 +190,19 @@ var _ = Describe("RequestReconciler", Ordered, func() { } err = k8sClient.Create(ctx, request) Expect(err).ToNot(HaveOccurred()) + + // verify podaccess request with Rollout + rolloutRequest = &v1alpha1.PodAccessRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: "createaccessresource-rollout-test", + Namespace: ns.GetName(), + }, + Spec: v1alpha1.PodAccessRequestSpec{ + TemplateName: rolloutTemplate.GetName(), + }, + } + err = k8sClient.Create(ctx, rolloutRequest) + Expect(err).ToNot(HaveOccurred()) }) AfterAll(func() { @@ -178,5 +261,56 @@ var _ = Describe("RequestReconciler", Ordered, func() { Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) }) + + It("CreateAccessResources() should succeed with Rollout", func() { + rolloutRequest.Status.PodName = "" + + // Execute + ret, err := builder.CreateAccessResources(ctx, k8sClient, rolloutRequest, rolloutTemplate) + + // VERIFY: No error returned + Expect(err).ToNot(HaveOccurred()) + + // VERIFY: Proper status string returned + Expect(ret).To(MatchRegexp(fmt.Sprintf( + "Success. Pod %s-.*, Role %s-.*, RoleBinding %s.* created", + rolloutRequest.GetName(), + rolloutRequest.GetName(), + rolloutRequest.GetName(), + ))) + + // VERIFY: Pod Created as expected + foundPod := &corev1.Pod{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundPod) + Expect(err).ToNot(HaveOccurred()) + Expect(foundPod.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundPod.Spec.Containers[0].Command[0]).To(Equal("/bin/sleep")) + Expect(foundPod.Spec.Containers[0].Args[0]).To(Equal("100")) + + // VERIFY: Role Created as expected + foundRole := &rbacv1.Role{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundRole) + Expect(err).ToNot(HaveOccurred()) + Expect(foundRole.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundRole.Rules[0].ResourceNames[0]).To(Equal(foundPod.GetName())) + Expect(foundRole.Rules[1].ResourceNames[0]).To(Equal(foundPod.GetName())) + + // VERIFY: RoleBinding Created as expected + foundRoleBinding := &rbacv1.RoleBinding{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: bldutil.GenerateResourceName(rolloutRequest), + Namespace: ns.GetName(), + }, foundRoleBinding) + Expect(err).ToNot(HaveOccurred()) + Expect(foundRoleBinding.GetOwnerReferences()).ToNot(BeNil()) + Expect(foundRoleBinding.RoleRef.Name).To(Equal(foundRole.GetName())) + Expect(foundRoleBinding.Subjects[0].Name).To(Equal("testGroupA")) + }) }) }) diff --git a/internal/builders/podaccessbuilder/suite_test.go b/internal/builders/podaccessbuilder/suite_test.go index 38feee27..27fdadc5 100644 --- a/internal/builders/podaccessbuilder/suite_test.go +++ b/internal/builders/podaccessbuilder/suite_test.go @@ -17,14 +17,16 @@ limitations under the License. package podaccessbuilder import ( + "fmt" + "os/exec" "path/filepath" + "strings" "testing" rolloutsv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/zap/zapcore" - "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" @@ -60,12 +62,23 @@ var _ = BeforeSuite(func() { logf.SetLogger(logger) By("bootstrapping test environment") + + var err error + + // grab go mod directory with Argo rollout CRD to be installed into test environment cluster + argoRolloutPath, err := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", "github.com/argoproj/argo-rollouts").Output() + Expect(err).NotTo(HaveOccurred()) + argoCRDPath := fmt.Sprintf("%s/manifests/crds", string(argoRolloutPath)) + argoCRDPath = strings.ReplaceAll(argoCRDPath, "\n", "") + testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{ + filepath.Join("..", "..", "..", "config", "crd", "bases"), + argoCRDPath, + }, ErrorIfCRDPathMissing: true, } - var err error // cfg is defined in this file globally. cfg, err = testEnv.Start() Expect(err).NotTo(HaveOccurred()) @@ -78,7 +91,6 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) From ffe6997455a41c1cc91b8ae207bcac03c1738204 Mon Sep 17 00:00:00 2001 From: Dennis Nguyen Date: Fri, 18 Aug 2023 09:11:28 -0700 Subject: [PATCH 4/4] clean up --- internal/builders/podaccessbuilder/suite_test.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/builders/podaccessbuilder/suite_test.go b/internal/builders/podaccessbuilder/suite_test.go index 27fdadc5..356156e5 100644 --- a/internal/builders/podaccessbuilder/suite_test.go +++ b/internal/builders/podaccessbuilder/suite_test.go @@ -66,10 +66,8 @@ var _ = BeforeSuite(func() { var err error // grab go mod directory with Argo rollout CRD to be installed into test environment cluster - argoRolloutPath, err := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", "github.com/argoproj/argo-rollouts").Output() + argoCRDPath, err := extractCRDPath("github.com/argoproj/argo-rollouts", "manifests/crds") Expect(err).NotTo(HaveOccurred()) - argoCRDPath := fmt.Sprintf("%s/manifests/crds", string(argoRolloutPath)) - argoCRDPath = strings.ReplaceAll(argoCRDPath, "\n", "") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -101,3 +99,14 @@ var _ = AfterSuite(func() { err := testEnv.Stop() Expect(err).NotTo(HaveOccurred()) }) + +// extractCRDPath returns an absolute path to CRD path given a package dependency +func extractCRDPath(dep string, crdRelativePath string) (string, error) { + p, err := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", dep).Output() + if err != nil { + return "", err + } + crdPath := fmt.Sprintf("%s/%s", string(p), crdRelativePath) + crdPath = strings.ReplaceAll(crdPath, "\n", "") + return crdPath, nil +}