diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index c4cbc658..506bb010 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -22,7 +22,7 @@ jobs: # All Kubernetes version in between expose the same APIs, hence the operator # should be compatible with them. kube-version: - - "1.31" + - "1.34" group: - e2e steps: @@ -31,10 +31,10 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "~1.23.3" + go-version: "~1.24.10" - name: Setup kind env: - KIND_VERSION: "0.25.0" + KIND_VERSION: "0.30.0" run: go install sigs.k8s.io/kind@v${KIND_VERSION} - name: "install kuttl" run: ./hack/install-kuttl.sh diff --git a/.github/workflows/integration_tests.yaml b/.github/workflows/integration_tests.yaml index d8152f4d..d18e46c2 100644 --- a/.github/workflows/integration_tests.yaml +++ b/.github/workflows/integration_tests.yaml @@ -22,21 +22,21 @@ jobs: # All Kubernetes version in between expose the same APIs, hence the operator # should be compatible with them. kube-version: - - "1.31" + - "1.34" steps: - name: Check out code into the Go module directory uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "~1.23.3" + go-version: "~1.24.10" - name: Configure Git run: | git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - name: Setup kind env: - KIND_VERSION: "0.25.0" + KIND_VERSION: "0.30.0" run: go install sigs.k8s.io/kind@v${KIND_VERSION} - name: "install kuttl" run: ./hack/install-kuttl.sh diff --git a/Dockerfile b/Dockerfile index b692774a..96c31f1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM GO_BUILD_IMG AS builder +FROM --platform=$BUILDPLATFORM GO_BUILD_IMG AS builder ARG AUTHOR=Layer7 ARG VENDOR="Broadcom Inc." @@ -28,7 +28,7 @@ COPY scripts/ scripts/ ENV GOPROXY=${GOPROXY} RUN go mod download -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager cmd/main.go +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -a -o manager cmd/main.go FROM DISTROLESS_IMG diff --git a/Jenkinsfile b/Jenkinsfile index ea035c41..6adf33b6 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,13 +4,14 @@ pipeline { agent { label "default" } environment { ARTIFACTORY_DOCKER_IMS_IMAGE_REG = "ims-base-images-docker-release-local.usw1.packages.broadcom.com" - ARTIFACTORY_DOCKER_IMS_IMAGE = "ims-distro-debian12-static:202505-amd64" + ARTIFACTORY_DOCKER_IMS_IMAGE = "ims-distro-debian13-static:202510" ARTIFACTORY_DOCKER_GO_IMAGE_REG = "docker-hub.usw1.packages.broadcom.com" ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST = "apim-docker-dev-local.usw1.packages.broadcom.com" ARTIFACT_HOST = "${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST}" ARTIFACTORY_DOCKER_DEV_LOCAL_REG_PROJECT = "apim-gateway" IMAGE_NAME = "layer7-operator" IMAGE_TAG_BASE = "${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_PROJECT}/${IMAGE_NAME}" + TARGET_PLATFORMS="linux/amd64,linux/arm64" ARTIFACTORY_CREDS = credentials('ARTIFACTORY_USERNAME_TOKEN') DOCKER_HUB_CREDS = credentials('DOCKERHUB_USERNAME_PASSWORD_RW') def CREATED = sh(script: "echo `date -u +%Y-%m-%dT%H:%M:%SZ`", returnStdout: true).trim() @@ -37,15 +38,34 @@ pipeline { fi fi + info "Getting the Docker and driver info" + docker --version + + DOCKER_BUILDER_NAME=multiarch-builder + info "Using docker buildx builder ${DOCKER_BUILDER_NAME}" + + # temporary workaround for buildx builder with driver docker-container + if docker buildx inspect ${DOCKER_BUILDER_NAME}; then + info "${DOCKER_BUILDER_NAME} already exists" + + if docker buildx inspect ${DOCKER_BUILDER_NAME} | grep ^Driver: | grep -q docker-container; then + info "docker builder ${DOCKER_BUILDER_NAME} is using docker-container driver." + else + error "docker builder ${DOCKER_BUILDER_NAME} is not using docker-container driver." + fi + else + info "Creating docker builder ${DOCKER_BUILDER_NAME}" + docker buildx create --name ${DOCKER_BUILDER_NAME} --driver docker-container + fi + GOPROXY="https://${ARTIFACTORY_DEV_LOCAL_USERNAME}:${ARTIFACTORY_DEV_LOCAL_APIKEY}@usw1.packages.broadcom.com/artifactory/api/go/apim-golang-virtual" docker login ${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST} -u ${ARTIFACTORY_DEV_LOCAL_USERNAME} -p ${ARTIFACTORY_DEV_LOCAL_APIKEY} docker login ${ARTIFACTORY_DOCKER_IMS_IMAGE_REG} -u ${ARTIFACTORY_DEV_LOCAL_USERNAME} -p ${ARTIFACTORY_DEV_LOCAL_APIKEY} docker login ${ARTIFACTORY_DOCKER_GO_IMAGE_REG} -u ${ARTIFACTORY_DEV_LOCAL_USERNAME} -p ${ARTIFACTORY_DEV_LOCAL_APIKEY} DISTROLESS_IMG=${ARTIFACTORY_DOCKER_IMS_IMAGE_REG}/${ARTIFACTORY_DOCKER_IMS_IMAGE} - GO_BUILD_IMG=${ARTIFACTORY_DOCKER_GO_IMAGE_REG}/golang:1.23 + GO_BUILD_IMG=${ARTIFACTORY_DOCKER_GO_IMAGE_REG}/golang:1.24 cat Dockerfile | sed -e "s~DISTROLESS_IMG~${DISTROLESS_IMG}~g" | sed -e "s~GO_BUILD_IMG~${GO_BUILD_IMG}~g" > operator.Dockerfile - docker build -f operator.Dockerfile -t ${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST}/${IMAGE_TAG_BASE}:${RELEASE_VERSION} . --build-arg TITLE="${IMAGE_NAME}" --build-arg COPYRIGHT="${COPYRIGHT}" --build-arg VERSION="${RELEASE_VERSION}" --build-arg CREATED="${CREATED}" --build-arg GOPROXY="${GOPROXY}" - docker push ${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST}/${IMAGE_TAG_BASE}:${RELEASE_VERSION} + docker buildx build -f operator.Dockerfile -t ${ARTIFACTORY_DOCKER_DEV_LOCAL_REG_HOST}/${IMAGE_TAG_BASE}:${RELEASE_VERSION} --builder "${DOCKER_BUILDER_NAME}" --platform="${TARGET_PLATFORMS}" --build-arg TITLE="${IMAGE_NAME}" --build-arg COPYRIGHT="${COPYRIGHT}" --build-arg VERSION="${RELEASE_VERSION}" --build-arg CREATED="${CREATED}" --build-arg GOPROXY="${GOPROXY}" . --push ''' } } diff --git a/Makefile b/Makefile index c3cca59c..04fd8906 100644 --- a/Makefile +++ b/Makefile @@ -65,11 +65,11 @@ ENVTEST_K8S_VERSION = 1.30.0 START_KIND_CLUSTER ?= true -KUBE_VERSION ?= 1.30 +KUBE_VERSION ?= 1.34 KIND_CONFIG ?= kind-$(KUBE_VERSION).yaml -GATEWAY_IMG ?= docker.io/caapim/gateway:11.1.2 -GO_BUILD_IMG ?= golang:1.23 +GATEWAY_IMG ?= docker.io/caapim/gateway:11.1.3 +GO_BUILD_IMG ?= golang:1.24 DISTROLESS_IMG ?= gcr.io/distroless/static:nonroot GO_PROXY ?= "" @@ -218,7 +218,7 @@ build: manifests generate fmt vet ## Build manager binary. .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go --zap-log-level=10 + go run ./cmd/main.go --zap-log-level=5 .PHONY: docker-build docker-build: dockerfile #test ## Build docker image with the manager. @@ -307,8 +307,8 @@ CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen ENVTEST ?= $(LOCALBIN)/setup-envtest ## Tool Versions -KUSTOMIZE_VERSION ?= v5.4.2 -CONTROLLER_TOOLS_VERSION ?= v0.16.5 +KUSTOMIZE_VERSION ?= v5.6.0 +CONTROLLER_TOOLS_VERSION ?= v0.19.0 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. @@ -328,7 +328,7 @@ $(CONTROLLER_GEN): $(LOCALBIN) .PHONY: envtest envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. $(ENVTEST): $(LOCALBIN) - test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.20 + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.22 .PHONY: operator-sdk OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk diff --git a/README.md b/README.md index d75170c0..85865af6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Layer7 Gateway Operator The Layer7 Gateway Operator, built using the [Operator SDK](https://github.com/operator-framework/operator-sdk) covers all aspects of deploying, maintaining and upgrading API Gateways in Kubernetes. -##### Note: The Operator examples currently use ***Gateway 11.1.2*** as a base. +##### Note: The Operator examples currently use ***Gateway 11.1.3*** as a base. ## [Getting Started](https://github.com/CAAPIM/layer7-operator/wiki/Getting-Started) ## [Additional Documentation](https://github.com/CAAPIM/layer7-operator/wiki) diff --git a/api/v1/gateway_types.go b/api/v1/gateway_types.go index 8ad8787e..41fcad93 100644 --- a/api/v1/gateway_types.go +++ b/api/v1/gateway_types.go @@ -142,6 +142,12 @@ type GatewayRepositoryStatus struct { Commit string `json:"commit,omitempty"` // Type is static or dynamic Type string `json:"type,omitempty"` + // RepoType - git, http, local, statestore + RepoType string `json:"repoType,omitempty"` + // Vendor i.e. Github, Gitlab, BitBucket, Azure + Vendor string `json:"vendor,omitempty"` + // AuthType defaults to basic, possible options are none, basic or ssh + AuthType string `json:"authType,omitempty"` //SecretName is used to mount the correct repository secret to the initContainer SecretName string `json:"secretName,omitempty"` //StorageSecretName is used to mount existing repository bundles to the initContainer @@ -161,6 +167,8 @@ type GatewayRepositoryStatus struct { StateStoreKey string `json:"stateStoreKey,omitempty"` // Conditions Conditions []RepositoryCondition `json:"conditions,omitempty"` + // Directories + Directories []string `json:"directories,omitempty"` } type RepositoryCondition struct { @@ -221,13 +229,19 @@ type App struct { // this enables scheduled tasks that are set to execute on a single node and jms destinations that are outbound // to be applied to one ephemeral gateway only. // This works inconjunction with repository references and only supports dynamic repository references. - SingletonExtraction bool `json:"singletonExtraction,omitempty"` - RepositoryReferences []RepositoryReference `json:"repositoryReferences,omitempty"` - Ingress Ingress `json:"ingress,omitempty"` - Sidecars []corev1.Container `json:"sidecars,omitempty"` - InitContainers []corev1.Container `json:"initContainers,omitempty"` - Resources PodResources `json:"resources,omitempty"` - Autoscaling Autoscaling `json:"autoscaling,omitempty"` + SingletonExtraction bool `json:"singletonExtraction,omitempty"` + // BootstrapRepositoryReferences bootstraps repositoryReferences of type dynamic to avoid service unavailable at gateway ready. + RepositoryReferenceBootstrap RepositoryReferenceBootstrap `json:"repositoryReferenceBootstrap,omitempty"` + // RepositoryReferenceDelete enables repository delete when a repositoryReference is disabled or removed. + // To avoid potential conflicts the current gateway state is reset by reapplying all other repository references post + // delete + RepositoryReferenceDelete RepositoryReferenceDelete `json:"repositoryReferenceDelete,omitempty"` + RepositoryReferences []RepositoryReference `json:"repositoryReferences,omitempty"` + Ingress Ingress `json:"ingress,omitempty"` + Sidecars []corev1.Container `json:"sidecars,omitempty"` + InitContainers []corev1.Container `json:"initContainers,omitempty"` + Resources PodResources `json:"resources,omitempty"` + Autoscaling Autoscaling `json:"autoscaling,omitempty"` // ServiceAccount to use for the Gateway Deployment ServiceAccount ServiceAccount `json:"serviceAccount,omitempty"` Hazelcast Hazelcast `json:"hazelcast,omitempty"` @@ -256,6 +270,40 @@ type App struct { Otel Otel `json:"otel,omitempty"` } +// RepositoryReferenceBootstrap facilitates bootstrap of dynamic repo references and the desired source of truth. +type RepositoryReferenceBootstrap struct { + // Enable or disable bootstrapping repository references + Enabled bool `json:"enabled,omitempty"` + // If a L7StateStore is configured the initContainer will default to retrieving configuration from redis over git if a secret is not available (i.e. the repository is greater than 1MB in size) + // this configuration prioritizes git over the L7StateStore configuration to avoid excessive redis egress for large gateway deployments. + PreferGit bool `json:"preferGit,omitempty"` +} + +// RepositoryReferenceBootstrap facilitates bootstrap of dynamic repo references and the desired source of truth. +type RepositoryReferenceDelete struct { + // Enable or disable deleting repository references + // by default this only applies to repositories that have a statestore reference + Enabled bool `json:"enabled,omitempty"` + // IncludeEfs we track deltas between repositories on the operators ephemeral filesystem + // setting this to true will enable delete functionality for all repositoryReferences + // USE WITH CAUTION, an operator restart removes the ephemeral filesystem with the state that is tracked there. + // We DO NOT recommend this setting for database backed gateways, ephemeral gateways can be restarted to reset state. + // use mappings instead + IncludeEfs bool `json:"includeEfs,omitempty"` + // ReconcileReferences resets the commits for all other repositories that have been applied + // this triggers a reconcile which replaces any entities that may have overlapped with the repository that was removed. + // example: + // myrepo1 ==> contains cwp1 + // myrepo2 ==> also contains a cwp1 + // if myrepo1 is deleted cwp1 will be removed. This functionality will then reapply myrepo2 which will reconcile cwp1 + ReconcileReferences bool `json:"reconcileReferences,omitempty"` + // ReconcileDirectoryChanges will create and apply mappings if your dynamic repositoryReference folders change. + // Changes will be based on the current commit + // This is not recommended if you are using a database backed gateway + // Use mappings in your repo instead + ReconcileDirectoryChanges bool `json:"reconcileDirectoryChanges,omitempty"` +} + // Otel used when no dedicated OTel agent is present. This enriches the telemetry that the SDK is able to emit to your observability backend type Otel struct { OtelSDKOnly OtelSDKOnly `json:"sdkOnly,omitempty"` diff --git a/api/v1/gateway_webhook.go b/api/v1/gateway_webhook.go index 920b7eb2..4d7e27c8 100644 --- a/api/v1/gateway_webhook.go +++ b/api/v1/gateway_webhook.go @@ -12,11 +12,14 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package v1 import ( + "context" "fmt" "strings" @@ -24,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -34,42 +36,48 @@ import ( func (r *Gateway) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). For(r). + WithDefaulter(r). + WithValidator(r). Complete() } //+kubebuilder:webhook:path=/mutate-security-brcmlabs-com-v1-gateway,mutating=true,failurePolicy=fail,sideEffects=None,groups=security.brcmlabs.com,resources=gateways,verbs=create;update,versions=v1,name=mgateway.kb.io,admissionReviewVersions=v1 -var _ webhook.Defaulter = &Gateway{} +var _ admission.CustomDefaulter = &Gateway{} // Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *Gateway) Default() { - //gatewaylog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. - +func (r *Gateway) Default(ctx context.Context, obj runtime.Object) error { + return nil } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. //+kubebuilder:webhook:path=/validate-security-brcmlabs-com-v1-gateway,mutating=false,failurePolicy=fail,sideEffects=None,groups=security.brcmlabs.com,resources=gateways,verbs=create;update,versions=v1,name=vgateway.kb.io,admissionReviewVersions=v1 -var _ webhook.Validator = &Gateway{} +var _ admission.CustomValidator = &Gateway{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *Gateway) ValidateCreate() (admission.Warnings, error) { - return validateGateway(r) +func (r *Gateway) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + gateway, ok := obj.(*Gateway) + if !ok { + return nil, fmt.Errorf("expected a Gateway, received %T", obj) + } + return validateGateway(gateway) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *Gateway) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - _, ok := old.(*Gateway) +func (r *Gateway) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + _, ok := oldObj.(*Gateway) + if !ok { + return nil, fmt.Errorf("expected a Gateway for oldObj, received %T", oldObj) + } + gateway, ok := newObj.(*Gateway) if !ok { - return nil, fmt.Errorf("expected a Gateway, received %T", r) + return nil, fmt.Errorf("expected a Gateway for newObj, received %T", newObj) } - return validateGateway(r) + return validateGateway(gateway) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *Gateway) ValidateDelete() (admission.Warnings, error) { +func (r *Gateway) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { //gatewaylog.Info("validate delete", "name", r.Name) return []string{}, nil } diff --git a/api/v1/repository_types.go b/api/v1/repository_types.go index 36f97d98..ec5e65c5 100644 --- a/api/v1/repository_types.go +++ b/api/v1/repository_types.go @@ -166,14 +166,10 @@ type RepositoryStatus struct { // +operator-sdk:csv:customresourcedefinitions:type=status // +operator-sdk:csv:customresourcedefinitions:displayName="StorageSecretName" StorageSecretName string `json:"storageSecretName,omitempty"` - // StateStoreVersion tracks version in state store - // +operator-sdk:csv:customresourcedefinitions:type=status - // +operator-sdk:csv:customresourcedefinitions:displayName="StateStoreVersion" - StateStoreVersion int `json:"stateStoreVersion,omitempty"` // StateStoreSynced whether or not the state store has been written to correctly // +operator-sdk:csv:customresourcedefinitions:type=status // +operator-sdk:csv:customresourcedefinitions:displayName="StateStoreVersion" - StateStoreSynced bool `json:"stateStoreSynced,omitempty"` + StateStoreSynced bool `json:"stateStoreSynced"` } func init() { diff --git a/api/v1/repository_webhook.go b/api/v1/repository_webhook.go index 7fc176c9..d0dfef9a 100644 --- a/api/v1/repository_webhook.go +++ b/api/v1/repository_webhook.go @@ -12,55 +12,67 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package v1 import ( + "context" "fmt" "strings" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) func (r *Repository) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). For(r). + WithDefaulter(r). + WithValidator(r). Complete() } //+kubebuilder:webhook:path=/mutate-security-brcmlabs-com-v1-repository,mutating=true,failurePolicy=fail,sideEffects=None,groups=security.brcmlabs.com,resources=repositories,verbs=create;update,versions=v1,name=mrepository.kb.io,admissionReviewVersions=v1 -var _ webhook.Defaulter = &Repository{} +var _ admission.CustomDefaulter = &Repository{} // Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *Repository) Default() { - //repositorylog.Info("default", "name", r.Name) +func (r *Repository) Default(ctx context.Context, obj runtime.Object) error { + return nil } //+kubebuilder:webhook:path=/validate-security-brcmlabs-com-v1-repository,mutating=false,failurePolicy=fail,sideEffects=None,groups=security.brcmlabs.com,resources=repositories,verbs=create;update,versions=v1,name=vrepository.kb.io,admissionReviewVersions=v1 -var _ webhook.Validator = &Repository{} +var _ admission.CustomValidator = &Repository{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *Repository) ValidateCreate() (admission.Warnings, error) { - return validateRepository(r) +func (r *Repository) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + repository, ok := obj.(*Repository) + if !ok { + return nil, fmt.Errorf("expected a Repository, received %T", obj) + } + return validateRepository(repository) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *Repository) ValidateUpdate(obj runtime.Object) (admission.Warnings, error) { - _, ok := obj.(*Repository) +func (r *Repository) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + _, ok := oldObj.(*Repository) if !ok { - return nil, fmt.Errorf("expected a Repository, received %T", obj) + return nil, fmt.Errorf("expected a Repository for oldObj, received %T", oldObj) } - return validateRepository(r) + repository, ok := newObj.(*Repository) + if !ok { + return nil, fmt.Errorf("expected a Repository for newObj, received %T", newObj) + } + return validateRepository(repository) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *Repository) ValidateDelete() (admission.Warnings, error) { +func (r *Repository) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { // Could extend to checking which gateways reference this before deletion. return []string{}, nil } @@ -87,9 +99,9 @@ func validateRepository(r *Repository) (admission.Warnings, error) { switch strings.ToLower(string(r.Spec.Type)) { case "git": - if !strings.HasPrefix(r.Spec.Endpoint, "https://") && !strings.HasPrefix(r.Spec.Endpoint, "ssh://") { - return warnings, fmt.Errorf("repository endpoint must start with https:// or ssh://. name: %s ", r.Name) - } + // if !strings.HasPrefix(r.Spec.Endpoint, "https://") && !strings.HasPrefix(r.Spec.Endpoint, "ssh://") { + // return warnings, fmt.Errorf("repository endpoint must start with https:// or ssh://. name: %s ", r.Name) + // } if r.Spec.Auth != (RepositoryAuth{}) { if r.Spec.Auth.Type != RepositoryAuthTypeNone && r.Spec.Auth.Type != RepositoryAuthTypeBasic && r.Spec.Auth.Type != RepositoryAuthTypeSSH { return warnings, fmt.Errorf("please set a valid auth type, valid options for Git are none, basic and ssh. name: %s ", r.Name) diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 1d284f96..3fec98ec 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -81,6 +81,8 @@ func (in *App) DeepCopyInto(out *App) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.RepositoryReferenceBootstrap = in.RepositoryReferenceBootstrap + out.RepositoryReferenceDelete = in.RepositoryReferenceDelete if in.RepositoryReferences != nil { in, out := &in.RepositoryReferences, &out.RepositoryReferences *out = make([]RepositoryReference, len(*in)) @@ -576,6 +578,11 @@ func (in *GatewayRepositoryStatus) DeepCopyInto(out *GatewayRepositoryStatus) { *out = make([]RepositoryCondition, len(*in)) copy(*out, *in) } + if in.Directories != nil { + in, out := &in.Directories, &out.Directories + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayRepositoryStatus. @@ -1540,6 +1547,36 @@ func (in *RepositoryReference) DeepCopy() *RepositoryReference { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RepositoryReferenceBootstrap) DeepCopyInto(out *RepositoryReferenceBootstrap) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryReferenceBootstrap. +func (in *RepositoryReferenceBootstrap) DeepCopy() *RepositoryReferenceBootstrap { + if in == nil { + return nil + } + out := new(RepositoryReferenceBootstrap) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RepositoryReferenceDelete) DeepCopyInto(out *RepositoryReferenceDelete) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryReferenceDelete. +func (in *RepositoryReferenceDelete) DeepCopy() *RepositoryReferenceDelete { + if in == nil { + return nil + } + out := new(RepositoryReferenceDelete) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) { *out = *in diff --git a/api/v1alpha1/l7statestore_types.go b/api/v1alpha1/l7statestore_types.go index 67663509..f46d79cd 100644 --- a/api/v1alpha1/l7statestore_types.go +++ b/api/v1alpha1/l7statestore_types.go @@ -45,7 +45,7 @@ type L7StateStoreSpec struct { // L7StateStoreStatus defines the observed state of L7StateStore type L7StateStoreStatus struct { - Ready bool `json:"ready,omitempty"` + Ready bool `json:"ready"` } // +kubebuilder:object:root=true @@ -72,6 +72,7 @@ type L7StateStoreList struct { type Redis struct { Type RedisType `json:"type,omitempty"` ExistingSecret string `json:"existingSecret,omitempty"` + Tls RedisTls `json:"tls,omitempty"` Username string `json:"username,omitempty"` MasterPassword string `json:"masterPassword,omitempty"` GroupName string `json:"groupName,omitempty"` @@ -81,6 +82,12 @@ type Redis struct { Database int `json:"database,omitempty"` } +type RedisTls struct { + Enabled bool `json:"enabled,omitempty"` + RedisCrt string `json:"redisCrt,omitempty"` + VerifyPeer bool `json:"verifyPeer,omitempty"` +} + type RedisSentinel struct { Master string `json:"master,omitempty"` Nodes []RedisSentinelNode `json:"nodes,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 78efdc5c..499d29f1 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -516,6 +516,7 @@ func (in *ProxyGateway) DeepCopy() *ProxyGateway { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Redis) DeepCopyInto(out *Redis) { *out = *in + out.Tls = in.Tls out.Standalone = in.Standalone in.Sentinel.DeepCopyInto(&out.Sentinel) } @@ -580,6 +581,21 @@ func (in *RedisStandalone) DeepCopy() *RedisStandalone { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RedisTls) DeepCopyInto(out *RedisTls) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedisTls. +func (in *RedisTls) DeepCopy() *RedisTls { + if in == nil { + return nil + } + out := new(RedisTls) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecurePassword) DeepCopyInto(out *SecurePassword) { *out = *in diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 3cb73a41..ad5b4dbb 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=layer7-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.38.0 +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.42.0 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 diff --git a/bundle/manifests/layer7-operator.clusterserviceversion.yaml b/bundle/manifests/layer7-operator.clusterserviceversion.yaml index 978b9b9a..ddb9b35f 100644 --- a/bundle/manifests/layer7-operator.clusterserviceversion.yaml +++ b/bundle/manifests/layer7-operator.clusterserviceversion.yaml @@ -12,7 +12,7 @@ metadata: }, "spec": { "app": { - "image": "docker.io/caapim/gateway:11.1.2", + "image": "docker.io/caapim/gateway:11.1.3", "management": { "cluster": { "hostname": "gateway.brcmlabs.com", @@ -44,7 +44,7 @@ metadata: "accept": false, "secretName": "gateway-license" }, - "version": "11.1.2" + "version": "11.1.3" }, "status": {} }, @@ -119,14 +119,14 @@ metadata: ] capabilities: Basic Install certified: "false" - containerImage: docker.io/caapim/layer7-operator:v1.2.1 - createdAt: "2025-06-24T12:00:00Z" + containerImage: docker.io/caapim/layer7-operator:v1.2.2 + createdAt: "2025-11-24T09:17:56Z" operatorframework.io/suggested-namespace: layer7-operator-system - operators.operatorframework.io/builder: operator-sdk-v1.38.0 + operators.operatorframework.io/builder: operator-sdk-v1.42.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 repository: github.com/caapim/layer7-operator support: Broadcom Community - name: layer7-operator.v1.2.1 + name: layer7-operator.v1.2.2 spec: apiservicedefinitions: {} customresourcedefinitions: @@ -360,9 +360,6 @@ spec: to correctly displayName: State Store Synced path: stateStoreSynced - - description: StateStoreVersion tracks version in state store - displayName: State Store Version - path: stateStoreVersion - description: StorageSecretName is the Kubernetes Secret that this repository is stored in displayName: Storage Secret Name @@ -500,6 +497,13 @@ spec: - get - list - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: @@ -699,7 +703,7 @@ spec: value: localhost:4317 - name: OTEL_METRIC_PREFIX value: layer7_ - image: docker.io/caapim/layer7-operator:v1.2.1 + image: docker.io/caapim/layer7-operator:v1.2.2 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -721,7 +725,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi @@ -788,7 +792,7 @@ spec: provider: name: Broadcom url: https://www.broadcom.com/ - version: 1.2.1 + version: 1.2.2 webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/bundle/manifests/security.brcmlabs.com_gateways.yaml b/bundle/manifests/security.brcmlabs.com_gateways.yaml index f3909778..c0f0193a 100644 --- a/bundle/manifests/security.brcmlabs.com_gateways.yaml +++ b/bundle/manifests/security.brcmlabs.com_gateways.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 creationTimestamp: null name: gateways.security.brcmlabs.com spec: @@ -29,11 +29,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -42,7 +42,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -54,10 +54,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -67,9 +67,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -95,9 +95,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -122,8 +122,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -133,9 +133,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -148,9 +147,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -176,9 +175,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -215,10 +214,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -234,7 +233,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -268,7 +267,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -276,7 +275,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -291,7 +290,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -324,14 +323,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -339,7 +338,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -349,12 +348,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -365,8 +364,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -400,7 +398,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -408,7 +406,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -422,8 +420,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -456,14 +453,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -478,10 +475,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -497,7 +494,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -531,7 +528,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -539,7 +536,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -554,7 +551,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -587,14 +584,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -602,7 +599,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -612,12 +609,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -628,8 +625,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -663,7 +659,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -671,7 +667,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -685,8 +681,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -719,14 +714,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -738,12 +733,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -755,7 +750,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -763,15 +758,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -796,9 +790,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -806,15 +808,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -839,9 +840,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -852,12 +861,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -874,7 +882,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -883,13 +891,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -910,7 +917,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -922,7 +929,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -930,7 +937,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -973,7 +980,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -982,13 +989,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1008,11 +1014,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1040,7 +1046,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1048,7 +1054,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1091,7 +1097,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1100,13 +1106,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1125,9 +1130,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1139,7 +1143,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1147,7 +1151,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1190,7 +1194,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1199,13 +1203,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1225,7 +1228,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1238,7 +1241,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1247,13 +1250,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1284,8 +1286,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1325,12 +1327,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1338,7 +1339,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1418,7 +1419,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1442,7 +1443,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1451,8 +1452,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1474,7 +1475,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1502,8 +1503,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1521,7 +1522,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1543,7 +1544,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1570,12 +1571,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1583,7 +1584,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1595,7 +1596,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1605,8 +1606,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1614,7 +1615,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1639,8 +1640,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1652,9 +1653,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1679,7 +1679,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1689,7 +1689,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1714,7 +1714,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1729,7 +1729,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1775,7 +1775,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1794,11 +1794,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1814,12 +1814,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1889,7 +1889,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1899,8 +1899,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1940,7 +1941,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1970,7 +1971,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1981,9 +1982,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2037,7 +2037,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2053,8 +2053,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2084,26 +2084,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2148,8 +2148,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2178,24 +2178,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2240,8 +2239,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2269,16 +2268,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2286,12 +2290,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2300,14 +2303,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2352,7 +2356,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2363,12 +2367,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2386,7 +2390,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2440,11 +2444,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2452,12 +2457,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2466,14 +2470,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2518,7 +2523,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2529,12 +2534,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2552,7 +2557,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2632,16 +2637,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2649,7 +2653,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2731,7 +2735,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2755,7 +2759,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2768,11 +2772,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2780,12 +2785,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2794,14 +2798,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2846,7 +2851,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2857,12 +2862,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2880,7 +2885,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2891,16 +2896,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2908,7 +2913,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2919,7 +2924,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2948,7 +2953,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2958,9 +2963,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2968,7 +2972,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -2998,7 +3002,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3028,25 +3032,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3090,8 +3096,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3119,23 +3125,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3179,8 +3186,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3207,10 +3214,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3233,7 +3244,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3262,8 +3273,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3295,19 +3305,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3315,11 +3325,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3328,14 +3338,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3380,7 +3390,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3391,12 +3401,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3414,7 +3423,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3485,16 +3494,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3511,9 +3520,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3521,7 +3529,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3603,7 +3611,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3627,7 +3635,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3641,7 +3649,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3649,9 +3657,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3680,14 +3687,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3697,7 +3704,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3710,7 +3717,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3785,7 +3792,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3816,7 +3823,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3901,14 +3908,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3938,19 +3945,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3979,19 +3986,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4013,9 +4020,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4023,7 +4029,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4105,7 +4111,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4129,7 +4135,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4142,8 +4148,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4158,7 +4164,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4172,7 +4178,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4189,11 +4195,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4231,15 +4237,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4255,7 +4261,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4271,6 +4277,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4297,7 +4307,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4307,9 +4317,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4317,7 +4326,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4352,7 +4361,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4362,7 +4371,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4377,9 +4386,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4387,7 +4395,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4469,7 +4477,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4493,7 +4501,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4507,14 +4515,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4528,14 +4536,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4543,11 +4551,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4556,14 +4564,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4608,7 +4616,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4619,12 +4627,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4642,7 +4649,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4744,8 +4751,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4850,8 +4857,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4859,14 +4867,43 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: Enable or disable deleting repository references + type: boolean + limitToStateStore: + description: Limit deletion to repositories that have an external + statestore + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4874,8 +4911,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4883,7 +4920,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4929,7 +4966,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4961,7 +4998,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4990,14 +5027,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5007,7 +5044,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5020,7 +5057,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5107,7 +5144,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5137,7 +5174,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5148,9 +5185,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5204,7 +5240,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5220,8 +5256,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5251,26 +5287,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5315,8 +5351,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5345,24 +5381,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5407,8 +5442,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5436,16 +5471,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5453,12 +5493,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5467,14 +5506,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5519,7 +5559,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5530,12 +5570,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5553,7 +5593,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5607,11 +5647,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5619,12 +5660,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5633,14 +5673,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5685,7 +5726,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5696,12 +5737,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5719,7 +5760,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5799,16 +5840,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5816,7 +5856,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5898,7 +5938,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5922,7 +5962,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5935,11 +5975,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5947,12 +5988,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5961,14 +6001,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6013,7 +6054,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6024,12 +6065,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6047,7 +6088,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6058,16 +6099,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6075,7 +6116,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6086,7 +6127,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6115,7 +6156,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6125,9 +6166,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6135,7 +6175,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6165,14 +6205,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6186,8 +6225,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6199,7 +6238,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6209,7 +6248,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6239,9 +6278,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6258,20 +6296,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6291,7 +6327,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6311,9 +6347,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6321,7 +6356,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6332,7 +6367,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6441,7 +6476,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6457,8 +6492,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6477,6 +6516,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6490,9 +6534,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6502,7 +6549,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6510,6 +6557,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object diff --git a/bundle/manifests/security.brcmlabs.com_l7apis.yaml b/bundle/manifests/security.brcmlabs.com_l7apis.yaml index 437a0eb3..8d69d0a3 100644 --- a/bundle/manifests/security.brcmlabs.com_l7apis.yaml +++ b/bundle/manifests/security.brcmlabs.com_l7apis.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 creationTimestamp: null name: l7apis.security.brcmlabs.com spec: @@ -25,11 +25,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -38,18 +38,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal @@ -106,6 +106,28 @@ spec: type: array publishedTs: type: integer + securePasswordIdsForUndeployment: + items: + type: string + type: array + securePasswords: + items: + properties: + description: + type: string + id: + type: string + name: + type: string + value: + type: string + required: + - description + - id + - name + - value + type: object + type: array serviceId: type: string ssgServiceType: @@ -132,13 +154,22 @@ spec: gateways: items: properties: - checksum: - type: string + conditions: + items: + properties: + action: + type: string + actionTime: + type: string + checksum: + type: string + reason: + type: string + status: + type: string + type: object + type: array deployment: - description: Phase corev1. - type: string - lastUpdated: - description: Ready bool `json:"ready,omitempty"` type: string name: type: string diff --git a/bundle/manifests/security.brcmlabs.com_l7portals.yaml b/bundle/manifests/security.brcmlabs.com_l7portals.yaml index f17cae15..68aa2dbb 100644 --- a/bundle/manifests/security.brcmlabs.com_l7portals.yaml +++ b/bundle/manifests/security.brcmlabs.com_l7portals.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 creationTimestamp: null name: l7portals.security.brcmlabs.com spec: @@ -25,11 +25,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -50,7 +50,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -63,7 +63,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: diff --git a/bundle/manifests/security.brcmlabs.com_l7statestores.yaml b/bundle/manifests/security.brcmlabs.com_l7statestores.yaml index d95c6b87..c219613b 100644 --- a/bundle/manifests/security.brcmlabs.com_l7statestores.yaml +++ b/bundle/manifests/security.brcmlabs.com_l7statestores.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 creationTimestamp: null name: l7statestores.security.brcmlabs.com spec: @@ -15,18 +15,22 @@ spec: singular: l7statestore scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + name: v1alpha1 schema: openAPIV3Schema: description: L7StateStore is the Schema for the l7statestores API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -67,6 +71,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -81,6 +94,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true diff --git a/bundle/manifests/security.brcmlabs.com_repositories.yaml b/bundle/manifests/security.brcmlabs.com_repositories.yaml index 2e52994b..90f58088 100644 --- a/bundle/manifests/security.brcmlabs.com_repositories.yaml +++ b/bundle/manifests/security.brcmlabs.com_repositories.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 creationTimestamp: null name: repositories.security.brcmlabs.com spec: @@ -22,18 +22,38 @@ spec: singular: repository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + - description: checksum of content or git commit id + jsonPath: .status.commit + name: Commit + type: string + - description: repository type + jsonPath: .spec.type + name: Type + type: string + - description: Git Branch + jsonPath: .spec.branch + name: Branch + type: string + - description: checksum of content or git commit id + jsonPath: .spec.tag + name: Tag + type: string + name: v1 schema: openAPIV3Schema: description: Repository is the Schema for the repositories API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -47,7 +67,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -84,7 +104,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -99,7 +119,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -108,12 +128,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -136,7 +157,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -148,14 +169,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -165,6 +183,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index ac786168..5e77c829 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: layer7-operator operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.38.0 + operators.operatorframework.io.metrics.builder: operator-sdk-v1.42.0 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 diff --git a/charts/layer7-operator/Chart.yaml b/charts/layer7-operator/Chart.yaml index 503b8fbb..ddd7dc66 100644 --- a/charts/layer7-operator/Chart.yaml +++ b/charts/layer7-operator/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: layer7-operator description: The Layer7 Operator Helm Chart type: application -version: 0.1.8 -appVersion: "1.2.1" +version: 0.1.9 +appVersion: "1.2.2" home: https://github.com/CAAPIM/layer7-operator maintainers: - name: Gazza7205 diff --git a/charts/layer7-operator/README.md b/charts/layer7-operator/README.md index 2d1a66b3..ae7fcec8 100644 --- a/charts/layer7-operator/README.md +++ b/charts/layer7-operator/README.md @@ -64,11 +64,11 @@ helm upgrade -i layer7-operator layer7-operator/layer7-operator -n layer7-operat | `containerSecurityContext` | Layer7 Operator Container Security Context | `{}` | | `image.registry` | Layer7 Operator image registry | `docker.io` | | `image.repository` | Layer7 Operator image repository | `caapim/layer7-operator` | -| `image.tag` | Layer7 Operator image tag | `v1.2.1` | +| `image.tag` | Layer7 Operator image tag | `v1.2.2` | | `image.pullPolicy` | Layer7 Operator image pull policy | `IfNotPresent` | | `image.pullSecrets` | Layer7 Operator image pull secrets | `[]` | | `resources.limits.cpu` | The cpu limits for the Layer7 Operator container | `500m` | -| `resources.limits.memory` | The memory limits for the Layer7 Operator container | `256Mi` | +| `resources.limits.memory` | The memory limits for the Layer7 Operator container | `512Mi` | | `resources.requests.cpu` | The cpu requests for the Layer7 Operator container | `100m` | | `resources.requests.memory` | The memory requests for Layer7 Operator container | `64Mi` | | `args` | The arguments to pass to the Layer7 Operator Container. Setting --zap-log-level=10 will increase log verbosity | `["--health-probe-bind-address=:8081","--metrics-bind-address=:8443","--leader-elect","--zap-log-level=info","--zap-time-encoding=rfc3339nano"]` | diff --git a/charts/layer7-operator/crds/gateway-crd.yaml b/charts/layer7-operator/crds/gateway-crd.yaml index 45d13ae7..e7e9d3ac 100644 --- a/charts/layer7-operator/crds/gateway-crd.yaml +++ b/charts/layer7-operator/crds/gateway-crd.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: gateways.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -28,11 +28,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -41,7 +41,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -53,10 +53,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -66,9 +66,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -94,9 +94,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -121,8 +121,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -132,9 +132,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -147,9 +146,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -175,9 +174,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -214,10 +213,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -233,7 +232,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -267,7 +266,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -275,7 +274,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -290,7 +289,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -323,14 +322,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -338,7 +337,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -348,12 +347,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -364,8 +363,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -399,7 +397,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -407,7 +405,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -421,8 +419,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -455,14 +452,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -477,10 +474,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -496,7 +493,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -530,7 +527,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -538,7 +535,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -553,7 +550,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -586,14 +583,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -601,7 +598,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -611,12 +608,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -627,8 +624,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -662,7 +658,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -670,7 +666,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -684,8 +680,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -718,14 +713,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -737,12 +732,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -754,7 +749,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -762,15 +757,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -795,9 +789,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -805,15 +807,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -838,9 +839,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -851,12 +860,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -873,7 +881,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -882,13 +890,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -909,7 +916,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -921,7 +928,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -929,7 +936,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -972,7 +979,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -981,13 +988,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1007,11 +1013,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1039,7 +1045,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1047,7 +1053,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1090,7 +1096,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1099,13 +1105,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1124,9 +1129,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1138,7 +1142,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1146,7 +1150,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1189,7 +1193,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1198,13 +1202,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1224,7 +1227,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1237,7 +1240,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1246,13 +1249,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1283,8 +1285,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1324,12 +1326,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1337,7 +1338,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1417,7 +1418,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1441,7 +1442,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1450,8 +1451,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1473,7 +1474,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1501,8 +1502,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1520,7 +1521,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1542,7 +1543,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1569,12 +1570,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1582,7 +1583,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1594,7 +1595,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1604,8 +1605,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1613,7 +1614,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1638,8 +1639,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1651,9 +1652,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1678,7 +1678,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1688,7 +1688,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1713,7 +1713,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1728,7 +1728,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1774,7 +1774,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1793,11 +1793,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1813,12 +1813,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1888,7 +1888,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1898,8 +1898,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1939,7 +1940,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1969,7 +1970,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1980,9 +1981,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2036,7 +2036,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2052,8 +2052,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2083,26 +2083,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2147,8 +2147,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2177,24 +2177,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2239,8 +2238,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2268,16 +2267,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2285,12 +2289,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2299,14 +2302,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2351,7 +2355,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2362,12 +2366,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2385,7 +2389,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2439,11 +2443,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2451,12 +2456,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2465,14 +2469,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2517,7 +2522,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2528,12 +2533,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2551,7 +2556,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2631,16 +2636,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2648,7 +2652,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2730,7 +2734,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2754,7 +2758,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2767,11 +2771,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2779,12 +2784,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2793,14 +2797,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2845,7 +2850,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2856,12 +2861,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2879,7 +2884,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2890,16 +2895,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2907,7 +2912,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2918,7 +2923,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2947,7 +2952,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2957,9 +2962,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2967,7 +2971,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -2997,7 +3001,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3027,25 +3031,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3089,8 +3095,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3118,23 +3124,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3178,8 +3185,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3206,10 +3213,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3232,7 +3243,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3261,8 +3272,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3294,19 +3304,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3314,11 +3324,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3327,14 +3337,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3379,7 +3389,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3390,12 +3400,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3413,7 +3422,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3484,16 +3493,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3510,9 +3519,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3520,7 +3528,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3602,7 +3610,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3626,7 +3634,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3640,7 +3648,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3648,9 +3656,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3679,14 +3686,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3696,7 +3703,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3709,7 +3716,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3784,7 +3791,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3815,7 +3822,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3900,14 +3907,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3937,19 +3944,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3978,19 +3985,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4012,9 +4019,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4022,7 +4028,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4104,7 +4110,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4128,7 +4134,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4141,8 +4147,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4157,7 +4163,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4171,7 +4177,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4188,11 +4194,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4230,15 +4236,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4254,7 +4260,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4270,6 +4276,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4296,7 +4306,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4306,9 +4316,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4316,7 +4325,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4351,7 +4360,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4361,7 +4370,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4376,9 +4385,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4386,7 +4394,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4468,7 +4476,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4492,7 +4500,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4506,14 +4514,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4527,14 +4535,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4542,11 +4550,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4555,14 +4563,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4607,7 +4615,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4618,12 +4626,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4641,7 +4648,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4743,8 +4750,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4849,8 +4856,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4858,14 +4866,49 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: |- + Enable or disable deleting repository references + by default this only... + type: boolean + includeEfs: + description: IncludeEfs we track deltas between repositories + on the operators ephemeral... + type: boolean + reconcileDirectoryChanges: + description: ReconcileDirectoryChanges will create and apply + mappings if your dynamic... + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4873,8 +4916,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4882,7 +4925,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4928,7 +4971,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4960,7 +5003,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4989,14 +5032,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5006,7 +5049,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5019,7 +5062,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5106,7 +5149,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5136,7 +5179,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5147,9 +5190,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5203,7 +5245,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5219,8 +5261,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5250,26 +5292,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5314,8 +5356,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5344,24 +5386,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5406,8 +5447,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5435,16 +5476,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5452,12 +5498,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5466,14 +5511,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5518,7 +5564,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5529,12 +5575,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5552,7 +5598,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5606,11 +5652,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5618,12 +5665,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5632,14 +5678,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5684,7 +5731,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5695,12 +5742,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5718,7 +5765,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5798,16 +5845,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5815,7 +5861,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5897,7 +5943,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5921,7 +5967,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5934,11 +5980,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5946,12 +5993,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5960,14 +6006,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6012,7 +6059,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6023,12 +6070,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6046,7 +6093,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6057,16 +6104,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6074,7 +6121,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6085,7 +6132,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6114,7 +6161,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6124,9 +6171,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6134,7 +6180,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6164,14 +6210,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6185,8 +6230,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6198,7 +6243,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6208,7 +6253,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6238,9 +6283,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6257,20 +6301,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6290,7 +6332,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6310,9 +6352,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6320,7 +6361,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6331,7 +6372,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6440,7 +6481,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6456,8 +6497,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6476,6 +6521,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6489,9 +6539,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6501,7 +6554,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6509,6 +6562,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object diff --git a/charts/layer7-operator/crds/l7api-crd.yaml b/charts/layer7-operator/crds/l7api-crd.yaml index 6b7fc950..fb495ed7 100644 --- a/charts/layer7-operator/crds/l7api-crd.yaml +++ b/charts/layer7-operator/crds/l7api-crd.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7apis.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -24,11 +24,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -37,18 +37,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal diff --git a/charts/layer7-operator/crds/l7portal-crd.yaml b/charts/layer7-operator/crds/l7portal-crd.yaml index b5f6317a..fc92f505 100644 --- a/charts/layer7-operator/crds/l7portal-crd.yaml +++ b/charts/layer7-operator/crds/l7portal-crd.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7portals.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -24,11 +24,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -49,7 +49,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -62,7 +62,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: diff --git a/charts/layer7-operator/crds/l7statestore-crd.yaml b/charts/layer7-operator/crds/l7statestore-crd.yaml index b5191d3a..85b7111a 100644 --- a/charts/layer7-operator/crds/l7statestore-crd.yaml +++ b/charts/layer7-operator/crds/l7statestore-crd.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7statestores.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -14,18 +14,22 @@ spec: singular: l7statestore scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + name: v1alpha1 schema: openAPIV3Schema: description: L7StateStore is the Schema for the l7statestores API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -66,6 +70,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -80,6 +93,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true diff --git a/charts/layer7-operator/crds/repository-crd.yaml b/charts/layer7-operator/crds/repository-crd.yaml index 88433e3e..e38c3b16 100644 --- a/charts/layer7-operator/crds/repository-crd.yaml +++ b/charts/layer7-operator/crds/repository-crd.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: repositories.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -21,18 +21,38 @@ spec: singular: repository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + - description: checksum of content or git commit id + jsonPath: .status.commit + name: Commit + type: string + - description: repository type + jsonPath: .spec.type + name: Type + type: string + - description: Git Branch + jsonPath: .spec.branch + name: Branch + type: string + - description: checksum of content or git commit id + jsonPath: .spec.tag + name: Tag + type: string + name: v1 schema: openAPIV3Schema: description: Repository is the Schema for the repositories API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -46,7 +66,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -83,7 +103,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -98,7 +118,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -107,12 +127,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -135,7 +156,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -147,14 +168,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -164,6 +182,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true diff --git a/charts/layer7-operator/values.yaml b/charts/layer7-operator/values.yaml index f8835cc2..3dd11de9 100644 --- a/charts/layer7-operator/values.yaml +++ b/charts/layer7-operator/values.yaml @@ -92,7 +92,7 @@ containerSecurityContext: {} image: registry: docker.io repository: caapim/layer7-operator - tag: v1.2.1 + tag: v1.2.2 ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images @@ -117,7 +117,7 @@ image: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/cmd/main.go b/cmd/main.go index 0126a6b2..6d54749d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package main @@ -48,6 +49,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/filters" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" securityv1 "github.com/caapim/layer7-operator/api/v1" securityv1alpha1 "github.com/caapim/layer7-operator/api/v1alpha1" @@ -142,9 +144,15 @@ func main() { setupLog.Error(err, "failed to determine if Otel should be enabled") } + // Always configure webhook server to avoid errors, but only register webhooks if enabled + webhookServer := webhook.NewServer(webhook.Options{ + Port: 9443, + }) + options := ctrl.Options{ Scheme: scheme, Metrics: metricsServerOptions, + WebhookServer: webhookServer, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionNamespace: oNamespace, diff --git a/config/crd/bases/security.brcmlabs.com_gateways.yaml b/config/crd/bases/security.brcmlabs.com_gateways.yaml index e0971f4d..a473a499 100644 --- a/config/crd/bases/security.brcmlabs.com_gateways.yaml +++ b/config/crd/bases/security.brcmlabs.com_gateways.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: gateways.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -28,11 +28,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -41,7 +41,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -53,10 +53,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -66,9 +66,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -94,9 +94,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -121,8 +121,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -132,9 +132,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -147,9 +146,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -175,9 +174,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -214,10 +213,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -233,7 +232,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -267,7 +266,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -275,7 +274,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -290,7 +289,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -323,14 +322,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -338,7 +337,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -348,12 +347,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -364,8 +363,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -399,7 +397,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -407,7 +405,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -421,8 +419,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -455,14 +452,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -477,10 +474,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -496,7 +493,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -530,7 +527,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -538,7 +535,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -553,7 +550,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -586,14 +583,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -601,7 +598,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -611,12 +608,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -627,8 +624,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -662,7 +658,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -670,7 +666,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -684,8 +680,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -718,14 +713,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -737,12 +732,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -754,7 +749,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -762,15 +757,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -795,9 +789,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -805,15 +807,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -838,9 +839,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -851,12 +860,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -873,7 +881,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -882,13 +890,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -909,7 +916,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -921,7 +928,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -929,7 +936,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -972,7 +979,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -981,13 +988,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1007,11 +1013,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1039,7 +1045,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1047,7 +1053,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1090,7 +1096,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1099,13 +1105,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1124,9 +1129,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1138,7 +1142,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1146,7 +1150,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1189,7 +1193,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1198,13 +1202,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1224,7 +1227,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1237,7 +1240,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1246,13 +1249,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1283,8 +1285,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1324,12 +1326,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1337,7 +1338,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1417,7 +1418,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1441,7 +1442,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1450,8 +1451,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1473,7 +1474,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1501,8 +1502,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1520,7 +1521,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1542,7 +1543,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1569,12 +1570,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1582,7 +1583,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1594,7 +1595,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1604,8 +1605,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1613,7 +1614,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1638,8 +1639,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1651,9 +1652,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1678,7 +1678,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1688,7 +1688,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1713,7 +1713,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1728,7 +1728,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1774,7 +1774,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1793,11 +1793,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1813,12 +1813,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1888,7 +1888,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1898,8 +1898,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1939,7 +1940,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1969,7 +1970,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1980,9 +1981,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2036,7 +2036,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2052,8 +2052,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2083,26 +2083,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2147,8 +2147,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2177,24 +2177,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2239,8 +2238,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2268,16 +2267,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2285,12 +2289,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2299,14 +2302,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2351,7 +2355,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2362,12 +2366,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2385,7 +2389,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2439,11 +2443,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2451,12 +2456,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2465,14 +2469,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2517,7 +2522,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2528,12 +2533,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2551,7 +2556,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2631,16 +2636,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2648,7 +2652,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2730,7 +2734,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2754,7 +2758,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2767,11 +2771,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2779,12 +2784,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2793,14 +2797,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2845,7 +2850,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2856,12 +2861,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2879,7 +2884,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2890,16 +2895,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2907,7 +2912,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2918,7 +2923,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2947,7 +2952,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2957,9 +2962,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2967,7 +2971,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -2997,7 +3001,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3027,25 +3031,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3089,8 +3095,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3118,23 +3124,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3178,8 +3185,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3206,10 +3213,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3232,7 +3243,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3261,8 +3272,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3294,19 +3304,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3314,11 +3324,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3327,14 +3337,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3379,7 +3389,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3390,12 +3400,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3413,7 +3422,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3484,16 +3493,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3510,9 +3519,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3520,7 +3528,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3602,7 +3610,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3626,7 +3634,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3640,7 +3648,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3648,9 +3656,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3679,14 +3686,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3696,7 +3703,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3709,7 +3716,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3784,7 +3791,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3815,7 +3822,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3900,14 +3907,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3937,19 +3944,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3978,19 +3985,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4012,9 +4019,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4022,7 +4028,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4104,7 +4110,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4128,7 +4134,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4141,8 +4147,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4157,7 +4163,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4171,7 +4177,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4188,11 +4194,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4230,15 +4236,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4254,7 +4260,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4270,6 +4276,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4296,7 +4306,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4306,9 +4316,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4316,7 +4325,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4351,7 +4360,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4361,7 +4370,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4376,9 +4385,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4386,7 +4394,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4468,7 +4476,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4492,7 +4500,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4506,14 +4514,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4527,14 +4535,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4542,11 +4550,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4555,14 +4563,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4607,7 +4615,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4618,12 +4626,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4641,7 +4648,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4743,8 +4750,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4849,8 +4856,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4858,14 +4866,49 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: |- + Enable or disable deleting repository references + by default this only... + type: boolean + includeEfs: + description: IncludeEfs we track deltas between repositories + on the operators ephemeral... + type: boolean + reconcileDirectoryChanges: + description: ReconcileDirectoryChanges will create and apply + mappings if your dynamic... + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4873,8 +4916,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4882,7 +4925,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4928,7 +4971,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4960,7 +5003,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4989,14 +5032,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5006,7 +5049,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5019,7 +5062,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5106,7 +5149,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5136,7 +5179,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5147,9 +5190,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5203,7 +5245,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5219,8 +5261,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5250,26 +5292,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5314,8 +5356,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5344,24 +5386,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5406,8 +5447,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5435,16 +5476,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5452,12 +5498,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5466,14 +5511,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5518,7 +5564,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5529,12 +5575,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5552,7 +5598,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5606,11 +5652,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5618,12 +5665,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5632,14 +5678,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5684,7 +5731,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5695,12 +5742,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5718,7 +5765,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5798,16 +5845,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5815,7 +5861,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5897,7 +5943,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5921,7 +5967,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5934,11 +5980,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5946,12 +5993,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5960,14 +6006,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6012,7 +6059,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6023,12 +6070,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6046,7 +6093,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6057,16 +6104,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6074,7 +6121,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6085,7 +6132,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6114,7 +6161,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6124,9 +6171,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6134,7 +6180,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6164,14 +6210,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6185,8 +6230,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6198,7 +6243,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6208,7 +6253,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6238,9 +6283,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6257,20 +6301,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6290,7 +6332,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6310,9 +6352,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6320,7 +6361,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6331,7 +6372,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6440,7 +6481,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6456,8 +6497,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6476,6 +6521,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6489,9 +6539,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6501,7 +6554,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6509,6 +6562,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object diff --git a/config/crd/bases/security.brcmlabs.com_l7apis.yaml b/config/crd/bases/security.brcmlabs.com_l7apis.yaml index 64d9a03e..df8026a7 100644 --- a/config/crd/bases/security.brcmlabs.com_l7apis.yaml +++ b/config/crd/bases/security.brcmlabs.com_l7apis.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7apis.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -24,11 +24,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -37,18 +37,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal diff --git a/config/crd/bases/security.brcmlabs.com_l7portals.yaml b/config/crd/bases/security.brcmlabs.com_l7portals.yaml index a7a3ab3c..756bd306 100644 --- a/config/crd/bases/security.brcmlabs.com_l7portals.yaml +++ b/config/crd/bases/security.brcmlabs.com_l7portals.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7portals.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -24,11 +24,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -49,7 +49,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -62,7 +62,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: diff --git a/config/crd/bases/security.brcmlabs.com_l7statestores.yaml b/config/crd/bases/security.brcmlabs.com_l7statestores.yaml index 579b20d2..3ec754e5 100644 --- a/config/crd/bases/security.brcmlabs.com_l7statestores.yaml +++ b/config/crd/bases/security.brcmlabs.com_l7statestores.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7statestores.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -21,11 +21,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -66,6 +66,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -80,6 +89,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true diff --git a/config/crd/bases/security.brcmlabs.com_repositories.yaml b/config/crd/bases/security.brcmlabs.com_repositories.yaml index 90d4907a..3a63e7fd 100644 --- a/config/crd/bases/security.brcmlabs.com_repositories.yaml +++ b/config/crd/bases/security.brcmlabs.com_repositories.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: repositories.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -28,11 +28,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -46,7 +46,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -83,7 +83,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -98,7 +98,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -107,12 +107,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -135,7 +136,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -147,14 +148,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -164,6 +162,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 0bca90eb..96780624 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -9,6 +9,18 @@ resources: - bases/security.brcmlabs.com_l7statestores.yaml #+kubebuilder:scaffold:crdkustomizeresource + +patches: + - path: patches/printercollumns_in_repositories.yaml + target: + kind: CustomResourceDefinition + name: repositories.security.brcmlabs.com + - path: patches/printercollumns_in_l7statestores.yaml + target: + kind: CustomResourceDefinition + name: l7statestores.security.brcmlabs.com + + patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD diff --git a/config/crd/patches/printercollumns_in_l7statestores.yaml b/config/crd/patches/printercollumns_in_l7statestores.yaml new file mode 100644 index 00000000..035bc76c --- /dev/null +++ b/config/crd/patches/printercollumns_in_l7statestores.yaml @@ -0,0 +1,7 @@ +# The following patch adds printer collumns to the repository CRD +- op: add + path: /spec/versions/0/additionalPrinterColumns + value: + - name: Ready + type: boolean + jsonPath: .status.ready \ No newline at end of file diff --git a/config/crd/patches/printercollumns_in_repositories.yaml b/config/crd/patches/printercollumns_in_repositories.yaml new file mode 100644 index 00000000..c0013657 --- /dev/null +++ b/config/crd/patches/printercollumns_in_repositories.yaml @@ -0,0 +1,23 @@ +# The following patch adds printer collumns to the repository CRD +- op: add + path: /spec/versions/0/additionalPrinterColumns + value: + - name: Ready + type: boolean + jsonPath: .status.ready + - name: Commit + type: string + description: checksum of content or git commit id + jsonPath: .status.commit + - name: Type + type: string + description: repository type + jsonPath: .spec.type + - name: Branch + type: string + description: Git Branch + jsonPath: .spec.branch + - name: Tag + type: string + description: checksum of content or git commit id + jsonPath: .spec.tag \ No newline at end of file diff --git a/config/cw-operator/manager.yaml b/config/cw-operator/manager.yaml index ecedfef3..3729edf9 100644 --- a/config/cw-operator/manager.yaml +++ b/config/cw-operator/manager.yaml @@ -73,7 +73,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/config/cw-rbac/role.yaml b/config/cw-rbac/role.yaml index abb909a8..a0b192f6 100644 --- a/config/cw-rbac/role.yaml +++ b/config/cw-rbac/role.yaml @@ -121,6 +121,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: diff --git a/config/manifests/bases/layer7-operator.clusterserviceversion.yaml b/config/manifests/bases/layer7-operator.clusterserviceversion.yaml index b838a68f..116471c7 100644 --- a/config/manifests/bases/layer7-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/layer7-operator.clusterserviceversion.yaml @@ -5,7 +5,7 @@ metadata: alm-examples: '[]' capabilities: Basic Install certified: "false" - containerImage: docker.io/caapim/layer7-operator:v1.2.1 + containerImage: docker.io/caapim/layer7-operator:v1.2.2 operatorframework.io/suggested-namespace: layer7-operator-system repository: github.com/caapim/layer7-operator support: Broadcom Community @@ -243,9 +243,6 @@ spec: to correctly displayName: State Store Synced path: stateStoreSynced - - description: StateStoreVersion tracks version in state store - displayName: State Store Version - path: stateStoreVersion - description: StorageSecretName is the Kubernetes Secret that this repository is stored in displayName: Storage Secret Name diff --git a/config/operator/manager.yaml b/config/operator/manager.yaml index 1168c04b..af0a914e 100644 --- a/config/operator/manager.yaml +++ b/config/operator/manager.yaml @@ -47,7 +47,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 8f9d9733..5d9b5ffb 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -121,6 +121,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: diff --git a/config/samples/security_v1_gateway.yaml b/config/samples/security_v1_gateway.yaml index 3365ee62..f27ee66e 100644 --- a/config/samples/security_v1_gateway.yaml +++ b/config/samples/security_v1_gateway.yaml @@ -5,7 +5,7 @@ metadata: # spec Gateway Spec spec: # version is the gateway version this operator has been validated against - version: "11.1.2" + version: "11.1.3" # license is reference to a Gateway v11.x license. license.accept must be set to true for the gateway to start. license: accept: false @@ -13,7 +13,7 @@ spec: # app contains gateway application and deployment level specifications app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 management: username: admin password: 7layer diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 5532cb98..80400590 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: gateways.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -27,11 +27,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -40,7 +40,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -52,10 +52,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -65,9 +65,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -93,9 +93,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -120,8 +120,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -131,9 +131,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -146,9 +145,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -174,9 +173,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -213,10 +212,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -232,7 +231,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -266,7 +265,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -274,7 +273,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -289,7 +288,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -322,14 +321,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -337,7 +336,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -347,12 +346,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -363,8 +362,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -398,7 +396,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -406,7 +404,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -420,8 +418,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -454,14 +451,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -476,10 +473,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -495,7 +492,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -529,7 +526,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -537,7 +534,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -552,7 +549,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -585,14 +582,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -600,7 +597,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -610,12 +607,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -626,8 +623,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -661,7 +657,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -669,7 +665,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -683,8 +679,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -717,14 +712,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -736,12 +731,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -753,7 +748,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -761,15 +756,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -794,9 +788,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -804,15 +806,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -837,9 +838,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -850,12 +859,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -872,7 +880,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -881,13 +889,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -908,7 +915,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -920,7 +927,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -928,7 +935,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -971,7 +978,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -980,13 +987,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1006,11 +1012,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1038,7 +1044,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1046,7 +1052,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1089,7 +1095,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1098,13 +1104,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1123,9 +1128,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1137,7 +1141,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1145,7 +1149,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1188,7 +1192,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1197,13 +1201,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1223,7 +1226,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1236,7 +1239,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1245,13 +1248,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1282,8 +1284,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1323,12 +1325,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1336,7 +1337,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1416,7 +1417,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1440,7 +1441,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1449,8 +1450,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1472,7 +1473,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1500,8 +1501,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1519,7 +1520,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1541,7 +1542,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1568,12 +1569,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1581,7 +1582,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1593,7 +1594,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1603,8 +1604,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1612,7 +1613,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1637,8 +1638,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1650,9 +1651,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1677,7 +1677,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1687,7 +1687,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1712,7 +1712,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1727,7 +1727,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1773,7 +1773,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1792,11 +1792,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1812,12 +1812,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1887,7 +1887,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1897,8 +1897,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1938,7 +1939,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1968,7 +1969,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1979,9 +1980,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2035,7 +2035,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2051,8 +2051,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2082,26 +2082,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2146,8 +2146,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2176,24 +2176,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2238,8 +2237,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2267,16 +2266,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2284,12 +2288,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2298,14 +2301,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2350,7 +2354,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2361,12 +2365,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2384,7 +2388,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2438,11 +2442,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2450,12 +2455,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2464,14 +2468,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2516,7 +2521,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2527,12 +2532,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2550,7 +2555,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2630,16 +2635,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2647,7 +2651,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2729,7 +2733,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2753,7 +2757,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2766,11 +2770,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2778,12 +2783,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2792,14 +2796,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2844,7 +2849,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2855,12 +2860,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2878,7 +2883,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2889,16 +2894,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2906,7 +2911,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2917,7 +2922,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2946,7 +2951,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2956,9 +2961,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2966,7 +2970,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -2996,7 +3000,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3026,25 +3030,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3088,8 +3094,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3117,23 +3123,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3177,8 +3184,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3205,10 +3212,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3231,7 +3242,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3260,8 +3271,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3293,19 +3303,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3313,11 +3323,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3326,14 +3336,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3378,7 +3388,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3389,12 +3399,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3412,7 +3421,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3483,16 +3492,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3509,9 +3518,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3519,7 +3527,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3601,7 +3609,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3625,7 +3633,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3639,7 +3647,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3647,9 +3655,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3678,14 +3685,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3695,7 +3702,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3708,7 +3715,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3783,7 +3790,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3814,7 +3821,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3899,14 +3906,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3936,19 +3943,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3977,19 +3984,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4011,9 +4018,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4021,7 +4027,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4103,7 +4109,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4127,7 +4133,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4140,8 +4146,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4156,7 +4162,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4170,7 +4176,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4187,11 +4193,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4229,15 +4235,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4253,7 +4259,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4269,6 +4275,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4295,7 +4305,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4305,9 +4315,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4315,7 +4324,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4350,7 +4359,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4360,7 +4369,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4375,9 +4384,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4385,7 +4393,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4467,7 +4475,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4491,7 +4499,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4505,14 +4513,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4526,14 +4534,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4541,11 +4549,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4554,14 +4562,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4606,7 +4614,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4617,12 +4625,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4640,7 +4647,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4742,8 +4749,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4848,8 +4855,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4857,14 +4865,49 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: |- + Enable or disable deleting repository references + by default this only... + type: boolean + includeEfs: + description: IncludeEfs we track deltas between repositories + on the operators ephemeral... + type: boolean + reconcileDirectoryChanges: + description: ReconcileDirectoryChanges will create and apply + mappings if your dynamic... + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4872,8 +4915,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4881,7 +4924,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4927,7 +4970,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4959,7 +5002,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4988,14 +5031,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5005,7 +5048,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5018,7 +5061,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5105,7 +5148,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5135,7 +5178,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5146,9 +5189,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5202,7 +5244,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5218,8 +5260,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5249,26 +5291,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5313,8 +5355,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5343,24 +5385,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5405,8 +5446,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5434,16 +5475,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5451,12 +5497,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5465,14 +5510,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5517,7 +5563,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5528,12 +5574,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5551,7 +5597,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5605,11 +5651,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5617,12 +5664,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5631,14 +5677,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5683,7 +5730,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5694,12 +5741,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5717,7 +5764,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5797,16 +5844,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5814,7 +5860,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5896,7 +5942,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5920,7 +5966,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5933,11 +5979,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5945,12 +5992,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5959,14 +6005,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6011,7 +6058,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6022,12 +6069,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6045,7 +6092,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6056,16 +6103,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6073,7 +6120,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6084,7 +6131,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6113,7 +6160,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6123,9 +6170,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6133,7 +6179,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6163,14 +6209,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6184,8 +6229,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6197,7 +6242,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6207,7 +6252,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6237,9 +6282,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6256,20 +6300,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6289,7 +6331,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6309,9 +6351,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6319,7 +6360,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6330,7 +6371,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6439,7 +6480,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6455,8 +6496,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6475,6 +6520,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6488,9 +6538,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6500,7 +6553,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6508,6 +6561,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object @@ -6529,7 +6585,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7apis.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6550,11 +6606,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6563,18 +6619,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal @@ -6680,9 +6736,6 @@ spec: items: properties: conditions: - description: |- - Ready bool `json:"ready,omitempty"` - LastUpdated string `js items: properties: action: @@ -6698,7 +6751,6 @@ spec: type: object type: array deployment: - description: Phase corev1.PodPhase `json:"phase,omitempty"` type: string name: type: string @@ -6717,7 +6769,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7portals.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6738,11 +6790,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6763,7 +6815,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -6776,7 +6828,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: @@ -6845,7 +6897,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7statestores.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6856,18 +6908,22 @@ spec: singular: l7statestore scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + name: v1alpha1 schema: openAPIV3Schema: description: L7StateStore is the Schema for the l7statestores API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6908,6 +6964,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -6922,6 +6987,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true @@ -6933,7 +7000,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: repositories.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6951,18 +7018,38 @@ spec: singular: repository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + - description: checksum of content or git commit id + jsonPath: .status.commit + name: Commit + type: string + - description: repository type + jsonPath: .spec.type + name: Type + type: string + - description: Git Branch + jsonPath: .spec.branch + name: Branch + type: string + - description: checksum of content or git commit id + jsonPath: .spec.tag + name: Tag + type: string + name: v1 schema: openAPIV3Schema: description: Repository is the Schema for the repositories API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6976,7 +7063,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -7013,7 +7100,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -7028,7 +7115,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -7037,12 +7124,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -7065,7 +7153,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -7077,14 +7165,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -7094,6 +7179,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true @@ -7265,6 +7352,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: @@ -7564,7 +7658,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/deploy/crd.yaml b/deploy/crd.yaml index b97a4943..0596a22c 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: gateways.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -27,11 +27,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -40,7 +40,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -52,10 +52,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -65,9 +65,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -93,9 +93,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -120,8 +120,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -131,9 +131,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -146,9 +145,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -174,9 +173,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -213,10 +212,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -232,7 +231,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -266,7 +265,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -274,7 +273,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -289,7 +288,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -322,14 +321,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -337,7 +336,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -347,12 +346,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -363,8 +362,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -398,7 +396,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -406,7 +404,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -420,8 +418,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -454,14 +451,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -476,10 +473,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -495,7 +492,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -529,7 +526,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -537,7 +534,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -552,7 +549,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -585,14 +582,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -600,7 +597,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -610,12 +607,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -626,8 +623,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -661,7 +657,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -669,7 +665,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -683,8 +679,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -717,14 +712,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -736,12 +731,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -753,7 +748,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -761,15 +756,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -794,9 +788,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -804,15 +806,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -837,9 +838,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -850,12 +859,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -872,7 +880,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -881,13 +889,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -908,7 +915,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -920,7 +927,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -928,7 +935,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -971,7 +978,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -980,13 +987,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1006,11 +1012,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1038,7 +1044,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1046,7 +1052,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1089,7 +1095,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1098,13 +1104,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1123,9 +1128,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1137,7 +1141,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1145,7 +1149,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1188,7 +1192,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1197,13 +1201,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1223,7 +1226,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1236,7 +1239,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1245,13 +1248,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1282,8 +1284,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1323,12 +1325,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1336,7 +1337,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1416,7 +1417,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1440,7 +1441,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1449,8 +1450,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1472,7 +1473,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1500,8 +1501,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1519,7 +1520,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1541,7 +1542,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1568,12 +1569,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1581,7 +1582,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1593,7 +1594,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1603,8 +1604,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1612,7 +1613,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1637,8 +1638,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1650,9 +1651,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1677,7 +1677,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1687,7 +1687,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1712,7 +1712,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1727,7 +1727,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1773,7 +1773,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1792,11 +1792,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1812,12 +1812,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1887,7 +1887,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1897,8 +1897,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1938,7 +1939,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1968,7 +1969,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1979,9 +1980,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2035,7 +2035,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2051,8 +2051,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2082,26 +2082,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2146,8 +2146,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2176,24 +2176,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2238,8 +2237,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2267,16 +2266,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2284,12 +2288,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2298,14 +2301,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2350,7 +2354,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2361,12 +2365,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2384,7 +2388,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2438,11 +2442,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2450,12 +2455,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2464,14 +2468,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2516,7 +2521,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2527,12 +2532,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2550,7 +2555,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2630,16 +2635,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2647,7 +2651,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2729,7 +2733,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2753,7 +2757,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2766,11 +2770,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2778,12 +2783,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2792,14 +2796,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2844,7 +2849,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2855,12 +2860,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2878,7 +2883,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2889,16 +2894,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2906,7 +2911,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2917,7 +2922,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2946,7 +2951,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2956,9 +2961,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2966,7 +2970,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -2996,7 +3000,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3026,25 +3030,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3088,8 +3094,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3117,23 +3123,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3177,8 +3184,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3205,10 +3212,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3231,7 +3242,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3260,8 +3271,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3293,19 +3303,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3313,11 +3323,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3326,14 +3336,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3378,7 +3388,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3389,12 +3399,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3412,7 +3421,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3483,16 +3492,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3509,9 +3518,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3519,7 +3527,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3601,7 +3609,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3625,7 +3633,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3639,7 +3647,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3647,9 +3655,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3678,14 +3685,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3695,7 +3702,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3708,7 +3715,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3783,7 +3790,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3814,7 +3821,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3899,14 +3906,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3936,19 +3943,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3977,19 +3984,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4011,9 +4018,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4021,7 +4027,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4103,7 +4109,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4127,7 +4133,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4140,8 +4146,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4156,7 +4162,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4170,7 +4176,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4187,11 +4193,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4229,15 +4235,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4253,7 +4259,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4269,6 +4275,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4295,7 +4305,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4305,9 +4315,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4315,7 +4324,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4350,7 +4359,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4360,7 +4369,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4375,9 +4384,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4385,7 +4393,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4467,7 +4475,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4491,7 +4499,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4505,14 +4513,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4526,14 +4534,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4541,11 +4549,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4554,14 +4562,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4606,7 +4614,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4617,12 +4625,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4640,7 +4647,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4742,8 +4749,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4848,8 +4855,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4857,14 +4865,49 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: |- + Enable or disable deleting repository references + by default this only... + type: boolean + includeEfs: + description: IncludeEfs we track deltas between repositories + on the operators ephemeral... + type: boolean + reconcileDirectoryChanges: + description: ReconcileDirectoryChanges will create and apply + mappings if your dynamic... + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4872,8 +4915,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4881,7 +4924,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4927,7 +4970,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4959,7 +5002,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4988,14 +5031,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5005,7 +5048,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5018,7 +5061,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5105,7 +5148,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5135,7 +5178,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5146,9 +5189,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5202,7 +5244,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5218,8 +5260,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5249,26 +5291,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5313,8 +5355,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5343,24 +5385,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5405,8 +5446,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5434,16 +5475,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5451,12 +5497,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5465,14 +5510,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5517,7 +5563,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5528,12 +5574,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5551,7 +5597,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5605,11 +5651,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5617,12 +5664,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5631,14 +5677,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5683,7 +5730,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5694,12 +5741,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5717,7 +5764,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5797,16 +5844,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5814,7 +5860,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5896,7 +5942,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5920,7 +5966,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5933,11 +5979,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5945,12 +5992,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5959,14 +6005,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6011,7 +6058,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6022,12 +6069,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6045,7 +6092,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6056,16 +6103,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6073,7 +6120,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6084,7 +6131,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6113,7 +6160,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6123,9 +6170,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6133,7 +6179,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6163,14 +6209,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6184,8 +6229,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6197,7 +6242,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6207,7 +6252,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6237,9 +6282,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6256,20 +6300,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6289,7 +6331,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6309,9 +6351,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6319,7 +6360,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6330,7 +6371,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6439,7 +6480,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6455,8 +6496,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6475,6 +6520,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6488,9 +6538,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6500,7 +6553,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6508,6 +6561,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object @@ -6529,7 +6585,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7apis.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6550,11 +6606,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6563,18 +6619,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal @@ -6631,6 +6687,28 @@ spec: type: array publishedTs: type: integer + securePasswordIdsForUndeployment: + items: + type: string + type: array + securePasswords: + items: + properties: + description: + type: string + id: + type: string + name: + type: string + value: + type: string + required: + - description + - id + - name + - value + type: object + type: array serviceId: type: string ssgServiceType: @@ -6657,13 +6735,22 @@ spec: gateways: items: properties: - checksum: - type: string + conditions: + items: + properties: + action: + type: string + actionTime: + type: string + checksum: + type: string + reason: + type: string + status: + type: string + type: object + type: array deployment: - description: Phase corev1. - type: string - lastUpdated: - description: Ready bool `json:"ready,omitempty"` type: string name: type: string @@ -6682,7 +6769,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7portals.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6703,11 +6790,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6728,7 +6815,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -6741,7 +6828,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: @@ -6810,7 +6897,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7statestores.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6821,18 +6908,22 @@ spec: singular: l7statestore scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + name: v1alpha1 schema: openAPIV3Schema: description: L7StateStore is the Schema for the l7statestores API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6873,6 +6964,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -6887,6 +6987,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true @@ -6898,7 +7000,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: repositories.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6916,18 +7018,38 @@ spec: singular: repository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + - description: checksum of content or git commit id + jsonPath: .status.commit + name: Commit + type: string + - description: repository type + jsonPath: .spec.type + name: Type + type: string + - description: Git Branch + jsonPath: .spec.branch + name: Branch + type: string + - description: checksum of content or git commit id + jsonPath: .spec.tag + name: Tag + type: string + name: v1 schema: openAPIV3Schema: description: Repository is the Schema for the repositories API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6941,7 +7063,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -6978,7 +7100,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -6993,7 +7115,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -7002,12 +7124,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -7030,7 +7153,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -7042,14 +7165,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -7059,6 +7179,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index dc9f3c92..1be27732 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -11,7 +11,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: gateways.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -36,11 +36,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -49,7 +49,7 @@ spec: properties: app: description: App contains application specific configuration for the - Gateway and its dep + Gateway and its... properties: affinity: description: Affinity is a group of affinity scheduling rules. @@ -61,10 +61,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: description: An empty preferred scheduling term matches - all objects with implicit weight + all objects with implicit... properties: preference: description: A node selector term, associated with @@ -74,9 +74,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -102,9 +102,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -129,8 +129,8 @@ spec: type: object x-kubernetes-map-type: atomic weight: - description: 'Weight associated with matching the - corresponding nodeSelectorTerm, in the ' + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the... format: int32 type: integer required: @@ -140,9 +140,8 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -155,9 +154,9 @@ spec: description: A list of node selector requirements by node's labels. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -183,9 +182,9 @@ spec: description: A list of node selector requirements by node's fields. items: - description: 'A node selector requirement - is a selector that contains values, a key, - and ' + description: A node selector requirement is + a selector that contains values, a key, + and... properties: key: description: The label key that the selector @@ -222,10 +221,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affini + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -241,7 +240,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -275,7 +274,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -283,7 +282,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -298,7 +297,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -331,14 +330,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -346,7 +345,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -356,12 +355,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - schedul + description: If the affinity requirements specified by + this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -372,8 +371,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -407,7 +405,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -415,7 +413,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -429,8 +427,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -463,14 +460,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -485,10 +482,10 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the anti-a + the... items: - description: 'The weights of all of the matched WeightedPodAffinityTerm - fields are added ' + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added... properties: podAffinityTerm: description: Required. A pod affinity term, associated @@ -504,7 +501,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -538,7 +535,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -546,7 +543,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -561,7 +558,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label key @@ -594,14 +591,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located - (affinity) or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -609,7 +606,7 @@ spec: weight: description: |- weight associated with matching the corresponding podAffinityTerm, - in the r + in the... format: int32 type: integer required: @@ -619,12 +616,12 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - sc + description: If the anti-affinity requirements specified + by this field are not met at... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to... properties: labelSelector: description: A label query over a set of resources, @@ -635,8 +632,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -670,7 +666,7 @@ spec: matchLabelKeys: description: |- MatchLabelKeys is a set of pod label keys to select which pods will - be take + be... items: type: string type: array @@ -678,7 +674,7 @@ spec: mismatchLabelKeys: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will - be t + be... items: type: string type: array @@ -692,8 +688,7 @@ spec: selector requirements. items: description: A label selector requirement - is a selector that contains values, a key, - and + is a selector that contains values, a key,... properties: key: description: key is the label key that @@ -726,14 +721,14 @@ spec: x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list - of namespace names that the term applies + of namespace names that the term... items: type: string type: array x-kubernetes-list-type: atomic topologyKey: - description: 'This pod should be co-located (affinity) - or not co-located (anti-affinity) ' + description: This pod should be co-located (affinity) + or not co-located (anti-affinity)... type: string required: - topologyKey @@ -745,12 +740,12 @@ spec: annotations: additionalProperties: type: string - description: 'Annotations for Operator managed resources, these - do not apply to services ' + description: Annotations for Operator managed resources, these + do not apply to services... type: object autoMountServiceAccountToken: description: AutoMountServiceAccountToken optionally adds the - Gateway Container's Kubern + Gateway Container's... type: boolean autoscaling: description: Autoscaling configuration for the Gateway @@ -762,7 +757,7 @@ spec: properties: behavior: description: HorizontalPodAutoscalerBehavior configures - the scaling behavior of the targ + the scaling behavior of the... properties: scaleDown: description: scaleDown is scaling policy for scaling @@ -770,15 +765,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -803,9 +797,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 scaleUp: description: scaleUp is scaling policy for scaling @@ -813,15 +815,14 @@ spec: properties: policies: description: policies is a list of potential scaling - polices which can be used during sc + polices which can be used during... items: description: HPAScalingPolicy is a single policy - which must hold true for a specified pa + which must hold true for a specified... properties: periodSeconds: description: periodSeconds specifies the - window of time for which the policy should - hold + window of time for which the policy should... format: int32 type: integer type: @@ -846,9 +847,17 @@ spec: type: string stabilizationWindowSeconds: description: stabilizationWindowSeconds is the - number of seconds for which past recommen + number of seconds for which past... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: tolerance is the tolerance on the + ratio between the current and desired... + 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 type: object maxReplicas: @@ -859,12 +868,11 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and + (only `type`... properties: containerResource: - description: |- - containerResource refers to a resource metric (such as those specified in - r + description: containerResource refers to a resource + metric (such as those specified in... properties: container: description: container is the name of the container @@ -881,7 +889,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -890,13 +898,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -917,7 +924,7 @@ spec: external: description: |- external refers to a global metric that is not associated - with any Kubernet + with any... properties: metric: description: metric identifies the target metric @@ -929,7 +936,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -937,7 +944,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -980,7 +987,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -989,13 +996,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1015,11 +1021,11 @@ spec: object: description: |- object refers to a metric describing a single kubernetes object - (for exampl + (for... properties: describedObject: description: describedObject specifies the descriptions - of a object,such as kind,name ap + of a object,such as kind,name... properties: apiVersion: description: apiVersion is the API version @@ -1047,7 +1053,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1055,7 +1061,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1098,7 +1104,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1107,13 +1113,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1132,9 +1137,8 @@ spec: - target type: object pods: - description: |- - pods refers to a metric describing each pod in the current scale target - (fo + description: pods refers to a metric describing + each pod in the current scale target... properties: metric: description: metric identifies the target metric @@ -1146,7 +1150,7 @@ spec: type: string selector: description: selector is the string-encoded - form of a standard kubernetes label selector + form of a standard kubernetes label... properties: matchExpressions: description: matchExpressions is a list @@ -1154,7 +1158,7 @@ spec: items: description: A label selector requirement is a selector that contains values, - a key, and + a key,... properties: key: description: key is the label @@ -1197,7 +1201,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1206,13 +1210,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1232,7 +1235,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests a + requests... properties: name: description: name is the name of the resource @@ -1245,7 +1248,7 @@ spec: averageUtilization: description: |- averageUtilization is the target value of the average of the - resource metri + resource... format: int32 type: integer averageValue: @@ -1254,13 +1257,12 @@ spec: - type: string description: |- averageValue is the target value of the average of the - metric across all re + metric across all... pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: description: type represents whether the - metric type is Utilization, Value, or - AverageVa + metric type is Utilization, Value, or... type: string value: anyOf: @@ -1291,8 +1293,8 @@ spec: type: object type: object bootstrap: - description: 'Bootstrap - optionally add a bootstrap script to - the Gateway that migrates ' + description: Bootstrap - optionally add a bootstrap script to + the Gateway that migrates... properties: script: description: BootstrapScript - enable/disable this functionality @@ -1332,12 +1334,11 @@ spec: type: array containerSecurityContext: description: SecurityContext holds security configuration that - will be applied to a cont + will be applied to a... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether a process + can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to use @@ -1345,7 +1346,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -1425,7 +1426,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -1449,7 +1450,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -1458,8 +1459,8 @@ spec: type: object type: object customConfig: - description: 'CustomConfig Certain folders on the Container Gateway - are not writeable by ' + description: CustomConfig Certain folders on the Container Gateway + are not writeable by... properties: enabled: description: Enabled or disabled @@ -1481,7 +1482,7 @@ spec: properties: item: description: ConfigRefItem is the key in the secret - or configmap to mount, path is where + or configmap to mount, path is... properties: key: type: string @@ -1509,8 +1510,8 @@ spec: type: boolean hostAliases: items: - description: 'HostAlias holds the mapping between IP and - hostnames that will be injected ' + description: HostAlias holds the mapping between IP and + hostnames that will be injected... properties: hostnames: description: Hostnames for the above IP address. @@ -1528,7 +1529,7 @@ spec: type: object cwp: description: ClusterProperties are key value pairs of additional - cluster-wide properties + cluster-wide... properties: enabled: description: Enabled bootstraps clusterProperties to the Gateway @@ -1550,7 +1551,7 @@ spec: externalCerts: items: description: ExternalCert is a reference to an existing TLS - or Opaque Secret in Kubernet + or Opaque Secret in... properties: enabled: description: Enabled or disabled @@ -1577,12 +1578,12 @@ spec: items: description: |- ExternalKey is a reference to an existing TLS Secret in Kubernetes - The Laye + The... properties: alias: description: |- Alias overrides the key name that is stored in the Gateway - This is useful f + This is useful... type: string enabled: description: Enabled or disabled @@ -1590,7 +1591,7 @@ spec: keyUsageType: description: |- KeyUsageType allows keys to be marked as special purpose - only one key usage + only one key... type: string name: description: Name of the kubernetes.io/tls Secret which @@ -1602,7 +1603,7 @@ spec: items: description: |- ExternalSecret is a reference to an existing secret in Kubernetes - The Layer + The... properties: description: description: Description given the Stored Password in the @@ -1612,8 +1613,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -1621,7 +1622,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -1646,8 +1647,8 @@ spec: my.hazelcast:5701 type: string external: - description: 'External set to true adds config for an external - Hazelcast instance to the ' + description: External set to true adds config for an external + Hazelcast instance to the... type: boolean type: object image: @@ -1659,9 +1660,8 @@ spec: type: string imagePullSecrets: items: - description: |- - LocalObjectReference contains enough information to let you locate the - refe + description: LocalObjectReference contains enough information + to let you locate the... properties: name: default: "" @@ -1686,7 +1686,7 @@ spec: routes: description: |- Routes for Openshift - This allows for customization of the default route and + This allows for customization of the default route... items: description: RouteSpec from https://pkg.go.dev/github. properties: @@ -1696,7 +1696,7 @@ spec: type: string port: description: RoutePort defines a port mapping from a - router to an endpoint in the servic + router to an endpoint in the... properties: targetPort: anyOf: @@ -1721,7 +1721,7 @@ spec: type: string destinationCACertificate: description: destinationCACertificate provides the - contents of the ca certificate of the + contents of the ca certificate of... type: string externalCertificate: description: externalCertificate provides certificate @@ -1736,7 +1736,7 @@ spec: x-kubernetes-map-type: atomic insecureEdgeTerminationPolicy: description: insecureEdgeTerminationPolicy indicates - the desired behavior for insecure c + the desired behavior for insecure... enum: - Allow - None @@ -1782,7 +1782,7 @@ spec: weight: default: 100 description: weight as an integer between 0 and - 256, default 100, that specifies the tar + 256, default 100, that specifies the... format: int32 maximum: 256 minimum: 0 @@ -1801,11 +1801,11 @@ spec: description: Rules items: description: IngressRule represents the rules mapping the - paths under a specified host t + paths under a specified host... properties: host: description: host is the fully qualified domain name - of a network host, as defined by RF + of a network host, as defined by... type: string http: description: HTTPIngressRuleValue is a list of http @@ -1821,12 +1821,12 @@ spec: backend: description: |- backend defines the referenced service endpoint to which the traffic - will b + will... properties: resource: - description: |- - resource is an ObjectRef to another Kubernetes resource in the namespace - of + description: resource is an ObjectRef + to another Kubernetes resource in the + namespace... properties: apiGroup: description: APIGroup is the group @@ -1896,7 +1896,7 @@ spec: description: TLS items: description: IngressTLS describes the transport layer security - associated with an ingres + associated with an... properties: hosts: description: hosts is a list of hosts included in the @@ -1906,8 +1906,9 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: "secretName is the name of the secret used - to terminate TLS traffic on\nport " + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port... type: string type: object type: array @@ -1947,7 +1948,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -1977,7 +1978,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -1988,9 +1989,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -2044,7 +2044,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2060,8 +2060,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -2091,26 +2091,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2155,8 +2155,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2185,24 +2185,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -2247,8 +2246,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -2276,16 +2275,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2293,12 +2297,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2307,14 +2310,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2359,7 +2363,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2370,12 +2374,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2393,7 +2397,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2447,11 +2451,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2459,12 +2464,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2473,14 +2477,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2525,7 +2530,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2536,12 +2541,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2559,7 +2564,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2639,16 +2644,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -2656,7 +2660,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -2738,7 +2742,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -2762,7 +2766,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -2775,11 +2779,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -2787,12 +2792,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -2801,14 +2805,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -2853,7 +2858,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -2864,12 +2869,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -2887,7 +2892,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -2898,16 +2903,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -2915,7 +2920,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -2926,7 +2931,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -2955,7 +2960,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -2965,9 +2970,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -2975,7 +2979,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -3005,7 +3009,7 @@ spec: calculate: description: |- Calculate the JVMHeap size based on resource requests and limits - if resourc + if... type: boolean default: description: Default Heap Size to use if calculate is @@ -3035,25 +3039,27 @@ spec: type: object lifecycleHooks: description: Lifecycle describes actions that the management system - should take in respo + should take in... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3097,8 +3103,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3126,23 +3132,24 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a container + is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the + container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -3186,8 +3193,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that the container - should sleep before being ' + description: Sleep represents a duration that the container + should sleep. properties: seconds: description: Seconds is the number of seconds to sleep. @@ -3214,10 +3221,14 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be sent + to a container when it is... + type: string type: object listenPorts: - description: 'ListenPorts The Layer7 Gateway instantiates the - following HTTP(s) ports by ' + description: ListenPorts The Layer7 Gateway instantiates the following + HTTP(s) ports by... properties: custom: description: CustomListenPort - enable/disable custom listen @@ -3240,7 +3251,7 @@ spec: managementFeatures: description: |- ManagementFeatures that should be available on this port - - Published servic + - Published... items: type: string type: array @@ -3269,8 +3280,7 @@ spec: description: Tls configuration for Gateway Ports properties: cipherSuites: - description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t- - TLS_ECDHE_ECDSA_WI" + description: "CipherSuites\n\t- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t-..." items: type: string type: array @@ -3302,19 +3312,19 @@ spec: refreshOnKeyChanges: description: |- Refresh on Key Changes - If harden is true, the auto generated port bundle wi + If harden is true, the auto generated port bundle... type: boolean type: object livenessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -3322,11 +3332,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -3335,14 +3345,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -3387,7 +3397,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -3398,12 +3408,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -3421,7 +3430,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -3492,16 +3501,16 @@ spec: disabled: description: |- The Container Gateway uses diskless config by default - Disabling it will swi + Disabling it will... type: boolean type: object graphman: description: Graphman is a GraphQL Gateway Management interface - that can be automaticall + that can be... properties: dynamicSyncPort: description: DynamicSyncPort is the Port the Gateway controller - uses to apply dynamic re + uses to apply dynamic... type: integer enabled: description: Enabled optionally bootstrap the GraphQL @@ -3518,9 +3527,8 @@ spec: description: ContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -3528,7 +3536,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -3610,7 +3618,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -3634,7 +3642,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -3648,7 +3656,7 @@ spec: type: string restman: description: Restman is a Gateway Management interface that - can be automatically provisi + can be automatically... properties: enabled: description: Enabled optionally bootstrap the Restman @@ -3656,9 +3664,8 @@ spec: type: boolean type: object secretName: - description: |- - SecretName is reference to an existing secret that contains - SSG_ADMIN_USERN + description: SecretName is reference to an existing secret + that contains... type: string service: description: Service is the Gateway Management Service @@ -3687,14 +3694,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how - nodes distribute service traffic + nodes distribute service... type: string ipFamilies: items: @@ -3704,7 +3711,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -3717,7 +3724,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -3792,7 +3799,7 @@ spec: enabled: description: |- Enable or disable setting resource attributes - when enabled the following va + when enabled the following... type: boolean type: object type: object @@ -3823,7 +3830,7 @@ spec: existingSecret: description: |- ExistingSecret containing database credentials - The following keys can be se + The following keys can be... type: string gateway: description: GatewayUser configured in the Gateway @@ -3908,14 +3915,14 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnly: @@ -3945,19 +3952,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlClientReadOnlyConnectionName: description: SqlClientReadOnlyConnectionName for the JDBC - or Cassandra Connection Gatewa + or Cassandra Connection... type: string sqlReadOnly: description: SqlReadOnly configuration @@ -3986,19 +3993,19 @@ spec: jdbcDriverClass: description: |- JDBCDriverClass to use in the Gateway JDBC Connection entity - defaults to co + defaults to... type: string jdbcUrl: description: JDBCUrl for the OTK type: string manageSchema: - description: 'ManageSchema appends an additional initContainer - for the OTK that connects ' + description: ManageSchema appends an additional initContainer + for the OTK that connects... type: boolean type: object sqlReadOnlyConnectionName: description: SqlReadOnlyConnectionName for the JDBC or - Cassandra Connection Gateway enti + Cassandra Connection Gateway... type: string type: description: Type of OTK Database @@ -4020,9 +4027,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4030,7 +4036,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4112,7 +4118,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4136,7 +4142,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4149,8 +4155,8 @@ spec: port type: integer internalGatewayReference: - description: 'InternalOtkGatewayReference to an Operator managed - Gateway deployment that ' + description: InternalOtkGatewayReference to an Operator managed + Gateway deployment that... type: string maintenanceTasks: description: MaintenanceTasks for the OTK database are disabled @@ -4165,7 +4171,7 @@ spec: properties: bootstrapDirectory: description: BootstrapDirectory that is used for the initContainer - the default is /opt/S + the default is... type: string createTestClients: description: CreateTestClients for mysql & oracle setup @@ -4179,7 +4185,7 @@ spec: type: boolean managePostInstallPolicies: description: ManagePostInstallConfig represent post-installation - tasks required for inte + tasks required for... type: boolean skipInternalServerTools: description: |- @@ -4196,11 +4202,11 @@ spec: type: integer runtimeSyncIntervalSeconds: description: RuntimeSyncIntervalSeconds how often OTK Gateways - should be updated in inte + should be updated in... type: integer subSolutionKitNames: description: A list of subSolutionKitNames - all,internal - or dmz cover the primary use c + or dmz cover the primary use... items: type: string type: array @@ -4238,15 +4244,15 @@ spec: type: object podSecurityContext: description: PodSecurityContext holds pod-level security attributes - and common container + and common... properties: appArmorProfile: description: appArmorProfile is the AppArmor options to use - by the containers in this po + by the containers in this... properties: localhostProfile: description: localhostProfile indicates a profile loaded - on the node that should be used + on the node that should be... type: string type: description: type indicates which kind of AppArmor profile @@ -4262,7 +4268,7 @@ spec: type: integer fsGroupChangePolicy: description: fsGroupChangePolicy defines behavior of changing - ownership and permission o + ownership and permission... type: string runAsGroup: description: The GID to run the entrypoint of the container @@ -4278,6 +4284,10 @@ spec: process. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied... + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -4304,7 +4314,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile defined - in a file on the node should b + in a file on the node should... type: string type: description: type indicates which kind of seccomp profile @@ -4314,9 +4324,8 @@ spec: - type type: object supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - add + description: A list of groups applied to the first process + run in each container, in... items: format: int64 type: integer @@ -4324,7 +4333,7 @@ spec: x-kubernetes-list-type: atomic supplementalGroupsPolicy: description: Defines how supplemental groups of the first - container processes are calcul + container processes are... type: string sysctls: description: Sysctls hold a list of namespaced sysctls used @@ -4359,7 +4368,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' con + be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4369,7 +4378,7 @@ spec: type: object portalReference: description: PortalReference is for bulk syncing of Portal APIs - via initContainer (boots + via initContainer... properties: enabled: description: Enable or disable the Portal reference @@ -4384,9 +4393,8 @@ spec: description: InitContainerSecurityContext properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options to @@ -4394,7 +4402,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -4476,7 +4484,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -4500,7 +4508,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4514,14 +4522,14 @@ spec: type: object preStopScript: description: PreStopScript During upgrades and other events where - Gateway pods are repla + Gateway pods are... properties: enabled: description: Enabled or disabled type: boolean excludedPorts: description: ExcludedPorts is an array of port numbers, if - not set the defaults are 8777 + not set the defaults are... items: type: integer type: array @@ -4535,14 +4543,14 @@ spec: type: object readinessProbe: description: Probe describes a health check to be performed against - a container to deter + a container to... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in the container. properties: command: description: Command is the command line to execute inside - the container, the working di + the container, the working... items: type: string type: array @@ -4550,11 +4558,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe to - be considered failed after ha + be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number must @@ -4563,14 +4571,14 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service to place + in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to perform. properties: host: description: Host name to connect to, defaults to the @@ -4615,7 +4623,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has started - before liveness probes ar + before liveness probes... format: int32 type: integer periodSeconds: @@ -4626,12 +4634,11 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe to - be considered successful aft + be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. + description: TCPSocket specifies a connection to a TCP port. properties: host: description: 'Optional: Host name to connect to, defaults @@ -4649,7 +4656,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs to - terminate gracefully upon pro + terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -4751,8 +4758,8 @@ spec: type: object type: array certs: - description: 'CertSecrets provides a way to mount secrets - that contains certificates for ' + description: CertSecrets provides a way to mount secrets that + contains certificates for... items: properties: enabled: @@ -4857,8 +4864,9 @@ spec: description: Enable or disable a Redis integration type: boolean existingSecret: - description: "ExistingSecret mounts an existing secret containing - redis configuration\nto " + description: |- + ExistingSecret mounts an existing secret containing redis configuration + to... type: string type: object replicas: @@ -4866,14 +4874,49 @@ spec: enabled format: int32 type: integer + repositoryReferenceBootstrap: + description: BootstrapRepositoryReferences bootstraps repositoryReferences + of type... + properties: + enabled: + description: Enable or disable bootstrapping repository references + type: boolean + preferGit: + description: If a L7StateStore is configured the initContainer + will default to... + type: boolean + type: object + repositoryReferenceDelete: + description: RepositoryReferenceDelete enables repository delete + when a... + properties: + enabled: + description: |- + Enable or disable deleting repository references + by default this only... + type: boolean + includeEfs: + description: IncludeEfs we track deltas between repositories + on the operators ephemeral... + type: boolean + reconcileDirectoryChanges: + description: ReconcileDirectoryChanges will create and apply + mappings if your dynamic... + type: boolean + reconcileReferences: + description: ReconcileReferences resets the commits for all + other repositories that... + type: boolean + type: object repositoryReferences: items: - description: 'RepositoryReference is reference to a Git repository - or HTTP endpoint that ' + description: RepositoryReference is reference to a Git repository + or HTTP endpoint that... properties: directories: - description: "Directories from the remote repository to - sync with the Gateway\nLimited to " + description: |- + Directories from the remote repository to sync with the Gateway + Limited to... items: type: string type: array @@ -4881,8 +4924,8 @@ spec: description: Enabled or disabled type: boolean encryption: - description: 'BundleEncryption allows setting an encryption - passphrase per repository or ' + description: BundleEncryption allows setting an encryption + passphrase per repository or... properties: existingSecret: description: ExistingSecret - reference to an existing @@ -4890,7 +4933,7 @@ spec: type: string key: description: Key - the key in the kubernetes secret - that the encryption passphrase is st + that the encryption passphrase is... type: string passphrase: description: Passphrase - bundle encryption passphrase @@ -4936,7 +4979,7 @@ spec: type: description: |- Type static or dynamic - static repositories are bootstrapped to the containe + static repositories are bootstrapped to the... type: string required: - enabled @@ -4968,7 +5011,7 @@ spec: type: object restartOnConfigChange: description: RestartOnConfigChange restarts the Gateway if the - default configmaps are up + default configmaps are... type: boolean service: description: Service @@ -4997,14 +5040,14 @@ spec: type: string externalTrafficPolicy: description: ServiceExternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string healthCheckNodePort: format: int32 type: integer internalTrafficPolicy: description: ServiceInternalTrafficPolicy describes how nodes - distribute service traffic + distribute service... type: string ipFamilies: items: @@ -5014,7 +5057,7 @@ spec: type: array ipFamilyPolicy: description: IPFamilyPolicy represents the dual-stack-ness - requested or required by a Se + requested or required by a... type: string loadBalancerClass: type: string @@ -5027,7 +5070,7 @@ spec: ports: description: |- Ports exposed by the Service - These are appended to the Gateway deployment c + These are appended to the Gateway deployment... items: description: Ports properties: @@ -5114,7 +5157,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined e + using the previously defined... type: string valueFrom: description: Source for the environment variable's @@ -5144,7 +5187,7 @@ spec: properties: apiVersion: description: Version of the schema the FieldPath - is written in terms of, defaults to "v1 + is written in terms of, defaults to... type: string fieldPath: description: Path of the field to select in @@ -5155,9 +5198,8 @@ spec: type: object x-kubernetes-map-type: atomic resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (li + description: 'Selects a resource of the container: + only resources limits and requests...' properties: containerName: description: 'Container name: required for @@ -5211,7 +5253,7 @@ spec: in the container. items: description: EnvFromSource represents the source of a - set of ConfigMaps + set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5227,8 +5269,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. + description: Optional text to prepend to the name + of each environment variable. type: string secretRef: description: The Secret to select from @@ -5258,26 +5300,26 @@ spec: type: string lifecycle: description: Actions that the management system should take - in response to container lif + in response to container... properties: postStart: description: PostStart is called immediately after a container is created. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5322,8 +5364,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5352,24 +5394,23 @@ spec: type: object type: object preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - AP + description: PreStop is called immediately before a + container is terminated due to an... properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute + in the container. properties: command: description: Command is the command line to - execute inside the container, the working - di + execute inside the container, the working... items: type: string type: array x-kubernetes-list-type: atomic type: object httpGet: - description: HTTPGet specifies the http request + description: HTTPGet specifies an HTTP GET request to perform. properties: host: @@ -5414,8 +5455,8 @@ spec: - port type: object sleep: - description: 'Sleep represents the duration that - the container should sleep before being ' + description: Sleep represents a duration that the + container should sleep. properties: seconds: description: Seconds is the number of seconds @@ -5443,16 +5484,21 @@ spec: - port type: object type: object + stopSignal: + description: StopSignal defines which signal will be + sent to a container when it is... + type: string type: object livenessProbe: description: Periodic probe of container liveness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5460,12 +5506,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5474,14 +5519,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5526,7 +5572,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5537,12 +5583,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5560,7 +5606,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5614,11 +5660,12 @@ spec: description: Periodic probe of container service readiness. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5626,12 +5673,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5640,14 +5686,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -5692,7 +5739,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -5703,12 +5750,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -5726,7 +5773,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -5806,16 +5853,15 @@ spec: type: object restartPolicy: description: RestartPolicy defines the restart behavior - of individual containers in a po + of individual containers in a... type: string securityContext: description: SecurityContext defines the security options - the container should be run wi + the container should be run... properties: allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privilege + description: AllowPrivilegeEscalation controls whether + a process can gain more... type: boolean appArmorProfile: description: appArmorProfile is the AppArmor options @@ -5823,7 +5869,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - loaded on the node that should be used + loaded on the node that should be... type: string type: description: type indicates which kind of AppArmor @@ -5905,7 +5951,7 @@ spec: properties: localhostProfile: description: localhostProfile indicates a profile - defined in a file on the node should b + defined in a file on the node should... type: string type: description: type indicates which kind of seccomp @@ -5929,7 +5975,7 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' con + should be run as a 'Host Process'... type: boolean runAsUserName: description: The UserName in Windows to run the @@ -5942,11 +5988,12 @@ spec: initialized. properties: exec: - description: Exec specifies the action to take. + description: Exec specifies a command to execute in + the container. properties: command: description: Command is the command line to execute - inside the container, the working di + inside the container, the working... items: type: string type: array @@ -5954,12 +6001,11 @@ spec: type: object failureThreshold: description: Minimum consecutive failures for the probe - to be considered failed after ha + to be considered failed after... format: int32 type: integer grpc: - description: GRPC specifies an action involving a GRPC - port. + description: GRPC specifies a GRPC HealthCheckRequest. properties: port: description: Port number of the gRPC service. Number @@ -5968,14 +6014,15 @@ spec: type: integer service: default: "" - description: | - Service is the name of the service to place in the gRPC HealthCheckRequest + description: Service is the name of the service + to place in the gRPC HealthCheckRequest... type: string required: - port type: object httpGet: - description: HTTPGet specifies the http request to perform. + description: HTTPGet specifies an HTTP GET request to + perform. properties: host: description: Host name to connect to, defaults to @@ -6020,7 +6067,7 @@ spec: type: object initialDelaySeconds: description: Number of seconds after the container has - started before liveness probes ar + started before liveness probes... format: int32 type: integer periodSeconds: @@ -6031,12 +6078,12 @@ spec: type: integer successThreshold: description: Minimum consecutive successes for the probe - to be considered successful aft + to be considered successful... format: int32 type: integer tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. + description: TCPSocket specifies a connection to a TCP + port. properties: host: description: 'Optional: Host name to connect to, @@ -6054,7 +6101,7 @@ spec: type: object terminationGracePeriodSeconds: description: Optional duration in seconds the pod needs - to terminate gracefully upon pro + to terminate gracefully upon... format: int64 type: integer timeoutSeconds: @@ -6065,16 +6112,16 @@ spec: type: integer type: object stdin: - description: 'Whether this container should allocate a buffer - for stdin in the container ' + description: Whether this container should allocate a buffer + for stdin in the container... type: boolean stdinOnce: description: Whether the container runtime should close - the stdin channel after it has b + the stdin channel after it has... type: boolean terminationMessagePath: description: 'Optional: Path at which the file to which - the container''s termination messa' + the container''s termination...' type: string terminationMessagePolicy: description: Indicate how the termination message should @@ -6082,7 +6129,7 @@ spec: type: string tty: description: Whether this container should allocate a TTY - for itself, also requires 'std + for itself, also requires... type: boolean volumeDevices: description: volumeDevices is the list of block devices @@ -6093,7 +6140,7 @@ spec: properties: devicePath: description: devicePath is the path inside of the - container that the device will be mapp + container that the device will be... type: string name: description: name must match the name of a persistentVolumeClaim @@ -6122,7 +6169,7 @@ spec: mountPropagation: description: |- mountPropagation determines how mounts are propagated from the host - to cont + to... type: string name: description: This must match the Name of a Volume. @@ -6132,9 +6179,8 @@ spec: otherwise (false or unspecified). type: boolean recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recu + description: RecursiveReadOnly specifies whether read-only + mounts should be handled... type: string subPath: description: Path within the volume from which the @@ -6142,7 +6188,7 @@ spec: type: string subPathExpr: description: Expanded path within the volume from - which the container's volume should be + which the container's volume should... type: string required: - mountPath @@ -6172,14 +6218,13 @@ spec: type: object terminationGracePeriodSeconds: description: TerminationGracePeriodSeconds is the time kubernetes - will wait for the Gate + will wait for the... format: int64 type: integer tolerations: items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the + description: The pod this Toleration is attached to tolerates + any taint that matches... properties: effect: description: Effect indicates the taint effect to match. @@ -6193,8 +6238,8 @@ spec: the value. type: string tolerationSeconds: - description: 'TolerationSeconds represents the period of - time the toleration (which must ' + description: TolerationSeconds represents the period of + time the toleration (which must... format: int64 type: integer value: @@ -6206,7 +6251,7 @@ spec: topologySpreadConstraints: items: description: TopologySpreadConstraint specifies how to spread - matching pods among the gi + matching pods among the... properties: labelSelector: description: LabelSelector is used to find matching pods. @@ -6216,7 +6261,7 @@ spec: requirements. items: description: A label selector requirement is a selector - that contains values, a key, and + that contains values, a key,... properties: key: description: key is the label key that the selector @@ -6246,9 +6291,8 @@ spec: type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spr + description: MatchLabelKeys is a set of pod label keys to + select the pods over which... items: type: string type: array @@ -6265,20 +6309,18 @@ spec: type: integer nodeAffinityPolicy: description: NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelec + Pod's... type: string nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - p + description: NodeTaintsPolicy indicates how we will treat + node taints when calculating... type: string topologyKey: description: TopologyKey is the key of node labels. type: string whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - th + description: WhenUnsatisfiable indicates how to deal with + a pod if it doesn't satisfy... type: string required: - maxSkew @@ -6298,7 +6340,7 @@ spec: - type: integer - type: string description: The maximum number of pods that can be scheduled - above the desired number o + above the desired number... x-kubernetes-int-or-string: true maxUnavailable: anyOf: @@ -6318,9 +6360,8 @@ spec: accept: type: boolean secretName: - description: |- - SecretName is the Kubernetes Secret that contains the Gateway license - There + description: SecretName is the Kubernetes Secret that contains + the Gateway license... type: string required: - accept @@ -6328,7 +6369,7 @@ spec: type: object version: description: Version references the Gateway release that this Operator - is intended to be + is intended to... type: string required: - app @@ -6339,7 +6380,7 @@ spec: properties: PortalSyncStatus: description: PortalSyncStatus tracks the status of which portals are - synced with a gatew + synced with a... properties: apiCount: description: ApiCount is number of APIs that are related to the @@ -6448,7 +6489,7 @@ spec: type: array managementPod: description: Management Pod is a Gateway with a special annotation - is used as a selector + is used as a... type: string phase: description: PodPhase is a label for the condition of a pod at the @@ -6464,8 +6505,12 @@ spec: repositoryStatus: items: description: GatewayRepositoryStatus tracks the status of which - Graphman repositories ha + Graphman repositories... properties: + authType: + description: AuthType defaults to basic, possible options are + none, basic or ssh + type: string branch: description: Branch of the Git repo type: string @@ -6484,6 +6529,11 @@ spec: type: string type: object type: array + directories: + description: Directories + items: + type: string + type: array enabled: description: Enabled shows whether or not this repository reference is enabled @@ -6497,9 +6547,12 @@ spec: remoteName: description: RemoteName type: string + repoType: + description: RepoType - git, http, local, statestore + type: string secretName: description: SecretName is used to mount the correct repository - secret to the initContai + secret to the... type: string stateStoreKey: description: StateStoreKey @@ -6509,7 +6562,7 @@ spec: type: string storageSecretName: description: StorageSecretName is used to mount existing repository - bundles to the initC + bundles to the... type: string tag: description: Tag is the git tag in the Git repo @@ -6517,6 +6570,9 @@ spec: type: description: Type is static or dynamic type: string + vendor: + description: Vendor i.e. Github, Gitlab, BitBucket, Azure + type: string required: - enabled type: object @@ -6539,7 +6595,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7apis.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6560,11 +6616,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6573,18 +6629,18 @@ spec: properties: deploymentTags: description: DeploymentTags target Gateway deployments that this API - should be published + should be... items: type: string type: array graphmanBundle: description: |- GraphmanBundle associated with this API - currently limited to Service and Fr + currently limited to Service and... type: string l7Portal: description: L7Portal is the L7Portal that this API is associated - with when Portal Publi + with when Portal... type: string portalMeta: description: PortalMeta is reserved for the API Developer Portal @@ -6641,6 +6697,28 @@ spec: type: array publishedTs: type: integer + securePasswordIdsForUndeployment: + items: + type: string + type: array + securePasswords: + items: + properties: + description: + type: string + id: + type: string + name: + type: string + value: + type: string + required: + - description + - id + - name + - value + type: object + type: array serviceId: type: string ssgServiceType: @@ -6667,13 +6745,22 @@ spec: gateways: items: properties: - checksum: - type: string + conditions: + items: + properties: + action: + type: string + actionTime: + type: string + checksum: + type: string + reason: + type: string + status: + type: string + type: object + type: array deployment: - description: Phase corev1. - type: string - lastUpdated: - description: Ready bool `json:"ready,omitempty"` type: string name: type: string @@ -6693,7 +6780,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7portals.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6714,11 +6801,11 @@ spec: properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6739,7 +6826,7 @@ spec: type: object deploymentTags: description: Deployment Tags - determines which Gateway deployments - these APIs will be a + these APIs will be... items: type: string type: array @@ -6752,7 +6839,7 @@ spec: type: string enrollmentBundle: description: EnrollmentBundle - allows a custom enrollment bundle - to be set in the Porta + to be set in the... type: string labels: additionalProperties: @@ -6822,7 +6909,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: l7statestores.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6833,18 +6920,22 @@ spec: singular: l7statestore scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + name: v1alpha1 schema: openAPIV3Schema: description: L7StateStore is the Schema for the l7statestores API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6885,6 +6976,15 @@ spec: type: object storeId: type: string + tls: + properties: + enabled: + type: boolean + redisCrt: + type: string + verifyPeer: + type: boolean + type: object type: type: string username: @@ -6899,6 +6999,8 @@ spec: properties: ready: type: boolean + required: + - ready type: object type: object served: true @@ -6911,7 +7013,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: layer7-operator-system/layer7-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.16.5 + controller-gen.kubebuilder.io/version: v0.19.0 name: repositories.security.brcmlabs.com spec: group: security.brcmlabs.com @@ -6929,18 +7031,38 @@ spec: singular: repository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .status.ready + name: Ready + type: boolean + - description: checksum of content or git commit id + jsonPath: .status.commit + name: Commit + type: string + - description: repository type + jsonPath: .spec.type + name: Type + type: string + - description: Git Branch + jsonPath: .spec.branch + name: Branch + type: string + - description: checksum of content or git commit id + jsonPath: .spec.tag + name: Tag + type: string + name: v1 schema: openAPIV3Schema: description: Repository is the Schema for the repositories API properties: apiVersion: description: APIVersion defines the versioned schema of this representation - of an object + of an... type: string kind: description: Kind is a string value representing the REST resource this - object represent + object... type: string metadata: type: object @@ -6954,7 +7076,7 @@ spec: type: object auth: description: Auth contains a reference to the credentials required - to connect to your Gi + to connect to your... properties: existingSecretName: description: ExistingSecretName reference an existing secret @@ -6991,7 +7113,7 @@ spec: branch: description: |- Branch - specify which branch to clone - if branch and tag are both specified + if branch and tag are both... type: string enabled: description: Enabled - if enabled this repository will be synced @@ -7006,7 +7128,7 @@ spec: type: object localReference: description: LocalReference lets the Repository controller use a local - Kubernetes Secret + Kubernetes... properties: secretName: type: string @@ -7015,12 +7137,13 @@ spec: description: Remote Name - defaults to "origin" type: string stateStoreKey: - description: "StateStoreKey where the repository is stored in the - L7StateStore\nthis only " + description: |- + StateStoreKey where the repository is stored in the L7StateStore + this only... type: string stateStoreReference: description: StateStoreReference which L7StateStore connection should - be used to store o + be used to store... type: string sync: description: RepositorySyncConfig defines how often this repository @@ -7043,7 +7166,7 @@ spec: properties: commit: description: Commit is either current git commit that has been synced - or a sha1sum of th + or a sha1sum of... type: string lastAppliedSummary: type: string @@ -7055,14 +7178,11 @@ spec: type: boolean stateStoreSynced: description: StateStoreSynced whether or not the state store has been - written to correct + written to... type: boolean - stateStoreVersion: - description: StateStoreVersion tracks version in state store - type: integer storageSecretName: description: StorageSecretName is the Kubernetes Secret that this - repository is stored i + repository is stored... type: string summary: type: string @@ -7072,6 +7192,8 @@ spec: type: string vendor: type: string + required: + - stateStoreSynced type: object type: object served: true @@ -7245,6 +7367,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: @@ -7583,7 +7712,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/deploy/cw-operator.yaml b/deploy/cw-operator.yaml index 49e5472c..3c89262e 100644 --- a/deploy/cw-operator.yaml +++ b/deploy/cw-operator.yaml @@ -88,7 +88,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/deploy/cw-rbac.yaml b/deploy/cw-rbac.yaml index bfd46684..74795c97 100644 --- a/deploy/cw-rbac.yaml +++ b/deploy/cw-rbac.yaml @@ -164,6 +164,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: diff --git a/deploy/gateway.yaml b/deploy/gateway.yaml index 78c76dd6..59d1d327 100644 --- a/deploy/gateway.yaml +++ b/deploy/gateway.yaml @@ -4,7 +4,7 @@ metadata: name: ssg spec: app: - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 management: cluster: hostname: gateway.brcmlabs.com @@ -26,7 +26,7 @@ spec: license: accept: false secretName: gateway-license - version: 11.1.2 + version: 11.1.3 status: {} --- apiVersion: security.brcmlabs.com/v1 diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 28ac65dd..8baf701d 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -80,7 +80,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 512Mi requests: cpu: 100m memory: 64Mi diff --git a/deploy/rbac.yaml b/deploy/rbac.yaml index 946d3b51..ccc3d785 100644 --- a/deploy/rbac.yaml +++ b/deploy/rbac.yaml @@ -162,6 +162,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: diff --git a/docs/gateway.md b/docs/gateway.md index 53c81554..cd245c6b 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -426,6 +426,22 @@ alive or ready to receive traffic.
Format: int32
false + + repositoryReferenceBootstrap + object + + BootstrapRepositoryReferences bootstraps repositoryReferences of type dynamic to avoid service unavailable at gateway ready.
+ + false + + repositoryReferenceDelete + object + + RepositoryReferenceDelete enables repository delete when a repositoryReference is disabled or removed. +To avoid potential conflicts the current gateway state is reset by reapplying all other repository references post +delete
+ + false repositoryReferences []object @@ -1063,8 +1079,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. -Also, matchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, matchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1078,8 +1093,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. -Also, mismatchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1327,8 +1341,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. -Also, matchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, matchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1342,8 +1355,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. -Also, mismatchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1671,8 +1683,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. -Also, matchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, matchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1686,8 +1697,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. -Also, mismatchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1935,8 +1945,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. -Also, matchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, matchLabelKeys cannot be set when labelSelector isn't set.
false @@ -1950,8 +1959,7 @@ to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. -Also, mismatchLabelKeys cannot be set when labelSelector isn't set. -This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
+Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
false @@ -2301,7 +2309,9 @@ the last 300sec is used). []object policies is a list of potential scaling polices which can be used during scaling. -At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid
+If not set, use the default values: +- For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. +- For scale down: allow all pods to be removed in a 15s window.
false @@ -2326,6 +2336,23 @@ If not set, use the default values: Format: int32
false + + tolerance + int or string + + tolerance is the tolerance on the ratio between the current and desired +metric value under which no updates are made to the desired number of +replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not +set, the default cluster-wide tolerance is applied (by default 10%). + +For example, if autoscaling is configured with a memory consumption target of 100Mi, +and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be +triggered when the actual consumption falls below 95Mi or exceeds 101Mi. + +This is an alpha field and requires enabling the HPAConfigurableTolerance +feature gate.
+ + false @@ -2402,7 +2429,9 @@ No stabilization is used. []object policies is a list of potential scaling polices which can be used during scaling. -At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid
+If not set, use the default values: +- For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. +- For scale down: allow all pods to be removed in a 15s window.
false @@ -2427,6 +2456,23 @@ If not set, use the default values: Format: int32
false + + tolerance + int or string + + tolerance is the tolerance on the ratio between the current and desired +metric value under which no updates are made to the desired number of +replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not +set, the default cluster-wide tolerance is applied (by default 10%). + +For example, if autoscaling is configured with a memory consumption target of 100Mi, +and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be +triggered when the actual consumption falls below 95Mi or exceeds 101Mi. + +This is an alpha field and requires enabling the HPAConfigurableTolerance +feature gate.
+ + false @@ -2500,9 +2546,7 @@ MetricSpec specifies how to scale based on a single metric string type is the type of metric source. It should be one of "ContainerResource", "External", -"Object", "Pods" or "Resource", each mapping to a matching field in the object. -Note: "ContainerResource" type is available on when the feature-gate -HPAContainerMetrics is enabled
+"Object", "Pods" or "Resource", each mapping to a matching field in the object.
true @@ -2513,8 +2557,7 @@ HPAContainerMetrics is enabled
requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those -available to normal per-pod metrics using the "pods" source. -This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
+available to normal per-pod metrics using the "pods" source.
false @@ -2570,7 +2613,6 @@ requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the "pods" source. -This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. @@ -5801,7 +5843,7 @@ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/nam -EnvFromSource represents the source of a set of ConfigMaps +EnvFromSource represents the source of a set of ConfigMaps or Secrets
@@ -5823,7 +5865,7 @@ EnvFromSource represents the source of a set of ConfigMaps @@ -5959,6 +6001,15 @@ or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
+ + + + +
prefix string - An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
+ Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.
false
false
stopSignalstring + StopSignal defines which signal will be sent to a container when it is being stopped. +If not specified, the default is defined by the container runtime in use. +StopSignal can only be set for Pods with a non-empty .spec.os.name
+
false
@@ -5986,21 +6037,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false @@ -6008,8 +6059,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false @@ -6021,7 +6072,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container. @@ -6052,7 +6103,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -6146,7 +6197,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -6176,8 +6227,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -6236,21 +6287,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -6258,8 +6309,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -6271,7 +6322,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false
object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false
@@ -6302,7 +6353,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -6396,7 +6447,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -6426,8 +6477,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -6481,7 +6532,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -6498,14 +6549,14 @@ Defaults to 3. Minimum value is 1.
@@ -6542,7 +6593,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -6583,7 +6634,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -6614,7 +6665,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -6655,7 +6706,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -6749,7 +6800,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -6871,7 +6922,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -6888,14 +6939,14 @@ Defaults to 3. Minimum value is 1.
@@ -6932,7 +6983,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -6973,7 +7024,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -7004,7 +7055,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -7045,7 +7096,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -7139,7 +7190,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -7710,7 +7761,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -7727,14 +7778,14 @@ Defaults to 3. Minimum value is 1.
@@ -7771,7 +7822,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -7812,7 +7863,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -7843,7 +7894,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -7884,7 +7935,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -7978,7 +8029,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -8289,6 +8340,15 @@ or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
+ + + + +
false
stopSignalstring + StopSignal defines which signal will be sent to a container when it is being stopped. +If not specified, the default is defined by the container runtime in use. +StopSignal can only be set for Pods with a non-empty .spec.os.name
+
false
@@ -8316,21 +8376,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false @@ -8338,8 +8398,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false @@ -8351,7 +8411,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container. @@ -8382,7 +8442,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -8476,7 +8536,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -8506,8 +8566,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -8566,21 +8626,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -8588,8 +8648,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -8601,7 +8661,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false
object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false
@@ -8632,7 +8692,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -8726,7 +8786,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -8756,8 +8816,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -9114,7 +9174,7 @@ alive or ready to receive traffic. @@ -9131,14 +9191,14 @@ Defaults to 3. Minimum value is 1.
@@ -9175,7 +9235,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -9216,7 +9276,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -9247,7 +9307,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -9288,7 +9348,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -9382,7 +9442,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -11880,6 +11940,35 @@ Note that this field cannot be set when spec.os.name is windows.
Format: int64
+ + + + + @@ -12697,7 +12786,7 @@ alive or ready to receive traffic. @@ -12714,14 +12803,14 @@ Defaults to 3. Minimum value is 1.
@@ -12758,7 +12847,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -12799,7 +12888,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
false
seLinuxChangePolicystring + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. +It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. +Valid values are "MountOption" and "Recursive". + +"Recursive" means relabeling of all files on all Pod volumes by the container runtime. +This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + +"MountOption" mounts all eligible Pod volumes with `-o context` mount option. +This requires all Pods that share the same volume to use the same SELinux label. +It is not possible to share the same volume among privileged and unprivileged Pods. +Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes +whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their +CSIDriver instance. Other volumes are always re-labelled recursively. +"MountOption" value is allowed only when SELinuxMount feature gate is enabled. + +If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. +If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes +and "Recursive" for all other volumes. + +This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + +All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. +Note that this field cannot be set when spec.os.name is windows.
+
false
seLinuxOptions objectexec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -12830,7 +12919,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -12871,7 +12960,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -12965,7 +13054,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -13698,6 +13787,104 @@ Standalone configuration
+### Gateway.spec.app.repositoryReferenceBootstrap +[↩ Parent](#gatewayspecapp) + + + +BootstrapRepositoryReferences bootstraps repositoryReferences of type dynamic to avoid service unavailable at gateway ready. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
enabledboolean + Enable or disable bootstrapping repository references
+
false
preferGitboolean + If a L7StateStore is configured the initContainer will default to retrieving configuration from redis over git if a secret is not available (i.e. the repository is greater than 1MB in size) +this configuration prioritizes git over the L7StateStore configuration to avoid excessive redis egress for large gateway deployments.
+
false
+ + +### Gateway.spec.app.repositoryReferenceDelete +[↩ Parent](#gatewayspecapp) + + + +RepositoryReferenceDelete enables repository delete when a repositoryReference is disabled or removed. +To avoid potential conflicts the current gateway state is reset by reapplying all other repository references post +delete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
enabledboolean + Enable or disable deleting repository references +by default this only applies to repositories that have a statestore reference
+
false
includeEfsboolean + IncludeEfs we track deltas between repositories on the operators ephemeral filesystem +setting this to true will enable delete functionality for all repositoryReferences +USE WITH CAUTION, an operator restart removes the ephemeral filesystem with the state that is tracked there. +We DO NOT recommend this setting for database backed gateways, ephemeral gateways can be restarted to reset state. +use mappings instead
+
false
reconcileDirectoryChangesboolean + ReconcileDirectoryChanges will create and apply mappings if your dynamic repositoryReference folders change. +Changes will be based on the current commit +This is not recommended if you are using a database backed gateway +Use mappings in your repo instead
+
false
reconcileReferencesboolean + ReconcileReferences resets the commits for all other repositories that have been applied +this triggers a reconcile which replaces any entities that may have overlapped with the repository that was removed. +example: +myrepo1 ==> contains cwp1 +myrepo2 ==> also contains a cwp1 +if myrepo1 is deleted cwp1 will be removed. This functionality will then reapply myrepo2 which will reconcile cwp1
+
false
+ + ### Gateway.spec.app.repositoryReferences[index] [↩ Parent](#gatewayspecapp) @@ -14870,7 +15057,7 @@ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/nam -EnvFromSource represents the source of a set of ConfigMaps +EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -14892,7 +15079,7 @@ EnvFromSource represents the source of a set of ConfigMaps @@ -15028,6 +15215,15 @@ or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
+ + + + +
prefix string - An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
+ Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.
false
false
stopSignalstring + StopSignal defines which signal will be sent to a container when it is being stopped. +If not specified, the default is defined by the container runtime in use. +StopSignal can only be set for Pods with a non-empty .spec.os.name
+
false
@@ -15055,21 +15251,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false @@ -15077,8 +15273,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false @@ -15090,7 +15286,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container. @@ -15121,7 +15317,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -15215,7 +15411,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -15245,8 +15441,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -15305,21 +15501,21 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -15327,8 +15523,8 @@ More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-ho @@ -15340,7 +15536,7 @@ lifecycle hooks will fail in runtime when tcp handler is specified.
-Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
sleep object - Sleep represents the duration that the container should sleep before being terminated.
+ Sleep represents a duration that the container should sleep.
false
object Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified.
+for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
false
@@ -15371,7 +15567,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -15465,7 +15661,7 @@ This will be canonicalized upon output, so case-variant names will be understood -Sleep represents the duration that the container should sleep before being terminated. +Sleep represents a duration that the container should sleep.
@@ -15495,8 +15691,8 @@ Sleep represents the duration that the container should sleep before being termi Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept -for the backward compatibility. There are no validation of this field and -lifecycle hooks will fail in runtime when tcp handler is specified. +for backward compatibility. There is no validation of this field and +lifecycle hooks will fail at runtime when it is specified.
@@ -15550,7 +15746,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -15567,14 +15763,14 @@ Defaults to 3. Minimum value is 1.
@@ -15611,7 +15807,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -15652,7 +15848,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -15683,7 +15879,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -15724,7 +15920,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -15818,7 +16014,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -15940,7 +16136,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -15957,14 +16153,14 @@ Defaults to 3. Minimum value is 1.
@@ -16001,7 +16197,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -16042,7 +16238,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -16073,7 +16269,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -16114,7 +16310,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -16208,7 +16404,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -16779,7 +16975,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont @@ -16796,14 +16992,14 @@ Defaults to 3. Minimum value is 1.
@@ -16840,7 +17036,7 @@ Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
@@ -16881,7 +17077,7 @@ More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#cont -Exec specifies the action to take. +Exec specifies a command to execute in the container.
exec object - Exec specifies the action to take.
+ Exec specifies a command to execute in the container.
false
grpc object - GRPC specifies an action involving a GRPC port.
+ GRPC specifies a GRPC HealthCheckRequest.
false
httpGet object - HTTPGet specifies the http request to perform.
+ HTTPGet specifies an HTTP GET request to perform.
false
tcpSocket object - TCPSocket specifies an action involving a TCP port.
+ TCPSocket specifies a connection to a TCP port.
false
@@ -16912,7 +17108,7 @@ Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
-GRPC specifies an action involving a GRPC port. +GRPC specifies a GRPC HealthCheckRequest.
@@ -16953,7 +17149,7 @@ If this is not specified, the default behavior is defined by gRPC.
-HTTPGet specifies the http request to perform. +HTTPGet specifies an HTTP GET request to perform.
@@ -17047,7 +17243,7 @@ This will be canonicalized upon output, so case-variant names will be understood -TCPSocket specifies an action involving a TCP port. +TCPSocket specifies a connection to a TCP port.
@@ -17443,8 +17639,7 @@ when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. -If this value is nil, the behavior is equivalent to the Honor policy. -This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
+If this value is nil, the behavior is equivalent to the Honor policy.
@@ -17457,8 +17652,7 @@ pod topology spread skew. Options are: has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. -If this value is nil, the behavior is equivalent to the Ignore policy. -This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
+If this value is nil, the behavior is equivalent to the Ignore policy.
@@ -18000,6 +18194,13 @@ GatewayRepositoryStatus tracks the status of which Graphman repositories have be Enabled shows whether or not this repository reference is enabled
+ + + + + @@ -18021,6 +18222,13 @@ GatewayRepositoryStatus tracks the status of which Graphman repositories have be Conditions
+ + + + + @@ -18042,6 +18250,13 @@ GatewayRepositoryStatus tracks the status of which Graphman repositories have be RemoteName
+ + + + + @@ -18085,6 +18300,13 @@ these will be less than 1mb in size
Type is static or dynamic
+ + + + +
false
false
true
authTypestring + AuthType defaults to basic, possible options are none, basic or ssh
+
false
branch string false
directories[]string + Directories
+
false
endpoint string false
repoTypestring + RepoType - git, http, local, statestore
+
false
secretName string false
vendorstring + Vendor i.e. Github, Gitlab, BitBucket, Azure
+
false
diff --git a/docs/l7statestores.md b/docs/l7statestores.md index a408a58c..3300c0d3 100644 --- a/docs/l7statestores.md +++ b/docs/l7statestores.md @@ -166,6 +166,13 @@ Redis state store configuration
false + + tls + object + +
+ + false type string @@ -286,6 +293,47 @@ Redis state store configuration +### L7StateStore.spec.redis.tls +[↩ Parent](#l7statestorespecredis) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
enabledboolean +
+
false
redisCrtstring +
+
false
verifyPeerboolean +
+
false
+ + ### L7StateStore.status [↩ Parent](#l7statestore) @@ -308,6 +356,6 @@ L7StateStoreStatus defines the observed state of L7StateStore
- false + true diff --git a/docs/repository.md b/docs/repository.md index a189e50c..fc0b33cd 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -339,6 +339,13 @@ Status - Repository Status + stateStoreSynced + boolean + + StateStoreSynced whether or not the state store has been written to correctly
+ + true + commit string @@ -366,20 +373,6 @@ Status - Repository Status Ready to apply to Gateway Deployments
false - - stateStoreSynced - boolean - - StateStoreSynced whether or not the state store has been written to correctly
- - false - - stateStoreVersion - integer - - StateStoreVersion tracks version in state store
- - false storageSecretName string diff --git a/example/Makefile b/example/Makefile index ac38d101..9548e996 100644 --- a/example/Makefile +++ b/example/Makefile @@ -23,7 +23,7 @@ create-collector: rm -rf $(tmp) install: - kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml + kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml @$(MAKE) --silent t=10 wait kubectl wait --for=condition=ready --timeout=600s pod -l app.kubernetes.io/name=layer7-operator @@ -43,7 +43,7 @@ otk-single: kubectl apply -f ./gateway/otk/otk-single.yaml portal-example: redis - kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml -n ${NAMESPACE} + kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml -n ${NAMESPACE} @$(MAKE) --silent t=15 wait kubectl -n ${NAMESPACE} wait --for=condition=ready --timeout=600s pod -l app.kubernetes.io/name=layer7-operator kubectl apply -k ./base -n ${NAMESPACE} @@ -237,7 +237,7 @@ uninstall: -kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml -kubectl delete ns observability -kubectl delete ns monitoring - -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml + -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml -helm uninstall mysql -helm uninstall cassandra diff --git a/example/advanced/README.md b/example/advanced/README.md index 5d073b3d..d3b77961 100644 --- a/example/advanced/README.md +++ b/example/advanced/README.md @@ -76,7 +76,7 @@ ssg-7b7694d995-qptbj 1/1 Running 0 This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` ##### Verify the Operator is up and running @@ -317,7 +317,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -346,7 +346,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` ### Test your Gateway Deployment @@ -533,5 +533,5 @@ kubectl delete -k ./example/repositories/ ### Uninstall the Operator ``` -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` \ No newline at end of file diff --git a/example/basic/README.md b/example/basic/README.md index d63d65ee..abe2ae75 100644 --- a/example/basic/README.md +++ b/example/basic/README.md @@ -59,7 +59,7 @@ ssg-64ccd9dd48-bqstf 1/1 Running 0 This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` ##### Verify the Operator is up and running @@ -205,7 +205,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -234,7 +234,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` ### Test your Gateway Deployment @@ -322,5 +322,5 @@ kubectl delete -k ./example/repositories/ ### Uninstall the Operator ``` -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` \ No newline at end of file diff --git a/example/gateway/advanced-gateway.yaml b/example/gateway/advanced-gateway.yaml index 9a426dec..59c054ca 100644 --- a/example/gateway/advanced-gateway.yaml +++ b/example/gateway/advanced-gateway.yaml @@ -3,15 +3,21 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license app: replicas: 1 + repositoryReferenceBootstrap: + enabled: true + preferGit: false + repositoryReferenceDelete: + enabled: true + reconcileReferences: true restartOnConfigChange: true singletonExtraction: true - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent serviceAccount: create: true @@ -146,7 +152,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: hostname: gateway.brcmlabs.com database: diff --git a/example/gateway/basic-gateway.yaml b/example/gateway/basic-gateway.yaml index 1a4e870b..4544ba55 100644 --- a/example/gateway/basic-gateway.yaml +++ b/example/gateway/basic-gateway.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -76,7 +76,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: #password: 7layer hostname: gateway.brcmlabs.com diff --git a/example/gateway/openshift-gateway.yaml b/example/gateway/openshift-gateway.yaml index fc2b795e..d3b44509 100644 --- a/example/gateway/openshift-gateway.yaml +++ b/example/gateway/openshift-gateway.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license @@ -11,7 +11,7 @@ spec: replicas: 1 restartOnConfigChange: true singletonExtraction: true - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent serviceAccount: create: true @@ -115,7 +115,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 # initContainerSecurityContext: # runAsNonRoot: true # runAsUser: 1000670001 diff --git a/example/gateway/otel-elastic-gateway.yaml b/example/gateway/otel-elastic-gateway.yaml index ade86047..d2e97d1e 100644 --- a/example/gateway/otel-elastic-gateway.yaml +++ b/example/gateway/otel-elastic-gateway.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license @@ -15,7 +15,7 @@ spec: instrumentation.opentelemetry.io/inject-java: "true" instrumentation.opentelemetry.io/container-names: "gateway" replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -106,7 +106,7 @@ spec: enabled: true graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: hostname: gateway.brcmlabs.com database: diff --git a/example/gateway/otel-lgtm-gateway.yaml b/example/gateway/otel-lgtm-gateway.yaml index 3a2cb9b4..1ee781df 100644 --- a/example/gateway/otel-lgtm-gateway.yaml +++ b/example/gateway/otel-lgtm-gateway.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license @@ -15,7 +15,7 @@ spec: instrumentation.opentelemetry.io/inject-java: "true" instrumentation.opentelemetry.io/container-names: "gateway" replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -103,7 +103,7 @@ spec: enabled: true graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: hostname: gateway.brcmlabs.com database: diff --git a/example/gateway/otel-lgtm-sdk-only-gateway.yaml b/example/gateway/otel-lgtm-sdk-only-gateway.yaml index d4c0964f..e41b7e1c 100644 --- a/example/gateway/otel-lgtm-sdk-only-gateway.yaml +++ b/example/gateway/otel-lgtm-sdk-only-gateway.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license @@ -13,7 +13,7 @@ spec: podAnnotations: sidecar.opentelemetry.io/inject: "ssg-lgtm" replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -101,7 +101,7 @@ spec: enabled: true graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: hostname: gateway.brcmlabs.com database: diff --git a/example/gateway/otel-prometheus-gateway.yaml b/example/gateway/otel-prometheus-gateway.yaml index 0c2f0336..42ea05ec 100644 --- a/example/gateway/otel-prometheus-gateway.yaml +++ b/example/gateway/otel-prometheus-gateway.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license @@ -13,7 +13,7 @@ spec: instrumentation.opentelemetry.io/inject-java: "true" instrumentation.opentelemetry.io/container-names: "gateway" replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -74,7 +74,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: #password: 7layer hostname: gateway.brcmlabs.com diff --git a/example/gateway/otk/otk-dmz.yaml b/example/gateway/otk/otk-dmz.yaml index db8e7242..d87d8c52 100644 --- a/example/gateway/otk/otk-dmz.yaml +++ b/example/gateway/otk/otk-dmz.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: otk-ssg-dmz spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license app: replicas: 2 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -96,7 +96,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 dynamicSyncPort: 9443 cluster: #password: 7layer diff --git a/example/gateway/otk/otk-internal.yaml b/example/gateway/otk/otk-internal.yaml index 582ca6a1..d70af7e9 100644 --- a/example/gateway/otk/otk-internal.yaml +++ b/example/gateway/otk/otk-internal.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: otk-ssg-internal spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license app: replicas: 2 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate @@ -91,7 +91,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 cluster: #password: 7layer hostname: gateway.brcmlabs.com diff --git a/example/gateway/otk/otk-single.yaml b/example/gateway/otk/otk-single.yaml index 30cc5123..641592fd 100644 --- a/example/gateway/otk/otk-single.yaml +++ b/example/gateway/otk/otk-single.yaml @@ -3,14 +3,14 @@ kind: Gateway metadata: name: ssg spec: - version: "11.1.2" + version: "11.1.3" license: accept: false secretName: gateway-license app: replicas: 2 restartOnConfigChange: true - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent serviceAccount: create: true @@ -165,7 +165,7 @@ spec: enabled: false graphman: enabled: true - initContainerImage: docker.io/caapim/graphman-static-init:1.0.3 + initContainerImage: docker.io/caapim/graphman-static-init:1.0.4 initContainerImagePullPolicy: Always cluster: hostname: gateway.brcmlabs.com diff --git a/example/otel-elastic/README.md b/example/otel-elastic/README.md index 3132e140..1f9544ac 100644 --- a/example/otel-elastic/README.md +++ b/example/otel-elastic/README.md @@ -162,7 +162,7 @@ spec: - name: OTEL_TRACES_EXPORTER value: otlp - name: OTEL_RESOURCE_ATTRIBUTES - value: service.version=11.1.2,deployment.environment=development + value: service.version=11.1.3,deployment.environment=development exporter: endpoint: http://localhost:4317 propagators: @@ -578,7 +578,7 @@ There are additional APM Components that need to be installed via Kibana in a br This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` #### Verify the Operator is up and running @@ -716,7 +716,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -745,7 +745,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` #### Repository CR @@ -872,5 +872,5 @@ kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/mai ### Uninstall the Operator ``` -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` \ No newline at end of file diff --git a/example/otel-lgtm/readme.md b/example/otel-lgtm/readme.md index 63e42f90..36d8e3b3 100644 --- a/example/otel-lgtm/readme.md +++ b/example/otel-lgtm/readme.md @@ -304,7 +304,7 @@ kubectl apply -f ./otel-lgtm/ This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` #### Open Telemetry Support @@ -446,7 +446,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -475,7 +475,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` #### Repository CR diff --git a/example/otel-prometheus/README.md b/example/otel-prometheus/README.md index 1a651011..264133a6 100644 --- a/example/otel-prometheus/README.md +++ b/example/otel-prometheus/README.md @@ -559,7 +559,7 @@ https://github.com/kubernetes/ingress-nginx/tree/main/deploy/static/provider This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` #### Verify the Operator is up and running @@ -697,7 +697,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -726,7 +726,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` #### Repository CR @@ -844,5 +844,5 @@ kubectl delete ns observability ### Uninstall the Operator ``` -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` \ No newline at end of file diff --git a/example/otk/single/README.md b/example/otk/single/README.md index 92b01e18..b525c17a 100644 --- a/example/otk/single/README.md +++ b/example/otk/single/README.md @@ -80,7 +80,7 @@ ssg-7b7694d995-qptbj 1/1 Running 0 This step will deploy the Layer7 Operator and all of its resources in namespaced mode. This means that it will only manage Gateway and Repository Custom Resources in the Kubernetes Namespace that it's deployed in. ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` ##### Verify the Operator is up and running @@ -327,7 +327,7 @@ status: ready: true startTime: 2023-04-03 18:57:24 +0000 UTC host: gateway.brcmlabs.com - image: caapim/gateway:11.1.2 + image: caapim/gateway:11.1.3 ready: 1 replicas: 1 repositoryStatus: @@ -356,7 +356,7 @@ repositoryStatus: storageSecretName: l7-gw-mysubscriptions-repository type: dynamic state: Ready -version: 11.1.2 +version: 11.1.3 ``` ### Create Access Token @@ -472,5 +472,5 @@ kubectl delete -k ./example/repositories/ ### Uninstall the Operator ``` -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml ``` \ No newline at end of file diff --git a/example/portal-integration/readme.md b/example/portal-integration/readme.md index 303bf99d..2519d69b 100644 --- a/example/portal-integration/readme.md +++ b/example/portal-integration/readme.md @@ -230,9 +230,9 @@ Portal Configured to use Redis ``` --> ### Deploy the Layer7 Operator -This integration example uses v1.2.1 of the Layer7 Operator +This integration example uses v1.2.2 of the Layer7 Operator ``` -kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml -n ${NAMESPACE} +kubectl apply -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml -n ${NAMESPACE} kubectl wait --for=condition=ready --timeout=600s pod -l app.kubernetes.io/name=layer7-operator ``` @@ -252,7 +252,7 @@ kubectl get l7statestores ``` ### Create a Gateway -The [Gateway Custom Resource](../gateway/portal-gateway.yaml) is configured to use Redis and Gateway version 11.1.2 +The [Gateway Custom Resource](../gateway/portal-gateway.yaml) is configured to use Redis and Gateway version 11.1.3 Make sure that you've accepted the license in [portal-gateway.yaml](../gateway/portal-gateway.yaml) and placed a gateway v11 license in [example/base/resources/secrets/license/](../base/resources/secrets/license/) called license.xml. ``` @@ -669,7 +669,7 @@ Repository Status: State Store Reference: portal-state-store Storage Secret Name: _ Type: dynamic - Version: 11.1.2 + Version: 11.1.3 Events: ``` #### View the L7Api @@ -857,5 +857,5 @@ helm del portal kubectl delete statefulset portal-mysql kubectl delete pvc data-portal-mysql-0 data-rabbitmq-0 helm del redis -kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.1/bundle.yaml -n ${NAMESPACE} +kubectl delete -f https://github.com/CAAPIM/layer7-operator/releases/download/v1.2.2/bundle.yaml -n ${NAMESPACE} ``` \ No newline at end of file diff --git a/example/portal-integration/redis/redis-values.yaml b/example/portal-integration/redis/redis-values.yaml index 2daa9d37..2a511153 100644 --- a/example/portal-integration/redis/redis-values.yaml +++ b/example/portal-integration/redis/redis-values.yaml @@ -1,3 +1,6 @@ +global: + security: + allowInsecureImages: true auth: enabled: true password: 7layer @@ -10,7 +13,7 @@ tls: image: registry: docker.io repository: bitnamilegacy/redis - tag: 7.2.1-debian-11-r0 + tag: 8.2.1-debian-12-r0 pullPolicy: IfNotPresent # replication or standalone architecture: standalone diff --git a/example/state-store/example-state-store.yaml b/example/state-store/example-state-store.yaml index 2ebbfb59..c5673ffe 100644 --- a/example/state-store/example-state-store.yaml +++ b/example/state-store/example-state-store.yaml @@ -12,4 +12,11 @@ spec: standalone: host: standalone-redis-master port: 6379 - storeId: test \ No newline at end of file + storeId: test + tls: + enabled: false + verifyPeer: false + # redisCrt: |+ + # -----BEGIN CERTIFICATE----- + # MIIEWDCCA0CgAwIBAgIRAOp... + # -----END CERTIFICATE----- \ No newline at end of file diff --git a/go.mod b/go.mod index 3fa4efcb..9ddf5653 100644 --- a/go.mod +++ b/go.mod @@ -1,47 +1,48 @@ module github.com/caapim/layer7-operator -go 1.23.3 +go 1.24.10 require ( - github.com/Khan/genqlient v0.7.0 + github.com/Khan/genqlient v0.8.1 github.com/go-co-op/gocron v1.37.0 - github.com/go-git/go-git/v5 v5.16.0 - github.com/go-logr/logr v1.4.2 - github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.35.1 + github.com/go-git/go-git/v5 v5.16.3 + github.com/go-logr/logr v1.4.3 + github.com/onsi/ginkgo/v2 v2.25.1 + github.com/onsi/gomega v1.38.2 github.com/openshift/api v0.0.0-20241120064718-caf97963ed30 - github.com/redis/go-redis/v9 v9.7.3 + github.com/redis/go-redis/v9 v9.17.0 github.com/valyala/quicktemplate v1.8.0 - go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel v1.33.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 - go.opentelemetry.io/otel/metric v1.32.0 - go.opentelemetry.io/otel/sdk v1.32.0 + go.opentelemetry.io/otel/metric v1.33.0 + go.opentelemetry.io/otel/sdk v1.33.0 go.opentelemetry.io/otel/sdk/metric v1.32.0 - google.golang.org/grpc v1.68.0 + google.golang.org/grpc v1.68.1 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.31.3 - k8s.io/apimachinery v0.31.3 - k8s.io/client-go v0.31.3 - sigs.k8s.io/controller-runtime v0.19.1 + k8s.io/api v0.33.5 + k8s.io/apimachinery v0.33.5 + k8s.io/client-go v0.33.5 + sigs.k8s.io/controller-runtime v0.21.0 ) require ( - dario.cat/mergo v1.0.1 // indirect + cel.dev/expr v0.19.1 // indirect + dario.cat/mergo v1.0.2 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -55,74 +56,76 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.20.1 // indirect - github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.23.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect + github.com/kevinburke/ssh_config v1.4.0 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.1 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.3.1 // indirect + github.com/sergi/go-diff v1.4.0 // indirect + github.com/skeema/knownhosts v1.3.2 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/vektah/gqlparser/v2 v2.5.19 // indirect + github.com/vektah/gqlparser/v2 v2.5.31 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.32.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/proto/otlp v1.4.0 // indirect go.uber.org/atomic v1.11.0 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.37.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect - golang.org/x/time v0.8.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.38.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect - google.golang.org/protobuf v1.35.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/protobuf v1.36.7 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.31.3 // indirect - k8s.io/apiserver v0.31.3 // indirect - k8s.io/component-base v0.31.3 // indirect + k8s.io/apiextensions-apiserver v0.33.0 // indirect + k8s.io/apiserver v0.33.0 // indirect + k8s.io/component-base v0.33.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index fc908ad0..6fadaed4 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,16 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= -github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= +cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= +cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= +github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= @@ -15,8 +19,6 @@ github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8 github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -33,8 +35,8 @@ github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= +github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -49,8 +51,8 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= @@ -67,11 +69,11 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= -github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8= +github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -90,25 +92,25 @@ github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8J github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= -github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= -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/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= +github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -117,12 +119,14 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= +github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -143,30 +147,31 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/ginkgo/v2 v2.25.1 h1:Fwp6crTREKM+oA6Cz4MsO8RhKQzs2/gOIVOUscMAfZY= +github.com/onsi/ginkgo/v2 v2.25.1/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/openshift/api v0.0.0-20241120064718-caf97963ed30 h1:LrNXjO675I1FvPYE4P3UOFNlC0X37iKUUhgwk+huYnc= github.com/openshift/api v0.0.0-20241120064718-caf97963ed30/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= +github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= -github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= -github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= +github.com/redis/go-redis/v9 v9.17.0 h1:K6E+ZlYN95KSMmZeEQPbU/c++wfmEvfFB17yEAq/VhM= +github.com/redis/go-redis/v9 v9.17.0/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -174,76 +179,84 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= -github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= +github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg= +github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdqCysW5k= github.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM= -github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= -github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= +github.com/vektah/gqlparser/v2 v2.5.31 h1:YhWGA1mfTjID7qJhd1+Vxhpk5HTgydrGU9IgkWBTJ7k= +github.com/vektah/gqlparser/v2 v2.5.31/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= -go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= -go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= -go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= -go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= -go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= +go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -253,15 +266,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -271,38 +284,38 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= -golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= -golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= -google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= -google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= +google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -316,36 +329,38 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= -k8s.io/apiextensions-apiserver v0.31.3 h1:+GFGj2qFiU7rGCsA5o+p/rul1OQIq6oYpQw4+u+nciE= -k8s.io/apiextensions-apiserver v0.31.3/go.mod h1:2DSpFhUZZJmn/cr/RweH1cEVVbzFw9YBu4T+U3mf1e4= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.3 h1:+1oHTtCB+OheqFEz375D0IlzHZ5VeQKX1KGXnx+TTuY= -k8s.io/apiserver v0.31.3/go.mod h1:PrxVbebxrxQPFhJk4powDISIROkNMKHibTg9lTRQ0Qg= -k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= -k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= -k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ= -k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU= +k8s.io/api v0.33.5 h1:YR+uhYj05jdRpcksv8kjSliW+v9hwXxn6Cv10aR8Juw= +k8s.io/api v0.33.5/go.mod h1:2gzShdwXKT5yPGiqrTrn/U/nLZ7ZyT4WuAj3XGDVgVs= +k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= +k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= +k8s.io/apimachinery v0.33.5 h1:NiT64hln4TQXeYR18/ES39OrNsjGz8NguxsBgp+6QIo= +k8s.io/apimachinery v0.33.5/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc= +k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8= +k8s.io/client-go v0.33.5 h1:I8BdmQGxInpkMEnJvV6iG7dqzP3JRlpZZlib3OMFc3o= +k8s.io/client-go v0.33.5/go.mod h1:W8PQP4MxbM4ypgagVE65mUUqK1/ByQkSALF9tzuQ6u0= +k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk= +k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk= -sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= +sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/structured-merge-diff/v4 v4.4.3 h1:sCP7Vv3xx/CWIuTPVN38lUPx0uw0lcLfzaiDa8Ja01A= -sigs.k8s.io/structured-merge-diff/v4 v4.4.3/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hack/install-go.sh b/hack/install-go.sh deleted file mode 100755 index 0f071bef..00000000 --- a/hack/install-go.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -rm -rf /usr/local/go -curl -Lo /tmp/go1.21.5.linux-amd64.tar.gz https://go.dev/dl/go1.21.5.linux-amd64.tar.gz -tar -C /usr/local -xzf /tmp/go1.21.5.linux-amd64.tar.gz -export PATH=$PATH:/usr/local/go/bin -go version \ No newline at end of file diff --git a/hack/install-kind.sh b/hack/install-kind.sh deleted file mode 100755 index 85b36e90..00000000 --- a/hack/install-kind.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# For AMD64 / x86_64 -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 -# For ARM64 -[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-arm64 -chmod +x ./kind -mv ./kind /usr/local/bin/kind -kind delete cluster \ No newline at end of file diff --git a/hack/install-kuttl.sh b/hack/install-kuttl.sh index 0ed8c7a5..a4177d1d 100755 --- a/hack/install-kuttl.sh +++ b/hack/install-kuttl.sh @@ -1,5 +1,5 @@ #!/bin/bash -sudo curl -Lo /usr/local/bin/kubectl-kuttl https://github.com/kudobuilder/kuttl/releases/download/v0.16.0/kubectl-kuttl_0.16.0_linux_x86_64 +sudo curl -Lo /usr/local/bin/kubectl-kuttl https://github.com/kudobuilder/kuttl/releases/download/v0.22.0/kubectl-kuttl_0.22.0_linux_x86_64 sudo chmod +x /usr/local/bin/kubectl-kuttl export PATH=$PATH:/usr/local/bin \ No newline at end of file diff --git a/internal/controller/gateway/controller.go b/internal/controller/gateway/controller.go index 19656759..1ee34b0b 100644 --- a/internal/controller/gateway/controller.go +++ b/internal/controller/gateway/controller.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package gateway @@ -268,6 +269,10 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error { return true } + if oldGw.Status.ManagementPod != newGw.Status.ManagementPod { + return true + } + if reflect.DeepEqual(oldGw.Spec, newGw.Spec) { return false } @@ -293,10 +298,18 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error { if err != nil { return true } - if oldDep.Status.ReadyReplicas == newDep.Status.ReadyReplicas || newDep.Status.ReadyReplicas == 0 { //|| oldDep.Status.ReadyReplicas > newDep.Status.ReadyReplicas - return false + + // Trigger reconcile if ReadyReplicas changed + if oldDep.Status.ReadyReplicas != newDep.Status.ReadyReplicas { + return true } - return true + + // Trigger reconcile if annotations changed (e.g., repository delete/update) + if !reflect.DeepEqual(oldDep.ObjectMeta.Annotations, newDep.ObjectMeta.Annotations) { + return true + } + + return false } if objType == "*v1.PodDisruptionBudget" { diff --git a/internal/controller/repository/controller.go b/internal/controller/repository/controller.go index fbede38a..d921d14e 100644 --- a/internal/controller/repository/controller.go +++ b/internal/controller/repository/controller.go @@ -49,10 +49,13 @@ import ( "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" creconcile "sigs.k8s.io/controller-runtime/pkg/reconcile" ) +const repositoryFinalizer = "security.brcmlabs.com/layer7-operator" + // RepositoryReconciler reconciles a Repository object type RepositoryReconciler struct { client.Client @@ -75,6 +78,7 @@ func (r *RepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) {reconcile.Secret, "secrets"}, {reconcile.LocalReference, "local repositories"}, {reconcile.ScheduledJobs, "scheduled jobs"}, + {reconcile.Finalizer, "finalizer"}, } l7repository := &securityv1.Repository{} @@ -95,6 +99,15 @@ func (r *RepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) Instance: l7repository, } + // Add a finalizer for the L7Api + if !controllerutil.ContainsFinalizer(l7repository, repositoryFinalizer) { + controllerutil.AddFinalizer(l7repository, repositoryFinalizer) + err = r.Update(ctx, l7repository) + if err != nil { + return ctrl.Result{}, err + } + } + for _, op := range ops { err = op.Run(ctx, params) if err != nil { diff --git a/internal/controller/statestore/controller.go b/internal/controller/statestore/controller.go index 21548506..e9f18b5f 100644 --- a/internal/controller/statestore/controller.go +++ b/internal/controller/statestore/controller.go @@ -29,6 +29,7 @@ package statestore import ( "context" "sync" + "time" securityv1alpha1 "github.com/caapim/layer7-operator/api/v1alpha1" "github.com/caapim/layer7-operator/pkg/statestore/reconcile" @@ -52,7 +53,6 @@ type L7StateStoreReconciler struct { func (r *L7StateStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Log.WithValues("L7StateStore", req.NamespacedName) - log.Info("connecting to statestore", "statestore", "stateStore.Name") stateStore := &securityv1alpha1.L7StateStore{} err := r.Get(ctx, req.NamespacedName, stateStore) if err != nil { @@ -61,7 +61,7 @@ func (r *L7StateStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request } return ctrl.Result{}, err } - log.Info("connecting to statestore", "statestore", stateStore.Name) + log.V(5).Info("connecting to statestore", "statestore", stateStore.Name) params := reconcile.Params{ Client: r.Client, @@ -80,7 +80,7 @@ func (r *L7StateStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request if err != nil { return ctrl.Result{}, err } - return ctrl.Result{}, nil + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } // SetupWithManager sets up the controller with the Manager. diff --git a/internal/controller/tests/dynamic_repo_test.go b/internal/controller/tests/dynamic_repo_test.go index 5ff831ce..f3ed6f92 100644 --- a/internal/controller/tests/dynamic_repo_test.go +++ b/internal/controller/tests/dynamic_repo_test.go @@ -21,8 +21,8 @@ var _ = Describe("Gateway controller", func() { repoSecretName = "test-dynamic-repository-secret" namespace = "l7operator" gatewayName = "local-repo-ssg" - version = "11.1.2" - image = "docker.io/caapim/gateway:11.1.2" + version = "11.1.3" + image = "docker.io/caapim/gateway:11.1.3" repoName = "local-repo" repoType = securityv1.RepositoryTypeLocal dynamicChecksum = "" @@ -137,7 +137,7 @@ var _ = Describe("Gateway controller", func() { }, Graphman: securityv1.Graphman{ Enabled: true, - InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.3", + InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.4", }, Cluster: securityv1.Cluster{ Hostname: "gateway.brcmlabs.com", diff --git a/internal/controller/tests/gateway_podconfig_test.go b/internal/controller/tests/gateway_podconfig_test.go index 9713b33f..6dd4a154 100644 --- a/internal/controller/tests/gateway_podconfig_test.go +++ b/internal/controller/tests/gateway_podconfig_test.go @@ -18,8 +18,8 @@ var _ = Describe("Gateway controller", func() { gwLicenseSecretName = "gateway-license" namespace = "l7operator" gatewayName = "podconfig-ssg" - version = "11.1.2" - image = "docker.io/caapim/gateway:11.1.2" + version = "11.1.3" + image = "docker.io/caapim/gateway:11.1.3" ) BeforeEach(func() { @@ -78,7 +78,7 @@ var _ = Describe("Gateway controller", func() { }, Graphman: securityv1.Graphman{ Enabled: true, - InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.3", + InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.4", }, Cluster: securityv1.Cluster{ Hostname: "gateway.brcmlabs.com", diff --git a/internal/controller/tests/http_repo_test.go b/internal/controller/tests/http_repo_test.go index f69685fd..594c1d23 100644 --- a/internal/controller/tests/http_repo_test.go +++ b/internal/controller/tests/http_repo_test.go @@ -17,8 +17,8 @@ var _ = Describe("Gateway controller", func() { gwLicenseSecretName = "gateway-license" namespace = "l7operator" gatewayName = "http-repo-ssg" - version = "11.1.2" - image = "docker.io/caapim/gateway:11.1.2" + version = "11.1.3" + image = "docker.io/caapim/gateway:11.1.3" repoName = "http-repo" ) @@ -102,7 +102,7 @@ var _ = Describe("Gateway controller", func() { }, Graphman: securityv1.Graphman{ Enabled: true, - InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.3", + InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.4", }, Cluster: securityv1.Cluster{ Hostname: "gateway.brcmlabs.com", diff --git a/internal/controller/tests/repo_test.go b/internal/controller/tests/repo_test.go index 0592325d..3306d6ae 100644 --- a/internal/controller/tests/repo_test.go +++ b/internal/controller/tests/repo_test.go @@ -21,8 +21,8 @@ var _ = Describe("Gateway controller", func() { gwLicenseSecretName = "gateway-license" namespace = "l7operator" gatewayName = "git-repo-ssg" - version = "11.1.2" - image = "docker.io/caapim/gateway:11.1.2" + version = "11.1.3" + image = "docker.io/caapim/gateway:11.1.3" repoType = securityv1.RepositoryTypeGit ) @@ -151,7 +151,7 @@ var _ = Describe("Gateway controller", func() { Management: securityv1.Management{ Graphman: securityv1.Graphman{ Enabled: true, - InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.3", + InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.4", }, Cluster: securityv1.Cluster{ Hostname: "gateway.brcmlabs.com", @@ -187,7 +187,7 @@ var _ = Describe("Gateway controller", func() { if err != nil { return false } - req.Header.Add("Authorization", "Basic "+basicAuth("admin", "7layer")) + //req.Header.Add("Authorization", "Basic "+basicAuth("admin", "7layer")) req.Header.Add("client-id", "D63FA04C8447") resp, err := httpclient.Do(req) if err != nil { diff --git a/internal/controller/tests/static_repo_test.go b/internal/controller/tests/static_repo_test.go index 5131fc33..66021980 100644 --- a/internal/controller/tests/static_repo_test.go +++ b/internal/controller/tests/static_repo_test.go @@ -37,8 +37,8 @@ var _ = Describe("Gateway controller", func() { repoSecretName = "test-static-repository-secret" namespace = "l7operator" gatewayName = "static-repo-ssg" - version = "11.1.2" - image = "docker.io/caapim/gateway:11.1.2" + version = "11.1.3" + image = "docker.io/caapim/gateway:11.1.3" repoName = "local-repo" repoType = securityv1.RepositoryTypeLocal staticChecksum = "" @@ -159,7 +159,7 @@ var _ = Describe("Gateway controller", func() { }, Graphman: securityv1.Graphman{ Enabled: true, - InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.3", + InitContainerImage: "docker.io/caapim/graphman-static-init:1.0.4", }, Username: "admin", Password: "7layer", diff --git a/internal/graphman/bundle.go b/internal/graphman/bundle.go index eaff960b..31410173 100644 --- a/internal/graphman/bundle.go +++ b/internal/graphman/bundle.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package graphman @@ -116,6 +117,12 @@ type Bundle struct { Properties *BundleProperties `json:"properties,omitempty"` } +type BundleProperties struct { + Meta BundlePropertyMeta `json:"meta,omitempty"` + DefaultAction MappingAction `json:"defaultAction,omitempty"` + Mappings BundleMappings `json:"mappings,omitempty"` +} + type MappingInstructionInput struct { Action MappingAction `json:"action,omitempty"` Default bool `json:"default,omitempty"` @@ -133,12 +140,6 @@ type BundlePropertyMeta struct { TimeStamp string `json:"timestamp,omitempty"` } -type BundleProperties struct { - Meta BundlePropertyMeta `json:"meta,omitempty"` - DefaultAction MappingAction `json:"defaultAction,omitempty"` - Mappings BundleMappings `json:"mappings,omitempty"` -} - type BundleMappings struct { WebApiServices []*MappingInstructionInput `json:"webApiServices,omitempty"` InternalWebApiServices []*MappingInstructionInput `json:"internalWebApiServices,omitempty"` @@ -338,6 +339,61 @@ var entities = []string{ "kerberosConfigs", } +var entityFolderList = []string{ + "clusterProperties", + "encassConfigs", + "jdbcConnections", + "cassandraConnections", + "trustedCerts", + "schemas", + "dtds", + "fips", + "ldaps", + "internalGroups", + "fipGroups", + "internalUsers", + "fipUsers", + "scheduledTasks", + "jmsDestinations", + "secrets", + "keys", + "listenPorts", + "activeConnectors", + "serverModuleFiles", + "emailListeners", + "smConfigs", + "administrativeUserAccountProperties", + "passwordPolicies", + "revocationCheckPolicies", + "logSinks", + "httpConfigurations", + "customKeyValues", + "serviceResolutionConfigs", + "folders", + "federatedIdps", + "federatedGroups", + "federatedUsers", + "internalIdps", + "ldapIdps", + "simpleLdapIdps", + "policyBackedIdps", + "roles", + "genericEntities", + "auditConfigurations", + "kerberosConfigs", + "tree", +} + +// Contains returns true if string array contains string +func Contains(arr []string, str string) bool { + for _, a := range arr { + if strings.Contains(str, a) { + return true + } + } + return false +} + func ConcatBundle(src []byte, dest []byte) ([]byte, error) { srcBundle := Bundle{} destBundle := Bundle{} @@ -356,8 +412,11 @@ func ConcatBundle(src []byte, dest []byte) ([]byte, error) { return nil, err } - destBundle = combineBundle(srcBundle, destBundle) + destBundle, err = CombineWithOverwrite(srcBundle, destBundle) + if err != nil { + return nil, err + } bundleBytes, err := json.Marshal(destBundle) if err != nil { return nil, err @@ -365,7 +424,11 @@ func ConcatBundle(src []byte, dest []byte) ([]byte, error) { return bundleBytes, nil } -func AddMappings(src []byte, dest []byte) ([]byte, error) { +// ConcatBundlePreservingMappings concatenates bundles while preserving ALL DELETE mappings +// This is used for repository-controlled mappings (combined.json, latest.json) where the +// repository controller has already determined which entities should be deleted. +// Unlike ConcatBundle, this does NOT call CleanDeleteMappingsForEntities. +func ConcatBundlePreservingMappings(src []byte, dest []byte) ([]byte, error) { srcBundle := Bundle{} destBundle := Bundle{} @@ -383,8 +446,12 @@ func AddMappings(src []byte, dest []byte) ([]byte, error) { return nil, err } - destBundle.Properties = srcBundle.Properties + // Use CombineWithOverwritePreservingDeleteMappings instead of CombineWithOverwrite + destBundle, err = CombineWithOverwritePreservingDeleteMappings(srcBundle, destBundle) + if err != nil { + return nil, err + } bundleBytes, err := json.Marshal(destBundle) if err != nil { return nil, err @@ -500,7 +567,7 @@ func readBundle(entityType string, file string, bundle *Bundle) (Bundle, error) if err != nil { return *bundle, err } - bundle.WebApiServices = append(bundle.InternalWebApiServices, &internalWebApiService) + bundle.InternalWebApiServices = append(bundle.InternalWebApiServices, &internalWebApiService) case ".soap": soapService := SoapServiceInput{} err := json.Unmarshal(f, &soapService) @@ -514,7 +581,7 @@ func readBundle(entityType string, file string, bundle *Bundle) (Bundle, error) if err != nil { return *bundle, err } - bundle.SoapServices = append(bundle.InternalSoapServices, &internalSoapService) + bundle.InternalSoapServices = append(bundle.InternalSoapServices, &internalSoapService) case ".global": globalPolicy := GlobalPolicyInput{} err := json.Unmarshal(f, &globalPolicy) @@ -897,16 +964,22 @@ func parseBundleProperties(path string) (BundleProperties, error) { return bundleProperties, nil } -// implodeBundle takes a Graphman directory and returns a Bundle Object. -func implodeBundle(path string) (Bundle, error) { +func implodeBundle(path string, processNestedRepos bool) (Bundle, error) { + startPath := path + nestedRepos := []string{} bundle := Bundle{} err := filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } - if strings.Contains(path, "/.git") { + if strings.Contains(path, ".git") { + return nil + } + + if Contains(nestedRepos, path) && !processNestedRepos { return nil } + if !d.IsDir() { name, isEntity := parseEntity(path) if isEntity { @@ -916,6 +989,15 @@ func implodeBundle(path string) (Bundle, error) { } return nil } + } else { + containsRepo, err := determineRepoStructure(path) + if err != nil { + return err + } + if containsRepo && (len(strings.Split(startPath, "/")) != len(strings.Split(path, "/"))) { + nestedRepos = append(nestedRepos, path) + return nil + } } return nil }) @@ -925,1749 +1007,53 @@ func implodeBundle(path string) (Bundle, error) { return bundle, nil } -// SubtractBundle subtracts source from a new bundle by combining the diff and configuring delete mappings -func SubtractBundle(src []byte, new []byte) (delta []byte, combined []byte, err error) { - - var srcBundle Bundle - var newBundle Bundle - var deltaBundle Bundle - - deltaBundle.Properties = &BundleProperties{} - - err = json.Unmarshal(src, &srcBundle) - if err != nil { - return nil, nil, err - } - - err = json.Unmarshal(new, &newBundle) - if err != nil { - return nil, nil, err - } - - for _, s := range srcBundle.ActiveConnectors { - found := false - for _, d := range newBundle.ActiveConnectors { - if s.Name == d.Name { - if !reflect.DeepEqual(s, d) { - deltaBundle.ActiveConnectors = append(deltaBundle.ActiveConnectors, d) - } - s = d - found = true - } - } - if !found { - deltaBundle.ActiveConnectors = append(deltaBundle.ActiveConnectors, s) - newBundle.ActiveConnectors = append(newBundle.ActiveConnectors, s) - newBundle.Properties.Mappings.ActiveConnectors = append(newBundle.Properties.Mappings.ActiveConnectors, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.BackgroundTasks { - found := false - for _, d := range newBundle.BackgroundTasks { - if s.Name == d.Name { - if !reflect.DeepEqual(s, d) { - deltaBundle.BackgroundTasks = append(deltaBundle.BackgroundTasks, d) - } - s = d - found = true - } - } - if !found { - deltaBundle.BackgroundTasks = append(deltaBundle.BackgroundTasks, s) - newBundle.BackgroundTasks = append(newBundle.BackgroundTasks, s) - newBundle.Properties.Mappings.BackgroundTasks = append(newBundle.Properties.Mappings.BackgroundTasks, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.CassandraConnections { - found := false - for _, d := range newBundle.CassandraConnections { - if s.Name == d.Name { - if !reflect.DeepEqual(s, d) { - deltaBundle.CassandraConnections = append(deltaBundle.CassandraConnections, d) - } - s = d - found = true - } - } - if !found { - deltaBundle.CassandraConnections = append(deltaBundle.CassandraConnections, s) - newBundle.CassandraConnections = append(newBundle.CassandraConnections, s) - newBundle.Properties.Mappings.CassandraConnections = append(newBundle.Properties.Mappings.CassandraConnections, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.ClusterProperties { - found := false - for _, d := range newBundle.ClusterProperties { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.ClusterProperties = append(deltaBundle.ClusterProperties, d) - } - s = d - - } - } - if !found { - deltaBundle.ClusterProperties = append(deltaBundle.ClusterProperties, s) - newBundle.ClusterProperties = append(newBundle.ClusterProperties, s) - newBundle.Properties.Mappings.ClusterProperties = append(newBundle.Properties.Mappings.ClusterProperties, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.Dtds { - found := false - for _, d := range newBundle.Dtds { - if s.SystemId == d.SystemId { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Dtds = append(deltaBundle.Dtds, d) - } - s = d - } - } - if !found { - deltaBundle.Dtds = append(deltaBundle.Dtds, s) - newBundle.Dtds = append(newBundle.Dtds, s) - newBundle.Properties.Mappings.Dtds = append(newBundle.Properties.Mappings.Dtds, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - SystemId: s.SystemId, - }, - }) - } - } - - for _, s := range srcBundle.EmailListeners { - found := false - for _, d := range newBundle.EmailListeners { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.EmailListeners = append(deltaBundle.EmailListeners, d) - } - s = d - } - } - if !found { - deltaBundle.EmailListeners = append(deltaBundle.EmailListeners, s) - newBundle.EmailListeners = append(newBundle.EmailListeners, s) - newBundle.Properties.Mappings.EmailListeners = append(newBundle.Properties.Mappings.EmailListeners, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.EncassConfigs { - found := false - for _, d := range newBundle.EncassConfigs { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.EncassConfigs = append(deltaBundle.EncassConfigs, d) - } - s = d - } - } - if !found { - deltaBundle.EncassConfigs = append(deltaBundle.EncassConfigs, s) - newBundle.EncassConfigs = append(newBundle.EncassConfigs, s) - newBundle.Properties.Mappings.EncassConfigs = append(newBundle.Properties.Mappings.EncassConfigs, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FipGroups { - found := false - for _, d := range newBundle.FipGroups { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FipGroups = append(deltaBundle.FipGroups, d) - } - s = d - } - } - if !found { - deltaBundle.FipGroups = append(deltaBundle.FipGroups, s) - newBundle.FipGroups = append(newBundle.FipGroups, s) - newBundle.Properties.Mappings.FipGroups = append(newBundle.Properties.Mappings.FipGroups, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FipUsers { - found := false - for _, d := range newBundle.FipUsers { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FipUsers = append(deltaBundle.FipUsers, d) - } - s = d - } - } - if !found { - deltaBundle.FipUsers = append(deltaBundle.FipUsers, s) - newBundle.FipUsers = append(newBundle.FipUsers, s) - newBundle.Properties.Mappings.FipUsers = append(newBundle.Properties.Mappings.FipUsers, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.Fips { - found := false - for _, d := range newBundle.Fips { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Fips = append(deltaBundle.Fips, d) - } - s = d - } - } - if !found { - deltaBundle.Fips = append(deltaBundle.Fips, s) - newBundle.Fips = append(newBundle.Fips, s) - newBundle.Properties.Mappings.Fips = append(newBundle.Properties.Mappings.Fips, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.GlobalPolicies { - found := false - for _, d := range newBundle.GlobalPolicies { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.GlobalPolicies = append(deltaBundle.GlobalPolicies, d) - } - s = d - } - } - if !found { - deltaBundle.GlobalPolicies = append(deltaBundle.GlobalPolicies, s) - newBundle.GlobalPolicies = append(newBundle.GlobalPolicies, s) - newBundle.Properties.Mappings.GlobalPolicies = append(newBundle.Properties.Mappings.GlobalPolicies, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.InternalGroups { - found := false - for _, d := range newBundle.InternalGroups { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.InternalGroups = append(deltaBundle.InternalGroups, d) - } - s = d - } - } - if !found { - deltaBundle.InternalGroups = append(deltaBundle.InternalGroups, s) - newBundle.InternalGroups = append(newBundle.InternalGroups, s) - newBundle.Properties.Mappings.InternalGroups = append(newBundle.Properties.Mappings.InternalGroups, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.InternalSoapServices { - found := false - for _, d := range newBundle.InternalSoapServices { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.InternalSoapServices = append(deltaBundle.InternalSoapServices, d) - } - s = d - } - } - if !found { - deltaBundle.InternalSoapServices = append(deltaBundle.InternalSoapServices, s) - newBundle.InternalSoapServices = append(newBundle.InternalSoapServices, s) - newBundle.Properties.Mappings.InternalSoapServices = append(newBundle.Properties.Mappings.InternalSoapServices, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.InternalUsers { - found := false - for _, d := range newBundle.InternalUsers { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.InternalUsers = append(deltaBundle.InternalUsers, d) - } - s = d - } - } - if !found { - deltaBundle.InternalUsers = append(deltaBundle.InternalUsers, s) - newBundle.InternalUsers = append(newBundle.InternalUsers, s) - newBundle.Properties.Mappings.InternalUsers = append(newBundle.Properties.Mappings.InternalUsers, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.InternalWebApiServices { - found := false - for _, d := range newBundle.InternalWebApiServices { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.InternalWebApiServices = append(deltaBundle.InternalWebApiServices, d) - } - s = d - } - } - if !found { - deltaBundle.InternalWebApiServices = append(deltaBundle.InternalWebApiServices, s) - newBundle.InternalWebApiServices = append(newBundle.InternalWebApiServices, s) - newBundle.Properties.Mappings.InternalWebApiServices = append(newBundle.Properties.Mappings.InternalWebApiServices, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.JdbcConnections { - found := false - for _, d := range newBundle.JdbcConnections { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.JdbcConnections = append(deltaBundle.JdbcConnections, d) - } - s = d - } - } - if !found { - deltaBundle.JdbcConnections = append(deltaBundle.JdbcConnections, s) - newBundle.JdbcConnections = append(newBundle.JdbcConnections, s) - newBundle.Properties.Mappings.JdbcConnections = append(newBundle.Properties.Mappings.JdbcConnections, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.JmsDestinations { - found := false - for _, d := range newBundle.JmsDestinations { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.JmsDestinations = append(deltaBundle.JmsDestinations, d) - } - s = d - } - } - if !found { - deltaBundle.JmsDestinations = append(deltaBundle.JmsDestinations, s) - newBundle.JmsDestinations = append(newBundle.JmsDestinations, s) - newBundle.Properties.Mappings.JmsDestinations = append(newBundle.Properties.Mappings.JmsDestinations, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.Keys { - found := false - for _, d := range newBundle.Keys { - if s.Alias == d.Alias { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Keys = append(deltaBundle.Keys, d) - } - s = d - } - } - if !found { - deltaBundle.Keys = append(deltaBundle.Keys, s) - newBundle.Keys = append(newBundle.Keys, s) - newBundle.Properties.Mappings.Keys = append(newBundle.Properties.Mappings.Keys, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - KeystoreId: "00000000000000000000000000000002", - Alias: s.Alias, - }, - }) - } - } - - for _, s := range srcBundle.LdapIdps { - found := false - for _, d := range newBundle.LdapIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.LdapIdps = append(deltaBundle.LdapIdps, d) - } - s = d - } - } - if !found { - deltaBundle.LdapIdps = append(deltaBundle.LdapIdps, s) - newBundle.LdapIdps = append(newBundle.LdapIdps, s) - newBundle.Properties.Mappings.LdapIdps = append(newBundle.Properties.Mappings.LdapIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.ListenPorts { - found := false - for _, d := range newBundle.ListenPorts { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.ListenPorts = append(deltaBundle.ListenPorts, d) - } - s = d - } - } - if !found { - deltaBundle.ListenPorts = append(deltaBundle.ListenPorts, s) - newBundle.ListenPorts = append(newBundle.ListenPorts, s) - newBundle.Properties.Mappings.ListenPorts = append(newBundle.Properties.Mappings.ListenPorts, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.PolicyFragments { - found := false - for _, d := range newBundle.PolicyFragments { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.PolicyFragments = append(deltaBundle.PolicyFragments, d) - } - s = d - } - } - if !found { - deltaBundle.PolicyFragments = append(deltaBundle.PolicyFragments, s) - newBundle.PolicyFragments = append(newBundle.PolicyFragments, s) - newBundle.Properties.Mappings.PolicyFragments = append(newBundle.Properties.Mappings.PolicyFragments, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.ScheduledTasks { - found := false - for _, d := range newBundle.ScheduledTasks { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.ScheduledTasks = append(deltaBundle.ScheduledTasks, d) - } - s = d - } - } - if !found { - deltaBundle.ScheduledTasks = append(deltaBundle.ScheduledTasks, s) - newBundle.ScheduledTasks = append(newBundle.ScheduledTasks, s) - newBundle.Properties.Mappings.ScheduledTasks = append(newBundle.Properties.Mappings.ScheduledTasks, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) +func DetectGraphmanFolders(path string) (projects []string, err error) { + topLevelProjects := []string{} + err = filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err } - } - for _, s := range srcBundle.Schemas { - found := false - for _, d := range newBundle.Schemas { - if s.SystemId == d.SystemId { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Schemas = append(deltaBundle.Schemas, d) - } - s = d - } - } - if !found { - deltaBundle.Schemas = append(deltaBundle.Schemas, s) - newBundle.Schemas = append(newBundle.Schemas, s) - newBundle.Properties.Mappings.Schemas = append(newBundle.Properties.Mappings.Schemas, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - SystemId: s.SystemId, - }, - }) + if strings.Contains(path, ".git") || d.Name() == "." { + return nil } - } - - for _, s := range srcBundle.Secrets { - found := false - for _, d := range newBundle.Secrets { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Secrets = append(deltaBundle.Secrets, d) - } - s = d + if !Contains(entityFolderList, d.Name()) && d.IsDir() && d.Name() != ".git" { + containsRepo, err := determineRepoStructure(path) + if err != nil { + return err } - } - if !found { - deltaBundle.Secrets = append(deltaBundle.Secrets, s) - newBundle.Secrets = append(newBundle.Secrets, s) - newBundle.Properties.Mappings.Secrets = append(newBundle.Properties.Mappings.Secrets, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.ServerModuleFiles { - found := false - for _, d := range newBundle.ServerModuleFiles { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.ServerModuleFiles = append(deltaBundle.ServerModuleFiles, d) + if containsRepo { + absPath, err := filepath.Abs(path) + if err != nil { + return err } - s = d + topLevelProjects = append(topLevelProjects, absPath) } } - if !found { - deltaBundle.ServerModuleFiles = append(deltaBundle.ServerModuleFiles, s) - newBundle.ServerModuleFiles = append(newBundle.ServerModuleFiles, s) - newBundle.Properties.Mappings.ServerModuleFiles = append(newBundle.Properties.Mappings.ServerModuleFiles, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } + return nil + }) + if err != nil { + return nil, err } + return topLevelProjects, nil +} - for _, s := range srcBundle.SiteMinderConfigs { - found := false - for _, d := range newBundle.SiteMinderConfigs { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.SiteMinderConfigs = append(deltaBundle.SiteMinderConfigs, d) - } - s = d - } - } - if !found { - deltaBundle.SiteMinderConfigs = append(deltaBundle.SiteMinderConfigs, s) - newBundle.SiteMinderConfigs = append(newBundle.SiteMinderConfigs, s) - newBundle.Properties.Mappings.SiteMinderConfigs = append(newBundle.Properties.Mappings.SiteMinderConfigs, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } +func determineRepoStructure(path string) (containsRepo bool, err error) { + dirs, err := os.ReadDir(path) + if err != nil { + return false, err } - - for _, s := range srcBundle.SoapServices { - found := false - for _, d := range newBundle.SoapServices { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.SoapServices = append(deltaBundle.SoapServices, d) - } - s = d - } - } - if !found { - deltaBundle.SoapServices = append(deltaBundle.SoapServices, s) - newBundle.SoapServices = append(newBundle.SoapServices, s) - newBundle.Properties.Mappings.SoapServices = append(newBundle.Properties.Mappings.SoapServices, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) + for _, dir := range dirs { + if Contains(entityFolderList, dir.Name()) && dir.IsDir() && dir.Name() != ".git" { + containsRepo = true } - } - for _, s := range srcBundle.TrustedCerts { - found := false - for _, d := range newBundle.TrustedCerts { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.TrustedCerts = append(deltaBundle.TrustedCerts, d) - } - s = d - } - } - if !found { - deltaBundle.TrustedCerts = append(deltaBundle.TrustedCerts, s) - newBundle.TrustedCerts = append(newBundle.TrustedCerts, s) - newBundle.Properties.Mappings.TrustedCerts = append(newBundle.Properties.Mappings.TrustedCerts, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - ThumbprintSha1: s.ThumbprintSha1, - }, - }) - } } - - for _, s := range srcBundle.WebApiServices { - found := false - for _, d := range newBundle.WebApiServices { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.WebApiServices = append(deltaBundle.WebApiServices, d) - } - s = d - } - } - if !found { - deltaBundle.WebApiServices = append(deltaBundle.WebApiServices, s) - newBundle.WebApiServices = append(newBundle.WebApiServices, s) - newBundle.Properties.Mappings.WebApiServices = append(newBundle.Properties.Mappings.WebApiServices, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - // AdministrativeUserAccountProperties will be kept if removed as they can't actually be removed - // future versions may reset to default when not present, this may not represent expected behaviour or cause breaking changes - // so the default will be to persist even if they aren't present in the new bundle. - for _, s := range srcBundle.AdministrativeUserAccountProperties { - found := false - for _, d := range newBundle.AdministrativeUserAccountProperties { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.AdministrativeUserAccountProperties = append(deltaBundle.AdministrativeUserAccountProperties, d) - } - s = d - } - } - if !found { - deltaBundle.AdministrativeUserAccountProperties = append(deltaBundle.AdministrativeUserAccountProperties, s) - newBundle.AdministrativeUserAccountProperties = append(newBundle.AdministrativeUserAccountProperties, s) - } - } - - if len(newBundle.PasswordPolicies) == 0 { - newBundle.PasswordPolicies = append(newBundle.PasswordPolicies, srcBundle.PasswordPolicies...) - } - - for _, s := range srcBundle.RevocationCheckPolicies { - found := false - for _, d := range newBundle.RevocationCheckPolicies { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.RevocationCheckPolicies = append(deltaBundle.RevocationCheckPolicies, d) - } - s = d - } - } - if !found { - deltaBundle.RevocationCheckPolicies = append(deltaBundle.RevocationCheckPolicies, s) - newBundle.RevocationCheckPolicies = append(newBundle.RevocationCheckPolicies, s) - newBundle.Properties.Mappings.RevocationCheckPolicies = append(newBundle.Properties.Mappings.RevocationCheckPolicies, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.LogSinks { - found := false - for _, d := range newBundle.LogSinks { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.LogSinks = append(deltaBundle.LogSinks, d) - } - s = d - } - } - if !found { - deltaBundle.LogSinks = append(deltaBundle.LogSinks, s) - newBundle.LogSinks = append(newBundle.LogSinks, s) - newBundle.Properties.Mappings.LogSinks = append(newBundle.Properties.Mappings.LogSinks, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.HttpConfigurations { - found := false - for _, d := range newBundle.HttpConfigurations { - if s.Host == d.Host && s.Port == d.Port { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.HttpConfigurations = append(deltaBundle.HttpConfigurations, d) - } - s = d - } - } - if !found { - deltaBundle.HttpConfigurations = append(deltaBundle.HttpConfigurations, s) - newBundle.HttpConfigurations = append(newBundle.HttpConfigurations, s) - newBundle.Properties.Mappings.HttpConfigurations = append(newBundle.Properties.Mappings.HttpConfigurations, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Host, - Port: s.Port, - }, - }) - } - } - - for _, s := range srcBundle.CustomKeyValues { - found := false - for _, d := range newBundle.CustomKeyValues { - if s.Key == d.Key { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.CustomKeyValues = append(deltaBundle.CustomKeyValues, d) - } - s = d - } - } - if !found { - deltaBundle.CustomKeyValues = append(deltaBundle.CustomKeyValues, s) - newBundle.CustomKeyValues = append(newBundle.CustomKeyValues, s) - newBundle.Properties.Mappings.CustomKeyValues = append(newBundle.Properties.Mappings.CustomKeyValues, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Key: s.Key, - }, - }) - } - } - - if len(newBundle.ServiceResolutionConfigs) == 0 { - newBundle.ServiceResolutionConfigs = append(newBundle.ServiceResolutionConfigs, srcBundle.ServiceResolutionConfigs...) - } - - for _, s := range srcBundle.Folders { - found := false - for _, d := range newBundle.Folders { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Folders = append(deltaBundle.Folders, d) - } - s = d - } - } - if !found { - deltaBundle.Folders = append(deltaBundle.Folders, s) - newBundle.Folders = append(newBundle.Folders, s) - newBundle.Properties.Mappings.Folders = append(newBundle.Properties.Mappings.Folders, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FederatedIdps { - found := false - for _, d := range newBundle.FederatedIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FederatedIdps = append(deltaBundle.FederatedIdps, d) - } - s = d - } - } - if !found { - deltaBundle.FederatedIdps = append(deltaBundle.FederatedIdps, s) - newBundle.FederatedIdps = append(newBundle.FederatedIdps, s) - newBundle.Properties.Mappings.FederatedIdps = append(newBundle.Properties.Mappings.FederatedIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FederatedGroups { - found := false - for _, d := range newBundle.FederatedGroups { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FederatedGroups = append(deltaBundle.FederatedGroups, d) - } - s = d - } - } - if !found { - deltaBundle.FederatedGroups = append(deltaBundle.FederatedGroups, s) - newBundle.FederatedGroups = append(newBundle.FederatedGroups, s) - newBundle.Properties.Mappings.FederatedGroups = append(newBundle.Properties.Mappings.FederatedGroups, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FederatedUsers { - found := false - for _, d := range newBundle.FederatedUsers { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FederatedUsers = append(deltaBundle.FederatedUsers, d) - } - s = d - } - } - if !found { - deltaBundle.FederatedUsers = append(deltaBundle.FederatedUsers, s) - newBundle.FederatedUsers = append(newBundle.FederatedUsers, s) - newBundle.Properties.Mappings.FederatedUsers = append(newBundle.Properties.Mappings.FederatedUsers, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.FederatedUsers { - found := false - for _, d := range newBundle.FederatedUsers { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.FederatedUsers = append(deltaBundle.FederatedUsers, d) - } - s = d - } - } - if !found { - deltaBundle.FederatedUsers = append(deltaBundle.FederatedUsers, s) - newBundle.FederatedUsers = append(newBundle.FederatedUsers, s) - newBundle.Properties.Mappings.FederatedUsers = append(newBundle.Properties.Mappings.FederatedUsers, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.InternalIdps { - found := false - for _, d := range newBundle.InternalIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.InternalIdps = append(deltaBundle.InternalIdps, d) - } - s = d - } - } - if !found { - deltaBundle.InternalIdps = append(deltaBundle.InternalIdps, s) - newBundle.InternalIdps = append(newBundle.InternalIdps, s) - newBundle.Properties.Mappings.InternalIdps = append(newBundle.Properties.Mappings.InternalIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.LdapIdps { - found := false - for _, d := range newBundle.LdapIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.LdapIdps = append(deltaBundle.LdapIdps, d) - } - s = d - } - } - if !found { - deltaBundle.LdapIdps = append(deltaBundle.LdapIdps, s) - newBundle.LdapIdps = append(newBundle.LdapIdps, s) - newBundle.Properties.Mappings.LdapIdps = append(newBundle.Properties.Mappings.LdapIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.SimpleLdapIdps { - found := false - for _, d := range newBundle.SimpleLdapIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.SimpleLdapIdps = append(deltaBundle.SimpleLdapIdps, d) - } - s = d - } - } - if !found { - deltaBundle.SimpleLdapIdps = append(deltaBundle.SimpleLdapIdps, s) - newBundle.SimpleLdapIdps = append(newBundle.SimpleLdapIdps, s) - newBundle.Properties.Mappings.SimpleLdapIdps = append(newBundle.Properties.Mappings.SimpleLdapIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.PolicyBackedIdps { - found := false - for _, d := range newBundle.PolicyBackedIdps { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.PolicyBackedIdps = append(deltaBundle.PolicyBackedIdps, d) - } - s = d - } - } - if !found { - deltaBundle.PolicyBackedIdps = append(deltaBundle.PolicyBackedIdps, s) - newBundle.PolicyBackedIdps = append(newBundle.PolicyBackedIdps, s) - newBundle.Properties.Mappings.PolicyBackedIdps = append(newBundle.Properties.Mappings.PolicyBackedIdps, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.Policies { - found := false - for _, d := range newBundle.Policies { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Policies = append(deltaBundle.Policies, d) - } - s = d - } - } - if !found { - deltaBundle.Policies = append(deltaBundle.Policies, s) - newBundle.Policies = append(newBundle.Policies, s) - newBundle.Properties.Mappings.Policies = append(newBundle.Properties.Mappings.Policies, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.Services { - found := false - for _, d := range newBundle.Services { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Services = append(deltaBundle.Services, d) - } - s = d - } - } - if !found { - deltaBundle.Services = append(deltaBundle.Services, s) - newBundle.Services = append(newBundle.Services, s) - newBundle.Properties.Mappings.Services = append(newBundle.Properties.Mappings.Services, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - ResolutionPath: s.ResolutionPath, - }, - }) - } - } - - for _, s := range srcBundle.Roles { - found := false - for _, d := range newBundle.Roles { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.Roles = append(deltaBundle.Roles, d) - } - s = d - } - } - if !found { - deltaBundle.Roles = append(deltaBundle.Roles, s) - newBundle.Roles = append(newBundle.Roles, s) - newBundle.Properties.Mappings.Roles = append(newBundle.Properties.Mappings.Roles, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.GenericEntities { - found := false - for _, d := range newBundle.GenericEntities { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.GenericEntities = append(deltaBundle.GenericEntities, d) - } - s = d - } - } - if !found { - deltaBundle.GenericEntities = append(deltaBundle.GenericEntities, s) - newBundle.GenericEntities = append(newBundle.GenericEntities, s) - newBundle.Properties.Mappings.GenericEntities = append(newBundle.Properties.Mappings.GenericEntities, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - for _, s := range srcBundle.AuditConfigurations { - found := false - for _, d := range newBundle.AuditConfigurations { - if s.Name == d.Name { - found = true - if !reflect.DeepEqual(s, d) { - deltaBundle.AuditConfigurations = append(deltaBundle.AuditConfigurations, d) - } - s = d - } - } - if !found { - deltaBundle.AuditConfigurations = append(deltaBundle.AuditConfigurations, s) - newBundle.AuditConfigurations = append(newBundle.AuditConfigurations, s) - newBundle.Properties.Mappings.AuditConfigurations = append(newBundle.Properties.Mappings.AuditConfigurations, &MappingInstructionInput{ - Action: MappingActionDelete, - Source: MappingSource{ - Name: s.Name, - }, - }) - } - } - - deltaBundle.Properties.Mappings = newBundle.Properties.Mappings - - delta, err = json.Marshal(deltaBundle) - if err != nil { - return nil, nil, err - } - combined, err = json.Marshal(newBundle) - if err != nil { - return nil, nil, err - } - - return delta, combined, nil + return containsRepo, nil } -func combineBundle(srcBundle Bundle, destBundle Bundle) Bundle { - for _, s := range srcBundle.ActiveConnectors { - found := false - for _, d := range destBundle.ActiveConnectors { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.ActiveConnectors = append(destBundle.ActiveConnectors, s) - } - } - - for _, s := range srcBundle.BackgroundTasks { - found := false - for _, d := range destBundle.BackgroundTasks { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.BackgroundTasks = append(destBundle.BackgroundTasks, s) - } - } - - for _, s := range srcBundle.CassandraConnections { - found := false - for _, d := range destBundle.CassandraConnections { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.CassandraConnections = append(destBundle.CassandraConnections, s) - } - } - - for _, s := range srcBundle.ClusterProperties { - found := false - for _, d := range destBundle.ClusterProperties { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.ClusterProperties = append(destBundle.ClusterProperties, s) - } - } - - for _, s := range srcBundle.Dtds { - found := false - for _, d := range destBundle.Dtds { - if s.PublicId == d.PublicId { - found = true - } - } - if !found { - destBundle.Dtds = append(destBundle.Dtds, s) - } - } - - for _, s := range srcBundle.EmailListeners { - found := false - for _, d := range destBundle.EmailListeners { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.EmailListeners = append(destBundle.EmailListeners, s) - } - } - - for _, s := range srcBundle.EncassConfigs { - found := false - for _, d := range destBundle.EncassConfigs { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.EncassConfigs = append(destBundle.EncassConfigs, s) - } - } - - for _, s := range srcBundle.FipGroups { - found := false - for _, d := range destBundle.FipGroups { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FipGroups = append(destBundle.FipGroups, s) - } - } - - for _, s := range srcBundle.FipUsers { - found := false - for _, d := range destBundle.FipUsers { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FipUsers = append(destBundle.FipUsers, s) - } - } - - for _, s := range srcBundle.Fips { - found := false - for _, d := range destBundle.Fips { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Fips = append(destBundle.Fips, s) - } - } - - for _, s := range srcBundle.GlobalPolicies { - found := false - for _, d := range destBundle.GlobalPolicies { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.GlobalPolicies = append(destBundle.GlobalPolicies, s) - } - } - - for _, s := range srcBundle.InternalGroups { - found := false - for _, d := range destBundle.InternalGroups { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.InternalGroups = append(destBundle.InternalGroups, s) - } - } - - for _, s := range srcBundle.InternalSoapServices { - found := false - for _, d := range destBundle.InternalSoapServices { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.InternalSoapServices = append(destBundle.InternalSoapServices, s) - } - } - - for _, s := range srcBundle.InternalUsers { - found := false - for _, d := range destBundle.InternalUsers { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.InternalUsers = append(destBundle.InternalUsers, s) - } - } - - for _, s := range srcBundle.InternalWebApiServices { - found := false - for _, d := range destBundle.InternalWebApiServices { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.InternalWebApiServices = append(destBundle.InternalWebApiServices, s) - } - } - - for _, s := range srcBundle.JdbcConnections { - found := false - for _, d := range destBundle.JdbcConnections { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.JdbcConnections = append(destBundle.JdbcConnections, s) - } - } - - for _, s := range srcBundle.JmsDestinations { - found := false - for _, d := range destBundle.JmsDestinations { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.JmsDestinations = append(destBundle.JmsDestinations, s) - } - } - - for _, s := range srcBundle.Keys { - found := false - for _, d := range destBundle.Keys { - if s.Alias == d.Alias { - found = true - } - } - if !found { - destBundle.Keys = append(destBundle.Keys, s) - } - } - - for _, s := range srcBundle.LdapIdps { - found := false - for _, d := range destBundle.LdapIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.LdapIdps = append(destBundle.LdapIdps, s) - } - } - - for _, s := range srcBundle.ListenPorts { - found := false - for _, d := range destBundle.ListenPorts { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.ListenPorts = append(destBundle.ListenPorts, s) - } - } - - for _, s := range srcBundle.PolicyFragments { - found := false - for _, d := range destBundle.PolicyFragments { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.PolicyFragments = append(destBundle.PolicyFragments, s) - } - } - - for _, s := range srcBundle.ScheduledTasks { - found := false - for _, d := range destBundle.ScheduledTasks { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.ScheduledTasks = append(destBundle.ScheduledTasks, s) - } - } - - for _, s := range srcBundle.Schemas { - found := false - for _, d := range destBundle.Schemas { - if s.SystemId == d.SystemId { - found = true - } - } - if !found { - destBundle.Schemas = append(destBundle.Schemas, s) - } - } - - for _, s := range srcBundle.Secrets { - found := false - for _, d := range destBundle.Secrets { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Secrets = append(destBundle.Secrets, s) - } - } - - for _, s := range srcBundle.ServerModuleFiles { - found := false - for _, d := range destBundle.ServerModuleFiles { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.ServerModuleFiles = append(destBundle.ServerModuleFiles, s) - } - } - - for _, s := range srcBundle.SiteMinderConfigs { - found := false - for _, d := range destBundle.SiteMinderConfigs { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.SiteMinderConfigs = append(destBundle.SiteMinderConfigs, s) - } - } - - for _, s := range srcBundle.SoapServices { - found := false - for _, d := range destBundle.SoapServices { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.SoapServices = append(destBundle.SoapServices, s) - } - } - - for _, s := range srcBundle.TrustedCerts { - found := false - for _, d := range destBundle.TrustedCerts { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.TrustedCerts = append(destBundle.TrustedCerts, s) - } - } - - for _, s := range srcBundle.TrustedCerts { - found := false - for _, d := range destBundle.TrustedCerts { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.TrustedCerts = append(destBundle.TrustedCerts, s) - } - } - - for _, s := range srcBundle.WebApiServices { - found := false - for _, d := range destBundle.WebApiServices { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.WebApiServices = append(destBundle.WebApiServices, s) - } - } - - for _, s := range srcBundle.AdministrativeUserAccountProperties { - found := false - for _, d := range destBundle.AdministrativeUserAccountProperties { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.AdministrativeUserAccountProperties = append(destBundle.AdministrativeUserAccountProperties, s) - } - } - - if len(destBundle.PasswordPolicies) == 0 { - destBundle.PasswordPolicies = append(destBundle.PasswordPolicies, srcBundle.PasswordPolicies...) - } - - for _, s := range srcBundle.RevocationCheckPolicies { - found := false - for _, d := range destBundle.RevocationCheckPolicies { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.RevocationCheckPolicies = append(destBundle.RevocationCheckPolicies, s) - } - } - - for _, s := range srcBundle.LogSinks { - found := false - for _, d := range destBundle.LogSinks { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.LogSinks = append(destBundle.LogSinks, s) - } - } - - for _, s := range srcBundle.HttpConfigurations { - found := false - for _, d := range destBundle.HttpConfigurations { - if s.Host == d.Host { - found = true - } - } - if !found { - destBundle.HttpConfigurations = append(destBundle.HttpConfigurations, s) - } - } - - for _, s := range srcBundle.CustomKeyValues { - found := false - for _, d := range destBundle.CustomKeyValues { - if s.Key == d.Key { - found = true - } - } - if !found { - destBundle.CustomKeyValues = append(destBundle.CustomKeyValues, s) - } - } - - if len(destBundle.ServiceResolutionConfigs) == 0 { - destBundle.ServiceResolutionConfigs = append(destBundle.ServiceResolutionConfigs, srcBundle.ServiceResolutionConfigs...) - } - - for _, s := range srcBundle.Folders { - found := false - for _, d := range destBundle.Folders { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Folders = append(destBundle.Folders, s) - } - } - - for _, s := range srcBundle.FederatedIdps { - found := false - for _, d := range destBundle.FederatedIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FederatedIdps = append(destBundle.FederatedIdps, s) - } - } - - for _, s := range srcBundle.FederatedGroups { - found := false - for _, d := range destBundle.FederatedGroups { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FederatedGroups = append(destBundle.FederatedGroups, s) - } - } - - for _, s := range srcBundle.FederatedUsers { - found := false - for _, d := range destBundle.FederatedUsers { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FederatedUsers = append(destBundle.FederatedUsers, s) - } - } - - for _, s := range srcBundle.FederatedUsers { - found := false - for _, d := range destBundle.FederatedUsers { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.FederatedUsers = append(destBundle.FederatedUsers, s) - } - } - - for _, s := range srcBundle.InternalIdps { - found := false - for _, d := range destBundle.InternalIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.InternalIdps = append(destBundle.InternalIdps, s) - } - } - - for _, s := range srcBundle.LdapIdps { - found := false - for _, d := range destBundle.LdapIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.LdapIdps = append(destBundle.LdapIdps, s) - } - } - - for _, s := range srcBundle.SimpleLdapIdps { - found := false - for _, d := range destBundle.SimpleLdapIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.SimpleLdapIdps = append(destBundle.SimpleLdapIdps, s) - } - } - - for _, s := range srcBundle.PolicyBackedIdps { - found := false - for _, d := range destBundle.PolicyBackedIdps { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.PolicyBackedIdps = append(destBundle.PolicyBackedIdps, s) - } - } - - for _, s := range srcBundle.Policies { - found := false - for _, d := range destBundle.Policies { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Policies = append(destBundle.Policies, s) - } - } - - for _, s := range srcBundle.Services { - found := false - for _, d := range destBundle.Services { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Services = append(destBundle.Services, s) - } - } - - for _, s := range srcBundle.Roles { - found := false - for _, d := range destBundle.Roles { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.Roles = append(destBundle.Roles, s) - } - } - - for _, s := range srcBundle.GenericEntities { - found := false - for _, d := range destBundle.GenericEntities { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.GenericEntities = append(destBundle.GenericEntities, s) - } - } - - for _, s := range srcBundle.AuditConfigurations { - found := false - for _, d := range destBundle.AuditConfigurations { - if s.Name == d.Name { - found = true - } - } - if !found { - destBundle.AuditConfigurations = append(destBundle.AuditConfigurations, s) - } - } - - return destBundle +func ResetDelta(src []byte) (dst []byte, err error) { + return nil, nil } func installGenericBundle( diff --git a/internal/graphman/bundle_helpers.go b/internal/graphman/bundle_helpers.go new file mode 100644 index 00000000..00fac20c --- /dev/null +++ b/internal/graphman/bundle_helpers.go @@ -0,0 +1,1149 @@ +/* +* Copyright (c) 2025 Broadcom. All rights reserved. +* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +* All trademarks, trade names, service marks, and logos referenced +* herein belong to their respective companies. +* +* This software and all information contained therein is confidential +* and proprietary and shall not be duplicated, used, disclosed or +* disseminated in any way except as authorized by the applicable +* license agreement, without the express written permission of Broadcom. +* All authorized reproductions must be marked with this language. +* +* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE +* EXTENT PERMITTED BY APPLICABLE LAW OR AS AGREED BY BROADCOM IN ITS +* APPLICABLE LICENSE AGREEMENT, BROADCOM PROVIDES THIS DOCUMENTATION +* "AS IS" WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION, +* ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* PURPOSE, OR. NONINFRINGEMENT. IN NO EVENT WILL BROADCOM BE LIABLE TO +* THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR +* INDIRECT, FROM THE USE OF THIS DOCUMENTATION, INCLUDING WITHOUT LIMITATION, +* LOST PROFITS, LOST INVESTMENT, BUSINESS INTERRUPTION, GOODWILL, OR +* LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE +* POSSIBILITY OF SUCH LOSS OR DAMAGE. +* +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. + */ +package graphman + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" +) + +// CombineWithOverwrite combines bundles where src overwrites dest entities (latest wins) +// and removes delete mappings for re-added entities +func CombineWithOverwrite(src Bundle, dest Bundle) (Bundle, error) { + // Recover from reflection panics + defer func() { + if r := recover(); r != nil { + dest = Bundle{} + } + }() + + // Merge using reflection - src overwrites dest + destVal := reflect.ValueOf(&dest).Elem() + srcVal := reflect.ValueOf(src) + + for i := 0; i < srcVal.NumField(); i++ { + srcField := srcVal.Field(i) + destField := destVal.Field(i) + fieldName := srcVal.Type().Field(i).Name + + // Skip Properties field - handle separately + if fieldName == "Properties" { + continue + } + + // Only process slice fields (entity lists) + if srcField.Kind() != reflect.Slice || destField.Kind() != reflect.Slice { + continue + } + + if srcField.Len() == 0 { + continue + } + + // Get ID for entity matching + // Uses primary identifier fields based on entity type + getID := func(e reflect.Value, fieldName string) string { + if e.Kind() == reflect.Ptr { + e = e.Elem() + } + + // Define primary identifiers for different entity types + // These determine when entities are considered "the same" + var primaryFields []string + + switch fieldName { + case "Services", "Policies", "PolicyFragments": + // Services/Policies: Match on Name only (folder is just a property) + primaryFields = []string{"Name"} + case "HttpConfigurations": + // HTTP configs: Must match both Host AND Port + primaryFields = []string{"Host", "Port"} + case "Keys": + // Keys: Match on Alias (within default keystore) + primaryFields = []string{"Alias"} + case "TrustedCerts": + // Certs: Match on thumbprint + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + // Schemas/DTDs: Match on SystemId + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + // Custom KV: Match on Key + primaryFields = []string{"Key"} + default: + // Default: Match on Name + primaryFields = []string{"Name"} + } + + // Build ID from primary fields + var parts []string + for _, field := range primaryFields { + if f := e.FieldByName(field); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" { + parts = append(parts, val) + } + } + } + + if len(parts) == 0 { + return "" + } + + return strings.Join(parts, "|") + } + + // Build map of src entities by ID (deduplicates within src itself) + srcMap := make(map[string]reflect.Value) + for j := 0; j < srcField.Len(); j++ { + entity := srcField.Index(j) + if id := getID(entity, fieldName); id != "" { + srcMap[id] = entity // Later entries with same ID overwrite earlier ones + } + } + + // Overwrite/append: replace dest entities with src if same ID, keep others + newSlice := reflect.MakeSlice(destField.Type(), 0, destField.Len()+len(srcMap)) + + // Add dest entities (but skip if being overwritten by src) + for j := 0; j < destField.Len(); j++ { + entity := destField.Index(j) + id := getID(entity, fieldName) + if _, beingOverwritten := srcMap[id]; !beingOverwritten { + newSlice = reflect.Append(newSlice, entity) + } + } + + // Add unique src entities from map (this automatically deduplicates) + for _, entity := range srcMap { + newSlice = reflect.Append(newSlice, entity) + } + + destField.Set(newSlice) + } + + // Merge properties + if src.Properties != nil { + if dest.Properties == nil { + dest.Properties = &BundleProperties{} + } + if src.Properties.DefaultAction != "" { + dest.Properties.DefaultAction = src.Properties.DefaultAction + } + if src.Properties.Meta.Id != "" { + dest.Properties.Meta = src.Properties.Meta + } + // Merge mappings from src + if err := mergeMappings(&dest.Properties.Mappings, src.Properties.Mappings); err != nil { + return dest, fmt.Errorf("failed to merge mappings: %w", err) + } + } + + // Clean delete mappings only for entities that are being re-added from src + if err := CleanDeleteMappingsForEntities(&dest, src); err != nil { + return dest, fmt.Errorf("failed to clean delete mappings: %w", err) + } + + return dest, nil +} + +// CombineWithOverwritePreservingDeleteMappings merges bundles like CombineWithOverwrite but preserves ALL DELETE mappings. +// This is used when concatenating repository-controlled bundles (combined.json, latest.json) where the +// repository controller has already determined the correct DELETE mappings. +// Unlike CombineWithOverwrite, this does NOT call CleanDeleteMappingsForEntities. +func CombineWithOverwritePreservingDeleteMappings(src Bundle, dest Bundle) (Bundle, error) { + // Recover from reflection panics + defer func() { + if r := recover(); r != nil { + dest = Bundle{} + } + }() + + // Merge using reflection - src overwrites dest + destVal := reflect.ValueOf(&dest).Elem() + srcVal := reflect.ValueOf(src) + + for i := 0; i < srcVal.NumField(); i++ { + srcField := srcVal.Field(i) + destField := destVal.Field(i) + fieldName := srcVal.Type().Field(i).Name + + // Skip Properties field - handle separately + if fieldName == "Properties" { + continue + } + + // Only process slice fields (entity lists) + if srcField.Kind() != reflect.Slice || destField.Kind() != reflect.Slice { + continue + } + + if srcField.Len() == 0 { + continue + } + + // Get ID for entity matching + // Uses primary identifier fields based on entity type + getID := func(e reflect.Value, fieldName string) string { + if e.Kind() == reflect.Ptr { + e = e.Elem() + } + + // Define primary identifiers for different entity types + // These determine when entities are considered "the same" + var primaryFields []string + + switch fieldName { + case "Services", "Policies", "PolicyFragments": + // Services/Policies: Match on Name only (folder is just a property) + primaryFields = []string{"Name"} + case "HttpConfigurations": + // HTTP configs: Must match both Host AND Port + primaryFields = []string{"Host", "Port"} + case "Keys": + // Keys: Match on Alias (within default keystore) + primaryFields = []string{"Alias"} + case "TrustedCerts": + // Certs: Match on thumbprint + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + // Schemas/DTDs: Match on SystemId + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + // Custom KV: Match on Key + primaryFields = []string{"Key"} + default: + // Default: Match on Name + primaryFields = []string{"Name"} + } + + // Build ID from primary fields + var parts []string + for _, field := range primaryFields { + if f := e.FieldByName(field); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" { + parts = append(parts, val) + } + } + } + + if len(parts) == 0 { + return "" + } + + return strings.Join(parts, "|") + } + + // Build map of src entities by ID (deduplicates within src itself) + srcMap := make(map[string]reflect.Value) + for j := 0; j < srcField.Len(); j++ { + entity := srcField.Index(j) + if id := getID(entity, fieldName); id != "" { + srcMap[id] = entity // Later entries with same ID overwrite earlier ones + } + } + + // Overwrite/append: replace dest entities with src if same ID, keep others + newSlice := reflect.MakeSlice(destField.Type(), 0, destField.Len()+len(srcMap)) + + // Add dest entities (but skip if being overwritten by src) + for j := 0; j < destField.Len(); j++ { + entity := destField.Index(j) + id := getID(entity, fieldName) + if _, beingOverwritten := srcMap[id]; !beingOverwritten { + newSlice = reflect.Append(newSlice, entity) + } + } + + // Add unique src entities from map (this automatically deduplicates) + for _, entity := range srcMap { + newSlice = reflect.Append(newSlice, entity) + } + + destField.Set(newSlice) + } + + // Merge properties + if src.Properties != nil { + if dest.Properties == nil { + dest.Properties = &BundleProperties{} + } + if src.Properties.DefaultAction != "" { + dest.Properties.DefaultAction = src.Properties.DefaultAction + } + if src.Properties.Meta.Id != "" { + dest.Properties.Meta = src.Properties.Meta + } + // Merge mappings from src + if err := mergeMappings(&dest.Properties.Mappings, src.Properties.Mappings); err != nil { + return dest, fmt.Errorf("failed to merge mappings: %w", err) + } + } + + // SKIP CleanDeleteMappingsForEntities - preserve ALL DELETE mappings as-is + // The repository controller has already determined the correct mappings + + return dest, nil +} + +// mergeMappings combines mapping instructions from src into dest +func mergeMappings(dest *BundleMappings, src BundleMappings) error { + defer func() { + if r := recover(); r != nil { + // Silently recover from reflection panics + } + }() + + if dest == nil { + return fmt.Errorf("destination mappings is nil") + } + + destVal := reflect.ValueOf(dest).Elem() + srcVal := reflect.ValueOf(src) + + for i := 0; i < srcVal.NumField(); i++ { + srcField := srcVal.Field(i) + destField := destVal.Field(i) + + if srcField.Kind() == reflect.Slice && srcField.Len() > 0 { + // Append src mappings to dest + for j := 0; j < srcField.Len(); j++ { + destField.Set(reflect.Append(destField, srcField.Index(j))) + } + } + } + + return nil +} + +// CleanDeleteMappingsForEntities removes delete mappings only for entities that exist in the source bundle +// WITHOUT delete mappings. This ensures delete mappings are only removed when an entity is explicitly +// re-added (not when it's being deleted). +func CleanDeleteMappingsForEntities(bundle *Bundle, source Bundle) error { + defer func() { + if r := recover(); r != nil { + // Silently recover from reflection panics + } + }() + + if bundle == nil || bundle.Properties == nil { + return nil + } + + // Build set of entity IDs from source bundle (entities being added/updated) + sourceEntityIDs := make(map[string]map[string]bool) // fieldName -> {id -> true} + + // Build set of entity IDs that have DELETE mappings in source + sourceDeleteMappings := make(map[string]map[string]bool) // fieldName -> {id -> true} + + sourceVal := reflect.ValueOf(source) + for i := 0; i < sourceVal.NumField(); i++ { + fieldName := sourceVal.Type().Field(i).Name + + if fieldName == "Properties" { + continue + } + + srcField := sourceVal.Field(i) + if srcField.Kind() != reflect.Slice { + continue + } + + sourceEntityIDs[fieldName] = make(map[string]bool) + + for j := 0; j < srcField.Len(); j++ { + entity := srcField.Index(j) + if entity.Kind() == reflect.Ptr { + e := entity.Elem() + + // Get primary identifier based on entity type + var primaryFields []string + switch fieldName { + case "Services", "Policies", "PolicyFragments": + primaryFields = []string{"Name"} + case "HttpConfigurations": + primaryFields = []string{"Host", "Port"} + case "Keys": + primaryFields = []string{"Alias"} + case "TrustedCerts": + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + primaryFields = []string{"Key"} + default: + primaryFields = []string{"Name"} + } + + // Collect IDs from this entity + for _, field := range primaryFields { + if f := e.FieldByName(field); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" { + sourceEntityIDs[fieldName][val] = true + } + } + } + } + } + } + + // Build set of entity IDs that have DELETE mappings in source + if source.Properties != nil { + sourceMappingsVal := reflect.ValueOf(source.Properties.Mappings) + for i := 0; i < sourceMappingsVal.NumField(); i++ { + field := sourceMappingsVal.Field(i) + fieldName := sourceMappingsVal.Type().Field(i).Name + + if field.Kind() != reflect.Slice { + continue + } + + sourceDeleteMappings[fieldName] = make(map[string]bool) + + for j := 0; j < field.Len(); j++ { + m := field.Index(j).Interface().(*MappingInstructionInput) + if m.Action == MappingActionDelete { + var name, alias, systemId, key string + + if src, ok := m.Source.(MappingSource); ok { + name = src.Name + alias = src.Alias + systemId = src.SystemId + key = src.Key + } else if srcMap, ok := m.Source.(map[string]interface{}); ok { + if v, ok := srcMap["name"].(string); ok { + name = v + } + if v, ok := srcMap["alias"].(string); ok { + alias = v + } + if v, ok := srcMap["systemId"].(string); ok { + systemId = v + } + if v, ok := srcMap["key"].(string); ok { + key = v + } + } + + ids := []string{name, alias, systemId, key} + for _, id := range ids { + if id != "" { + sourceDeleteMappings[fieldName][id] = true + } + } + } + } + } + } + + // Now remove delete mappings only for entities present in source WITHOUT delete mappings + mappingsVal := reflect.ValueOf(&bundle.Properties.Mappings).Elem() + + for i := 0; i < mappingsVal.NumField(); i++ { + field := mappingsVal.Field(i) + fieldName := mappingsVal.Type().Field(i).Name + + if field.Kind() != reflect.Slice || field.Len() == 0 { + continue + } + + entityIDs := sourceEntityIDs[fieldName] + deleteMappingIDs := sourceDeleteMappings[fieldName] + + if len(entityIDs) == 0 { + continue // No entities from source for this type, keep all mappings + } + + // Filter mappings - keep only those NOT in source entities OR if source has delete mapping for them + newMappings := reflect.MakeSlice(field.Type(), 0, field.Len()) + + for j := 0; j < field.Len(); j++ { + mapping := field.Index(j) + m := mapping.Interface().(*MappingInstructionInput) + + shouldKeep := true + + if m.Action == MappingActionDelete { + // Check if this delete mapping is for an entity in source + var name, alias, systemId, key string + + if src, ok := m.Source.(MappingSource); ok { + name = src.Name + alias = src.Alias + systemId = src.SystemId + key = src.Key + } else if srcMap, ok := m.Source.(map[string]interface{}); ok { + if v, ok := srcMap["name"].(string); ok { + name = v + } + if v, ok := srcMap["alias"].(string); ok { + alias = v + } + if v, ok := srcMap["systemId"].(string); ok { + systemId = v + } + if v, ok := srcMap["key"].(string); ok { + key = v + } + } + + // Check if any ID matches an entity in source + ids := []string{name, alias, systemId, key} + for _, id := range ids { + if id != "" && entityIDs[id] { + // Entity exists in source - only remove delete mapping if source DOESN'T have delete mapping + if !deleteMappingIDs[id] { + shouldKeep = false // Entity being re-added, remove delete mapping + } + // If source HAS delete mapping for this ID, keep it (entity is being deleted) + break + } + } + } + + if shouldKeep { + newMappings = reflect.Append(newMappings, mapping) + } + } + + field.Set(newMappings) + } + + return nil +} + +// CalculateDelta compares current state with desired state +// Parameters: +// - current: the current state (what exists now on the gateway) +// - desired: the desired state (what you want it to be) +// Returns: +// - delta: minimal changes needed (new/changed entities + delete mappings) +// - combined: full bundle with all entities from desired + delete mappings for removed items +// - error: any error that occurred during processing +func CalculateDelta(current Bundle, desired Bundle) (delta Bundle, combined Bundle, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic during delta calculation: %v", r) + delta = Bundle{} + combined = Bundle{} + } + }() + delta = Bundle{ + Properties: &BundleProperties{ + Mappings: BundleMappings{}, + }, + } + + // Combined starts with all desired entities (deep copy) + combined = Bundle{ + Properties: &BundleProperties{ + Mappings: BundleMappings{}, + }, + } + + desiredVal := reflect.ValueOf(desired) + currentVal := reflect.ValueOf(current) + deltaVal := reflect.ValueOf(&delta).Elem() + combinedVal := reflect.ValueOf(&combined).Elem() + + getID := func(e reflect.Value, fieldName string) string { + if e.Kind() == reflect.Ptr { + e = e.Elem() + } + + // Define primary identifiers for different entity types + var primaryFields []string + + switch fieldName { + case "Services", "Policies", "PolicyFragments": + // Services/Policies: Match on Name only + primaryFields = []string{"Name"} + case "HttpConfigurations": + // HTTP configs: Must match both Host AND Port + primaryFields = []string{"Host", "Port"} + case "Keys": + // Keys: Match on Alias + primaryFields = []string{"Alias"} + case "TrustedCerts": + // Certs: Match on thumbprint + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + // Schemas/DTDs: Match on SystemId + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + // Custom KV: Match on Key + primaryFields = []string{"Key"} + default: + // Default: Match on Name + primaryFields = []string{"Name"} + } + + // Build ID from primary fields + var parts []string + for _, field := range primaryFields { + if f := e.FieldByName(field); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" { + parts = append(parts, val) + } + } + } + + if len(parts) == 0 { + return "" + } + + return strings.Join(parts, "|") + } + + getMappingSource := func(e reflect.Value, fieldName string) MappingSource { + if e.Kind() == reflect.Ptr { + e = e.Elem() + } + + src := MappingSource{} + + // Handle different ID types + if name := e.FieldByName("Name"); name.IsValid() && name.Kind() == reflect.String { + src.Name = name.String() + } + if alias := e.FieldByName("Alias"); alias.IsValid() && alias.Kind() == reflect.String { + src.Alias = alias.String() + } + if systemId := e.FieldByName("SystemId"); systemId.IsValid() && systemId.Kind() == reflect.String { + src.SystemId = systemId.String() + } + if key := e.FieldByName("Key"); key.IsValid() && key.Kind() == reflect.String { + src.Key = key.String() + } + if resPath := e.FieldByName("ResolutionPath"); resPath.IsValid() && resPath.Kind() == reflect.String { + src.ResolutionPath = resPath.String() + } + if thumb := e.FieldByName("ThumbprintSha1"); thumb.IsValid() && thumb.Kind() == reflect.String { + src.ThumbprintSha1 = thumb.String() + } + + // Special case for HttpConfiguration (Host + Port) + if fieldName == "HttpConfigurations" { + if host := e.FieldByName("Host"); host.IsValid() && host.Kind() == reflect.String { + src.Name = host.String() + } + if port := e.FieldByName("Port"); port.IsValid() && port.Kind() == reflect.Int { + src.Port = int(port.Int()) + } + } + + return src + } + + // Process each entity type + for i := 0; i < desiredVal.NumField(); i++ { + fieldName := desiredVal.Type().Field(i).Name + + // Skip Properties + if fieldName == "Properties" { + continue + } + + desiredField := desiredVal.Field(i) + currentField := currentVal.Field(i) + deltaField := deltaVal.Field(i) + combinedField := combinedVal.Field(i) + + // Only process slices + if desiredField.Kind() != reflect.Slice || currentField.Kind() != reflect.Slice { + continue + } + + // Build maps of entities by ID + desiredMap := make(map[string]reflect.Value) + currentMap := make(map[string]reflect.Value) + + for j := 0; j < desiredField.Len(); j++ { + entity := desiredField.Index(j) + if id := getID(entity, fieldName); id != "" { + desiredMap[id] = entity + } + } + + for j := 0; j < currentField.Len(); j++ { + entity := currentField.Index(j) + if id := getID(entity, fieldName); id != "" { + currentMap[id] = entity + } + } + + // Add ALL desired entities to combined + for j := 0; j < desiredField.Len(); j++ { + entity := desiredField.Index(j) + combinedField.Set(reflect.Append(combinedField, entity)) + } + + // Find entities to add/update (in desired but not in current OR changed) + for id, desiredEntity := range desiredMap { + if currentEntity, exists := currentMap[id]; !exists { + // New entity - add to delta + deltaField.Set(reflect.Append(deltaField, desiredEntity)) + } else { + // Entity exists - check if changed + if !reflect.DeepEqual(desiredEntity.Interface(), currentEntity.Interface()) { + // Changed - add to delta + deltaField.Set(reflect.Append(deltaField, desiredEntity)) + } + } + } + + // Find entities to delete (in current but not in desired) + mappingFieldName := fieldName + + // Add delete mappings to both delta and combined + deltaMappingsVal := reflect.ValueOf(&delta.Properties.Mappings).Elem() + combinedMappingsVal := reflect.ValueOf(&combined.Properties.Mappings).Elem() + + deltaMappingField := deltaMappingsVal.FieldByName(mappingFieldName) + combinedMappingField := combinedMappingsVal.FieldByName(mappingFieldName) + + if deltaMappingField.IsValid() && deltaMappingField.Kind() == reflect.Slice { + for id, currentEntity := range currentMap { + if _, existsInDesired := desiredMap[id]; !existsInDesired { + // Entity in current but not desired - add entity and delete mapping to both delta and combined + // Add the entity to delta (so gateway knows what to delete) + deltaField.Set(reflect.Append(deltaField, currentEntity)) + + // Add the entity to combined (so it has complete state) + combinedField.Set(reflect.Append(combinedField, currentEntity)) + + // Add delete mapping + deleteMapping := &MappingInstructionInput{ + Action: MappingActionDelete, + Source: getMappingSource(currentEntity, fieldName), + } + + // Add delete mapping to delta + deltaMappingField.Set(reflect.Append(deltaMappingField, reflect.ValueOf(deleteMapping))) + + // Add delete mapping to combined + if combinedMappingField.IsValid() && combinedMappingField.Kind() == reflect.Slice { + combinedMappingField.Set(reflect.Append(combinedMappingField, reflect.ValueOf(deleteMapping))) + } + } + } + } + } + + return delta, combined, nil +} + +// ResetMappings applies delete mappings to a bundle by removing entities marked for deletion +// and clearing the mappings. This is useful after applying a bundle to reset it for the next iteration. +func ResetMappings(bundle *Bundle) error { + defer func() { + if r := recover(); r != nil { + // Silently recover from reflection panics + } + }() + + if bundle == nil { + return fmt.Errorf("bundle is nil") + } + + if bundle.Properties == nil || len(bundle.Properties.Mappings.ClusterProperties) == 0 { + // No mappings to apply, but check all mapping types + hasAnyMappings := false + if bundle.Properties != nil { + mappingsVal := reflect.ValueOf(bundle.Properties.Mappings) + for i := 0; i < mappingsVal.NumField(); i++ { + field := mappingsVal.Field(i) + if field.Kind() == reflect.Slice && field.Len() > 0 { + hasAnyMappings = true + break + } + } + } + if !hasAnyMappings { + return nil // No mappings, nothing to do + } + } + + // Build set of entity IDs marked for deletion + toDelete := make(map[string]map[string]bool) // fieldName -> {id -> true} + + mappingsVal := reflect.ValueOf(bundle.Properties.Mappings) + for i := 0; i < mappingsVal.NumField(); i++ { + field := mappingsVal.Field(i) + fieldName := mappingsVal.Type().Field(i).Name + + if field.Kind() == reflect.Slice && field.Len() > 0 { + toDelete[fieldName] = make(map[string]bool) + + for j := 0; j < field.Len(); j++ { + m := field.Index(j).Interface().(*MappingInstructionInput) + + if m.Action == MappingActionDelete { + var name, alias, systemId, key, resolutionPath, thumbprint string + var port int + + // Handle both MappingSource struct and map[string]interface{} (from JSON) + if src, ok := m.Source.(MappingSource); ok { + name = src.Name + alias = src.Alias + systemId = src.SystemId + key = src.Key + resolutionPath = src.ResolutionPath + thumbprint = src.ThumbprintSha1 + port = src.Port + } else if srcMap, ok := m.Source.(map[string]interface{}); ok { + if v, ok := srcMap["name"].(string); ok { + name = v + } + if v, ok := srcMap["alias"].(string); ok { + alias = v + } + if v, ok := srcMap["systemId"].(string); ok { + systemId = v + } + if v, ok := srcMap["key"].(string); ok { + key = v + } + if v, ok := srcMap["resolutionPath"].(string); ok { + resolutionPath = v + } + if v, ok := srcMap["thumbprintSha1"].(string); ok { + thumbprint = v + } + if v, ok := srcMap["port"].(float64); ok { + port = int(v) + } + } + + // Collect all possible IDs from the mapping source + ids := []string{name, alias, systemId, key, resolutionPath, thumbprint} + for _, id := range ids { + if id != "" { + toDelete[fieldName][id] = true + } + } + // Handle composite IDs for HttpConfiguration + if name != "" && port != 0 { + compositeID := fmt.Sprintf("%s|%d", name, port) + toDelete[fieldName][compositeID] = true + } + } + } + } + } + + // Remove entities marked for deletion from each slice + bundleVal := reflect.ValueOf(bundle).Elem() + for i := 0; i < bundleVal.NumField(); i++ { + field := bundleVal.Field(i) + fieldName := bundleVal.Type().Field(i).Name + + // Skip Properties field + if fieldName == "Properties" { + continue + } + + if field.Kind() != reflect.Slice { + continue + } + + deleteSet, hasDeletes := toDelete[fieldName] + if !hasDeletes || len(deleteSet) == 0 { + continue + } + + // Filter out entities marked for deletion + newSlice := reflect.MakeSlice(field.Type(), 0, field.Len()) + + for j := 0; j < field.Len(); j++ { + entity := field.Index(j) + shouldDelete := false + + // Get entity ID using same logic as getID + if entity.Kind() == reflect.Ptr { + e := entity.Elem() + + // Check primary identifier fields + var primaryFields []string + switch fieldName { + case "Services", "Policies", "PolicyFragments": + primaryFields = []string{"Name"} + case "HttpConfigurations": + primaryFields = []string{"Host", "Port"} + case "Keys": + primaryFields = []string{"Alias"} + case "TrustedCerts": + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + primaryFields = []string{"Key"} + default: + primaryFields = []string{"Name"} + } + + // Check if this entity should be deleted + for _, fieldName := range primaryFields { + if f := e.FieldByName(fieldName); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" && deleteSet[val] { + shouldDelete = true + break + } + } + } + + // Special handling for HttpConfiguration composite ID + if fieldName == "HttpConfigurations" { + if host := e.FieldByName("Host"); host.IsValid() && host.Kind() == reflect.String { + if port := e.FieldByName("Port"); port.IsValid() && port.Kind() == reflect.Int { + compositeID := fmt.Sprintf("%s|%d", host.String(), port.Int()) + if deleteSet[compositeID] { + shouldDelete = true + } + } + } + } + } + + // Keep entity if not marked for deletion + if !shouldDelete { + newSlice = reflect.Append(newSlice, entity) + } + } + + field.Set(newSlice) + } + + // Clear all mappings after applying them + if bundle.Properties != nil { + bundle.Properties.Mappings = BundleMappings{} + } + + return nil +} + +// RemoveDuplicates removes duplicate entities from a bundle using the same unique identifier +// logic as CombineWithOverwrite (name, alias, thumbprint, systemId, etc. + goid). +// If an entity appears multiple times, only the first occurrence is kept. +// Takes a JSON byte array and returns a deduplicated JSON byte array. +func RemoveDuplicates(bundleBytes []byte) ([]byte, error) { + defer func() { + if r := recover(); r != nil { + // Silently recover from reflection panics + } + }() + + if len(bundleBytes) == 0 { + return bundleBytes, nil + } + + // Unmarshal the bundle + var bundle Bundle + err := json.Unmarshal(bundleBytes, &bundle) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle: %w", err) + } + + // Function to get multiple IDs for an entity - if ANY match, it's a duplicate + // This catches both name matches AND goid matches + getIDs := func(e reflect.Value, fieldName string) []string { + if e.Kind() == reflect.Ptr { + e = e.Elem() + } + + var ids []string + + // Define primary identifiers for different entity types + var primaryFields []string + + switch fieldName { + case "Services", "Policies", "PolicyFragments": + primaryFields = []string{"Name"} + case "HttpConfigurations": + primaryFields = []string{"Host", "Port"} + case "Keys": + primaryFields = []string{"Alias"} + case "TrustedCerts": + primaryFields = []string{"ThumbprintSha1"} + case "Schemas", "Dtds": + primaryFields = []string{"SystemId"} + case "CustomKeyValues": + primaryFields = []string{"Key"} + default: + primaryFields = []string{"Name"} + } + + // Build ID from primary fields + var parts []string + for _, field := range primaryFields { + if f := e.FieldByName(field); f.IsValid() { + var val string + switch f.Kind() { + case reflect.String: + val = f.String() + case reflect.Int, reflect.Int32, reflect.Int64: + if f.Int() != 0 { + val = fmt.Sprintf("%d", f.Int()) + } + } + if val != "" { + parts = append(parts, val) + } + } + } + + if len(parts) > 0 { + // Add primary identifier ID (e.g., "name:mydb") + ids = append(ids, "primary:"+strings.Join(parts, "|")) + } + + // Also check goid separately - if goid matches, it's a duplicate regardless of name + if goidField := e.FieldByName("Goid"); goidField.IsValid() && goidField.Kind() == reflect.String { + goid := goidField.String() + if goid != "" { + // Add goid as separate ID (e.g., "goid:84449671abe2a5b143051dbdfdf7e76e") + ids = append(ids, "goid:"+goid) + } + } + + return ids + } + + // Remove duplicates using reflection + bundleVal := reflect.ValueOf(&bundle).Elem() + + for i := 0; i < bundleVal.NumField(); i++ { + field := bundleVal.Field(i) + fieldName := bundleVal.Type().Field(i).Name + + // Skip Properties field + if fieldName == "Properties" { + continue + } + + // Only process slices + if field.Kind() != reflect.Slice { + continue + } + + if field.Len() == 0 { + continue + } + + // Track seen entities by their IDs (name OR goid can indicate duplicate) + seenIDs := make(map[string]bool) + newSlice := reflect.MakeSlice(field.Type(), 0, field.Len()) + + for j := 0; j < field.Len(); j++ { + entity := field.Index(j) + + // Get all possible IDs for this entity + ids := getIDs(entity, fieldName) + + if len(ids) == 0 { + // If we can't determine any ID, keep the entity + newSlice = reflect.Append(newSlice, entity) + continue + } + + // Check if we've seen ANY of these IDs before + isDuplicate := false + for _, id := range ids { + if seenIDs[id] { + isDuplicate = true + break + } + } + + if !isDuplicate { + // First occurrence, mark ALL IDs as seen and keep the entity + for _, id := range ids { + seenIDs[id] = true + } + newSlice = reflect.Append(newSlice, entity) + } + // If it's a duplicate, skip it (don't append) + } + + // Replace the original slice with the deduplicated one + field.Set(newSlice) + } + + // Marshal the bundle back to JSON + result, err := json.Marshal(bundle) + if err != nil { + return nil, fmt.Errorf("failed to marshal bundle: %w", err) + } + + return result, nil +} diff --git a/internal/graphman/bundle_helpers_test.go b/internal/graphman/bundle_helpers_test.go new file mode 100644 index 00000000..b94dfd6d --- /dev/null +++ b/internal/graphman/bundle_helpers_test.go @@ -0,0 +1,427 @@ +/* +* Copyright (c) 2025 Broadcom. All rights reserved. +* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +* All trademarks, trade names, service marks, and logos referenced +* herein belong to their respective companies. +* +* This software and all information contained therein is confidential +* and proprietary and shall not be duplicated, used, disclosed or +* disseminated in any way except as authorized by the applicable +* license agreement, without the express written permission of Broadcom. +* All authorized reproductions must be marked with this language. +* +* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE +* EXTENT PERMITTED BY APPLICABLE LAW OR AS AGREED BY BROADCOM IN ITS +* APPLICABLE LICENSE AGREEMENT, BROADCOM PROVIDES THIS DOCUMENTATION +* "AS IS" WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION, +* ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* PURPOSE, OR. NONINFRINGEMENT. IN NO EVENT WILL BROADCOM BE LIABLE TO +* THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR +* INDIRECT, FROM THE USE OF THIS DOCUMENTATION, INCLUDING WITHOUT LIMITATION, +* LOST PROFITS, LOST INVESTMENT, BUSINESS INTERRUPTION, GOODWILL, OR +* LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE +* POSSIBILITY OF SUCH LOSS OR DAMAGE. +* +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. + */ + +package graphman + +import ( + "encoding/json" + "testing" +) + +func TestCombineWithOverwrite_LatestWins(t *testing.T) { + // Test that when same entity appears in both bundles, src (latest) wins + bundle1 := Bundle{ + Services: []*L7ServiceInput{ + { + Name: "api1", + ResolutionPath: "/api1", + Goid: "goid1", + }, + }, + } + + bundle2 := Bundle{ + Services: []*L7ServiceInput{ + { + Name: "api1", + ResolutionPath: "/api1-updated", + Goid: "goid1", + }, + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.Services) != 1 { + t.Fatalf("Expected 1 service, got %d", len(result.Services)) + } + + if result.Services[0].ResolutionPath != "/api1-updated" { + t.Errorf("Expected updated resolution path '/api1-updated', got '%s'", result.Services[0].ResolutionPath) + } +} + +func TestCombineWithOverwrite_HttpConfigurationCompositeKey(t *testing.T) { + // Test that HttpConfiguration uses composite key (Host + Port) + bundle1 := Bundle{ + HttpConfigurations: []*HttpConfigurationInput{ + {Host: "localhost", Port: 8080, Path: "/old"}, + {Host: "localhost", Port: 8443, Path: "/ssl"}, + }, + } + + bundle2 := Bundle{ + HttpConfigurations: []*HttpConfigurationInput{ + {Host: "localhost", Port: 8080, Path: "/new"}, // Should overwrite same host:port + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.HttpConfigurations) != 2 { + t.Errorf("Expected 2 http configs, got %d", len(result.HttpConfigurations)) + } + + // Find the 8080 config + found := false + for _, cfg := range result.HttpConfigurations { + if cfg.Port == 8080 { + if cfg.Path != "/new" { + t.Errorf("Expected path '/new' for port 8080, got '%s'", cfg.Path) + } + found = true + } + } + if !found { + t.Errorf("Could not find http config for port 8080") + } +} + +func TestCombineWithOverwrite_KeysByAlias(t *testing.T) { + // Test that Keys are matched by Alias + bundle1 := Bundle{ + Keys: []*KeyInput{ + {Alias: "ssl-key", KeystoreId: "00000000000000000000000000000002:keystore1"}, + {Alias: "signing-key", KeystoreId: "00000000000000000000000000000002:keystore1"}, + }, + } + + bundle2 := Bundle{ + Keys: []*KeyInput{ + {Alias: "ssl-key", KeystoreId: "00000000000000000000000000000002:keystore2"}, // Should overwrite + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.Keys) != 2 { + t.Errorf("Expected 2 keys, got %d", len(result.Keys)) + } + + // Find ssl-key + found := false + for _, key := range result.Keys { + if key.Alias == "ssl-key" { + if key.KeystoreId != "00000000000000000000000000000002:keystore2" { + t.Errorf("Expected updated keystore for ssl-key") + } + found = true + } + } + if !found { + t.Errorf("Could not find ssl-key") + } +} + +func TestCombineWithOverwrite_TrustedCertsByThumbprint(t *testing.T) { + // Test that TrustedCerts are matched by ThumbprintSha1 + bundle1 := Bundle{ + TrustedCerts: []*TrustedCertInput{ + {Name: "cert1", ThumbprintSha1: "abc123"}, + {Name: "cert2", ThumbprintSha1: "def456"}, + }, + } + + bundle2 := Bundle{ + TrustedCerts: []*TrustedCertInput{ + {Name: "cert1-updated", ThumbprintSha1: "abc123"}, // Should overwrite based on thumbprint + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.TrustedCerts) != 2 { + t.Errorf("Expected 2 trusted certs, got %d", len(result.TrustedCerts)) + } + + // Find cert with thumbprint abc123 + found := false + for _, cert := range result.TrustedCerts { + if cert.ThumbprintSha1 == "abc123" { + if cert.Name != "cert1-updated" { + t.Errorf("Expected updated name for cert with thumbprint abc123") + } + found = true + } + } + if !found { + t.Errorf("Could not find cert with thumbprint abc123") + } +} + +func TestCombineWithOverwrite_SchemasBySystemId(t *testing.T) { + // Test that Schemas are matched by SystemId + bundle1 := Bundle{ + Schemas: []*SchemaInput{ + {SystemId: "http://example.com/schema1", Goid: "goid1"}, + {SystemId: "http://example.com/schema2", Goid: "goid2"}, + }, + } + + bundle2 := Bundle{ + Schemas: []*SchemaInput{ + {SystemId: "http://example.com/schema1", Goid: "goid3"}, // Should overwrite + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.Schemas) != 2 { + t.Errorf("Expected 2 schemas, got %d", len(result.Schemas)) + } + + // Find schema1 + found := false + for _, schema := range result.Schemas { + if schema.SystemId == "http://example.com/schema1" { + if schema.Goid != "goid3" { + t.Errorf("Expected updated goid for schema1") + } + found = true + } + } + if !found { + t.Errorf("Could not find schema1") + } +} + +func TestCombineWithOverwrite_DtdsBySystemId(t *testing.T) { + // Test that DTDs are matched by SystemId + bundle1 := Bundle{ + Dtds: []*DtdInput{ + {SystemId: "http://example.com/dtd1.dtd", Goid: "goid1"}, + }, + } + + bundle2 := Bundle{ + Dtds: []*DtdInput{ + {SystemId: "http://example.com/dtd1.dtd", Goid: "goid2"}, // Should overwrite + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.Dtds) != 1 { + t.Errorf("Expected 1 dtd, got %d", len(result.Dtds)) + } + + if result.Dtds[0].Goid != "goid2" { + t.Errorf("Expected updated goid for dtd") + } +} + +func TestCombineWithOverwrite_CustomKeyValuesByKey(t *testing.T) { + // Test that CustomKeyValues are matched by Key + bundle1 := Bundle{ + CustomKeyValues: []*CustomKeyValueInput{ + {Key: "custom.key1", Value: "value1"}, + {Key: "custom.key2", Value: "value2"}, + }, + } + + bundle2 := Bundle{ + CustomKeyValues: []*CustomKeyValueInput{ + {Key: "custom.key1", Value: "updated-value1"}, // Should overwrite + }, + } + + result, err := CombineWithOverwrite(bundle2, bundle1) + if err != nil { + t.Fatalf("CombineWithOverwrite failed: %v", err) + } + + if len(result.CustomKeyValues) != 2 { + t.Errorf("Expected 2 custom key values, got %d", len(result.CustomKeyValues)) + } + + // Find custom.key1 + found := false + for _, kv := range result.CustomKeyValues { + if kv.Key == "custom.key1" { + if kv.Value != "updated-value1" { + t.Errorf("Expected updated value for custom.key1") + } + found = true + } + } + if !found { + t.Errorf("Could not find custom.key1") + } +} + +func TestCalculateDelta_DetectsNewEntities(t *testing.T) { + // Test that new entities are detected + current := Bundle{} + desired := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1"}, + }, + } + + delta, combined, err := CalculateDelta(current, desired) + if err != nil { + t.Fatalf("CalculateDelta failed: %v", err) + } + + if len(delta.Services) != 1 { + t.Errorf("Expected 1 service in delta, got %d", len(delta.Services)) + } + if len(combined.Services) != 1 { + t.Errorf("Expected 1 service in combined, got %d", len(combined.Services)) + } +} + +func TestCalculateDelta_DetectsDeletedEntities(t *testing.T) { + // Test that deleted entities get delete mappings + current := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1"}, + }, + } + desired := Bundle{} + + delta, combined, err := CalculateDelta(current, desired) + if err != nil { + t.Fatalf("CalculateDelta failed: %v", err) + } + + // Delta should include the entity with delete mapping + if len(delta.Services) != 1 { + t.Errorf("Expected 1 service in delta, got %d", len(delta.Services)) + } + if delta.Properties == nil || len(delta.Properties.Mappings.Services) != 1 { + t.Errorf("Expected 1 delete mapping in delta") + } + + // Combined should also have entity with delete mapping + if len(combined.Services) != 1 { + t.Errorf("Expected 1 service in combined, got %d", len(combined.Services)) + } + if combined.Properties == nil || len(combined.Properties.Mappings.Services) != 1 { + t.Errorf("Expected 1 delete mapping in combined") + } + if combined.Properties.Mappings.Services[0].Action != MappingActionDelete { + t.Errorf("Expected delete action in mapping") + } +} + +func TestResetMappings_RemovesEntitiesWithDeleteMappings(t *testing.T) { + // Test that ResetMappings removes entities marked for deletion + bundle := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1"}, + {Name: "api2", ResolutionPath: "/api2"}, + }, + Properties: &BundleProperties{ + Mappings: BundleMappings{ + Services: []*MappingInstructionInput{ + { + Action: MappingActionDelete, + Source: MappingSource{Name: "api1"}, + }, + }, + }, + }, + } + + err := ResetMappings(&bundle) + if err != nil { + t.Fatalf("ResetMappings failed: %v", err) + } + + // api1 should be removed, api2 should remain + if len(bundle.Services) != 1 { + t.Errorf("Expected 1 service after reset, got %d", len(bundle.Services)) + } + if bundle.Services[0].Name != "api2" { + t.Errorf("Expected api2 to remain, got %s", bundle.Services[0].Name) + } + + // Mappings should be cleared + if bundle.Properties != nil && len(bundle.Properties.Mappings.Services) != 0 { + t.Errorf("Expected mappings to be cleared") + } +} + +func TestRemoveDuplicates_RemovesDuplicatesByName(t *testing.T) { + // Test that duplicates by name are removed (first wins) + bundleBytes := []byte(`{"services":[{"name":"api1","resolutionPath":"/api1","goid":"goid1"},{"name":"api1","resolutionPath":"/api1-dup","goid":"goid2"}]}`) + + result, err := RemoveDuplicates(bundleBytes) + if err != nil { + t.Fatalf("RemoveDuplicates failed: %v", err) + } + + var resultBundle Bundle + if err := json.Unmarshal(result, &resultBundle); err != nil { + t.Fatalf("Failed to unmarshal result: %v", err) + } + + if len(resultBundle.Services) != 1 { + t.Errorf("Expected 1 service after deduplication, got %d", len(resultBundle.Services)) + } + if resultBundle.Services[0].ResolutionPath != "/api1" { + t.Errorf("Expected first occurrence to be kept, got '%s'", resultBundle.Services[0].ResolutionPath) + } +} + +func TestRemoveDuplicates_RemovesDuplicatesByGoid(t *testing.T) { + // Test that duplicates by goid are removed + bundleBytes := []byte(`{"services":[{"name":"api1","resolutionPath":"/api1","goid":"same-goid"},{"name":"api2","resolutionPath":"/api2","goid":"same-goid"}]}`) + + result, err := RemoveDuplicates(bundleBytes) + if err != nil { + t.Fatalf("RemoveDuplicates failed: %v", err) + } + + var resultBundle Bundle + if err := json.Unmarshal(result, &resultBundle); err != nil { + t.Fatalf("Failed to unmarshal result: %v", err) + } + + if len(resultBundle.Services) != 1 { + t.Errorf("Expected 1 service after deduplication by goid, got %d", len(resultBundle.Services)) + } +} diff --git a/internal/graphman/bundle_test.go b/internal/graphman/bundle_test.go new file mode 100644 index 00000000..0b0c8a85 --- /dev/null +++ b/internal/graphman/bundle_test.go @@ -0,0 +1,238 @@ +/* +* Copyright (c) 2025 Broadcom. All rights reserved. +* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +* All trademarks, trade names, service marks, and logos referenced +* herein belong to their respective companies. +* +* This software and all information contained therein is confidential +* and proprietary and shall not be duplicated, used, disclosed or +* disseminated in any way except as authorized by the applicable +* license agreement, without the express written permission of Broadcom. +* All authorized reproductions must be marked with this language. +* +* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE +* EXTENT PERMITTED BY APPLICABLE LAW OR AS AGREED BY BROADCOM IN ITS +* APPLICABLE LICENSE AGREEMENT, BROADCOM PROVIDES THIS DOCUMENTATION +* "AS IS" WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION, +* ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* PURPOSE, OR. NONINFRINGEMENT. IN NO EVENT WILL BROADCOM BE LIABLE TO +* THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR +* INDIRECT, FROM THE USE OF THIS DOCUMENTATION, INCLUDING WITHOUT LIMITATION, +* LOST PROFITS, LOST INVESTMENT, BUSINESS INTERRUPTION, GOODWILL, OR +* LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE +* POSSIBILITY OF SUCH LOSS OR DAMAGE. +* +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. + */ + +package graphman + +import ( + "encoding/json" + "testing" +) + +func TestConcatBundle_EmptyAccumulator(t *testing.T) { + // Test concatenating into an empty accumulator + newBundle := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1"}, + }, + } + + newBytes, _ := json.Marshal(newBundle) + result, err := ConcatBundle(newBytes, []byte("{}")) + if err != nil { + t.Fatalf("ConcatBundle failed: %v", err) + } + + var resultBundle Bundle + json.Unmarshal(result, &resultBundle) + + if len(resultBundle.Services) != 1 { + t.Errorf("Expected 1 service, got %d", len(resultBundle.Services)) + } + if resultBundle.Services[0].Name != "api1" { + t.Errorf("Expected service 'api1', got '%s'", resultBundle.Services[0].Name) + } +} + +func TestConcatBundle_LatestWins(t *testing.T) { + // Test that latest bundle wins when same entity appears in multiple bundles + // This is the key scenario we discussed - later bundles overwrite earlier ones + acc := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1", Enabled: false}, + }, + } + + newBundle := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1-updated", Enabled: true}, + }, + } + + accBytes, _ := json.Marshal(acc) + newBytes, _ := json.Marshal(newBundle) + resultBytes, err := ConcatBundle(newBytes, accBytes) + if err != nil { + t.Fatalf("ConcatBundle failed: %v", err) + } + + var result Bundle + json.Unmarshal(resultBytes, &result) + + if len(result.Services) != 1 { + t.Errorf("Expected 1 service, got %d", len(result.Services)) + } + if result.Services[0].ResolutionPath != "/api1-updated" { + t.Errorf("Expected '/api1-updated', got '%s'", result.Services[0].ResolutionPath) + } + if !result.Services[0].Enabled { + t.Errorf("Expected enabled=true from latest bundle") + } +} + +func TestConcatBundle_MultipleIterations(t *testing.T) { + // Test multiple concatenations to ensure ordering is preserved + // folder1/api1, folder2/api1 (should overwrite), folder3/api2 + + // First folder - api1 with value A + folder1 := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1", Goid: "valueA"}, + }, + } + folder1Bytes, _ := json.Marshal(folder1) + result1, err := ConcatBundle(folder1Bytes, []byte("{}")) + if err != nil { + t.Fatalf("ConcatBundle failed on iteration 1: %v", err) + } + + // Second folder - api1 with value B (should overwrite) + folder2 := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1", Goid: "valueB"}, + }, + } + folder2Bytes, _ := json.Marshal(folder2) + result2, err := ConcatBundle(folder2Bytes, result1) + if err != nil { + t.Fatalf("ConcatBundle failed on iteration 2: %v", err) + } + + // Third folder - api2 (new entity) + folder3 := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api2", ResolutionPath: "/api2", Goid: "valueC"}, + }, + } + folder3Bytes, _ := json.Marshal(folder3) + result3, err := ConcatBundle(folder3Bytes, result2) + if err != nil { + t.Fatalf("ConcatBundle failed on iteration 3: %v", err) + } + + var finalResult Bundle + json.Unmarshal(result3, &finalResult) + + // Final result should have: api1 with valueB (from folder2), api2 with valueC (from folder3) + if len(finalResult.Services) != 2 { + t.Fatalf("Expected 2 services, got %d", len(finalResult.Services)) + } + + // Find api1 + foundApi1 := false + for _, svc := range finalResult.Services { + if svc.Name == "api1" { + if svc.Goid != "valueB" { + t.Errorf("Expected api1 to have valueB (from folder2), got '%s'", svc.Goid) + } + foundApi1 = true + } + } + if !foundApi1 { + t.Errorf("api1 not found in result") + } +} + +func TestConcatBundle_PreservesUniqueEntities(t *testing.T) { + // Test that unique entities from each bundle are preserved + acc := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1"}, + }, + Policies: []*L7PolicyInput{ + {Name: "policy1"}, + }, + } + + newBundle := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api2", ResolutionPath: "/api2"}, + }, + ClusterProperties: []*ClusterPropertyInput{ + {Name: "cluster.hostname", Value: "test"}, + }, + } + + accBytes, _ := json.Marshal(acc) + newBytes, _ := json.Marshal(newBundle) + resultBytes, err := ConcatBundle(newBytes, accBytes) + if err != nil { + t.Fatalf("ConcatBundle failed: %v", err) + } + + var result Bundle + json.Unmarshal(resultBytes, &result) + + if len(result.Services) != 2 { + t.Errorf("Expected 2 services, got %d", len(result.Services)) + } + if len(result.Policies) != 1 { + t.Errorf("Expected 1 policy, got %d", len(result.Policies)) + } + if len(result.ClusterProperties) != 1 { + t.Errorf("Expected 1 cluster property, got %d", len(result.ClusterProperties)) + } +} + +func TestConcatBundle_DuplicatesAcrossFolders(t *testing.T) { + // This is the key scenario we discussed - when same API appears in folder1 and folder2, + // the one from folder2 (processed later) should win + folder1 := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1", FolderPath: "/folder1"}, + }, + } + + folder2 := Bundle{ + Services: []*L7ServiceInput{ + {Name: "api1", ResolutionPath: "/api1", FolderPath: "/folder2"}, + }, + } + + // Simulate processing folder1 then folder2 + folder1Bytes, _ := json.Marshal(folder1) + result, err := ConcatBundle(folder1Bytes, []byte("{}")) + if err != nil { + t.Fatalf("ConcatBundle failed on folder1: %v", err) + } + + folder2Bytes, _ := json.Marshal(folder2) + result, err = ConcatBundle(folder2Bytes, result) + if err != nil { + t.Fatalf("ConcatBundle failed on folder2: %v", err) + } + + var finalResult Bundle + json.Unmarshal(result, &finalResult) + + // Should have only 1 service with folder path from folder2 + if len(finalResult.Services) != 1 { + t.Errorf("Expected 1 service after deduplication, got %d", len(finalResult.Services)) + } + if finalResult.Services[0].FolderPath != "/folder2" { + t.Errorf("Expected folder path '/folder2' (latest), got '%s'", finalResult.Services[0].FolderPath) + } +} diff --git a/internal/graphman/graphman.go b/internal/graphman/graphman.go index c89ef4dc..d0faae73 100644 --- a/internal/graphman/graphman.go +++ b/internal/graphman/graphman.go @@ -33,8 +33,8 @@ import ( ) // Implode - convert an exploded Graphman directory into a single JSON file. -func Implode(path string) ([]byte, error) { - bundle, err := implodeBundle(path) +func Implode(path string, processNestedRepos bool) ([]byte, error) { + bundle, err := implodeBundle(path, processNestedRepos) if err != nil { return nil, err } diff --git a/kind-1.34.yaml b/kind-1.34.yaml new file mode 100644 index 00000000..b64452d3 --- /dev/null +++ b/kind-1.34.yaml @@ -0,0 +1,18 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + image: kindest/node:v1.34.0 + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP \ No newline at end of file diff --git a/pkg/api/util.go b/pkg/api/util.go index 0c48b61d..8801b813 100644 --- a/pkg/api/util.go +++ b/pkg/api/util.go @@ -5,6 +5,7 @@ import ( "encoding/json" "encoding/xml" "fmt" + "github.com/caapim/layer7-operator/internal/graphman" "github.com/caapim/layer7-operator/internal/templategen" ) diff --git a/pkg/gateway/config_test.go b/pkg/gateway/config_test.go index 5118b747..97aa78e7 100755 --- a/pkg/gateway/config_test.go +++ b/pkg/gateway/config_test.go @@ -1,6 +1,7 @@ package gateway import ( + "encoding/json" "strconv" "strings" "testing" @@ -296,32 +297,36 @@ func TestCustomListenPortBundle(t *testing.T) { } -func TestRepositoryConfigWithAuth(t *testing.T) { +func TestRepositoryConfigWithLocalReference(t *testing.T) { gateway := securityv1.Gateway{ ObjectMeta: v1.ObjectMeta{ Name: "test", }, Status: securityv1.GatewayStatus{ RepositoryStatus: []securityv1.GatewayRepositoryStatus{{ - Enabled: true, - Name: "testrepo", - Commit: "1234", - Type: "static", - SecretName: "testSecret", - Branch: "testBranch", - Endpoint: "github.com", + Enabled: true, + Name: "testrepo", + Commit: "1234", + Type: "static", + StorageSecretName: "testrepoSecret", + Branch: "testBranch", + Endpoint: "github.com", }}, }, } configMap := NewConfigMap(&gateway, gateway.Name+"-repository-init-config") - repositoryConfig := configMap.Data["config.json"] - if !strings.Contains(repositoryConfig, "/graphman/secrets/testrepo") { - t.Errorf("repositoryConfig %s should contain auth %s", repositoryConfig, "/graphman/secrets/testrepo") + initContainerStaticConfig := InitContainerStaticConfig{} + if err := json.Unmarshal([]byte(configMap.Data["config.json"]), &initContainerStaticConfig); err != nil { + t.Errorf("failed to unmarshal repository config") + } + + if initContainerStaticConfig.Repositories[0].LocalReference != "/graphman/localref/testrepoSecret" { + t.Errorf("repository config localReference %v should be %s", initContainerStaticConfig.Repositories[0].LocalReference, "/graphman/localref/testSecret") } } -func TestRepositoryConfigWithLocalRef(t *testing.T) { +func TestRepositoryConfigWithAuthentication(t *testing.T) { gateway := securityv1.Gateway{ ObjectMeta: v1.ObjectMeta{ Name: "test", @@ -331,14 +336,23 @@ func TestRepositoryConfigWithLocalRef(t *testing.T) { Enabled: true, Name: "testrepo", Type: "static", - StorageSecretName: "testStorageSecret", + Branch: "testBranch", + Commit: "1234", + Endpoint: "github.com", + StorageSecretName: "_", + AuthType: string(securityv1.RepositoryAuthTypeBasic), }}, }, } configMap := NewConfigMap(&gateway, gateway.Name+"-repository-init-config") - repositoryConfig := configMap.Data["config.json"] - if !strings.Contains(repositoryConfig, "/graphman/localref/testStorageSecret/testrepo.gz") { - t.Errorf("repositoryConfig %s should contain auth %s", repositoryConfig, "/graphman/secrets/testrepo") + + initContainerStaticConfig := InitContainerStaticConfig{} + if err := json.Unmarshal([]byte(configMap.Data["config.json"]), &initContainerStaticConfig); err != nil { + t.Errorf("failed to unmarshal repository config") + } + + if initContainerStaticConfig.Repositories[0].AuthType != string(securityv1.RepositoryAuthTypeBasic) { + t.Errorf("repository config authType %s should be %s", initContainerStaticConfig.Repositories[0].AuthType, "basic") } } diff --git a/pkg/gateway/configmap.go b/pkg/gateway/configmap.go index c5ff47f5..a60578ba 100644 --- a/pkg/gateway/configmap.go +++ b/pkg/gateway/configmap.go @@ -43,20 +43,26 @@ import ( type InitContainerStaticConfig struct { Version string `json:"version"` + PreferGit bool `json:"preferGit"` Repositories []RepositoryConfig `json:"repositories,omitempty"` } type RepositoryConfig struct { - Name string `json:"name"` - Endpoint string `json:"endpoint"` - Branch string `json:"branch"` - Auth string `json:"auth"` - LocalReference string `json:"localReference,omitempty"` - Tag string `json:"tag,omitempty"` - RemoteName string `json:"remoteName,omitempty"` - StateStoreReference string `json:"stateStoreReference,omitempty"` - StateStoreKey string `json:"stateStoreKey,omitempty"` - SingletonExtraction bool `json:"singletonExtraction,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + Endpoint string `json:"endpoint"` + Branch string `json:"branch"` + Auth string `json:"auth"` + LocalReference string `json:"localReference,omitempty"` + Tag string `json:"tag,omitempty"` + RemoteName string `json:"remoteName,omitempty"` + StateStoreReference string `json:"stateStoreReference,omitempty"` + StateStoreKey string `json:"stateStoreKey,omitempty"` + SingletonExtraction bool `json:"singletonExtraction,omitempty"` + Vendor string `json:"vendor,omitempty"` + AuthType string `json:"authType,omitempty"` + Namespace string `json:"namespace,omitempty"` + Directories []string `json:"directories,omitempty"` } // NewConfigMap @@ -138,43 +144,41 @@ func NewConfigMap(gw *securityv1.Gateway, name string) *corev1.ConfigMap { data["listen-ports.json"] = string(bundle) case gw.Name + "-repository-init-config": initContainerStaticConfig := InitContainerStaticConfig{} - initContainerStaticConfig.Version = "1.0" + initContainerStaticConfig.Version = "2.0" + initContainerStaticConfig.PreferGit = gw.Spec.App.RepositoryReferenceBootstrap.PreferGit for i := range gw.Status.RepositoryStatus { var localRef string - if gw.Status.RepositoryStatus[i].Enabled && gw.Status.RepositoryStatus[i].Type == "static" { - //if gw.Status.RepositoryStatus[i].Type == "static" { - if gw.Status.RepositoryStatus[i].StateStoreReference == "" { - if gw.Status.RepositoryStatus[i].StorageSecretName != "" { - localRef = "/graphman/localref/" + gw.Status.RepositoryStatus[i].StorageSecretName + "/" + gw.Status.RepositoryStatus[i].Name + ".gz" + if gw.Status.RepositoryStatus[i].Enabled && (gw.Status.RepositoryStatus[i].Type == "static" || gw.Spec.App.RepositoryReferenceBootstrap.Enabled) { + /// always default to storage secret if it exists + if !gw.Spec.App.Management.Database.Enabled || gw.Status.RepositoryStatus[i].Type == "static" { + if gw.Status.RepositoryStatus[i].StorageSecretName != "_" { + localRef = "/graphman/localref/" + gw.Status.RepositoryStatus[i].StorageSecretName initContainerStaticConfig.Repositories = append(initContainerStaticConfig.Repositories, RepositoryConfig{ Name: gw.Status.RepositoryStatus[i].Name, LocalReference: localRef, SingletonExtraction: gw.Spec.App.SingletonExtraction, + Directories: gw.Status.RepositoryStatus[i].Directories, }) } else { - if !gw.Spec.App.Management.Database.Enabled { - initContainerStaticConfig.Repositories = append(initContainerStaticConfig.Repositories, RepositoryConfig{ - Name: gw.Status.RepositoryStatus[i].Name, - Endpoint: gw.Status.RepositoryStatus[i].Endpoint, - Branch: gw.Status.RepositoryStatus[i].Branch, - RemoteName: gw.Status.RepositoryStatus[i].RemoteName, - Tag: gw.Status.RepositoryStatus[i].Tag, - Auth: "/graphman/secrets/" + gw.Status.RepositoryStatus[i].Name, - SingletonExtraction: gw.Spec.App.SingletonExtraction, - }) - } - } - } else { - if gw.Status.RepositoryStatus[i].StateStoreReference != "" && !gw.Spec.App.Management.Database.Enabled { + // only bootstrap if the Gateway is running in ephemeral mode + // bootstrapping large policy sets to database backed gateways causes start up delay initContainerStaticConfig.Repositories = append(initContainerStaticConfig.Repositories, RepositoryConfig{ Name: gw.Status.RepositoryStatus[i].Name, + Endpoint: gw.Status.RepositoryStatus[i].Endpoint, + Branch: gw.Status.RepositoryStatus[i].Branch, + RemoteName: gw.Status.RepositoryStatus[i].RemoteName, + Type: gw.Status.RepositoryStatus[i].RepoType, + Vendor: gw.Status.RepositoryStatus[i].Vendor, + AuthType: gw.Status.RepositoryStatus[i].AuthType, + Tag: gw.Status.RepositoryStatus[i].Tag, + Auth: "/graphman/secrets/" + gw.Status.RepositoryStatus[i].Name, + SingletonExtraction: gw.Spec.App.SingletonExtraction, StateStoreReference: gw.Status.RepositoryStatus[i].StateStoreReference, StateStoreKey: gw.Status.RepositoryStatus[i].StateStoreKey, - SingletonExtraction: gw.Spec.App.SingletonExtraction, + Directories: gw.Status.RepositoryStatus[i].Directories, }) } } - // } } } initContainerStaticConfigBytes, _ := json.Marshal(initContainerStaticConfig) diff --git a/pkg/gateway/deployment.go b/pkg/gateway/deployment.go index 4d485cde..d16fd90a 100644 --- a/pkg/gateway/deployment.go +++ b/pkg/gateway/deployment.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package gateway @@ -45,21 +46,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { optional := false ports := []corev1.ContainerPort{} - defaultUser := int64(1001) - defaultGroup := int64(1001) - runAsNonRoot := true - - ocPodSecurityContext := corev1.PodSecurityContext{ - RunAsUser: &defaultUser, - RunAsGroup: &defaultGroup, - RunAsNonRoot: &runAsNonRoot, - } - ocContainerSecurityContext := corev1.SecurityContext{ - RunAsUser: &defaultUser, - RunAsNonRoot: &runAsNonRoot, - Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, - } - for p := range gw.Spec.App.Service.Ports { ports = append(ports, corev1.ContainerPort{ Name: gw.Spec.App.Service.Ports[p].Name, @@ -233,7 +219,7 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { } if gw.Spec.App.Redis.Enabled { - secretName := gw.Name + "-shared-state-client-configuration" + secretName := gw.Name + "-shared-state-config" if gw.Spec.App.Redis.ExistingSecret != "" { secretName = gw.Spec.App.Redis.ExistingSecret } @@ -640,12 +626,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { for _, ic := range gw.Spec.App.InitContainers { ic.TerminationMessagePath = corev1.TerminationMessagePathDefault ic.TerminationMessagePolicy = corev1.TerminationMessageReadFile - if platform == "openshift" && ic.SecurityContext == nil { - ic.SecurityContext = &ocContainerSecurityContext - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { - ic.SecurityContext = &gw.Spec.App.ContainerSecurityContext - } - } if ic.ImagePullPolicy == "" { ic.ImagePullPolicy = corev1.PullIfNotPresent } @@ -653,42 +633,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { } gmanInitContainerVolumeMounts := []corev1.VolumeMount{} - for _, staticRepository := range gw.Status.RepositoryStatus { - if staticRepository.Enabled && staticRepository.Type == "static" { - if staticRepository.SecretName != "" { - gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ - Name: staticRepository.SecretName, - MountPath: "/graphman/secrets/" + staticRepository.Name, - }) - volumes = append(volumes, corev1.Volume{ - Name: staticRepository.SecretName, - VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ - SecretName: staticRepository.SecretName, - DefaultMode: &defaultMode, - Optional: &optional, - }}, - }) - } - - // if the repository compressed is less than 1mb in size it will be - // available as an existing Kubernetes secret which reduces reliance on an external Git repository for Gateway boot. - // these secrets are managed by the Repository controller. - if staticRepository.StorageSecretName != "" && staticRepository.StorageSecretName != "_" { - gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ - Name: staticRepository.StorageSecretName, - MountPath: "/graphman/localref/" + staticRepository.StorageSecretName, - }) - volumes = append(volumes, corev1.Volume{ - Name: staticRepository.StorageSecretName, - VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ - SecretName: staticRepository.StorageSecretName, - DefaultMode: &defaultMode, - Optional: &optional, - }}, - }) - } - } - } gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ Name: gw.Name + "-repository-init-config", @@ -720,7 +664,7 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { volumeMounts = append(volumeMounts, gmanInitContainerVolumeMounts...) - graphmanInitContainerImage := "docker.io/caapim/graphman-static-init:1.0.3" + graphmanInitContainerImage := "docker.io/caapim/graphman-static-init:1.0.4" graphmanInitContainerImagePullPolicy := corev1.PullIfNotPresent graphmanInitContainerSecurityContext := corev1.SecurityContext{} @@ -732,10 +676,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { graphmanInitContainerImagePullPolicy = gw.Spec.App.Management.Graphman.InitContainerImagePullPolicy } - if platform == "openshift" { - graphmanInitContainerSecurityContext = ocContainerSecurityContext - } - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { graphmanInitContainerSecurityContext = gw.Spec.App.ContainerSecurityContext } @@ -753,6 +693,12 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { Env: []corev1.EnvVar{{ Name: "BOOTSTRAP_BASE", Value: "/opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0", + }, { + Name: "STATESTORE_CONFIG", + Value: "/graphman/statestore-config/", + }, { + Name: "STATESTORE_SECRET", + Value: "/graphman/statestore-secret/", }}, TerminationMessagePath: corev1.TerminationMessagePathDefault, TerminationMessagePolicy: corev1.TerminationMessageReadFile, @@ -808,10 +754,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { portalInitContainerImagePullPolicy = gw.Spec.App.PortalReference.InitContainerImagePullPolicy } - if platform == "openshift" { - portalInitContainerSecurityContext = ocContainerSecurityContext - } - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { portalInitContainerSecurityContext = gw.Spec.App.ContainerSecurityContext } @@ -856,10 +798,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { otkInitContainerImagePullPolicy = gw.Spec.App.Otk.InitContainerImagePullPolicy } - if platform == "openshift" { - otkInitContainerSecurityContext = ocContainerSecurityContext - } - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { otkInitContainerSecurityContext = gw.Spec.App.ContainerSecurityContext } @@ -975,11 +913,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { gatewayContainerSecurityContext := corev1.SecurityContext{} podSecurityContext := corev1.PodSecurityContext{} - if platform == "openshift" { - gatewayContainerSecurityContext = ocContainerSecurityContext - podSecurityContext = ocPodSecurityContext - } - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { gatewayContainerSecurityContext = gw.Spec.App.ContainerSecurityContext } @@ -1109,12 +1042,6 @@ func NewDeployment(gw *securityv1.Gateway, platform string) *appsv1.Deployment { sidecars := []corev1.Container{} for _, sc := range gw.Spec.App.Sidecars { - if platform == "openshift" && sc.SecurityContext == nil { - sc.SecurityContext = &ocContainerSecurityContext - if gw.Spec.App.ContainerSecurityContext != (corev1.SecurityContext{}) { - sc.SecurityContext = &gw.Spec.App.ContainerSecurityContext - } - } sidecars = append(sidecars, sc) } diff --git a/pkg/gateway/reconcile/deployment.go b/pkg/gateway/reconcile/deployment.go index 0effc9b3..eb72bc03 100644 --- a/pkg/gateway/reconcile/deployment.go +++ b/pkg/gateway/reconcile/deployment.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package reconcile @@ -29,6 +30,8 @@ import ( "context" "crypto/sha1" "fmt" + "sort" + "strconv" "strings" securityv1 "github.com/caapim/layer7-operator/api/v1" @@ -42,8 +45,162 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) +// getOpenShiftUIDRange extracts the UID/GID range from OpenShift namespace annotations +// Returns the minimum UID and GID from the assigned range, or nil if not found/not OpenShift +func getOpenShiftUIDRange(ctx context.Context, k8sClient client.Client, namespace string) (*int64, *int64, error) { + // Get the namespace + ns := &corev1.Namespace{} + if err := k8sClient.Get(ctx, types.NamespacedName{Name: namespace}, ns); err != nil { + return nil, nil, fmt.Errorf("failed to get namespace: %w", err) + } + + // Parse OpenShift UID annotation + // Example format: "openshift.io/sa.scc.uid-range: 1001620000/10000" + uidRange := ns.Annotations["openshift.io/sa.scc.uid-range"] + if uidRange == "" { + // Not OpenShift or no range set + return nil, nil, nil + } + + // Parse "1001620000/10000" format + parts := strings.Split(uidRange, "/") + if len(parts) != 2 { + return nil, nil, fmt.Errorf("invalid uid-range format: %s", uidRange) + } + + minUID, err := strconv.ParseInt(parts[0], 10, 64) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse UID: %w", err) + } + + // Use the same value for GID (OpenShift typically assigns matching ranges) + return &minUID, &minUID, nil +} + +// applyDefaultCapabilities ensures all init containers and sidecars drop ALL capabilities by default +// This is a security best practice unless explicitly overridden by the user +func applyDefaultCapabilities(dep *appsv1.Deployment) { + // Apply to all init containers + for i := range dep.Spec.Template.Spec.InitContainers { + if dep.Spec.Template.Spec.InitContainers[i].SecurityContext == nil { + dep.Spec.Template.Spec.InitContainers[i].SecurityContext = &corev1.SecurityContext{} + } + if dep.Spec.Template.Spec.InitContainers[i].SecurityContext.Capabilities == nil { + dep.Spec.Template.Spec.InitContainers[i].SecurityContext.Capabilities = &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + } + } + } + + // Apply to main container (gateway) + for i := range dep.Spec.Template.Spec.Containers { + if dep.Spec.Template.Spec.Containers[i].SecurityContext == nil { + dep.Spec.Template.Spec.Containers[i].SecurityContext = &corev1.SecurityContext{} + } + if dep.Spec.Template.Spec.Containers[i].SecurityContext.Capabilities == nil { + dep.Spec.Template.Spec.Containers[i].SecurityContext.Capabilities = &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + } + } + } +} + +// applyOpenShiftSecurityDefaults applies OpenShift-specific security context defaults +// including UID/GID auto-detection and capability dropping +func applyOpenShiftSecurityDefaults(ctx context.Context, params Params) { + // If either PodSecurityContext or ContainerSecurityContext has RunAsUser set, use it for both + // Otherwise, auto-detect from OpenShift namespace annotations + if params.Instance.Spec.App.PodSecurityContext.RunAsUser == nil || params.Instance.Spec.App.ContainerSecurityContext.RunAsUser == nil { + var uid, gid *int64 + var runAsNonRootPtr *bool + + // Check if one is already set and use it (only UID/GID/RunAsNonRoot) + if params.Instance.Spec.App.PodSecurityContext.RunAsUser != nil { + uid = params.Instance.Spec.App.PodSecurityContext.RunAsUser + gid = params.Instance.Spec.App.PodSecurityContext.RunAsGroup + runAsNonRootPtr = params.Instance.Spec.App.PodSecurityContext.RunAsNonRoot + } else if params.Instance.Spec.App.ContainerSecurityContext.RunAsUser != nil { + // Copy only UID/GID/RunAsNonRoot from ContainerSecurityContext to PodSecurityContext + // Don't copy container-specific fields like Capabilities or AllowPrivilegeEscalation + uid = params.Instance.Spec.App.ContainerSecurityContext.RunAsUser + gid = params.Instance.Spec.App.ContainerSecurityContext.RunAsGroup + runAsNonRootPtr = params.Instance.Spec.App.ContainerSecurityContext.RunAsNonRoot + } else { + // Neither is set, auto-detect from OpenShift + var err error + uid, gid, err = getOpenShiftUIDRange(ctx, params.Client, params.Instance.Namespace) + if err != nil { + params.Log.V(2).Info("failed to detect OpenShift UID range, using defaults", + "namespace", params.Instance.Namespace, + "error", err.Error()) + uid = nil + } else if uid != nil && gid != nil { + params.Log.V(2).Info("auto-detected OpenShift UID/GID from namespace annotations", + "namespace", params.Instance.Namespace, + "uid", *uid, + "gid", *gid) + runAsNonRoot := true + runAsNonRootPtr = &runAsNonRoot + } + } + + // Apply the UID/GID to both contexts if we have values + if uid != nil { + // Set PodSecurityContext if RunAsUser is not set + if params.Instance.Spec.App.PodSecurityContext.RunAsUser == nil { + params.Instance.Spec.App.PodSecurityContext.RunAsUser = uid + params.Instance.Spec.App.PodSecurityContext.RunAsGroup = gid + params.Instance.Spec.App.PodSecurityContext.RunAsNonRoot = runAsNonRootPtr + } + + // Set ContainerSecurityContext if RunAsUser is not set + if params.Instance.Spec.App.ContainerSecurityContext.RunAsUser == nil { + params.Instance.Spec.App.ContainerSecurityContext.RunAsUser = uid + params.Instance.Spec.App.ContainerSecurityContext.RunAsGroup = gid + params.Instance.Spec.App.ContainerSecurityContext.RunAsNonRoot = runAsNonRootPtr + } + + // Set security context for init containers if not already set + for i := range params.Instance.Spec.App.InitContainers { + if params.Instance.Spec.App.InitContainers[i].SecurityContext == nil { + params.Instance.Spec.App.InitContainers[i].SecurityContext = &corev1.SecurityContext{ + RunAsUser: uid, + RunAsGroup: gid, + RunAsNonRoot: runAsNonRootPtr, + } + } + } + + // Set security context for sidecar containers if not already set + for i := range params.Instance.Spec.App.Sidecars { + if params.Instance.Spec.App.Sidecars[i].SecurityContext == nil { + params.Instance.Spec.App.Sidecars[i].SecurityContext = &corev1.SecurityContext{ + RunAsUser: uid, + RunAsGroup: gid, + RunAsNonRoot: runAsNonRootPtr, + } + } + } + } + } + + // Drop all capabilities by default if not explicitly set + if params.Instance.Spec.App.ContainerSecurityContext.Capabilities == nil { + params.Instance.Spec.App.ContainerSecurityContext.Capabilities = &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + } + } +} + func Deployment(ctx context.Context, params Params) error { + // Auto-detect and set OpenShift UID/GID if on OpenShift platform + // and user hasn't explicitly set RunAsUser + if params.Platform == "openshift" { + applyOpenShiftSecurityDefaults(ctx, params) + } + desiredDeployment := gateway.NewDeployment(params.Instance, params.Platform) + currentDeployment := &appsv1.Deployment{} if err := controllerutil.SetControllerReference(params.Instance, desiredDeployment, params.Scheme); err != nil { @@ -53,21 +210,23 @@ func Deployment(ctx context.Context, params Params) error { err := params.Client.Get(ctx, types.NamespacedName{Name: params.Instance.Name, Namespace: params.Instance.Namespace}, currentDeployment) if err != nil && k8serrors.IsNotFound(err) { - desiredDeployment, err = setLabels(ctx, params, desiredDeployment) if err != nil { return err } - desiredDeployment, err = setStateStoreConfig(ctx, params, desiredDeployment) if err != nil { return err } + desiredDeployment, err = setGmanInitContainerVolumeMounts(ctx, params, desiredDeployment) + if err != nil { + return err + } + if err = params.Client.Create(ctx, desiredDeployment); err != nil { return fmt.Errorf("failed creating deployment: %w", err) } - params.Log.Info("created deployment", "name", params.Instance.Name, "namespace", params.Instance.Namespace) return nil } @@ -80,15 +239,23 @@ func Deployment(ctx context.Context, params Params) error { desiredDeployment.Spec.Replicas = currentDeployment.Spec.Replicas } - updatedDeployment := currentDeployment.DeepCopy() - updatedDeployment.Spec = desiredDeployment.Spec - - updatedDeployment.ObjectMeta.OwnerReferences = desiredDeployment.ObjectMeta.OwnerReferences - desiredDeployment, err = setLabels(ctx, params, desiredDeployment) if err != nil { return err } + desiredDeployment, err = setStateStoreConfig(ctx, params, desiredDeployment) + if err != nil { + return err + } + desiredDeployment, err = setGmanInitContainerVolumeMounts(ctx, params, desiredDeployment) + if err != nil { + return err + } + + // Start with current deployment (preserves API server defaults) and merge in desired changes + updatedDeployment := currentDeployment.DeepCopy() + updatedDeployment.Spec = desiredDeployment.Spec + updatedDeployment.ObjectMeta.OwnerReferences = desiredDeployment.ObjectMeta.OwnerReferences if params.Instance.Spec.App.Autoscaling.Enabled { updatedDeployment.Spec.Replicas = currentDeployment.Spec.Replicas @@ -110,15 +277,21 @@ func Deployment(ctx context.Context, params Params) error { updatedDeployment.Spec.Template.ObjectMeta.Labels[k] = v } - desiredDeployment, err = setStateStoreConfig(ctx, params, desiredDeployment) + patch := client.MergeFrom(currentDeployment) + + // Check if there are actual changes + patchData, err := patch.Data(updatedDeployment) if err != nil { - return err + return fmt.Errorf("failed to generate patch: %w", err) } - updatedDeployment.Spec.Template.Spec.InitContainers = desiredDeployment.Spec.Template.Spec.InitContainers - updatedDeployment.Spec.Template.Spec.Volumes = desiredDeployment.Spec.Template.Spec.Volumes - - patch := client.MergeFrom(currentDeployment) + // Skip empty patches + if string(patchData) == "{}" || string(patchData) == "{\"metadata\":{\"creationTimestamp\":null}}" { + params.Log.V(2).Info("no deployment changes detected, skipping patch", + "name", params.Instance.Name, + "namespace", params.Instance.Namespace) + return nil + } if err := params.Client.Patch(ctx, updatedDeployment, patch); err != nil { return fmt.Errorf("failed to apply updates: %w", err) @@ -168,7 +341,7 @@ func setLabels(ctx context.Context, params Params, dep *appsv1.Deployment) (*app } } if params.Instance.Spec.App.Redis.Enabled && params.Instance.Spec.App.Redis.ExistingSecret == "" { - secrets = append(secrets, params.Instance.Name+"-shared-state-client-configuration") + secrets = append(secrets, params.Instance.Name+"-shared-state-config") } for _, secretName := range secrets { @@ -262,3 +435,197 @@ func setStateStoreConfig(ctx context.Context, params Params, dep *appsv1.Deploym } return dep, nil } + +func setGmanInitContainerVolumeMounts(ctx context.Context, params Params, dep *appsv1.Deployment) (*appsv1.Deployment, error) { + + var ( + gw = params.Instance + defaultMode = int32(444) + optional = false + gmanInitContainerVolumeMounts = []corev1.VolumeMount{} + repoRefStatuses = []string{} + ) + + for _, repoRef := range gw.Status.RepositoryStatus { + if repoRef.Type == "static" || (gw.Spec.App.RepositoryReferenceBootstrap.Enabled && !gw.Spec.App.Management.Database.Enabled) { + repoRefStatuses = append(repoRefStatuses, repoRef.Name) + // if the repository compressed is less than 1mb in size it will be + // available as an existing Kubernetes secret which reduces reliance on an external Git repository for Gateway boot. + // these secrets are managed by the Repository controller. + // if the storageSecret is available we don't need to mount the secrets. + if repoRef.StorageSecretName != "" && repoRef.StorageSecretName != "_" { + gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ + Name: repoRef.StorageSecretName, + MountPath: "/graphman/localref/" + repoRef.StorageSecretName, + }) + + existingVolume := false + for _, v := range dep.Spec.Template.Spec.Volumes { + if v.Name == repoRef.StorageSecretName { + existingVolume = true + } + } + + if !existingVolume { + dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: repoRef.StorageSecretName, + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ + SecretName: repoRef.StorageSecretName, + DefaultMode: &defaultMode, + Optional: &optional, + }}, + }) + } + } else { + if repoRef.SecretName != "" { + gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ + Name: repoRef.SecretName, + MountPath: "/graphman/secrets/" + repoRef.Name, + }) + + existingVolume := false + for _, v := range dep.Spec.Template.Spec.Volumes { + if v.Name == repoRef.SecretName { + existingVolume = true + } + } + if !existingVolume { + dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: repoRef.SecretName, + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ + SecretName: repoRef.SecretName, + DefaultMode: &defaultMode, + Optional: &optional, + }}, + }) + } + } + } + } + } + + // look at repoRefs in spec. If in spec but not in status then add or replace volumes + for _, repoRefSpec := range gw.Spec.App.RepositoryReferences { + found := false + for _, repoRefStatus := range repoRefStatuses { + if repoRefStatus == repoRefSpec.Name { + found = true + + } + } + if !found { + repo := securityv1.Repository{} + err := params.Client.Get(ctx, types.NamespacedName{Name: repoRefSpec.Name, Namespace: params.Instance.Namespace}, &repo) + if err != nil { + return nil, fmt.Errorf("failed to retrieve repository: %s", repoRefSpec.Name) + } + + if repoRefSpec.Type == "static" || (gw.Spec.App.RepositoryReferenceBootstrap.Enabled && !gw.Spec.App.Management.Database.Enabled) { + repoRefStatuses = append(repoRefStatuses, repoRefSpec.Name) + // if the repository compressed is less than 1mb in size it will be + // available as an existing Kubernetes secret which reduces reliance on an external Git repository for Gateway boot. + // these secrets are managed by the Repository controller. + // if the storageSecret is available we don't need to mount the secrets. + if repo.Status.StorageSecretName != "_" { + gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ + Name: repo.Status.StorageSecretName, + MountPath: "/graphman/localref/" + repo.Status.StorageSecretName, + }) + + existingVolume := false + for _, v := range dep.Spec.Template.Spec.Volumes { + if v.Name == repo.Status.StorageSecretName { + existingVolume = true + } + } + + if !existingVolume { + dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: repo.Status.StorageSecretName, + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ + SecretName: repo.Status.StorageSecretName, + DefaultMode: &defaultMode, + Optional: &optional, + }}, + }) + } + } else { + + secretName := repo.Name + if repo.Spec.Auth.ExistingSecretName != "" { + secretName = repo.Spec.Auth.ExistingSecretName + } + + if repo.Spec.Auth == (securityv1.RepositoryAuth{}) { + secretName = "" + } + + if secretName != "" { + gmanInitContainerVolumeMounts = append(gmanInitContainerVolumeMounts, corev1.VolumeMount{ + Name: secretName, + MountPath: "/graphman/secrets/" + repoRefSpec.Name, + }) + + existingVolume := false + for _, v := range dep.Spec.Template.Spec.Volumes { + if v.Name == secretName { + existingVolume = true + } + } + if !existingVolume { + dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: secretName, + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ + SecretName: secretName, + DefaultMode: &defaultMode, + Optional: &optional, + }}, + }) + } + } + } + } + } + } + + for index, ic := range dep.Spec.Template.Spec.InitContainers { + if ic.Name == "graphman-static-init" { + + for _, nvm := range gmanInitContainerVolumeMounts { + found := false + for _, vm := range dep.Spec.Template.Spec.InitContainers[index].VolumeMounts { + if nvm.Name == vm.Name { + found = true + } + } + if !found { + dep.Spec.Template.Spec.InitContainers[index].VolumeMounts = append(dep.Spec.Template.Spec.InitContainers[index].VolumeMounts, nvm) + } + } + + // Sort volume mounts to ensure consistent ordering + sort.Slice(dep.Spec.Template.Spec.InitContainers[index].VolumeMounts, func(i, j int) bool { + return dep.Spec.Template.Spec.InitContainers[index].VolumeMounts[i].Name < + dep.Spec.Template.Spec.InitContainers[index].VolumeMounts[j].Name + }) + } + } + + // Sort volumes to ensure consistent ordering across reconciliations + sort.Slice(dep.Spec.Template.Spec.Volumes, func(i, j int) bool { + return dep.Spec.Template.Spec.Volumes[i].Name < dep.Spec.Template.Spec.Volumes[j].Name + }) + + // Also sort volume mounts on the main gateway container + for i, container := range dep.Spec.Template.Spec.Containers { + if container.Name == "gateway" { + sort.Slice(dep.Spec.Template.Spec.Containers[i].VolumeMounts, func(j, k int) bool { + return dep.Spec.Template.Spec.Containers[i].VolumeMounts[j].Name < + dep.Spec.Template.Spec.Containers[i].VolumeMounts[k].Name + }) + break + } + } + + return dep, nil +} diff --git a/pkg/gateway/reconcile/gateway.go b/pkg/gateway/reconcile/gateway.go index 10d65aa8..f01acbc3 100644 --- a/pkg/gateway/reconcile/gateway.go +++ b/pkg/gateway/reconcile/gateway.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package reconcile @@ -35,8 +36,8 @@ import ( "errors" "fmt" "net" - "net/url" "os" + "reflect" "regexp" "strconv" "strings" @@ -156,19 +157,31 @@ func NewGwUpdateRequest(ctx context.Context, gateway *securityv1.Gateway, params switch gwUpdReq.bundleType { case BundleTypeRepository: - if (gwUpdReq.repository.Spec.StateStoreReference == "" && !gwUpdReq.repositoryReference.Enabled) || !gwUpdReq.repository.Spec.Enabled { - return nil, nil + if !gwUpdReq.delete { + if (gwUpdReq.repository.Spec.StateStoreReference == "" && !gwUpdReq.repositoryReference.Enabled) || !gwUpdReq.repository.Spec.Enabled { + return nil, nil + } } gwUpdReq.patchAnnotation = "security.brcmlabs.com/" + gwUpdReq.repositoryReference.Name + "-" + string(gwUpdReq.repositoryReference.Type) graphmanEncryptionPassphrase := gwUpdReq.repositoryReference.Encryption.Passphrase - /// if no pods are ready return nil + // check for directory change + directoryChange := false + for _, repoStatus := range gwUpdReq.gateway.Status.RepositoryStatus { + if gwUpdReq.repositoryReference.Name == repoStatus.Name { + if !reflect.DeepEqual(gwUpdReq.repositoryReference.Directories, repoStatus.Directories) { + directoryChange = true + } + } + } + + /// if no pods are ready return nil if gwUpdReq.ephemeral { updCntr := 0 ready := false for _, pod := range gwUpdReq.podList.Items { - if pod.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum || pod.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum+"-leader" { + if (pod.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum && pod.ObjectMeta.Labels["management-access"] != "leader") || pod.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum+"-leader" { updCntr = updCntr + 1 } for _, ps := range pod.Status.ContainerStatuses { @@ -177,11 +190,22 @@ func NewGwUpdateRequest(ctx context.Context, gateway *securityv1.Gateway, params } } } - if (updCntr == len(gwUpdReq.podList.Items) || !ready) && !gwUpdReq.delete { + + if updCntr == len(gwUpdReq.podList.Items) && !gwUpdReq.delete && !directoryChange { return nil, nil } + + // If pods aren't ready yet, only proceed if bootstrap is enabled OR if it's a delete + if !ready && !gwUpdReq.delete { + // With bootstrap enabled, we can patch pods that just started but aren't ready yet + if !gwUpdReq.gateway.Spec.App.RepositoryReferenceBootstrap.Enabled { + return nil, nil + } + // If bootstrap enabled and not ready, continue to patch with checksum + } + } else { - if (gwUpdReq.deployment.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum || gwUpdReq.repositoryReference.Type == securityv1.RepositoryReferenceTypeStatic) && !gwUpdReq.delete { + if (gwUpdReq.deployment.Annotations[gwUpdReq.patchAnnotation] == gwUpdReq.checksum || gwUpdReq.repositoryReference.Type == securityv1.RepositoryReferenceTypeStatic) && !gwUpdReq.delete && !directoryChange { return nil, nil } } @@ -193,54 +217,17 @@ func NewGwUpdateRequest(ctx context.Context, gateway *securityv1.Gateway, params } } - if gwUpdReq.repository.Spec.StateStoreReference != "" { - gwUpdReq.stateStore = true + if len(gwUpdReq.repositoryReference.Directories) == 0 { gwUpdReq.repositoryReference.Directories = []string{"/"} - statestore, err := getStateStore(ctx, params, gwUpdReq.repository.Spec.StateStoreReference) + } + + if gwUpdReq.repository.Spec.Type == securityv1.RepositoryTypeLocal { + gwUpdReq.bundle, err = readLocalReference(ctx, gwUpdReq.repository, params) if err != nil { return nil, err } - - if statestore.Spec.Redis.ExistingSecret != "" { - stateStoreSecret, err := getStateStoreSecret(ctx, statestore.Spec.Redis.ExistingSecret, statestore, params) - if err != nil { - return nil, err - } - statestore.Spec.Redis.Username = string(stateStoreSecret.Data["username"]) - statestore.Spec.Redis.MasterPassword = string(stateStoreSecret.Data["masterPassword"]) - } - - rc := util.RedisClient(&statestore.Spec.Redis) - bundleString := "" - if gwUpdReq.repository.Spec.StateStoreKey != "" { - bundleString, err = rc.Get(ctx, gwUpdReq.repository.Spec.StateStoreKey).Result() - if err != nil { - return nil, err - } - gwUpdReq.bundle = []byte(bundleString) - } else { - bundleString, err = rc.Get(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+gwUpdReq.repository.Status.StorageSecretName+":latest").Result() - if err != nil { - return nil, err - } - gwUpdReq.bundle, err = util.GzipDecompress([]byte(bundleString)) - if err != nil { - return nil, err - } - } - - if gwUpdReq.delete { - gwUpdReq.bundle, err = util.DeleteBundle(gwUpdReq.bundle) - if err != nil { - return nil, err - } - } } else { - if len(gwUpdReq.repositoryReference.Directories) == 0 { - gwUpdReq.repositoryReference.Directories = []string{"/"} - } - - gwUpdReq.bundle, err = buildBundle(ctx, params, gwUpdReq.repositoryReference, gwUpdReq.repository) + gwUpdReq.bundle, err = buildBundle(ctx, params, gwUpdReq.repositoryReference, gwUpdReq.repository, gwUpdReq.gateway, gwUpdReq.delete) if err != nil { return nil, err } @@ -282,7 +269,7 @@ func NewGwUpdateRequest(ctx context.Context, gateway *securityv1.Gateway, params bundle.Properties = &graphman.BundleProperties{} for _, deletedCwp := range notFound { - mappingSource := MappingSource{Name: deletedCwp} + mappingSource := graphman.MappingSource{Name: deletedCwp} bundle.ClusterProperties = append(bundle.ClusterProperties, &graphman.ClusterPropertyInput{ Name: deletedCwp, Value: "to be deleted", @@ -354,7 +341,7 @@ func NewGwUpdateRequest(ctx context.Context, gateway *securityv1.Gateway, params bundle.Properties = &graphman.BundleProperties{} for _, deletedListenPort := range notFound { - mappingSource := MappingSource{Name: deletedListenPort} + mappingSource := graphman.MappingSource{Name: deletedListenPort} bundle.ListenPorts = append(bundle.ListenPorts, &graphman.ListenPortInput{ Name: deletedListenPort, Port: 1, @@ -787,188 +774,750 @@ func SyncGateway(ctx context.Context, params Params, gwUpdReq GatewayUpdateReque return nil } -func buildBundle(ctx context.Context, params Params, repoRef *securityv1.RepositoryReference, repository *securityv1.Repository) (bundleBytes []byte, err error) { - var ( - bundlePath = "" - tmpPath = "/tmp/bundles/" + repository.Name - fileName = "" - dirChecksum = "" - ) - // create a checksum of directories - for _, d := range repoRef.Directories { - h := sha1.New() - h.Write([]byte(d)) - sha1Sum := fmt.Sprintf("%x", h.Sum(nil)) - dirChecksum = dirChecksum + sha1Sum +// buildDeleteBundle handles repository deletion by creating a bundle with delete mappings +func buildDeleteBundle(repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, gateway *securityv1.Gateway, params Params) ([]byte, error) { + // Check if delete is enabled + if !gateway.Spec.App.RepositoryReferenceDelete.Enabled { + params.Log.V(2).Info("repository delete skipped - RepositoryReferenceDelete.Enabled is false", "repository", repoRef.Name) + return []byte("{}"), nil + } + + // Check if we should skip delete for non-statestore repos + if repository.Spec.StateStoreReference == "" && !gateway.Spec.App.RepositoryReferenceDelete.IncludeEfs { + params.Log.V(2).Info("repository delete skipped - non-statestore repo and IncludeEfs is false", "repository", repoRef.Name) + return []byte("{}"), nil } - // combine with commitId - h := sha1.New() - h.Write([]byte(repository.Status.Commit + dirChecksum)) - sha1Sum := fmt.Sprintf("%x", h.Sum(nil)) - fileName = sha1Sum[30:] + ".json" + // Determine cache location + cachePath, cacheFileName := determineCacheLocation(repository, gateway) - _, dErr := os.Stat(tmpPath) - if dErr != nil { - _ = os.MkdirAll(tmpPath, 0755) + // Build bundle from cache + bundleBytes, err := buildBundleFromCache(repository, repoRef, cachePath, cacheFileName) + if err != nil { + return nil, fmt.Errorf("failed to build delete bundle from cache: %w", err) } - if len(repoRef.Directories) == 1 && strings.ToLower(string(repository.Spec.Type)) != "git" { - switch strings.ToLower(string(repository.Spec.Type)) { - case "http": - fileURL, err := url.Parse(repository.Spec.Endpoint) - if err != nil { - return nil, err - } - path := fileURL.Path - segments := strings.Split(path, "/") - artifactName := segments[len(segments)-1] - ext := strings.Split(artifactName, ".")[len(strings.Split(artifactName, "."))-1] - folderName := strings.ReplaceAll(artifactName, "."+ext, "") - if ext == "gz" && strings.Split(artifactName, ".")[len(strings.Split(artifactName, "."))-2] == "tar" { - folderName = strings.ReplaceAll(artifactName, ".tar.gz", "") - } - bundlePath = "/tmp/" + repository.Name + "-" + params.Instance.Namespace + "-" + folderName + // Set default action to delete + var bundle graphman.Bundle + if err := json.Unmarshal(bundleBytes, &bundle); err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle for delete: %w", err) + } - _, fErr := os.Stat(tmpPath + "/" + fileName) - if fErr != nil { + bundle.Properties = &graphman.BundleProperties{DefaultAction: graphman.MappingActionDelete} - // remove bundles 10 days or older to avoid - // growing the ephemeral filesystem - existingBundles, _ := os.ReadDir(tmpPath) - for _, f := range existingBundles { - fInfo, err := f.Info() - if err != nil { - return nil, err - } - if time.Since(fInfo.ModTime()) > 240*time.Hour { - os.Remove(tmpPath + "/" + f.Name()) - } + bundleBytes, err = json.Marshal(bundle) + if err != nil { + return nil, fmt.Errorf("failed to marshal bundle with delete mapping: %w", err) + } - } - bundleBytes, err = util.BuildAndValidateBundle(bundlePath) - if err != nil { - return nil, err - // bundleBytes, err = readStorageSecret(ctx, repository, params) - // if err != nil { - // return nil, err - // } - } - err = os.WriteFile(tmpPath+"/"+fileName, bundleBytes, 0755) - if err != nil { - return nil, err - } + params.Log.V(2).Info("applied delete mapping to bundle", "repository", repoRef.Name) + return bundleBytes, nil +} - } else { - bundleBytes, err = os.ReadFile(tmpPath + "/" + fileName) - if err != nil { - return nil, err +// checkRetryScenario checks if we should retry the last applied bundle due to previous failure +func checkRetryScenario(gateway *securityv1.Gateway, repoRefName string, currentCommit string, tmpPath string, params Params) (shouldRetry bool, bundle []byte) { + // Check gateway status for apply failures for this repository + for _, repoStatus := range gateway.Status.RepositoryStatus { + if repoStatus.Name == repoRefName { + // Check if there's a failure condition with "failed" or "error" in reason + for _, condition := range repoStatus.Conditions { + // Look for failures in the reason field + reasonLower := strings.ToLower(condition.Reason) + if (strings.Contains(reasonLower, "failed") || strings.Contains(reasonLower, "error")) && condition.Status != "success" { + // Found a failure - check if commit has changed + if repoStatus.Commit == currentCommit { + // Commit unchanged, this is a retry scenario + lastAppliedFile := tmpPath + "/last_applied_" + repoRefName + ".json" + if bundleBytes, err := os.ReadFile(lastAppliedFile); err == nil { + params.Log.V(2).Info("retry scenario detected - using last applied bundle", + "repository", repoRefName, + "commit", currentCommit, + "failureReason", condition.Reason) + return true, bundleBytes + } else { + params.Log.V(2).Info("retry scenario but last applied bundle not found, will rebuild", + "repository", repoRefName, + "error", err) + return true, nil + } + } } } + } + } + return false, nil +} + +// determineCacheLocation returns the cache path and filename based on repository and gateway configuration +func determineCacheLocation(repository *securityv1.Repository, gateway *securityv1.Gateway) (cachePath string, cacheFileName string) { + // Local and HTTP repos always use vanilla bundles (no operator-generated delete mappings) + if repository.Spec.Type == securityv1.RepositoryTypeLocal || repository.Spec.Type == securityv1.RepositoryTypeHttp { + cachePath = "/tmp/repo-cache/" + repository.Name + cacheFileName = repository.Status.Commit + ".json" + return cachePath, cacheFileName + } + + if repository.Spec.StateStoreReference != "" { + // Statestore-backed repository + cachePath = "/tmp/statestore/" + repository.Name + cacheFileName = "latest.json" + } else if gateway.Spec.App.RepositoryReferenceDelete.Enabled && gateway.Spec.App.RepositoryReferenceDelete.IncludeEfs { + // Non-statestore with delete enabled + cachePath = "/tmp/repo-cache/" + repository.Name + cacheFileName = "combined.json" + } else { + // Non-statestore with delete disabled (vanilla) + cachePath = "/tmp/repo-cache/" + repository.Name + cacheFileName = repository.Status.Commit + ".json" + } + return cachePath, cacheFileName +} + +// shouldSkipDeltaComparison determines if we should skip delta comparison and build a vanilla bundle +func shouldSkipDeltaComparison(gateway *securityv1.Gateway, repository *securityv1.Repository) bool { + // Local and HTTP repos are ALWAYS vanilla (no delta comparison) + if repository.Spec.Type == securityv1.RepositoryTypeLocal || repository.Spec.Type == securityv1.RepositoryTypeHttp { + return true + } + + // If master flag is disabled, always skip delta comparison + if !gateway.Spec.App.RepositoryReferenceDelete.Enabled { + return true + } + + // If non-statestore and includeEfs is false, skip delta comparison + if repository.Spec.StateStoreReference == "" && !gateway.Spec.App.RepositoryReferenceDelete.IncludeEfs { + return true + } + + return false +} + +// buildVanillaBundleAndCache builds a vanilla bundle from cache and stores it +func buildVanillaBundleAndCache(repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, gateway *securityv1.Gateway, cachePath string, cacheFileName string, tmpPath string, fileName string, params Params) ([]byte, error) { + // Build bundle from cache + bundleBytes, err := buildBundleFromCache(repository, repoRef, cachePath, cacheFileName) + if err != nil { + return nil, fmt.Errorf("failed to build vanilla bundle: %w", err) + } - case "local": - bundlePath = "" - bundleBytes, err = readLocalReference(ctx, repository, params) + // Write to cache and last_applied + if err := writeBundlesToDisk(repository, repoRef, gateway, bundleBytes, nil, tmpPath, fileName, cachePath, params); err != nil { + return nil, err + } + + return bundleBytes, nil +} + +// handleDirectoryChange handles directory changes with delta calculation +func handleDirectoryChange(ctx context.Context, params Params, repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, gateway *securityv1.Gateway, cachePath string, cacheFileName string, tmpPath string, fileName string, previousDirectories []string) ([]byte, error) { + // Step 1: Build new bundle from current directories + newBundleBytes, err := buildBundleFromCache(repository, repoRef, cachePath, cacheFileName) + if err != nil { + return nil, fmt.Errorf("failed to build new bundle for directory change: %w", err) + } + + // For combined.json and latest.json (StateStore) with directory additions/reordering (not removals), repository mappings are correct + // But if directories were removed, we need to calculate delta to generate DELETE mappings + // Check if any previous directories are missing from current directories + directoriesRemoved := false + for _, prevDir := range previousDirectories { + found := false + for _, currDir := range repoRef.Directories { + if prevDir == currDir { + found = true + break + } + } + if !found { + directoriesRemoved = true + params.Log.Info("directory removed, calculating delta", + "repository", repoRef.Name, + "removedDirectory", prevDir) + break + } + } + + // If no directories were removed, just use repository bundle as-is for repository-controlled mappings + if (cacheFileName == "combined.json" || cacheFileName == "latest.json") && !directoriesRemoved { + sourceType := cacheFileName + params.Log.V(2).Info("directory change with repository-controlled mappings - using repository mappings", + "repository", repoRef.Name, + "sourceType", sourceType, + "previousDirs", previousDirectories, + "currentDirs", repoRef.Directories) + + if err := writeBundlesToDisk(repository, repoRef, gateway, newBundleBytes, nil, tmpPath, fileName, cachePath, params); err != nil { + return nil, err + } + return newBundleBytes, nil + } + + // Step 2: Look up previous bundle + var previousBundleBytes []byte + + if len(previousDirectories) == 0 { + // No previous directories tracked - treat as first deployment + params.Log.Info("no previous directories tracked, treating as first deployment", + "repository", repoRef.Name) + + // Just write and return the new bundle + if err := writeBundlesToDisk(repository, repoRef, gateway, newBundleBytes, nil, tmpPath, fileName, cachePath, params); err != nil { + return nil, err + } + return newBundleBytes, nil + } + + // Known previous directories - try to read the bundle + previousFileName := calculateBundleFileName(params.Instance, repoRef.Name, previousDirectories) + + // Try cachePath first (persistent for StateStore), then tmpPath (ephemeral) + previousBundleBytes, err = os.ReadFile(cachePath + "/" + previousFileName) + if err != nil { + // Try tmpPath as fallback + previousBundleBytes, err = os.ReadFile(tmpPath + "/" + previousFileName) + if err != nil { + // Previous bundle file not found (e.g. after operator restart) + // But we know what directories were applied from status + // Reconstruct the previous bundle from cache + params.Log.Info("previous bundle file not found, reconstructing from cache", + "repository", repoRef.Name, + "previousDirectories", previousDirectories, + "previousFileName", previousFileName) + + // Create a temporary repoRef with previous directories to reconstruct + tempRepoRef := &securityv1.RepositoryReference{ + Name: repoRef.Name, + Enabled: repoRef.Enabled, + Type: repoRef.Type, + Directories: previousDirectories, + } + + previousBundleBytes, err = buildBundleFromCache(repository, tempRepoRef, cachePath, cacheFileName) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to reconstruct previous bundle from cache: %w", err) } + + params.Log.V(2).Info("successfully reconstructed previous bundle from cache", + "repository", repoRef.Name, + "previousDirectories", previousDirectories) + } else { + params.Log.V(2).Info("found previous bundle in tmpPath", + "repository", repoRef.Name, + "previousFileName", previousFileName) } - return bundleBytes, nil + } else { + params.Log.V(2).Info("found previous bundle in cachePath", + "repository", repoRef.Name, + "previousFileName", previousFileName) } - _, fErr := os.Stat(tmpPath + "/" + fileName) - if fErr != nil { - bundleMap := map[string][]byte{} - for d := range repoRef.Directories { - ext := repository.Spec.Branch - if ext == "" { - ext = repository.Spec.Tag - } + // Step 3: Parse bundles + var previousBundle, newBundle graphman.Bundle + if err := json.Unmarshal(previousBundleBytes, &previousBundle); err != nil { + return nil, fmt.Errorf("failed to unmarshal previous bundle: %w", err) + } + if err := json.Unmarshal(newBundleBytes, &newBundle); err != nil { + return nil, fmt.Errorf("failed to unmarshal new bundle: %w", err) + } - dir := repoRef.Directories[d] - if dir == "/" { - dir = "" - } + // Step 4: For repository-controlled mappings (combined.json/latest.json), preserve existing DELETE mappings + // The repository controller has already determined what should be deleted based on commit changes + // We only need to ADD delete mappings for entities in removed directories + preserveRepoMappings := (cacheFileName == "combined.json" || cacheFileName == "latest.json") - bundlePath = "/tmp/" + repoRef.Name + "-" + params.Instance.Namespace + "-" + ext + "/" + dir + // Save the repository-generated DELETE mappings before any processing + var repoDeleteMappings graphman.BundleMappings + if preserveRepoMappings && newBundle.Properties != nil { + repoDeleteMappings = newBundle.Properties.Mappings + } - _, fErr := os.Stat(tmpPath + "/" + fileName) - if fErr != nil { + // Step 5: Reset mappings on previous bundle + if err := graphman.ResetMappings(&previousBundle); err != nil { + params.Log.V(2).Info("failed to reset mappings on previous bundle, continuing anyway", "error", err) + } - bundleMap[strconv.Itoa(d)+".json"], err = util.BuildAndValidateBundle(bundlePath) - if err != nil { - return nil, err - // bundleBytes, err = readStorageSecret(ctx, repository, params) - // if err != nil { - // return nil, err - // } - } + // Step 6: Calculate delta for removed directories + _, combinedBundle, err := graphman.CalculateDelta(previousBundle, newBundle) + if err != nil { + return nil, fmt.Errorf("failed to calculate delta for directory change: %w", err) + } + + // Step 7: For repository-controlled mappings, merge back the repository DELETE mappings + // This ensures DELETE mappings from commit changes are preserved alongside directory-change DELETEs + if preserveRepoMappings { + if combinedBundle.Properties == nil { + combinedBundle.Properties = &graphman.BundleProperties{} + } + // Merge repository DELETE mappings with calculated delta DELETE mappings + // We need to preserve DELETE mappings from the repository (commit-based deletes) + // while adding new DELETE mappings from directory changes + combinedBundle.Properties.Mappings.Services = append(combinedBundle.Properties.Mappings.Services, repoDeleteMappings.Services...) + combinedBundle.Properties.Mappings.WebApiServices = append(combinedBundle.Properties.Mappings.WebApiServices, repoDeleteMappings.WebApiServices...) + combinedBundle.Properties.Mappings.InternalWebApiServices = append(combinedBundle.Properties.Mappings.InternalWebApiServices, repoDeleteMappings.InternalWebApiServices...) + combinedBundle.Properties.Mappings.SoapServices = append(combinedBundle.Properties.Mappings.SoapServices, repoDeleteMappings.SoapServices...) + combinedBundle.Properties.Mappings.InternalSoapServices = append(combinedBundle.Properties.Mappings.InternalSoapServices, repoDeleteMappings.InternalSoapServices...) + combinedBundle.Properties.Mappings.Policies = append(combinedBundle.Properties.Mappings.Policies, repoDeleteMappings.Policies...) + combinedBundle.Properties.Mappings.PolicyFragments = append(combinedBundle.Properties.Mappings.PolicyFragments, repoDeleteMappings.PolicyFragments...) + combinedBundle.Properties.Mappings.EncassConfigs = append(combinedBundle.Properties.Mappings.EncassConfigs, repoDeleteMappings.EncassConfigs...) + combinedBundle.Properties.Mappings.HttpConfigurations = append(combinedBundle.Properties.Mappings.HttpConfigurations, repoDeleteMappings.HttpConfigurations...) + combinedBundle.Properties.Mappings.Keys = append(combinedBundle.Properties.Mappings.Keys, repoDeleteMappings.Keys...) + combinedBundle.Properties.Mappings.TrustedCerts = append(combinedBundle.Properties.Mappings.TrustedCerts, repoDeleteMappings.TrustedCerts...) + combinedBundle.Properties.Mappings.Schemas = append(combinedBundle.Properties.Mappings.Schemas, repoDeleteMappings.Schemas...) + combinedBundle.Properties.Mappings.Dtds = append(combinedBundle.Properties.Mappings.Dtds, repoDeleteMappings.Dtds...) + combinedBundle.Properties.Mappings.CustomKeyValues = append(combinedBundle.Properties.Mappings.CustomKeyValues, repoDeleteMappings.CustomKeyValues...) + combinedBundle.Properties.Mappings.ClusterProperties = append(combinedBundle.Properties.Mappings.ClusterProperties, repoDeleteMappings.ClusterProperties...) + combinedBundle.Properties.Mappings.JdbcConnections = append(combinedBundle.Properties.Mappings.JdbcConnections, repoDeleteMappings.JdbcConnections...) + combinedBundle.Properties.Mappings.CassandraConnections = append(combinedBundle.Properties.Mappings.CassandraConnections, repoDeleteMappings.CassandraConnections...) + combinedBundle.Properties.Mappings.JmsDestinations = append(combinedBundle.Properties.Mappings.JmsDestinations, repoDeleteMappings.JmsDestinations...) + combinedBundle.Properties.Mappings.Secrets = append(combinedBundle.Properties.Mappings.Secrets, repoDeleteMappings.Secrets...) + combinedBundle.Properties.Mappings.Fips = append(combinedBundle.Properties.Mappings.Fips, repoDeleteMappings.Fips...) + combinedBundle.Properties.Mappings.Ldaps = append(combinedBundle.Properties.Mappings.Ldaps, repoDeleteMappings.Ldaps...) + combinedBundle.Properties.Mappings.InternalGroups = append(combinedBundle.Properties.Mappings.InternalGroups, repoDeleteMappings.InternalGroups...) + combinedBundle.Properties.Mappings.FipGroups = append(combinedBundle.Properties.Mappings.FipGroups, repoDeleteMappings.FipGroups...) + combinedBundle.Properties.Mappings.InternalUsers = append(combinedBundle.Properties.Mappings.InternalUsers, repoDeleteMappings.InternalUsers...) + combinedBundle.Properties.Mappings.FipUsers = append(combinedBundle.Properties.Mappings.FipUsers, repoDeleteMappings.FipUsers...) + combinedBundle.Properties.Mappings.GlobalPolicies = append(combinedBundle.Properties.Mappings.GlobalPolicies, repoDeleteMappings.GlobalPolicies...) + combinedBundle.Properties.Mappings.BackgroundTasks = append(combinedBundle.Properties.Mappings.BackgroundTasks, repoDeleteMappings.BackgroundTasks...) + combinedBundle.Properties.Mappings.ScheduledTasks = append(combinedBundle.Properties.Mappings.ScheduledTasks, repoDeleteMappings.ScheduledTasks...) + combinedBundle.Properties.Mappings.ServerModuleFiles = append(combinedBundle.Properties.Mappings.ServerModuleFiles, repoDeleteMappings.ServerModuleFiles...) + combinedBundle.Properties.Mappings.SiteMinderConfigs = append(combinedBundle.Properties.Mappings.SiteMinderConfigs, repoDeleteMappings.SiteMinderConfigs...) + combinedBundle.Properties.Mappings.ActiveConnectors = append(combinedBundle.Properties.Mappings.ActiveConnectors, repoDeleteMappings.ActiveConnectors...) + combinedBundle.Properties.Mappings.EmailListeners = append(combinedBundle.Properties.Mappings.EmailListeners, repoDeleteMappings.EmailListeners...) + combinedBundle.Properties.Mappings.ListenPorts = append(combinedBundle.Properties.Mappings.ListenPorts, repoDeleteMappings.ListenPorts...) + combinedBundle.Properties.Mappings.AdministrativeUserAccountProperties = append(combinedBundle.Properties.Mappings.AdministrativeUserAccountProperties, repoDeleteMappings.AdministrativeUserAccountProperties...) + combinedBundle.Properties.Mappings.PasswordPolicies = append(combinedBundle.Properties.Mappings.PasswordPolicies, repoDeleteMappings.PasswordPolicies...) + combinedBundle.Properties.Mappings.RevocationCheckPolicies = append(combinedBundle.Properties.Mappings.RevocationCheckPolicies, repoDeleteMappings.RevocationCheckPolicies...) + combinedBundle.Properties.Mappings.LogSinks = append(combinedBundle.Properties.Mappings.LogSinks, repoDeleteMappings.LogSinks...) + combinedBundle.Properties.Mappings.ServiceResolutionConfigs = append(combinedBundle.Properties.Mappings.ServiceResolutionConfigs, repoDeleteMappings.ServiceResolutionConfigs...) + combinedBundle.Properties.Mappings.Folders = append(combinedBundle.Properties.Mappings.Folders, repoDeleteMappings.Folders...) + combinedBundle.Properties.Mappings.FederatedIdps = append(combinedBundle.Properties.Mappings.FederatedIdps, repoDeleteMappings.FederatedIdps...) + combinedBundle.Properties.Mappings.FederatedGroups = append(combinedBundle.Properties.Mappings.FederatedGroups, repoDeleteMappings.FederatedGroups...) + combinedBundle.Properties.Mappings.FederatedUsers = append(combinedBundle.Properties.Mappings.FederatedUsers, repoDeleteMappings.FederatedUsers...) + combinedBundle.Properties.Mappings.InternalIdps = append(combinedBundle.Properties.Mappings.InternalIdps, repoDeleteMappings.InternalIdps...) + combinedBundle.Properties.Mappings.LdapIdps = append(combinedBundle.Properties.Mappings.LdapIdps, repoDeleteMappings.LdapIdps...) + combinedBundle.Properties.Mappings.SimpleLdapIdps = append(combinedBundle.Properties.Mappings.SimpleLdapIdps, repoDeleteMappings.SimpleLdapIdps...) + combinedBundle.Properties.Mappings.PolicyBackedIdps = append(combinedBundle.Properties.Mappings.PolicyBackedIdps, repoDeleteMappings.PolicyBackedIdps...) + combinedBundle.Properties.Mappings.Roles = append(combinedBundle.Properties.Mappings.Roles, repoDeleteMappings.Roles...) + combinedBundle.Properties.Mappings.GenericEntities = append(combinedBundle.Properties.Mappings.GenericEntities, repoDeleteMappings.GenericEntities...) + combinedBundle.Properties.Mappings.AuditConfigurations = append(combinedBundle.Properties.Mappings.AuditConfigurations, repoDeleteMappings.AuditConfigurations...) + + params.Log.V(2).Info("merged repository DELETE mappings with directory delta", + "repository", repoRef.Name, + "sourceType", cacheFileName, + "repoServiceMappings", len(repoDeleteMappings.Services), + "deltaServiceMappings", len(combinedBundle.Properties.Mappings.Services)-len(repoDeleteMappings.Services)) + } + + // Step 8: Marshal the combined bundle (with delete mappings) + bundleWithMappings, err := json.Marshal(combinedBundle) + if err != nil { + return nil, fmt.Errorf("failed to marshal combined bundle: %w", err) + } + + // Step 9: Create clean version (reset mappings) + cleanBundle := combinedBundle + if err := graphman.ResetMappings(&cleanBundle); err != nil { + params.Log.V(2).Info("failed to reset mappings for clean bundle", "error", err) + } + cleanBundleBytes, err := json.Marshal(cleanBundle) + if err != nil { + return nil, fmt.Errorf("failed to marshal clean bundle: %w", err) + } + + // Step 10: Write bundles to disk + if err := writeBundlesToDisk(repository, repoRef, gateway, bundleWithMappings, cleanBundleBytes, tmpPath, fileName, cachePath, params); err != nil { + return nil, err + } + + params.Log.V(2).Info("directory change handled with delta calculation", + "repository", repoRef.Name, + "previousDirs", previousDirectories, + "currentDirs", repoRef.Directories) + + return bundleWithMappings, nil +} + +// handleCommitChange handles commit changes with optional delta calculation +func handleCommitChange(ctx context.Context, params Params, repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, gateway *securityv1.Gateway, cachePath string, cacheFileName string, tmpPath string, fileName string) ([]byte, error) { + // Step 1: Build new bundle from latest commit + newBundleBytes, err := buildBundleFromCache(repository, repoRef, cachePath, cacheFileName) + if err != nil { + return nil, fmt.Errorf("failed to build bundle for new commit: %w", err) + } + + // Step 2: For combined.json and statestore, the repository controller already calculated deltas + // Just apply the bundle with its mappings as-is + if cacheFileName == "combined.json" || repository.Spec.StateStoreReference != "" { + sourceType := "combined.json" + if repository.Spec.StateStoreReference != "" { + sourceType = "statestore" + } + + params.Log.V(2).Info("commit change - using repository-calculated mappings", + "repository", repoRef.Name, + "commit", repository.Status.Commit, + "sourceType", sourceType) + + // Log bundle details to verify mappings are present + var newBundle graphman.Bundle + if err := json.Unmarshal(newBundleBytes, &newBundle); err == nil { + serviceMappingsCount := 0 + if newBundle.Properties != nil { + serviceMappingsCount = len(newBundle.Properties.Mappings.Services) } + params.Log.Info("bundle from repository", + "repository", repoRef.Name, + "services", len(newBundle.Services), + "serviceMappings", serviceMappingsCount) } - bundleBytes, err = util.ConcatBundles(bundleMap) - if err != nil { + + // Write and return the bundle (repository controller already added delete mappings) + if err := writeBundlesToDisk(repository, repoRef, gateway, newBundleBytes, nil, tmpPath, fileName, cachePath, params); err != nil { return nil, err } - // remove bundles 10 days or older to avoid - // growing the ephemeral filesystem - existingBundles, _ := os.ReadDir(tmpPath) - for _, f := range existingBundles { - fInfo, err := f.Info() - if err != nil { - return nil, err - } - if time.Since(fInfo.ModTime()) > 240*time.Hour { - os.Remove(tmpPath + "/" + f.Name()) + return newBundleBytes, nil + } + + // Step 3: For {commit}.json (vanilla bundles), just write and return + // User controls all mappings explicitly - no operator-generated deletes + params.Log.V(2).Info("commit change with vanilla bundle - no delta calculation", + "repository", repoRef.Name, + "commit", repository.Status.Commit) + + // Write and return the bundle as-is (user-defined mappings only) + if err := writeBundlesToDisk(repository, repoRef, gateway, newBundleBytes, nil, tmpPath, fileName, cachePath, params); err != nil { + return nil, err + } + return newBundleBytes, nil +} + +// writeBundlesToDisk writes bundle versions to disk for caching and retry +func writeBundlesToDisk(repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, gateway *securityv1.Gateway, bundleWithMappings []byte, cleanBundle []byte, tmpPath string, fileName string, cachePath string, params Params) error { + // Clean up old bundles + cleanupOldBundles(tmpPath) + + // Write commit marker + commitMarkerPath := tmpPath + "/" + repository.Status.Commit + ".txt" + if err := os.WriteFile(commitMarkerPath, []byte{}, 0755); err != nil { + return fmt.Errorf("failed to write commit marker: %w", err) + } + + // Write clean bundle (if provided) + if cleanBundle != nil { + // Write to tmpPath for immediate access + cleanBundlePath := tmpPath + "/" + fileName + if err := os.WriteFile(cleanBundlePath, cleanBundle, 0755); err != nil { + return fmt.Errorf("failed to write clean bundle to tmp: %w", err) + } + params.Log.V(5).Info("wrote clean bundle to tmp", "path", cleanBundlePath) + + // Also write to cachePath for persistence (for directory change comparisons) + cleanBundleCachePath := cachePath + "/" + fileName + if err := os.WriteFile(cleanBundleCachePath, cleanBundle, 0755); err != nil { + params.Log.V(2).Info("failed to write clean bundle to cache, continuing", "error", err, "path", cleanBundleCachePath) + } else { + params.Log.V(5).Info("wrote clean bundle to cache", "path", cleanBundleCachePath) + } + } else { + // If no separate clean bundle, write the main bundle as clean + cleanBundlePath := tmpPath + "/" + fileName + if err := os.WriteFile(cleanBundlePath, bundleWithMappings, 0755); err != nil { + return fmt.Errorf("failed to write bundle to tmp: %w", err) + } + params.Log.V(5).Info("wrote bundle to tmp", "path", cleanBundlePath) + + // Also write to cachePath for persistence + cleanBundleCachePath := cachePath + "/" + fileName + if err := os.WriteFile(cleanBundleCachePath, bundleWithMappings, 0755); err != nil { + params.Log.V(2).Info("failed to write bundle to cache, continuing", "error", err, "path", cleanBundleCachePath) + } else { + params.Log.V(5).Info("wrote bundle to cache", "path", cleanBundleCachePath) + } + } + + // Write bundle with mappings (if different from clean) + if cleanBundle != nil { + bundleWithMappingsPath := tmpPath + "/" + fileName + "_with_mappings" + if err := os.WriteFile(bundleWithMappingsPath, bundleWithMappings, 0755); err != nil { + return fmt.Errorf("failed to write bundle with mappings: %w", err) + } + params.Log.V(5).Info("wrote bundle with mappings", "path", bundleWithMappingsPath) + } + + // Write last applied bundle for retry mechanism (to tmpPath for immediate access) + lastAppliedTmpPath := tmpPath + "/last_applied_" + repoRef.Name + ".json" + if err := os.WriteFile(lastAppliedTmpPath, bundleWithMappings, 0755); err != nil { + return fmt.Errorf("failed to write last applied bundle to tmp: %w", err) + } + params.Log.V(5).Info("wrote last applied bundle to tmp", "path", lastAppliedTmpPath) + + // Also write to cachePath for persistence across pod restarts + // Use repository name + reference name for consistency across directory changes + lastAppliedCachePath := cachePath + "/last_applied_" + repoRef.Name + ".json" + if err := os.WriteFile(lastAppliedCachePath, bundleWithMappings, 0755); err != nil { + return fmt.Errorf("failed to write last applied bundle to cache: %w", err) + } + params.Log.V(5).Info("wrote last applied bundle to cache", "path", lastAppliedCachePath) + + return nil +} + +func buildBundle(ctx context.Context, params Params, repoRef *securityv1.RepositoryReference, repository *securityv1.Repository, gateway *securityv1.Gateway, delete bool) (bundleBytes []byte, err error) { + tmpPath := "/tmp/bundles/" + repository.Name + fileName := calculateBundleFileName(params.Instance, repoRef.Name, repoRef.Directories) + + // Ensure temp directory exists + if err := os.MkdirAll(tmpPath, 0755); err != nil { + return nil, fmt.Errorf("failed to create temp directory: %w", err) + } + + // Step 1: Handle delete operations + if delete { + return buildDeleteBundle(repository, repoRef, gateway, params) + } + + // Step 2: Check for retry scenario + if shouldRetry, retryBundle := checkRetryScenario(gateway, repoRef.Name, repository.Status.Commit, tmpPath, params); shouldRetry { + if retryBundle != nil { + params.Log.V(2).Info("retrying last applied bundle due to previous failure", "repository", repoRef.Name) + return retryBundle, nil + } + } + + // Step 3: Determine cache location and file + cachePath, cacheFileName := determineCacheLocation(repository, gateway) + params.Log.V(5).Info("using cache", "cachePath", cachePath, "cacheFileName", cacheFileName, "repository", repoRef.Name) + + // Step 4: Check if we should skip delta comparison (vanilla bundle) + if shouldSkipDeltaComparison(gateway, repository) { + params.Log.V(5).Info("skipping delta comparison, building vanilla bundle", "repository", repoRef.Name) + return buildVanillaBundleAndCache(repository, repoRef, gateway, cachePath, cacheFileName, tmpPath, fileName, params) + } + + // Step 5: Check if commit changed + newCommit := false + if _, err := os.Stat(tmpPath + "/" + repository.Status.Commit + ".txt"); err != nil { + newCommit = true + params.Log.V(5).Info("new commit detected", "repository", repoRef.Name, "commit", repository.Status.Commit) + } + + // Step 6: Check if directories changed + directoryChanged := false + var previousDirectories []string + for _, repoStatus := range gateway.Status.RepositoryStatus { + if repoStatus.Name == repoRef.Name { + previousDirectories = repoStatus.Directories + if len(previousDirectories) > 0 && !reflect.DeepEqual(repoRef.Directories, repoStatus.Directories) { + directoryChanged = true + params.Log.Info("directory change detected", "repository", repoRef.Name, "previous", previousDirectories, "current", repoRef.Directories) } + break + } + } + // Step 7: Return cached bundle if nothing changed + if !newCommit && !directoryChanged { + // If delete/reconcile is enabled, try to use the bundle with mappings first + // This ensures we continue applying delete mappings if needed + if !shouldSkipDeltaComparison(gateway, repository) { + if bundleWithMappings, err := os.ReadFile(tmpPath + "/" + fileName + "_with_mappings"); err == nil { + params.Log.V(5).Info("returning cached bundle with mappings (no changes)", "repository", repoRef.Name) + return bundleWithMappings, nil + } } - err = os.WriteFile(tmpPath+"/"+fileName, bundleBytes, 0755) - if err != nil { - return nil, err + + // Otherwise use the clean bundle + if cachedBundle, err := os.ReadFile(tmpPath + "/" + fileName); err == nil { + params.Log.V(5).Info("returning cached bundle (no changes)", "repository", repoRef.Name) + return cachedBundle, nil } + } - } else { - bundleBytes, err = os.ReadFile(tmpPath + "/" + fileName) - if err != nil { - return nil, err + // Step 8: Route to appropriate handler + if directoryChanged && gateway.Spec.App.RepositoryReferenceDelete.ReconcileDirectoryChanges { + params.Log.V(2).Info("handling directory change with reconciliation", "repository", repoRef.Name) + return handleDirectoryChange(ctx, params, repository, repoRef, gateway, cachePath, cacheFileName, tmpPath, fileName, previousDirectories) + } else if directoryChanged && !gateway.Spec.App.RepositoryReferenceDelete.ReconcileDirectoryChanges { + params.Log.V(5).Info("directory changed but reconciliation disabled, building vanilla bundle", "repository", repoRef.Name) + return buildVanillaBundleAndCache(repository, repoRef, gateway, cachePath, cacheFileName, tmpPath, fileName, params) + } else if newCommit { + params.Log.V(2).Info("handling commit change", "repository", repoRef.Name, "commit", repository.Status.Commit) + return handleCommitChange(ctx, params, repository, repoRef, gateway, cachePath, cacheFileName, tmpPath, fileName) + } + + // Fallback: build vanilla bundle + params.Log.V(5).Info("building vanilla bundle (fallback)", "repository", repoRef.Name) + return buildVanillaBundleAndCache(repository, repoRef, gateway, cachePath, cacheFileName, tmpPath, fileName, params) +} + +// calculateBundleFileName generates a unique filename based on directories and commit +func calculateBundleFileName(gateway *securityv1.Gateway, referenceName string, directories []string) string { + dirChecksum := "" + for _, d := range directories { + h := sha1.New() + h.Write([]byte(d)) + dirChecksum += fmt.Sprintf("%x", h.Sum(nil)) + } + + h := sha1.New() + h.Write([]byte(gateway.Name + "-" + referenceName + "-" + dirChecksum)) + sha1Sum := fmt.Sprintf("%x", h.Sum(nil)) + return sha1Sum[30:] + ".json" +} + +// buildBundleFromCache loads bundles from cached directory structure or storage secret +func buildBundleFromCache(repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, cachePath string, fileName string) ([]byte, error) { + //fileName := repository.Status.Commit + ".json" + + bundleMapBytes, err := os.ReadFile(cachePath + "/" + fileName) + if err != nil { + // Cache not available - this might happen if repository isn't ready yet + // In this case, we cannot build the bundle + return nil, fmt.Errorf("failed to read cached bundle: %w", err) + } + + bundleMap := map[string][]byte{} + if err := json.Unmarshal(bundleMapBytes, &bundleMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle map: %w", err) + } + + // Determine if we should preserve repository mappings + // For combined.json and latest.json (StateStore), preserve DELETE mappings from repository controller + // For commit.json (user-controlled), clean DELETE mappings for re-added entities + preserveRepoMappings := (fileName == "combined.json" || fileName == "latest.json") + + // Local and HTTP repos ALWAYS use all directories ["/"] regardless of what's specified in Gateway CR + // This gives users full control and simplifies the model for development/testing repos + isLocalOrHttp := (repository.Spec.Type == securityv1.RepositoryTypeLocal || repository.Spec.Type == securityv1.RepositoryTypeHttp) + + // If requesting all directories OR if it's a local/http repo, concatenate everything, no ordering + if isLocalOrHttp || (len(repoRef.Directories) == 1 && repoRef.Directories[0] == "/") { + if preserveRepoMappings { + return util.ConcatBundlesPreservingMappings(bundleMap) } + return util.ConcatBundles(bundleMap) + } + + // Otherwise, filter by specific directories (git repos only) + return buildBundleFromDirectories(repoRef.Directories, bundleMap, preserveRepoMappings) +} + +// buildBundleFromDirectories combines bundles from specific directories +// Processes directories in order, with later directories overwriting earlier ones +// preserveRepoMappings: if true, preserve DELETE mappings from repository controller (for combined.json) +// +// if false, clean DELETE mappings for re-added entities (for commit.json) +func buildBundleFromDirectories(directories []string, bundleMap map[string][]byte, preserveRepoMappings bool) ([]byte, error) { + srcBundle := graphman.Bundle{} + bundleBytes, err := json.Marshal(srcBundle) + if err != nil { + return nil, err + } + + // Process directories in the order specified + for _, d := range directories { + keyName := strings.TrimPrefix(strings.ReplaceAll(d, "/", "-"), "-") + + // Use full bundles (not deltas) for concatenation + bundleKey := keyName + ".gz" + + if bundleGz, exists := bundleMap[bundleKey]; exists { + decompressedBytes, err := util.GzipDecompress(bundleGz) + if err != nil { + return nil, fmt.Errorf("failed to decompress bundle %s: %w", bundleKey, err) + } + + var bundle graphman.Bundle + if err := json.Unmarshal(decompressedBytes, &bundle); err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle from %s: %w", bundleKey, err) + } + cleanBytes, err := json.Marshal(bundle) + if err != nil { + return nil, fmt.Errorf("failed to marshal clean bundle from %s: %w", bundleKey, err) + } + + // Concatenate bundles + if preserveRepoMappings { + // For repository-controlled mappings (combined.json, latest.json), + // preserve DELETE mappings as-is - don't clean them + bundleBytes, err = graphman.ConcatBundlePreservingMappings(cleanBytes, bundleBytes) + } else { + // For user-controlled mappings (commit.json), + // clean DELETE mappings for re-added entities + bundleBytes, err = graphman.ConcatBundle(cleanBytes, bundleBytes) + } + if err != nil { + return nil, fmt.Errorf("failed to concat bundle from %s: %w", bundleKey, err) + } + } } + return bundleBytes, nil } -func checkLocalRepoOnFs(params Params, repository *securityv1.Repository) (bool, error) { +// buildBundleFromStorageSecret reads bundles from storage secret when cache is not available +func buildBundleFromStorageSecret(ctx context.Context, repository *securityv1.Repository, repoRef *securityv1.RepositoryReference, params Params) ([]byte, error) { + storageSecret, err := getGatewaySecret(ctx, params, repository.Status.StorageSecretName) + if err != nil { + return nil, fmt.Errorf("failed to read storage secret: %w", err) + } - if repository.Spec.StateStoreReference != "" { - return true, nil + // Storage secret Data contains the same bundleMap structure as the cache + // If requesting all directories, concatenate everything + if len(repoRef.Directories) == 1 && repoRef.Directories[0] == "/" { + return util.ConcatBundles(storageSecret.Data) } - gitPath := "" - ext := repository.Spec.Branch - dir := "/" - gitPath = "/tmp/" + repository.Name + "-" + params.Instance.Namespace + "-" + ext + "/" + dir + // Otherwise, filter by specific directories + // For storage secret, we preserve user-defined mappings (not repository-controlled) + return buildBundleFromDirectories(repoRef.Directories, storageSecret.Data, false) +} + +// cleanupOldBundles removes bundles older than 10 days +func cleanupOldBundles(tmpPath string) { + existingBundles, err := os.ReadDir(tmpPath) + if err != nil { + return + } - switch strings.ToLower(string(repository.Spec.Type)) { - case "http": - fileURL, err := url.Parse(repository.Spec.Endpoint) + for _, f := range existingBundles { + fInfo, err := f.Info() if err != nil { - return false, err + continue } - path := fileURL.Path - segments := strings.Split(path, "/") - fileName := segments[len(segments)-1] - ext := strings.Split(fileName, ".")[len(strings.Split(fileName, "."))-1] - folderName := strings.ReplaceAll(fileName, "."+ext, "") - if ext == "gz" && strings.Split(fileName, ".")[len(strings.Split(fileName, "."))-2] == "tar" { - folderName = strings.ReplaceAll(fileName, ".tar.gz", "") + if time.Since(fInfo.ModTime()) > 240*time.Hour { + os.Remove(tmpPath + "/" + f.Name()) } - gitPath = "/tmp/" + repository.Name + "-" + params.Instance.Namespace + "-" + folderName } +} + +func checkLocalRepoOnFs(params Params, repository *securityv1.Repository) (bool, error) { - if gitPath != "" { - _, fErr := os.Stat(gitPath) - if fErr != nil { - return false, nil + // Check if pre-built bundle cache exists + var cachePath string + if repository.Spec.StateStoreReference != "" { + cachePath = "/tmp/statestore/" + repository.Name + fileName := "latest.json" + if _, err := os.Stat(cachePath + "/" + fileName); err == nil { + return true, nil + } + } else { + cachePath = "/tmp/repo-cache/" + repository.Name + fileName := repository.Status.Commit + ".json" + if _, err := os.Stat(cachePath + "/" + fileName); err == nil { + // Pre-built bundle cache exists, can use it + return true, nil + } + } + + // If no cache, check if raw repository exists on filesystem + if repository.Spec.StateStoreReference != "" { + // For state store repos, check if state store path exists + stateStorePath := "/tmp/statestore/" + repository.Name + if _, err := os.Stat(stateStorePath); err == nil { + return true, nil } } @@ -993,15 +1542,39 @@ func updateGatewayDeployment(ctx context.Context, params Params, gwUpdReq *Gatew } currentChecksum := gwUpdReq.deployment.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] + // Skip if it already has the correct checksum and no directory change + if currentChecksum == gwUpdReq.checksum && !gwUpdReq.delete { + // Check if there's a directory change for repositories + if gwUpdReq.bundleType == BundleTypeRepository { + directoryChangeForPod := false + for _, repoStatus := range gwUpdReq.gateway.Status.RepositoryStatus { + if repoStatus.Name == gwUpdReq.repositoryReference.Name { + if !reflect.DeepEqual(gwUpdReq.repositoryReference.Directories, repoStatus.Directories) { + directoryChangeForPod = true + } + break + } + } + if !directoryChangeForPod { + return nil // skip, it's already up to date + } + } else { + return nil //skip, it's already up to date + } + } if gwUpdReq.bundleType == BundleTypeRepository { if (currentChecksum == "deleted" && !gwUpdReq.repositoryReference.Enabled) || (currentChecksum == "" && (gwUpdReq.delete || !gwUpdReq.repositoryReference.Enabled)) { return nil } - } - - if currentChecksum == gwUpdReq.checksum && !gwUpdReq.delete { - return nil + for _, repoStatus := range gwUpdReq.gateway.Status.RepositoryStatus { + if repoStatus.Name == gwUpdReq.repositoryReference.Name { + if !reflect.DeepEqual(gwUpdReq.repositoryReference.Directories, repoStatus.Directories) { + update = true + } + break + } + } } if currentChecksum != gwUpdReq.checksum || currentChecksum == "" || gwUpdReq.delete { @@ -1012,11 +1585,41 @@ func updateGatewayDeployment(ctx context.Context, params Params, gwUpdReq *Gatew ready = true } - patch := fmt.Sprintf("{\"metadata\": {\"annotations\": {\"%s\": \"%s\"}}}", gwUpdReq.patchAnnotation, gwUpdReq.checksum) + // Build patch with annotations + annotations := make(map[string]string) + if gwUpdReq.delete { - patch = fmt.Sprintf("{\"metadata\": {\"annotations\": {\"%s\": \"%s\"}}}", gwUpdReq.patchAnnotation, "deleted") + annotations[gwUpdReq.patchAnnotation] = "deleted" + + // If ReconcileReferences is enabled, also clear other repository annotations to force reapply + if gwUpdReq.gateway.Spec.App.RepositoryReferenceDelete.ReconcileReferences { + for _, repoRef := range gwUpdReq.gateway.Spec.App.RepositoryReferences { + if repoRef.Name == gwUpdReq.repositoryReference.Name { + continue + } + // Skip static type repositories - there are no singleton configs with database backed gateways + if repoRef.Type == securityv1.RepositoryReferenceTypeStatic { + continue + } + annotationKey := "security.brcmlabs.com/" + repoRef.Name + "-" + string(repoRef.Type) + annotations[annotationKey] = "" + } + } + } else { + annotations[gwUpdReq.patchAnnotation] = gwUpdReq.checksum } + patchData := map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": annotations, + }, + } + patchBytes, err := json.Marshal(patchData) + if err != nil { + return err + } + patch := string(patchBytes) + if ready && update { requestCacheEntry := gwUpdReq.deployment.Name + "-" + gwUpdReq.cacheEntry syncRequest, err := syncCache.Read(requestCacheEntry) @@ -1031,14 +1634,29 @@ func updateGatewayDeployment(ctx context.Context, params Params, gwUpdReq *Gatew syncCache.Update(util.SyncRequest{RequestName: requestCacheEntry, Attempts: 1}, time.Now().Add(3*time.Second).Unix()) start := time.Now() - params.Log.V(5).Info("applying latest "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + + logAction := "applying latest" + if gwUpdReq.delete { + logAction = "removing" + } + + params.Log.V(5).Info(logAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) err = util.ApplyToGraphmanTarget(gwUpdReq.bundle, true, gwUpdReq.username, gwUpdReq.password, endpoint, gwUpdReq.graphmanEncryptionPassphrase, gwUpdReq.delete) if err != nil { - params.Log.Info("failed to apply "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + failedAction := "failed to apply" + if gwUpdReq.delete { + failedAction = "failed to remove" + } + params.Log.Info(failedAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) _ = captureGraphmanMetrics(ctx, params, start, gwUpdReq.deployment.Name, string(gwUpdReq.bundleType), gwUpdReq.bundleName, gwUpdReq.checksum, true) return err } - params.Log.Info("applied latest "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "hash", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + + successAction := "applied latest" + if gwUpdReq.delete { + successAction = "removed" + } + params.Log.Info(successAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "hash", gwUpdReq.checksum, "deployment", gwUpdReq.deployment.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) _ = captureGraphmanMetrics(ctx, params, start, gwUpdReq.deployment.Name, string(gwUpdReq.bundleType), gwUpdReq.bundleName, gwUpdReq.checksum, false) err = updateEntityStatus(ctx, string(gwUpdReq.bundleType), gwUpdReq.bundleName, gwUpdReq.bundle, params) @@ -1052,11 +1670,7 @@ func updateGatewayDeployment(ctx context.Context, params Params, gwUpdReq *Gatew return err } } else { - // startTime := time.Now() - // if gwUpdReq.podList.Items[i].Status.StartTime != nil { - // startTime = gwUpdReq.podList.Items[i].Status.StartTime.Time - // } - if (!ready && gwUpdReq.bundleType == BundleTypeClusterProp) || (!ready && gwUpdReq.bundleType == BundleTypeListenPort) { //(startTime.Before(time.Now().Add(120*time.Second)) && gwUpdReq.stateStore) || + if (!ready && gwUpdReq.bundleType == BundleTypeClusterProp) || (!ready && gwUpdReq.bundleType == BundleTypeListenPort) { if err := params.Client.Patch(ctx, gwUpdReq.deployment, client.RawPatch(types.StrategicMergePatchType, []byte(patch))); err != nil { params.Log.Error(err, "failed to update deployment annotations", "namespace", params.Instance.Namespace, "name", params.Instance.Name) @@ -1076,6 +1690,10 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda update := false ready := false + if pod.DeletionTimestamp != nil { + continue + } + for _, containerStatus := range pod.Status.ContainerStatuses { if containerStatus.Name == "gateway" { ready = containerStatus.Ready @@ -1090,6 +1708,32 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda currentChecksum := pod.ObjectMeta.Annotations[gwUpdReq.patchAnnotation] + // For repositories with SingletonExtraction, adjust checksum for leader before comparison + if gwUpdReq.bundleType == BundleTypeRepository && gwUpdReq.gateway.Spec.App.SingletonExtraction && pod.ObjectMeta.Labels["management-access"] == "leader" { + checksum = gwUpdReq.checksum + "-leader" + } + + // Skip this pod if it already has the correct checksum and no directory change + if currentChecksum == checksum && !gwUpdReq.delete { + // Check if there's a directory change for repositories + if gwUpdReq.bundleType == BundleTypeRepository { + directoryChangeForPod := false + for _, repoStatus := range gwUpdReq.gateway.Status.RepositoryStatus { + if repoStatus.Name == gwUpdReq.repositoryReference.Name { + if !reflect.DeepEqual(gwUpdReq.repositoryReference.Directories, repoStatus.Directories) { + directoryChangeForPod = true + } + break + } + } + if !directoryChangeForPod { + continue // Skip this pod, it's already up to date + } + } else { + continue // Skip this pod, it's already up to date + } + } + if gwUpdReq.bundleType == BundleTypeOTKDatabaseMaintenance { if pod.ObjectMeta.Labels["management-access"] == "leader" { checksum = gwUpdReq.checksum + "-leader" @@ -1100,16 +1744,32 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda } if gwUpdReq.bundleType == BundleTypeRepository { - if (currentChecksum == "deleted" && !gwUpdReq.repositoryReference.Enabled) || (currentChecksum == "" && (gwUpdReq.delete || !gwUpdReq.repositoryReference.Enabled)) { + // Skip if already deleted (annotation = "deleted" and repo still disabled) + if currentChecksum == "deleted" && !gwUpdReq.repositoryReference.Enabled { return nil } + for _, repoStatus := range gwUpdReq.gateway.Status.RepositoryStatus { + if repoStatus.Name == gwUpdReq.repositoryReference.Name { + if !reflect.DeepEqual(gwUpdReq.repositoryReference.Directories, repoStatus.Directories) { + update = true + } + break + } + } + if gwUpdReq.gateway.Spec.App.SingletonExtraction && pod.ObjectMeta.Labels["management-access"] == "leader" { checksum = gwUpdReq.checksum + "-leader" singleton = true } + // Handle static repositories - only apply to leader pod if gwUpdReq.repositoryReference.Type == securityv1.RepositoryReferenceTypeStatic { + if pod.ObjectMeta.Labels["management-access"] != "leader" { + continue // Skip non-leader pods for static repos + } + + // Extract singleton entities for static repos bundle := graphman.Bundle{} singletonBundle := graphman.Bundle{} err = json.Unmarshal(gwUpdReq.bundle, &bundle) @@ -1127,26 +1787,51 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda singletonBundle.JmsDestinations = append(singletonBundle.JmsDestinations, jmsDestination) } } + if len(singletonBundle.ScheduledTasks) > 0 || len(singletonBundle.JmsDestinations) > 0 { gwUpdReq.bundle, err = json.Marshal(singletonBundle) if err != nil { return err } } else { - continue - } - if pod.ObjectMeta.Labels["management-access"] != "leader" { - continue + continue // No singleton entities to apply for static repo } } } - patch := fmt.Sprintf("{\"metadata\": {\"annotations\": {\"%s\": \"%s\"}}}", gwUpdReq.patchAnnotation, checksum) + // Build patch with annotations + annotations := make(map[string]string) if gwUpdReq.delete { - patch = fmt.Sprintf("{\"metadata\": {\"annotations\": {\"%s\": \"%s\"}}}", gwUpdReq.patchAnnotation, "deleted") + annotations[gwUpdReq.patchAnnotation] = "deleted" + + // If ReconcileReferences is enabled, also clear other repository annotations to force reapply + if gwUpdReq.gateway.Spec.App.RepositoryReferenceDelete.ReconcileReferences { + for _, repoRef := range gwUpdReq.gateway.Spec.App.RepositoryReferences { + if repoRef.Name == gwUpdReq.repositoryReference.Name { + continue + } + annotationKey := "security.brcmlabs.com/" + repoRef.Name + "-" + string(repoRef.Type) + annotations[annotationKey] = "" + } + } + } else { + annotations[gwUpdReq.patchAnnotation] = checksum } + patchData := map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": annotations, + }, + } + patchBytes, err := json.Marshal(patchData) + if err != nil { + return err + } + patch := string(patchBytes) + + // Set update=true if checksums don't match, checksum is empty, or it's a delete + // (update may already be true from directory change check above) if currentChecksum != checksum || currentChecksum == "" || gwUpdReq.delete { update = true } @@ -1170,14 +1855,29 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda if tryRequest { syncCache.Update(util.SyncRequest{RequestName: requestCacheEntry, Attempts: 1}, time.Now().Add(3*time.Second).Unix()) start := time.Now() - params.Log.V(5).Info("applying latest "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + + logAction := "applying latest" + if gwUpdReq.delete { + logAction = "removing" + } + + params.Log.V(5).Info(logAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) err = util.ApplyToGraphmanTarget(gwUpdReq.bundle, singleton, gwUpdReq.username, gwUpdReq.password, endpoint, gwUpdReq.graphmanEncryptionPassphrase, gwUpdReq.delete) if err != nil { - params.Log.Info("failed to apply "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + failedAction := "failed to apply" + if gwUpdReq.delete { + failedAction = "failed to remove" + } + params.Log.Info(failedAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "checksum", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) _ = captureGraphmanMetrics(ctx, params, start, pod.Name, string(gwUpdReq.bundleType), gwUpdReq.bundleName, checksum, true) return err } - params.Log.Info("applied latest "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "hash", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) + + successAction := "applied latest" + if gwUpdReq.delete { + successAction = "removed" + } + params.Log.Info(successAction+" "+string(gwUpdReq.bundleType)+" "+gwUpdReq.bundleName, "hash", checksum, "pod", pod.Name, "name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) _ = captureGraphmanMetrics(ctx, params, start, pod.Name, string(gwUpdReq.bundleType), gwUpdReq.bundleName, checksum, false) if err := params.Client.Patch(ctx, &gwUpdReq.podList.Items[i], @@ -1187,7 +1887,10 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda } } } else { - if (!ready && gwUpdReq.bundleType == BundleTypeClusterProp) || (!ready && gwUpdReq.bundleType == BundleTypeListenPort) { + // Patch annotation for non-ready pods + if (!ready && gwUpdReq.bundleType == BundleTypeClusterProp) || + (!ready && gwUpdReq.bundleType == BundleTypeListenPort) || + (!ready && gwUpdReq.bundleType == BundleTypeRepository && gwUpdReq.gateway.Spec.App.RepositoryReferenceBootstrap.Enabled && pod.ObjectMeta.Labels["management-access"] != "leader" && !singleton) { if err := params.Client.Patch(ctx, &gwUpdReq.podList.Items[i], client.RawPatch(types.StrategicMergePatchType, []byte(patch))); err != nil { params.Log.Error(err, "failed to update pod label", "Name", gwUpdReq.gateway.Name, "namespace", gwUpdReq.gateway.Namespace) @@ -1197,7 +1900,7 @@ func updateGatewayPods(ctx context.Context, params Params, gwUpdReq *GatewayUpda } } - if updateStatus || (!updateStatus && string(gwUpdReq.bundleType) == "cluster properties") || (!updateStatus && string(gwUpdReq.bundleType) == "listen ports") { + if updateStatus || (!updateStatus && gwUpdReq.bundleType == BundleTypeClusterProp) || (!updateStatus && gwUpdReq.bundleType == BundleTypeListenPort) { err := updateEntityStatus(ctx, string(gwUpdReq.bundleType), gwUpdReq.bundleName, gwUpdReq.bundle, params) if err != nil { return err @@ -1539,30 +2242,29 @@ func ReconcileDBGateway(ctx context.Context, params Params, kind string, gateway return nil } -func disabledOrDeleteRepoRefStatus(ctx context.Context, params Params, repository securityv1.Repository, disabled bool) (err error) { - repositoryStatuses := params.Instance.Status.RepositoryStatus - for i, repositoryStatus := range repositoryStatuses { - if repositoryStatus.Name == repository.Name { - if disabled { - repositoryStatuses[i].Enabled = false - } else { - repositoryStatuses = append(repositoryStatuses[:i], repositoryStatuses[i+1:]...) +func updateRepoRefStatus(ctx context.Context, params Params, repository securityv1.Repository, repoRef securityv1.RepositoryReference, commit string, applyError error, delete bool) (err error) { + gatewayStatus := params.Instance.Status + + // If delete was successful, remove the repository from status + if delete && applyError == nil { + var updatedStatus []securityv1.GatewayRepositoryStatus + for _, rs := range gatewayStatus.RepositoryStatus { + if rs.Name != repoRef.Name { + updatedStatus = append(updatedStatus, rs) } - break } - } + gatewayStatus.RepositoryStatus = updatedStatus - params.Instance.Status.RepositoryStatus = repositoryStatuses - err = params.Client.Status().Update(ctx, params.Instance) - if err != nil { - params.Log.V(2).Info("failed to disabled/delete gateway status", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) - return err + params.Instance.Status = gatewayStatus + err = params.Client.Status().Update(ctx, params.Instance) + if err != nil { + params.Log.V(2).Info("failed to update gateway status after delete", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) + return err + } + params.Log.Info("removed repository from gateway status", "repository", repoRef.Name, "gateway", params.Instance.Name, "namespace", params.Instance.Namespace) + return nil } - return nil -} -func updateRepoRefStatus(ctx context.Context, params Params, repository securityv1.Repository, referenceType securityv1.RepositoryReferenceType, commit string, applyError error, delete bool) (err error) { - gatewayStatus := params.Instance.Status var conditions []securityv1.RepositoryCondition secretName := repository.Name if repository.Spec.Auth.ExistingSecretName != "" { @@ -1576,11 +2278,15 @@ func updateRepoRefStatus(ctx context.Context, params Params, repository security nrs := securityv1.GatewayRepositoryStatus{ Commit: commit, Enabled: !delete, - Name: repository.Name, - Type: string(referenceType), + Name: repoRef.Name, + RepoType: string(repository.Spec.Type), + Vendor: repository.Spec.Auth.Vendor, + AuthType: string(repository.Spec.Auth.Type), + Type: string(repoRef.Type), SecretName: secretName, StorageSecretName: repository.Status.StorageSecretName, Endpoint: repository.Spec.Endpoint, + Directories: repoRef.Directories, } if repository.Spec.Tag != "" && repository.Spec.Branch == "" { @@ -1640,17 +2346,19 @@ func updateRepoRefStatus(ctx context.Context, params Params, repository security nrs.Conditions = conditions if repository.Spec.StateStoreReference != "" { + ext := repository.Spec.Branch + if ext == "" { + ext = repository.Spec.Tag + } + stateStoreKey := repository.Name + "-repository-" + ext nrs.StateStoreReference = repository.Spec.StateStoreReference - statestore := &securityv1alpha1.L7StateStore{} - err := params.Client.Get(ctx, types.NamespacedName{Name: repository.Spec.StateStoreReference, Namespace: params.Instance.Namespace}, statestore) if err != nil && k8serrors.IsNotFound(err) { params.Log.Info("state store not found", "name", repository.Spec.StateStoreReference, "repository", repository.Name, "namespace", params.Instance.Namespace) return err } - - nrs.StateStoreKey = statestore.Spec.Redis.GroupName + ":" + statestore.Spec.Redis.StoreId + ":" + "repository" + ":" + repository.Status.StorageSecretName + ":latest" + nrs.StateStoreKey = statestore.Spec.Redis.GroupName + ":" + statestore.Spec.Redis.StoreId + ":" + "repository" + ":" + stateStoreKey + ":latest" if repository.Spec.StateStoreKey != "" { nrs.StateStoreKey = repository.Spec.StateStoreKey } diff --git a/pkg/gateway/reconcile/l7repositories.go b/pkg/gateway/reconcile/l7repositories.go index e206524e..353cb2d8 100644 --- a/pkg/gateway/reconcile/l7repositories.go +++ b/pkg/gateway/reconcile/l7repositories.go @@ -27,6 +27,7 @@ package reconcile import ( "context" + "fmt" securityv1 "github.com/caapim/layer7-operator/api/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -83,40 +84,42 @@ func reconcileDynamicRepository(ctx context.Context, params Params, repoRef secu if !repository.Status.Ready { params.Log.Info("repository not ready", "repository", repository.Name, "name", gateway.Name, "namespace", gateway.Namespace) - ok, err := checkLocalRepoOnFs(params, repository) + localRepoAvailable, err := checkLocalRepoOnFs(params, repository) if err != nil { - return err + //return err + params.Log.Info("repository not available on local fs", "repository", repository.Name, "name", gateway.Name, "namespace", gateway.Namespace) } - - if !ok { - return nil + // If repository not available locally, check if storage secret exists + // storageSecret primary use is bootstrap, does not track delta so this is not reliable for delete + if !localRepoAvailable { + if !gateway.Spec.App.RepositoryReferenceDelete.Enabled && (repository.Status.StorageSecretName != "" && repository.Status.StorageSecretName != "_") { + _, err := getGatewaySecret(ctx, params, repository.Status.StorageSecretName) + if err != nil { + params.Log.V(2).Info("storage secret not found", "secret", repository.Status.StorageSecretName, "repository", repository.Name) + return nil + } + } else { + params.Log.Info("repository not reconcilable via storage secret", "repository", repository.Name, "name", gateway.Name, "namespace", gateway.Namespace) + return fmt.Errorf("unable to apply repository reference: %s to gateway: %s in namespace: %s", repository.Name, gateway.Name, gateway.Namespace) + } } - - // check secret if not using directories... - - // if !found { - // if repository.Status.StorageSecretName != "" { - // rs, err := getGatewaySecret(ctx, params, repository.Status.StorageSecretName) - // if err != nil { - // return err - // } - // for k, v := range rs.Data { - // if strings.HasSuffix(k, ".gz") { - // if len(v) < 20 { - // return nil - // } - // } - // } - // } - // } } commit := repository.Status.Commit - // only support delete if a statestore is used - if repository.Spec.StateStoreReference == "" { + + // Only enable delete functionality if delete was requested (repository disabled/removed) + // AND RepositoryReferenceDelete is enabled + + if delete && !gateway.Spec.App.RepositoryReferenceDelete.Enabled { delete = false } + if delete && gateway.Spec.App.RepositoryReferenceDelete.Enabled { + if !gateway.Spec.App.RepositoryReferenceDelete.IncludeEfs && repository.Spec.StateStoreReference == "" { + delete = false + } + } + gwUpdReq, err := NewGwUpdateRequest( ctx, gateway, @@ -138,7 +141,7 @@ func reconcileDynamicRepository(ctx context.Context, params Params, repoRef secu err = SyncGateway(ctx, params, *gwUpdReq) - _ = updateRepoRefStatus(ctx, params, *gwUpdReq.repository, gwUpdReq.repositoryReference.Type, gwUpdReq.checksum, err, delete) + _ = updateRepoRefStatus(ctx, params, *gwUpdReq.repository, *gwUpdReq.repositoryReference, gwUpdReq.checksum, err, delete) gwUpdReq = nil if err != nil { return err diff --git a/pkg/gateway/reconcile/secret.go b/pkg/gateway/reconcile/secret.go index bf5796f8..14849c3e 100644 --- a/pkg/gateway/reconcile/secret.go +++ b/pkg/gateway/reconcile/secret.go @@ -38,7 +38,7 @@ func Secrets(ctx context.Context, params Params) error { } if params.Instance.Spec.App.Redis.Enabled && params.Instance.Spec.App.Redis.ExistingSecret == "" { - desiredSecret, err := gateway.NewSecret(params.Instance, params.Instance.Name+"-shared-state-client-configuration") + desiredSecret, err := gateway.NewSecret(params.Instance, params.Instance.Name+"-shared-state-config") if err != nil { return err } diff --git a/pkg/gateway/reconcile/serviceaccount.go b/pkg/gateway/reconcile/serviceaccount.go index 86943d4b..60d3b772 100644 --- a/pkg/gateway/reconcile/serviceaccount.go +++ b/pkg/gateway/reconcile/serviceaccount.go @@ -11,7 +11,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -// / TODO: Should auto-delete if not used... func ServiceAccount(ctx context.Context, params Params) error { if !params.Instance.Spec.App.ServiceAccount.Create { diff --git a/pkg/gateway/reconcile/status.go b/pkg/gateway/reconcile/status.go index e7bd289c..24c040de 100644 --- a/pkg/gateway/reconcile/status.go +++ b/pkg/gateway/reconcile/status.go @@ -87,58 +87,25 @@ func GatewayStatus(ctx context.Context, params Params) error { found := false for i, repoStatus := range gatewayStatus.RepositoryStatus { if repoStatus.Name == repository.Name { - gatewayStatus.RepositoryStatus[i].Enabled = repoRef.Enabled - gatewayStatus.RepositoryStatus[i].Commit = repository.Status.Commit - gatewayStatus.RepositoryStatus[i].Type = string(repoRef.Type) + rs, err := buildRepoStatus(ctx, params, *repository, repoRef) + if err != nil { + params.Log.V(2).Info("failed to build repository status", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) + return err + } + if len(gatewayStatus.RepositoryStatus[i].Conditions) > 0 { + rs.Conditions = gatewayStatus.RepositoryStatus[i].Conditions + } + rs.Directories = gatewayStatus.RepositoryStatus[i].Directories + gatewayStatus.RepositoryStatus[i] = rs found = true } } - if !found { - secretName := repository.Name - if repository.Spec.Auth.ExistingSecretName != "" { - secretName = repository.Spec.Auth.ExistingSecretName - } - - if repository.Spec.Auth == (securityv1.RepositoryAuth{}) { - secretName = "" - } - - rs := securityv1.GatewayRepositoryStatus{ - Commit: repository.Status.Commit, - Enabled: repoRef.Enabled, - Name: repoRef.Name, - Type: string(repoRef.Type), - SecretName: secretName, - StorageSecretName: repository.Status.StorageSecretName, - Endpoint: repository.Spec.Endpoint, - } - - if repository.Spec.Tag != "" && repository.Spec.Branch == "" { - rs.Tag = repository.Spec.Tag - } - - if repository.Spec.Branch != "" { - rs.Branch = repository.Spec.Branch - } - - rs.RemoteName = "origin" - if repository.Spec.RemoteName != "" { - rs.RemoteName = repository.Spec.RemoteName - } - - if repository.Spec.StateStoreReference != "" { - rs.StateStoreReference = repository.Spec.StateStoreReference - statestore := &securityv1alpha1.L7StateStore{} - err := params.Client.Get(ctx, types.NamespacedName{Name: repository.Spec.StateStoreReference, Namespace: params.Instance.Namespace}, statestore) - if err != nil && k8serrors.IsNotFound(err) { - params.Log.Info("state store not found", "name", repository.Spec.StateStoreReference, "repository", repository.Name, "namespace", params.Instance.Namespace) - return err - } - rs.StateStoreKey = statestore.Spec.Redis.GroupName + ":" + statestore.Spec.Redis.StoreId + ":" + "repository" + ":" + repository.Status.StorageSecretName + ":latest" - if repository.Spec.StateStoreKey != "" { - rs.StateStoreKey = repository.Spec.StateStoreKey - } + if !found && repoRef.Enabled { + rs, err := buildRepoStatus(ctx, params, *repository, repoRef) + if err != nil { + params.Log.V(2).Info("failed to build repository status", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) + return err } gatewayStatus.RepositoryStatus = append(gatewayStatus.RepositoryStatus, rs) } @@ -163,3 +130,61 @@ func GatewayStatus(ctx context.Context, params Params) error { } return nil } + +func buildRepoStatus(ctx context.Context, params Params, repository securityv1.Repository, repoRef securityv1.RepositoryReference) (repoStatus securityv1.GatewayRepositoryStatus, err error) { + secretName := repository.Name + if repository.Spec.Auth.ExistingSecretName != "" { + secretName = repository.Spec.Auth.ExistingSecretName + } + + if repository.Spec.Auth == (securityv1.RepositoryAuth{}) { + secretName = "" + } + + rs := securityv1.GatewayRepositoryStatus{ + Commit: repository.Status.Commit, + Enabled: repoRef.Enabled, + Name: repoRef.Name, + RepoType: string(repository.Spec.Type), + Vendor: repository.Spec.Auth.Vendor, + AuthType: string(repository.Spec.Auth.Type), + Type: string(repoRef.Type), + SecretName: secretName, + StorageSecretName: repository.Status.StorageSecretName, + Endpoint: repository.Spec.Endpoint, + //Directories: repoRef.Directories, + } + + if repository.Spec.Tag != "" && repository.Spec.Branch == "" { + rs.Tag = repository.Spec.Tag + } + + if repository.Spec.Branch != "" { + rs.Branch = repository.Spec.Branch + } + + rs.RemoteName = "origin" + if repository.Spec.RemoteName != "" { + rs.RemoteName = repository.Spec.RemoteName + } + + if repository.Spec.StateStoreReference != "" { + ext := repository.Spec.Branch + if ext == "" { + ext = repository.Spec.Tag + } + stateStoreKey := repository.Name + "-repository-" + ext + rs.StateStoreReference = repository.Spec.StateStoreReference + statestore := &securityv1alpha1.L7StateStore{} + err := params.Client.Get(ctx, types.NamespacedName{Name: repository.Spec.StateStoreReference, Namespace: params.Instance.Namespace}, statestore) + if err != nil && k8serrors.IsNotFound(err) { + params.Log.Info("state store not found", "name", repository.Spec.StateStoreReference, "repository", repository.Name, "namespace", params.Instance.Namespace) + return securityv1.GatewayRepositoryStatus{}, err + } + rs.StateStoreKey = statestore.Spec.Redis.GroupName + ":" + statestore.Spec.Redis.StoreId + ":" + "repository" + ":" + stateStoreKey + ":latest" + if repository.Spec.StateStoreKey != "" { + rs.StateStoreKey = repository.Spec.StateStoreKey + } + } + return rs, nil +} diff --git a/pkg/gateway/secrets.go b/pkg/gateway/secrets.go index fda27885..9d4fb811 100644 --- a/pkg/gateway/secrets.go +++ b/pkg/gateway/secrets.go @@ -55,7 +55,7 @@ func NewSecret(gw *securityv1.Gateway, name string) (*corev1.Secret, error) { data["OTK_CLIENT_READ_DATABASE_PASSWORD"] = []byte(gw.Spec.App.Otk.Database.Auth.ClientReadOnlyUser.Password) } - case gw.Name + "-shared-state-client-configuration": + case gw.Name + "-shared-state-config": redisGroupName := "l7GW" sentinelMasterSet := "mymaster" commandTimeout := 5000 diff --git a/pkg/gateway/secrets_test.go b/pkg/gateway/secrets_test.go index c2ed2558..f4c6b254 100755 --- a/pkg/gateway/secrets_test.go +++ b/pkg/gateway/secrets_test.go @@ -220,7 +220,7 @@ redis: enabled: false ` - secret, _ := NewSecret(&gateway, gateway.Name+"-shared-state-client-configuration") + secret, _ := NewSecret(&gateway, gateway.Name+"-shared-state-config") if strings.TrimSpace(string(secret.Data["sharedstate_client.yaml"])) != strings.TrimSpace(expectedRedisConfig) { t.Errorf("expected %s, actual %s", strings.TrimSpace(expectedRedisConfig), strings.TrimSpace(string(secret.Data["sharedstate_client.yaml"]))) @@ -251,7 +251,7 @@ redis: enabled: false ` - secret, _ = NewSecret(&gateway, gateway.Name+"-shared-state-client-configuration") + secret, _ = NewSecret(&gateway, gateway.Name+"-shared-state-config") if strings.TrimSpace(string(secret.Data["sharedstate_client.yaml"])) != strings.TrimSpace(expectedRedisConfig) { t.Errorf("expected %s, actual %s", strings.TrimSpace(expectedRedisConfig), strings.TrimSpace(string(secret.Data["sharedstate_client.yaml"]))) diff --git a/pkg/repository/reconcile/finalizer.go b/pkg/repository/reconcile/finalizer.go new file mode 100644 index 00000000..b070de41 --- /dev/null +++ b/pkg/repository/reconcile/finalizer.go @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2025 Broadcom. All rights reserved. +* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +* All trademarks, trade names, service marks, and logos referenced +* herein belong to their respective companies. +* +* This software and all information contained therein is confidential +* and proprietary and shall not be duplicated, used, disclosed or +* disseminated in any way except as authorized by the applicable +* license agreement, without the express written permission of Broadcom. +* All authorized reproductions must be marked with this language. +* +* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE +* EXTENT PERMITTED BY APPLICABLE LAW OR AS AGREED BY BROADCOM IN ITS +* APPLICABLE LICENSE AGREEMENT, BROADCOM PROVIDES THIS DOCUMENTATION +* "AS IS" WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION, +* ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* PURPOSE, OR. NONINFRINGEMENT. IN NO EVENT WILL BROADCOM BE LIABLE TO +* THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR +* INDIRECT, FROM THE USE OF THIS DOCUMENTATION, INCLUDING WITHOUT LIMITATION, +* LOST PROFITS, LOST INVESTMENT, BUSINESS INTERRUPTION, GOODWILL, OR +* LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE +* POSSIBILITY OF SUCH LOSS OR DAMAGE. +* +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. + */ +package reconcile + +import ( + "context" + "fmt" + "net/url" + "os" + "strings" + + v1 "github.com/caapim/layer7-operator/api/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +const repositoryFinalizer = "security.brcmlabs.com/layer7-operator" + +func Finalizer(ctx context.Context, params Params) (err error) { + isMarkedToBeDeleted := false + if params.Instance.DeletionTimestamp != nil { + isMarkedToBeDeleted = true + } + + if isMarkedToBeDeleted { + // Check if repository is still being actively used by any gateways + inUse, gatewayNames, err := isRepositoryInUse(ctx, params) + if err != nil { + params.Log.Error(err, "failed to check if repository is in use", "name", params.Instance.Name) + return err + } + + if inUse { + params.Log.Info("repository is still referenced by active gateways, skipping deletion", + "repository", params.Instance.Name, + "namespace", params.Instance.Namespace, + "gateways", gatewayNames) + return fmt.Errorf("repository %s is still referenced by gateways: %v", params.Instance.Name, gatewayNames) + } + + // Clean up repository files and folders + switch params.Instance.Spec.Type { + case v1.RepositoryTypeGit: + ref := params.Instance.Spec.Tag + + if params.Instance.Spec.Branch != "" { + ref = params.Instance.Spec.Branch + } + + err = os.RemoveAll("/tmp/" + params.Instance.Name + "-" + params.Instance.Namespace + "-" + ref) + + if err != nil { + return err + } + case v1.RepositoryTypeHttp: + fileURL, _ := url.Parse(params.Instance.Spec.Endpoint) + path := fileURL.Path + segments := strings.Split(path, "/") + fileName := segments[len(segments)-1] + ext := strings.Split(fileName, ".")[len(strings.Split(fileName, "."))-1] + folderName := strings.ReplaceAll(fileName, "."+ext, "") + if ext == "gz" && strings.Split(fileName, ".")[len(strings.Split(fileName, "."))-2] == "tar" { + folderName = strings.ReplaceAll(fileName, ".tar.gz", "") + } + + fileName = "/tmp/" + params.Instance.Name + "-" + params.Instance.Namespace + "-" + fileName + folderName = "/tmp/" + params.Instance.Name + "-" + params.Instance.Namespace + "-" + folderName + + err = os.RemoveAll(folderName) + if err != nil { + return err + } + + err = os.Remove(fileName) + if err != nil { + return err + } + default: + break + } + + // Clean up cache directory + cachePath := "/tmp/repo-cache/" + params.Instance.Name + if err := os.RemoveAll(cachePath); err != nil { + params.Log.V(2).Info("failed to remove cache directory", "path", cachePath, "error", err.Error()) + } + + // Clean up statestore cache if it exists + stateStorePath := "/tmp/statestore/" + params.Instance.Name + if err := os.RemoveAll(stateStorePath); err != nil { + params.Log.V(2).Info("failed to remove statestore cache directory", "path", stateStorePath, "error", err.Error()) + } + + // todo + // remove from statestore if push + err = removeFinalizer(ctx, params) + if err != nil { + return err + } + } + return nil +} + +// isRepositoryInUse checks if the repository is actively referenced by any gateways +func isRepositoryInUse(ctx context.Context, params Params) (bool, []string, error) { + // List all gateways in the same namespace + gatewayList := &v1.GatewayList{} + if err := params.Client.List(ctx, gatewayList, client.InNamespace(params.Instance.Namespace)); err != nil { + return false, nil, fmt.Errorf("failed to list gateways: %w", err) + } + + var referencingGateways []string + + // Check each gateway for references to this repository + for _, gateway := range gatewayList.Items { + for _, repoRef := range gateway.Spec.App.RepositoryReferences { + if repoRef.Name == params.Instance.Name && repoRef.Enabled { + referencingGateways = append(referencingGateways, gateway.Name) + break + } + } + } + + if len(referencingGateways) > 0 { + return true, referencingGateways, nil + } + + return false, nil, nil +} + +func removeFinalizer(ctx context.Context, params Params) error { + params.Log.V(2).Info("removing finalizer", "name", params.Instance.Name, "namespace", params.Instance.Namespace) + controllerutil.RemoveFinalizer(params.Instance, repositoryFinalizer) + err := params.Client.Update(ctx, params.Instance) + if err != nil { + params.Log.V(2).Info("fail to remove finalizer", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) + return err + } + + return nil +} diff --git a/pkg/repository/reconcile/repository.go b/pkg/repository/reconcile/repository.go index 2d3263da..78f9e8c0 100644 --- a/pkg/repository/reconcile/repository.go +++ b/pkg/repository/reconcile/repository.go @@ -22,18 +22,22 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package reconcile import ( "context" + "encoding/json" "net/url" + "os" "reflect" "strings" "time" securityv1 "github.com/caapim/layer7-operator/api/v1" securityv1alpha1 "github.com/caapim/layer7-operator/api/v1alpha1" + "github.com/caapim/layer7-operator/internal/graphman" "github.com/caapim/layer7-operator/pkg/util" "github.com/go-git/go-git/v5" "go.opentelemetry.io/otel" @@ -54,6 +58,7 @@ func syncRepository(ctx context.Context, params Params) error { var sshKeyPass string var knownHosts []byte var statestore securityv1alpha1.L7StateStore + stateStoreSynced := true authType := repository.Spec.Auth.Type if err != nil { @@ -88,16 +93,6 @@ func syncRepository(ctx context.Context, params Params) error { sshKey = repositorySecret.Data["SSH_KEY"] sshKeyPass = string(repositorySecret.Data["SSH_KEY_PASS"]) knownHosts = repositorySecret.Data["KNOWN_HOSTS"] - authType = repository.Spec.Auth.Type - - if authType == "" && username != "" && token != "" { - authType = securityv1.RepositoryAuthTypeBasic - } - - if authType == "" && username == "" && sshKey != nil { - authType = securityv1.RepositoryAuthTypeSSH - } - } ext := repository.Spec.Branch @@ -124,6 +119,7 @@ func syncRepository(ctx context.Context, params Params) error { } if repository.Spec.StateStoreReference != "" { + storageSecretName = "_" statestore, err = getStateStore(ctx, params) if err != nil { params.Log.V(2).Error(err, "failed to retrieve statestore", "namespace", params.Instance.Namespace, "name", params.Instance.Name) @@ -179,26 +175,17 @@ func syncRepository(ctx context.Context, params Params) error { } case "git": commit, err = util.CloneRepository(repository.Spec.Endpoint, username, token, sshKey, sshKeyPass, repository.Spec.Branch, repository.Spec.Tag, repository.Spec.RemoteName, repository.Name, repository.Spec.Auth.Vendor, string(authType), knownHosts, repository.Namespace) - - stateStoreSynced := true if err == git.NoErrAlreadyUpToDate || err == git.ErrRemoteExists { params.Log.V(5).Info(err.Error(), "name", repository.Name, "namespace", repository.Namespace) - if repository.Spec.StateStoreReference != "" && !repository.Status.StateStoreSynced { - err = StateStorage(ctx, params, statestore) - if err != nil { - params.Log.V(2).Info("failed to reconcile state storage", "name", repository.Name+"-repository", "namespace", repository.Namespace, "error", err.Error()) - stateStoreSynced = false - } + // Check if we need to build cache/storage secret (only if status doesn't match) + if params.Instance.Status.Commit == commit && (params.Instance.Status.StorageSecretName != "" && params.Instance.Status.StorageSecretName != "_") { + params.Log.V(5).Info("already up-to-date with cache built", "name", repository.Name, "namespace", repository.Namespace) + return nil } - params.Instance.Status.StateStoreSynced = stateStoreSynced - updateErr := updateStatus(ctx, params, commit, storageSecretName) - if updateErr != nil { - _ = captureRepositorySyncMetrics(ctx, params, start, commit, true) - params.Log.Info("failed to update repository status", "namespace", repository.Namespace, "name", repository.Name, "error", err.Error()) - } - return nil + // Continue to build cache and storage secret if status doesn't match + err = nil } if err != nil { @@ -231,7 +218,6 @@ func syncRepository(ctx context.Context, params Params) error { params.Log.V(5).Info("already up-to-date", "name", repository.Name, "namespace", repository.Namespace) return nil } - case "local": return nil default: @@ -240,16 +226,34 @@ func syncRepository(ctx context.Context, params Params) error { } if strings.ToLower(string(repository.Spec.Type)) != "statestore" { + if repository.Spec.StateStoreReference != "" { - err = StateStorage(ctx, params, statestore) + // For state store repos, sync to Redis + err = StateStorage(ctx, params, statestore, commit) if err != nil { params.Log.V(2).Info("failed to reconcile state storage", "name", repository.Name+"-repository", "namespace", repository.Namespace, "error", err.Error()) params.Instance.Status.StateStoreSynced = false } - } else { - err = StorageSecret(ctx, params) + } + + // Create storage secret from bundleMap for all repos + // Filter out delta bundles - we don't use them in Gateway yet and they take up space + if storageSecretName != "_" && storageSecretName != "" { + // Build directory-based bundle cache for all repos (state store and non-state store) + bundleMap, err := BuildRepositoryCache(ctx, params, commit, storageSecretName) + if err != nil { + params.Log.V(2).Info("failed to build repository cache", "name", repository.Name+"-repository", "namespace", repository.Namespace, "error", err.Error()) + } + + storageSecretBundleMap := make(map[string][]byte) + for k, v := range bundleMap { + if !strings.HasSuffix(k, "-delta.gz") { + storageSecretBundleMap[k] = v + } + } + + err = StorageSecretFromBundleMap(ctx, params, storageSecretBundleMap, storageSecretName) if err != nil { - // add a check here that prevents the Operator trying to sync the secret repeatedly params.Log.V(2).Info("failed to reconcile storage secret", "name", repository.Name+"-repository", "namespace", repository.Namespace, "error", err.Error()) storageSecretName = "" if err.Error() == "exceededMaxSize" { @@ -259,7 +263,15 @@ func syncRepository(ctx context.Context, params Params) error { } } - err = updateStatus(ctx, params, commit, storageSecretName) + if repository.Spec.StateStoreReference != "" && (!repository.Status.StateStoreSynced || commit != repository.Status.Commit) { + err = StateStorage(ctx, params, statestore, commit) + if err != nil { + params.Log.V(2).Info("failed to reconcile state storage", "name", repository.Name+"-repository", "namespace", repository.Namespace, "error", err.Error()) + stateStoreSynced = false + } + } + + err = updateStatus(ctx, params, commit, storageSecretName, stateStoreSynced) if err != nil { _ = captureRepositorySyncMetrics(ctx, params, start, commit, true) params.Log.Info("failed to update repository status", "namespace", repository.Namespace, "name", repository.Name, "error", err.Error()) @@ -296,7 +308,7 @@ func getRepository(ctx context.Context, params Params) (securityv1.Repository, e return repository, nil } -func updateStatus(ctx context.Context, params Params, commit string, storageSecretName string) (err error) { +func updateStatus(ctx context.Context, params Params, commit string, storageSecretName string, stateStoreSynced bool) (err error) { if params.Instance.Status.StorageSecretName == "_" { storageSecretName = "_" @@ -309,6 +321,7 @@ func updateStatus(ctx context.Context, params Params, commit string, storageSecr rs.Name = r.Name rs.Vendor = r.Spec.Auth.Vendor rs.Ready = true + rs.StateStoreSynced = stateStoreSynced if r.Spec.Type == "http" { rs.Summary = r.Spec.Endpoint @@ -316,20 +329,9 @@ func updateStatus(ctx context.Context, params Params, commit string, storageSecr rs.StorageSecretName = storageSecretName - if !reflect.DeepEqual(rs, r.Status) { + if !reflect.DeepEqual(rs, r.Status) || r.Status.StateStoreSynced != rs.StateStoreSynced { params.Log.Info("syncing repository", "name", r.Name, "namespace", r.Namespace) rs.Updated = time.Now().String() - - if rs.StateStoreSynced { - if r.Spec.StateStoreReference != "" { - if rs.StateStoreVersion == 0 { - rs.StateStoreVersion = 1 - } else { - rs.StateStoreVersion = rs.StateStoreVersion + 1 - } - } - } - r.Status = rs err = params.Client.Status().Update(ctx, r) if err != nil { @@ -353,6 +355,246 @@ func setRepoReady(ctx context.Context, params Params, patch []byte) error { return nil } +// BuildRepositoryCache scans a repository, builds bundles per directory, and caches them +// Returns the bundleMap for reuse (e.g., in StorageSecret) +func BuildRepositoryCache(ctx context.Context, params Params, commit string, storageSecretName string) (map[string][]byte, error) { + repository := params.Instance + cachePath := "/tmp/repo-cache/" + repository.Name + // fileName := commit + ".json" + + // there is a flag that facilitates delete being managed using mappings outside of the operator which is the default + // behaviour if you are not using a L7StateStore. + // This is a safer approach for database backed gateways. + combinedBundlefileName := "combined.json" + trackedBundleFileName := commit + ".json" + + // Create cache directory + if err := os.MkdirAll(cachePath, 0755); err != nil { + return nil, err + } + + // Check if already cached - load and return existing bundleMap + if _, err := os.Stat(cachePath + "/" + trackedBundleFileName); err == nil { + params.Log.V(2).Info("repository cache already exists", "name", repository.Name, "commit", commit) + + // Read existing cache + bundleMapBytes, err := os.ReadFile(cachePath + "/" + trackedBundleFileName) + if err != nil { + return nil, err + } + + bundleMap := map[string][]byte{} + if err := json.Unmarshal(bundleMapBytes, &bundleMap); err != nil { + return nil, err + } + return bundleMap, nil + } + + _, repositoryPath, _, err := localRepoStorageInfo(params) + if err != nil { + return nil, err + } + + // Detect all graphman folders in the repository + projects, err := util.DetectGraphmanFolders(repositoryPath) + if err != nil { + return nil, err + } + + bundleMap := map[string][]byte{} + currentBundles := map[string][]byte{} + + // Build the current commit + for _, project := range projects { + // need to see what a base level directory has here so we can account for that + // may require new build of graphman-static-init + // empty directory prob covers it already.. + + bundleBytes, err := util.BuildAndValidateBundle(project, false) + if err != nil { + return nil, err + } + + // Generate key name (normalize directory path) + keyName := strings.Replace(project, repositoryPath, "", 1) + keyName = strings.TrimPrefix(strings.ReplaceAll(keyName, "/", "-"), "-") + + currentBundles[keyName+".json"] = bundleBytes + + // Compress the bundle + bundleGzip, err := util.GzipCompress(bundleBytes) + if err != nil { + return nil, err + } + + bundleMap[keyName+".gz"] = bundleGzip + } + + // Write the current commit to file + bundleMapBytes, err := json.Marshal(bundleMap) + if err != nil { + return nil, err + } + + if err := os.WriteFile(cachePath+"/"+trackedBundleFileName, bundleMapBytes, 0755); err != nil { + return nil, err + } + + // Load previous bundle map for delta calculation (if exists) + previousBundleMap := map[string][]byte{} + if repository.Status.Commit != "" && repository.Status.Commit != commit { + if previousBytes, err := os.ReadFile(cachePath + "/" + combinedBundlefileName); err == nil { + _ = json.Unmarshal(previousBytes, &previousBundleMap) + } + } + + // Calculate deltas against previous version (exactly like StateStorage does) + if len(previousBundleMap) > 0 { + for k1, b1bytes := range currentBundles { + keyName := strings.TrimSuffix(k1, ".json") + + for k2, b2 := range previousBundleMap { + // Look for the full bundle from previous commit (not delta) + if k2 == keyName+".gz" { + // Decompress previous bundle + b2Bytes, err := util.GzipDecompress(b2) + if err != nil { + b2Bytes = b2 + } + + srcBundle := graphman.Bundle{} + destBundle := graphman.Bundle{} + + if err := json.Unmarshal(b2Bytes, &srcBundle); err != nil { + continue + } + if err := json.Unmarshal(b1bytes, &destBundle); err != nil { + continue + } + + // Reset mappings from previous state (removes delete mappings from last iteration) + if err := graphman.ResetMappings(&srcBundle); err != nil { + continue + } + + // Calculate delta: current (cleaned previous) vs desired (new) + deltaBundle, combinedBundle, err := graphman.CalculateDelta(srcBundle, destBundle) + if err != nil { + continue + } + + // Store delta bundle + deltaBundleBytes, err := json.Marshal(deltaBundle) + if err != nil { + continue + } + deltaGzip, err := util.GzipCompress(deltaBundleBytes) + if err != nil { + continue + } + bundleMap[keyName+"-delta.gz"] = deltaGzip + + // Overwrite the full bundle with combined (has delete mappings for next iteration) + // This is the same as StateStorage - the full bundle becomes the "state" for next delta + combinedBundleBytes, err := json.Marshal(combinedBundle) + if err != nil { + continue + } + combinedGzip, err := util.GzipCompress(combinedBundleBytes) + if err != nil { + continue + } + bundleMap[keyName+".gz"] = combinedGzip + break + } + } + } + + // Handle deleted folders (folders in previous but not in current) + for k2, b2 := range previousBundleMap { + // Skip delta bundles, only process full bundles + if strings.HasSuffix(k2, "-delta.gz") { + continue + } + + keyName := strings.TrimSuffix(k2, ".gz") + found := false + + for k1 := range currentBundles { + if strings.TrimSuffix(k1, ".json") == keyName { + found = true + break + } + } + + if !found { + // Folder was deleted - create delete bundle + b2Bytes, err := util.GzipDecompress(b2) + if err != nil { + b2Bytes = b2 + } + + srcBundle := graphman.Bundle{} + if err := json.Unmarshal(b2Bytes, &srcBundle); err != nil { + continue + } + + // Reset mappings (clean the state) + if err := graphman.ResetMappings(&srcBundle); err != nil { + continue + } + + // Calculate delta against empty bundle (deletes everything) + emptyBundle := graphman.Bundle{} + deltaBundle, combinedBundle, err := graphman.CalculateDelta(srcBundle, emptyBundle) + if err != nil { + continue + } + + // Store delta bundle + deltaBundleBytes, err := json.Marshal(deltaBundle) + if err != nil { + continue + } + deltaGzip, err := util.GzipCompress(deltaBundleBytes) + if err != nil { + continue + } + bundleMap[keyName+"-delta.gz"] = deltaGzip + + // Store combined bundle with delete mappings + combinedBundleBytes, err := json.Marshal(combinedBundle) + if err != nil { + continue + } + combinedGzip, err := util.GzipCompress(combinedBundleBytes) + if err != nil { + continue + } + bundleMap[keyName+".gz"] = combinedGzip + } + } + } + + // Marshal the bundle map + bundleMapBytes, err = json.Marshal(bundleMap) + if err != nil { + return nil, err + } + + // Write dynamic bundle to file + if err := os.WriteFile(cachePath+"/"+combinedBundlefileName, bundleMapBytes, 0755); err != nil { + return nil, err + } + + params.Log.Info("built repository cache", + "name", repository.Name, + "directories", len(bundleMap), + "commit", commit) + + return bundleMap, nil +} + func captureRepositorySyncMetrics(ctx context.Context, params Params, start time.Time, commitId string, hasError bool) error { operatorNamespace, err := util.GetOperatorNamespace() if err != nil { diff --git a/pkg/repository/reconcile/secret.go b/pkg/repository/reconcile/secret.go index c744bf96..12605d83 100644 --- a/pkg/repository/reconcile/secret.go +++ b/pkg/repository/reconcile/secret.go @@ -22,10 +22,13 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package reconcile import ( + "bytes" + "compress/gzip" "context" "errors" "fmt" @@ -119,13 +122,52 @@ func StorageSecret(ctx context.Context, params Params) error { return errors.New("exceededMaxSize") } - bundleGzip, err := util.CompressGraphmanBundle("/tmp/" + params.Instance.Name + "-" + params.Instance.Namespace + "-" + ext) + projects, err := util.DetectGraphmanFolders("/tmp/" + params.Instance.Name + "-" + params.Instance.Namespace + "-" + ext) + if err != nil { return err } - data := map[string][]byte{ - params.Instance.Name + ".gz": bundleGzip, + data := map[string][]byte{} + + secretSize := 0 + for _, p := range projects { + + bundleGzip, err := util.CompressGraphmanBundle(p, false) + if err != nil { + return err + } + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err = zw.Write(bundleGzip) + if err != nil { + return err + } + + if err := zw.Close(); err != nil { + return err + } + if buf.Len() > 900000 { + return errors.New("file size exceeded") + } + + secretSize = secretSize + buf.Len() + + if secretSize > 900000 { + return errors.New("combined file size exceeded") + } + + keyName := strings.Replace(p, "/tmp/"+params.Instance.Name+"-"+params.Instance.Namespace+"-"+ext, "", 1) + keyName = strings.Replace(strings.ReplaceAll(keyName, "/", "-"), "-", "", 1) + ".gz" + data[keyName] = bundleGzip + buf.Reset() + } + + /// get secret if it exists and remove it, if it has the old format + currentSecret, _ := getRepositorySecret(ctx, *params.Instance, params) + + if currentSecret.Data[params.Instance.Name+".gz"] != nil { + currentSecret.Data[params.Instance.Name+".gz"] = nil } desiredSecret := repository.NewSecret(params.Instance, storageSecretName, data) @@ -137,6 +179,57 @@ func StorageSecret(ctx context.Context, params Params) error { return nil } +// StorageSecretFromBundleMap creates a storage secret from an existing bundleMap +// This avoids rebuilding bundles that were already built in BuildRepositoryCache +func StorageSecretFromBundleMap(ctx context.Context, params Params, bundleMap map[string][]byte, storageSecretName string) error { + if params.Instance.Status.StorageSecretName == "_" { + return nil + } + + if len(bundleMap) == 0 { + params.Log.V(2).Info("bundleMap is empty, skipping storage secret creation") + return nil + } + + // Calculate total size and check limits + secretSize := 0 + for _, bundleGzip := range bundleMap { + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err := zw.Write(bundleGzip) + if err != nil { + return err + } + if err := zw.Close(); err != nil { + return err + } + + if buf.Len() > 900000 { + return errors.New("file size exceeded") + } + + secretSize += buf.Len() + if secretSize > 900000 { + return errors.New("combined file size exceeded") + } + } + + // Get secret if it exists and remove old format data + currentSecret, _ := getRepositorySecret(ctx, *params.Instance, params) + if currentSecret.Data[params.Instance.Name+".gz"] != nil { + currentSecret.Data[params.Instance.Name+".gz"] = nil + } + + // Create new secret with bundleMap data + desiredSecret := repository.NewSecret(params.Instance, storageSecretName, bundleMap) + + if err := reconcileSecret(ctx, params, desiredSecret); err != nil { + return fmt.Errorf("failed to reconcile secrets: %w", err) + } + + return nil +} + func getDirSize(path string) (sizef float64, err error) { var size int64 var mu sync.Mutex diff --git a/pkg/repository/reconcile/statestorage.go b/pkg/repository/reconcile/statestorage.go index bf2e454e..f3b29e02 100644 --- a/pkg/repository/reconcile/statestorage.go +++ b/pkg/repository/reconcile/statestorage.go @@ -22,15 +22,20 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package reconcile import ( + "bytes" + "compress/gzip" "context" "crypto/sha1" + "encoding/json" "errors" "fmt" "net/url" + "os" "strings" v1 "github.com/caapim/layer7-operator/api/v1" @@ -41,12 +46,25 @@ import ( "k8s.io/apimachinery/pkg/types" ) -func StateStorage(ctx context.Context, params Params, statestore securityv1alpha1.L7StateStore) error { +func StateStorage(ctx context.Context, params Params, statestore securityv1alpha1.L7StateStore, commit string) error { storageSecretName, repositoryPath, _, err := localRepoStorageInfo(params) if err != nil { return err } + tmpPath := "/tmp/statestore/" + params.Instance.Name + commitTracker := commit + ".txt" + fileName := "latest.json" + _, dErr := os.Stat(tmpPath) + if dErr != nil { + _ = os.MkdirAll(tmpPath, 0755) + } + + _, fErr := os.Stat(tmpPath + "/" + commitTracker) + if fErr == nil { + return nil + } + // Retrieve existing secret for Redis // this will need to be updated for multi-state store provider support if statestore.Spec.Redis.ExistingSecret != "" { @@ -58,67 +76,218 @@ func StateStorage(ctx context.Context, params Params, statestore securityv1alpha statestore.Spec.Redis.MasterPassword = string(stateStoreSecret.Data["masterPassword"]) } - rc := util.RedisClient(&statestore.Spec.Redis) - version := params.Instance.Status.StateStoreVersion - - // this represents the current version - bundleGzip, err := util.CompressGraphmanBundle(repositoryPath) + rc, err := util.RedisClient(&statestore.Spec.Redis) + if err != nil { + return fmt.Errorf("failed to connect to state store: %w", err) + } + projects, err := util.DetectGraphmanFolders(repositoryPath) if err != nil { return err } - if version == 0 { - rs := rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest", bundleGzip, 0) - if rs.Err() != nil { - return fmt.Errorf("failed to reconcile state storage: %w", rs.Err()) + bundles := map[string][]byte{} + compressedBundle := map[string][]byte{} + for _, p := range projects { + bundle, err := util.BuildAndValidateBundle(p, false) + if err != nil { + return err } - return nil + bundleGzip, err := util.GzipCompress(bundle) + if err != nil { + return err + } + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err = zw.Write(bundleGzip) + if err != nil { + return err + } + + if err := zw.Close(); err != nil { + return err + } + + keyName := strings.Replace(p, repositoryPath, "", 1) + keyName = strings.Replace(strings.ReplaceAll(keyName, "/", "-"), "-", "", 1) + bundles[keyName+".json"] = bundle + compressedBundle[keyName+".gz"] = bundleGzip + + buf.Reset() + } + + compressedBundleBytes, err := json.Marshal(compressedBundle) + if err != nil { + return err } // check for previous version - statestore may be empty - previousVersionGzip, err := rc.Get(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest").Result() + stateStoreBundleMapString, err := rc.Get(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest").Result() if err != nil { // if the previous version can't be retrieved, write the current version - rs := rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest", bundleGzip, 0) + rs := rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest", compressedBundleBytes, 0) if rs.Err() != nil { return fmt.Errorf("failed to reconcile state storage: %w", rs.Err()) } + + // then write that to file... + err = os.WriteFile(tmpPath+"/"+fileName, compressedBundleBytes, 0755) + if err != nil { + return err + } + err = os.WriteFile(tmpPath+"/"+commitTracker, []byte{}, 0755) + if err != nil { + return err + } + return nil } - // calculate delta - currentVersion, err := util.GzipDecompress(bundleGzip) + stateStoreBundleMap := map[string][]byte{} + err = json.Unmarshal([]byte(stateStoreBundleMapString), &stateStoreBundleMap) if err != nil { - return fmt.Errorf("failed to decompress bundle: %w", err) + return err } - previousVersion, err := util.GzipDecompress([]byte(previousVersionGzip)) - if err != nil { - return fmt.Errorf("failed to decompress previous version bundle: %w", err) - } - deltaBytes, combinedBytes, err := graphman.SubtractBundle(previousVersion, currentVersion) - if err != nil { - return fmt.Errorf("failed to subtract current and previous version bundles: %w", err) + for k1, b1bytes := range bundles { + for k2, b2 := range stateStoreBundleMap { + if strings.Split(k1, ".")[0] == strings.Split(k2, ".")[0] { + b2Bytes, err := util.GzipDecompress(b2) + if err != nil { + //return fmt.Errorf("failed to decompress bundle 1: %s %w", k2, err) + b2Bytes = b2 + } + + // reset current mappings from statestore + // delete mappings should only persist for one version. + srcBundle := graphman.Bundle{} + destBundle := graphman.Bundle{} + err = json.Unmarshal(b2Bytes, &srcBundle) + if err != nil { + return fmt.Errorf("failed to unmarshal state store bundle: %s %w", strings.Split(k2, ".")[0], err) + } + err = json.Unmarshal(b1bytes, &destBundle) + if err != nil { + return fmt.Errorf("failed to unmarshal local bundle: %s %w", strings.Split(k2, ".")[0], err) + } + + // Reset mappings - removes entities marked for delete and clears all mappings + // This represents the actual state after the last apply + err = graphman.ResetMappings(&srcBundle) + if err != nil { + return fmt.Errorf("failed to reset mappings: %s %w", strings.Split(k2, ".")[0], err) + } + + // Calculate delta: current=srcBundle (cleaned), desired=destBundle (filesystem) + deltaBundle, combinedBundle, err := graphman.CalculateDelta(srcBundle, destBundle) + if err != nil { + return fmt.Errorf("failed to subtract current and previous version bundle: %s %w", strings.Split(k2, ".")[0], err) + } + + deltaBundleBytes, err := json.Marshal(deltaBundle) + if err != nil { + return fmt.Errorf("failed to marshal delta bundle: %s %w", strings.Split(k1, ".")[0], err) + } + deltaGzip, err := util.GzipCompress(deltaBundleBytes) + if err != nil { + return fmt.Errorf("failed to compress delta bundle: %s %w", strings.Split(k1, ".")[0], err) + } + compressedBundle[strings.Split(k1, ".")[0]+"-delta.gz"] = deltaGzip + + // Store combined bundle (with delete mappings) for next iteration + combinedBundleBytes, err := json.Marshal(combinedBundle) + if err != nil { + return fmt.Errorf("failed to marshal combined bundle: %s %w", strings.Split(k1, ".")[0], err) + } + combinedGzip, err := util.GzipCompress(combinedBundleBytes) + if err != nil { + return fmt.Errorf("failed to compress combined bundle: %w", err) + } + compressedBundle[strings.Split(k1, ".")[0]+".gz"] = combinedGzip + } + } } - combinedGzip, err := util.GzipCompress(combinedBytes) - if err != nil { - return fmt.Errorf("failed to compress combined bundle: %w", err) + + // prepare delete bundles for folders that have been removed + for k2, b2 := range stateStoreBundleMap { + found := false + for k1 := range bundles { + if strings.Split(k2, ".")[0] == strings.Split(k1, ".")[0] || strings.HasSuffix(k2, "-delta.gz") { + found = true + } + } + if !found { + b2Bytes, err := util.GzipDecompress(b2) + if err != nil { + b2Bytes = b2 + } + + // reset current mappings from statestore + // delete mappings should only persist for one version. + srcBundle := graphman.Bundle{} + err = json.Unmarshal(b2Bytes, &srcBundle) + if err != nil { + return fmt.Errorf("failed to unmarshal state store bundle: %s %w", strings.Split(k2, ".")[0], err) + } + + // Reset mappings to get clean state (what's actually on gateway after last apply) + err = graphman.ResetMappings(&srcBundle) + if err != nil { + return fmt.Errorf("failed to reset mappings: %s %w", strings.Split(k2, ".")[0], err) + } + + // To delete all entities in srcBundle: current=srcBundle (cleaned), desired=empty + // This generates delete mappings for everything. + emptyBundle := graphman.Bundle{} + deltaBundle, combinedBundle, err := graphman.CalculateDelta(srcBundle, emptyBundle) + if err != nil { + return fmt.Errorf("failed to subtract current and previous version bundle: %s %w", strings.Split(k2, ".")[0], err) + } + + deltaBundleBytes, err := json.Marshal(deltaBundle) + if err != nil { + return fmt.Errorf("failed to marshal delta bundle: %s %w", strings.Split(k2, ".")[0], err) + } + + deltaGzip, err := util.GzipCompress(deltaBundleBytes) + if err != nil { + return fmt.Errorf("failed to compress delta bundle: %s %w", strings.Split(k2, ".")[0], err) + } + compressedBundle[strings.Split(k2, ".")[0]+"-delta.gz"] = deltaGzip + + // Store combined bundle with delete mappings + combinedBundleBytes, err := json.Marshal(combinedBundle) + if err != nil { + return fmt.Errorf("failed to marshal combined bundle: %s %w", strings.Split(k2, ".")[0], err) + } + combinedGzip, err := util.GzipCompress(combinedBundleBytes) + if err != nil { + return fmt.Errorf("failed to compress combined bundle: %w", err) + } + compressedBundle[strings.Split(k2, ".")[0]+".gz"] = combinedGzip + } } - deltaGzip, err := util.GzipCompress(deltaBytes) + + compressedBundleBytes, err = json.Marshal(compressedBundle) if err != nil { - return fmt.Errorf("failed to compress delta bundle: %w", err) + return err } - rs := rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest", combinedGzip, 0) + rs := rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":latest", compressedBundleBytes, 0) if rs.Err() != nil { return fmt.Errorf("failed to reconcile state storage: %w", rs.Err()) } - rs = rc.Set(ctx, statestore.Spec.Redis.GroupName+":"+statestore.Spec.Redis.StoreId+":"+"repository"+":"+storageSecretName+":delta", deltaGzip, 0) - if rs.Err() != nil { - return fmt.Errorf("failed to reconcile state storage: %w", rs.Err()) + err = os.WriteFile(tmpPath+"/"+fileName, compressedBundleBytes, 0755) + if err != nil { + return err + } + + err = os.WriteFile(tmpPath+"/"+commitTracker, []byte{}, 0755) + if err != nil { + return err } + return nil } @@ -136,11 +305,14 @@ func GetStateStoreChecksum(ctx context.Context, params Params, statestore securi statestore.Spec.Redis.MasterPassword = string(stateStoreSecret.Data["masterPassword"]) } - rc := util.RedisClient(&statestore.Spec.Redis) + rc, err := util.RedisClient(&statestore.Spec.Redis) + if err != nil { + return "", fmt.Errorf("failed to connect to state store: %w", err) + } bundle, err := rc.Get(ctx, params.Instance.Spec.StateStoreKey).Result() if err != nil { - return "", fmt.Errorf("failed to bundle from state store: %w", err) + return "", fmt.Errorf("failed to retrieve bundle from state store: %w", err) } h := sha1.New() diff --git a/pkg/statestore/reconcile/statestore.go b/pkg/statestore/reconcile/statestore.go index 530ba979..19284c07 100644 --- a/pkg/statestore/reconcile/statestore.go +++ b/pkg/statestore/reconcile/statestore.go @@ -38,42 +38,63 @@ import ( func RedisStateStore(ctx context.Context, params Params) error { statestore := params.Instance + status := statestore.Status + // Retrieve existing secret for Redis // this will need to be updated for multi-state store provider support if statestore.Spec.Redis.ExistingSecret != "" { stateStoreSecret, err := getStateStoreSecret(ctx, statestore.Spec.Redis.ExistingSecret, *statestore, params) if err != nil { + params.Log.V(2).Info("failed to retrieve credential secret", "name", statestore.Name, "namespace", statestore.Namespace, "message", err.Error()) + status.Ready = false + statusErr := updateStatus(ctx, params, status) + if statusErr != nil { + return statusErr + } return err } statestore.Spec.Redis.Username = string(stateStoreSecret.Data["username"]) statestore.Spec.Redis.MasterPassword = string(stateStoreSecret.Data["masterPassword"]) } - c := util.RedisClient(&statestore.Spec.Redis) + c, err := util.RedisClient(&statestore.Spec.Redis) + if err != nil { + params.Recorder.Eventf(statestore, "Warning", "ConnectionFailed", "%s in namespace %s", statestore.Name, statestore.Namespace) + params.Log.V(2).Info("failed to connect to state store", "name", statestore.Name, "namespace", statestore.Namespace, "message", err.Error()) + status.Ready = false + statusErr := updateStatus(ctx, params, status) + if statusErr != nil { + return statusErr + } + return err + } ping := c.Ping(ctx) - status := statestore.Status pong, err := ping.Result() if err != nil { - params.Recorder.Eventf(statestore, "Warning", "ConnectionFailed", "%s in namespace %s", statestore.Name, statestore.Namespace) + if status.Ready { + params.Recorder.Eventf(statestore, "Warning", "ConnectionFailed", "%s in namespace %s", statestore.Name, statestore.Namespace) + status.Ready = false + } params.Log.V(2).Info("failed to connect to state store", "name", statestore.Name, "namespace", statestore.Namespace, "message", err.Error()) - } - status.Ready = false + statusErr := updateStatus(ctx, params, status) + if statusErr != nil { + return statusErr + } + return err + } if pong == "PONG" { - params.Recorder.Eventf(statestore, "Normal", "ConnectionSuccess", "%s status in namespace %s", statestore.Name, statestore.Namespace) - status.Ready = true + if !status.Ready { + params.Recorder.Eventf(statestore, "Normal", "ConnectionSuccess", "Successfully connected to l7statestore %s in namespace %s", statestore.Name, statestore.Namespace) + status.Ready = true + } } - if !reflect.DeepEqual(statestore, status) { - statestore.Status = status - err = params.Client.Status().Update(ctx, statestore) - if err != nil { - params.Log.V(2).Info("failed to update state store status", "name", statestore.Name, "namespace", statestore.Namespace, "message", err.Error()) - return err - } - params.Log.V(2).Info("updated state store status", "name", statestore.Name, "namespace", statestore.Namespace) + statusErr := updateStatus(ctx, params, status) + if statusErr != nil { + return statusErr } return nil } @@ -87,3 +108,16 @@ func getStateStoreSecret(ctx context.Context, name string, statestore securityv1 } return statestoreSecret, nil } + +func updateStatus(ctx context.Context, params Params, status securityv1alpha1.L7StateStoreStatus) error { + if !reflect.DeepEqual(params.Instance, status) { + params.Instance.Status = status + err := params.Client.Status().Update(ctx, params.Instance) + if err != nil { + params.Log.V(2).Info("failed to update state store status", "name", params.Instance.Name, "namespace", params.Instance.Namespace, "message", err.Error()) + return err + } + params.Log.V(2).Info("updated state store status", "name", params.Instance.Name, "namespace", params.Instance.Namespace) + } + return nil +} diff --git a/pkg/util/artifact.go b/pkg/util/artifact.go index 2bbbbf50..4acfb9cb 100644 --- a/pkg/util/artifact.go +++ b/pkg/util/artifact.go @@ -208,7 +208,7 @@ func validateGraphmanBundle(fileName string, folderName string) error { return nil } - bundleBytes, err := graphman.Implode(folderName) + bundleBytes, err := graphman.Implode(folderName, true) if err != nil { return err } @@ -217,7 +217,7 @@ func validateGraphmanBundle(fileName string, folderName string) error { if err != nil { return err } - if strings.Contains(path, "/.git") { + if strings.Contains(path, ".git") { return nil } if !d.IsDir() { diff --git a/pkg/util/graphman.go b/pkg/util/graphman.go index f7a58d7b..cabd1049 100644 --- a/pkg/util/graphman.go +++ b/pkg/util/graphman.go @@ -22,6 +22,7 @@ * LOST DATA, EVEN IF BROADCOM IS EXPRESSLY ADVISED IN ADVANCE OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGE. * +* AI assistance has been used to generate some or all contents of this file. That includes, but is not limited to, new code, modifying existing code, stylistic edits. */ package util @@ -87,14 +88,6 @@ type GraphmanOtkConfig struct { InternalGatewayReference string `json:"internalGatewayReference,omitempty"` } -type MappingSource struct { - Name string `json:"name,omitempty"` - Alias string `json:"alias,omitempty"` - KeystoreId string `json:"keystoreId,omitempty"` - ThumbprintSha1 string `json:"thumbprintSha1,omitempty"` - SystemId string `json:"systemId,omitempty"` -} - func ApplyToGraphmanTarget(bundleBytes []byte, singleton bool, username string, password string, target string, encpass string, delete bool) error { bundle := graphman.Bundle{} var err error @@ -174,9 +167,9 @@ func ConvertX509ToGraphmanBundle(keys []GraphmanKey, notFound []string) ([]byte, KeystoreId: "00000000000000000000000000000002", Pem: key.Key, Alias: key.Name, - KeyType: "RSA", - SubjectDn: "CN=" + certDN, - CertChain: certsChain, + //KeyType: "RSA", + SubjectDn: "CN=" + certDN, + CertChain: certsChain, } if key.Alias != "" { @@ -203,7 +196,7 @@ func ConvertX509ToGraphmanBundle(keys []GraphmanKey, notFound []string) ([]byte, //UsageTypes: []graphman.KeyUsageType{graphman.KeyUsageTypeSsl}, KeystoreId: "00000000000000000000000000000002", }) - mappingSource := MappingSource{Alias: nf, KeystoreId: "00000000000000000000000000000002"} + mappingSource := graphman.MappingSource{Alias: nf, KeystoreId: "00000000000000000000000000000002"} if bundle.Properties == nil { bundle.Properties = &graphman.BundleProperties{} } @@ -272,7 +265,7 @@ func ConvertCertsToGraphmanBundle(certs []GraphmanCert, notFound []string) ([]by TrustedFor: []graphman.TrustedForType{graphman.TrustedForTypeSsl}, RevocationCheckPolicyType: graphman.PolicyUsageTypeUseDefault, }) - mappingSource := MappingSource{ThumbprintSha1: strings.Split(nf, "-")[1]} + mappingSource := graphman.MappingSource{ThumbprintSha1: strings.Split(nf, "-")[1]} if bundle.Properties == nil { bundle.Properties = &graphman.BundleProperties{} } @@ -324,7 +317,7 @@ func ConvertOpaqueMapToGraphmanBundle(secrets []GraphmanSecret, notFound []strin VariableReferencable: false, Secret: "DELETED", }) - mappingSource := MappingSource{Name: nf} + mappingSource := graphman.MappingSource{Name: nf} if bundle.Properties == nil { bundle.Properties = &graphman.BundleProperties{} } @@ -378,8 +371,8 @@ func DeleteBundle(src []byte) (bundle []byte, err error) { return bundle, nil } -func CompressGraphmanBundle(path string) ([]byte, error) { - bundleBytes, err := BuildAndValidateBundle(path) +func CompressGraphmanBundle(path string, statestore bool) ([]byte, error) { + bundleBytes, err := BuildAndValidateBundle(path, false) if err != nil { return nil, err } @@ -394,9 +387,12 @@ func CompressGraphmanBundle(path string) ([]byte, error) { if err := zw.Close(); err != nil { return nil, err } - if buf.Len() > 900000 { - buf.Reset() - return nil, errors.New("exceededMaxSize") + + if !statestore { + if buf.Len() > 900000 { + buf.Reset() + return nil, errors.New("exceededMaxSize") + } } compressedBundle := buf.Bytes() @@ -405,38 +401,99 @@ func CompressGraphmanBundle(path string) ([]byte, error) { return compressedBundle, nil } -func ConcatBundles(bundleMap map[string][]byte) (combinedBundle []byte, err error) { +func ConcatBundles(bundleMap map[string][]byte) (combinedBundleBytes []byte, err error) { + + combinedBundle := graphman.Bundle{} + + for k, v := range bundleMap { + if strings.HasSuffix(k, "-delta.gz") || strings.HasSuffix(k, "-delta.json") { + continue + } - for k, bundle := range bundleMap { + bundle := graphman.Bundle{} if strings.HasSuffix(k, ".json") { - combinedBundle, err = graphman.ConcatBundle(combinedBundle, bundle) + err = json.Unmarshal(v, &bundle) + if err != nil { + return nil, err + } + combinedBundle, err = graphman.CombineWithOverwrite(bundle, combinedBundle) if err != nil { return nil, err } } if strings.HasSuffix(k, ".gz") { - bundle, err := GzipDecompress(bundle) + bundleBytes, err := GzipDecompress(v) + if err != nil { + return nil, err + } + err = json.Unmarshal(bundleBytes, &bundle) + if err != nil { + return nil, err + } + combinedBundle, err = graphman.CombineWithOverwrite(bundle, combinedBundle) + if err != nil { + return nil, err + } + } + } + + combinedBundleBytes, err = json.Marshal(combinedBundle) + if err != nil { + return nil, err + } + + return combinedBundleBytes, nil + +} + +// ConcatBundlesPreservingMappings concatenates all bundles in a bundle map while preserving DELETE mappings +// This is used for repository-controlled bundles (combined.json, latest.json) when directories=["/"] +func ConcatBundlesPreservingMappings(bundleMap map[string][]byte) (combinedBundleBytes []byte, err error) { + + combinedBundle := graphman.Bundle{} + + for k, v := range bundleMap { + if strings.HasSuffix(k, "-delta.gz") || strings.HasSuffix(k, "-delta.json") { + continue + } + + bundle := graphman.Bundle{} + if strings.HasSuffix(k, ".json") { + err = json.Unmarshal(v, &bundle) if err != nil { return nil, err } - combinedBundle, err = graphman.ConcatBundle(combinedBundle, bundle) + combinedBundle, err = graphman.CombineWithOverwritePreservingDeleteMappings(bundle, combinedBundle) if err != nil { return nil, err } } - if k == "bundle-properties.json" { - combinedBundle, err = graphman.AddMappings(combinedBundle, bundle) + if strings.HasSuffix(k, ".gz") { + bundleBytes, err := GzipDecompress(v) + if err != nil { + return nil, err + } + err = json.Unmarshal(bundleBytes, &bundle) + if err != nil { + return nil, err + } + combinedBundle, err = graphman.CombineWithOverwritePreservingDeleteMappings(bundle, combinedBundle) if err != nil { return nil, err } } } - return combinedBundle, nil + combinedBundleBytes, err = json.Marshal(combinedBundle) + if err != nil { + return nil, err + } + + return combinedBundleBytes, nil } -func BuildAndValidateBundle(path string) (bundleBytes []byte, err error) { +func BuildAndValidateBundle(path string, processNestedRepos bool) (bundleBytes []byte, err error) { if path == "" { return nil, nil } @@ -445,7 +502,7 @@ func BuildAndValidateBundle(path string) (bundleBytes []byte, err error) { return nil, err } - bundleBytes, err = graphman.Implode(path) + bundleBytes, err = graphman.Implode(path, processNestedRepos) if err != nil { return nil, err } @@ -454,7 +511,7 @@ func BuildAndValidateBundle(path string) (bundleBytes []byte, err error) { if err != nil { return err } - if strings.Contains(path, "/.git") { + if strings.Contains(path, ".git") { return nil } if !d.IsDir() { @@ -596,6 +653,14 @@ func BuildOtkOverrideBundle(mode string, gatewayHost string, otkPort int) ([]byt return bundleBytes.Bytes(), bundleCheckSum, nil } +func DetectGraphmanFolders(path string) (projects []string, err error) { + projects, err = graphman.DetectGraphmanFolders(path) + if err != nil { + return nil, err + } + return projects, nil +} + func createDummyKey() (string, string, error) { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) diff --git a/pkg/util/redis.go b/pkg/util/redis.go index 27e9b867..b6fafd45 100644 --- a/pkg/util/redis.go +++ b/pkg/util/redis.go @@ -26,6 +26,11 @@ package util import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "fmt" "strconv" "strings" @@ -33,7 +38,7 @@ import ( "github.com/redis/go-redis/v9" ) -func RedisClient(c *v1alpha1.Redis) *redis.Client { +func RedisClient(c *v1alpha1.Redis) (rdb *redis.Client, err error) { username := "" if c.Username != "" { username = c.Username @@ -51,6 +56,52 @@ func RedisClient(c *v1alpha1.Redis) *redis.Client { rType := strings.ToLower(string(c.Type)) + tlsConfig := tls.Config{} + + if c.Tls.Enabled { + tlsConfig.MinVersion = tls.VersionTLS12 + localCrts := []x509.Certificate{} + + tlsConfig.InsecureSkipVerify = false + + if !c.Tls.VerifyPeer { + tlsConfig.InsecureSkipVerify = true + } + + if c.Tls.VerifyPeer && c.Tls.RedisCrt != "" { + certValidations := 0 + tlsConfig.InsecureSkipVerify = true + if strings.Contains(string(c.Tls.RedisCrt), "-----BEGIN CERTIFICATE-----") { + crtStrings := strings.SplitAfter(string(c.Tls.RedisCrt), "-----END CERTIFICATE-----") + crtStrings = crtStrings[:len(crtStrings)-1] + for crt := range crtStrings { + b, _ := pem.Decode([]byte(crtStrings[crt])) + crtX509, err := x509.ParseCertificate(b.Bytes) + if err != nil { + return nil, err + } + localCrts = append(localCrts, *crtX509) + } + + tlsConfig.VerifyConnection = func(cs tls.ConnectionState) error { + // validate local certs against server certs + for _, localCert := range localCrts { + for _, peerCert := range cs.PeerCertificates { + if bytes.Equal(localCert.Raw, peerCert.Raw) { + certValidations = certValidations + 1 + } + } + } + + if certValidations != len(localCrts) { + return fmt.Errorf("certificate validation failed") + } + return nil + } + } + } + } + switch rType { case string(v1alpha1.RedisTypeStandalone): rdb := redis.NewClient(&redis.Options{ @@ -60,7 +111,11 @@ func RedisClient(c *v1alpha1.Redis) *redis.Client { DB: database, }) - return rdb + if c.Tls.Enabled { + rdb.Options().TLSConfig = &tlsConfig + } + + return rdb, nil case string(v1alpha1.RedisTypeSentinel): sentinelAddrs := []string{} @@ -74,7 +129,12 @@ func RedisClient(c *v1alpha1.Redis) *redis.Client { Password: password, DB: database, }) - return rdb + + if c.Tls.Enabled { + rdb.Options().TLSConfig = &tlsConfig + } + + return rdb, nil } - return nil + return nil, err } diff --git a/tests/e2e/gateway-autoscaling/00-install.yaml b/tests/e2e/gateway-autoscaling/00-install.yaml index 302c2151..c6dd0168 100644 --- a/tests/e2e/gateway-autoscaling/00-install.yaml +++ b/tests/e2e/gateway-autoscaling/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-autoscaling-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: diff --git a/tests/e2e/gateway-bundles/00-assert.yaml b/tests/e2e/gateway-bundles/00-assert.yaml index cd5a2135..cf185e12 100644 --- a/tests/e2e/gateway-bundles/00-assert.yaml +++ b/tests/e2e/gateway-bundles/00-assert.yaml @@ -17,7 +17,7 @@ spec: name: ssg-bundle-test - secretRef: name: ssg-bundle-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -56,21 +56,21 @@ spec: - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml name: gateway-license subPath: license.xml - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-bundle-test-listen-port-bundle - name: ssg-bundle-test-listen-port-bundle - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/restman-bootstrap-bundle - name: restman-bootstrap-bundle - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/restman-bootstrap-secret-bundle - name: restman-bootstrap-secret-bundle - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/2 name: graphman-bootstrap-bundle - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/3 name: graphman-bootstrap-secret-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/restman-bootstrap-bundle + name: restman-bootstrap-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/restman-bootstrap-secret-bundle + name: restman-bootstrap-secret-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-bundle-test-listen-port-bundle + name: ssg-bundle-test-listen-port-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 + name: ssg-bundle-test-repository-bundle-dest - mountPath: /graphman/config.json name: ssg-bundle-test-repository-init-config subPath: config.json - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - name: ssg-bundle-test-repository-bundle-dest dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -88,10 +88,14 @@ spec: optional: false secretName: gateway-license - configMap: - defaultMode: 493 - name: ssg-bundle-test-listen-port-bundle + defaultMode: 444 + name: graphman-bootstrap-bundle optional: false - name: ssg-bundle-test-listen-port-bundle + name: graphman-bootstrap-bundle + - name: graphman-bootstrap-secret-bundle + secret: + defaultMode: 444 + secretName: graphman-bootstrap-secret-bundle - configMap: defaultMode: 444 name: restman-bootstrap-bundle @@ -102,20 +106,15 @@ spec: defaultMode: 444 secretName: restman-bootstrap-secret-bundle - configMap: - defaultMode: 444 - name: graphman-bootstrap-bundle + defaultMode: 493 + name: ssg-bundle-test-listen-port-bundle optional: false - name: graphman-bootstrap-bundle - - name: graphman-bootstrap-secret-bundle - secret: - defaultMode: 444 - secretName: graphman-bootstrap-secret-bundle + name: ssg-bundle-test-listen-port-bundle + - emptyDir: {} + name: ssg-bundle-test-repository-bundle-dest - configMap: defaultMode: 493 name: ssg-bundle-test-repository-init-config optional: false name: ssg-bundle-test-repository-init-config - - emptyDir: {} - name: ssg-bundle-test-repository-bundle-dest - diff --git a/tests/e2e/gateway-bundles/00-install.yaml b/tests/e2e/gateway-bundles/00-install.yaml index 04589981..d5fa689f 100644 --- a/tests/e2e/gateway-bundles/00-install.yaml +++ b/tests/e2e/gateway-bundles/00-install.yaml @@ -43,13 +43,13 @@ kind: Gateway metadata: name: ssg-bundle-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent #serviceAccountName: ssg-serviceaccount autoscaling: diff --git a/tests/e2e/gateway-configmaps/00-install.yaml b/tests/e2e/gateway-configmaps/00-install.yaml index 45d6c278..2012cb74 100644 --- a/tests/e2e/gateway-configmaps/00-install.yaml +++ b/tests/e2e/gateway-configmaps/00-install.yaml @@ -3,20 +3,25 @@ kind: Gateway metadata: name: ssg-configmap-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: database: enabled: true jdbcUrl: "jdbc:mysql://cluster1-haproxy.pxc.svc.cluster.local:3306/ssg" + username: gateway + password: 7layer cluster: hostname: "gateway.brcmlabs.com" + password: 7layer + username: admin + password: 7layer updateStrategy: type: rollingUpdate rollingUpdate: diff --git a/tests/e2e/gateway-deployment/00-assert.yaml b/tests/e2e/gateway-deployment/00-assert.yaml index 9881c79f..106b30ad 100644 --- a/tests/e2e/gateway-deployment/00-assert.yaml +++ b/tests/e2e/gateway-deployment/00-assert.yaml @@ -30,7 +30,7 @@ spec: name: ssg-deployment-test - secretRef: name: ssg-deployment-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: postStart: @@ -80,29 +80,29 @@ spec: terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/conf/sample.properties + name: config-override-secret + subPath: sample.properties - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml name: gateway-license subPath: license.xml - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-deployment-test-listen-port-bundle - name: ssg-deployment-test-listen-port-bundle - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/services/restman - name: restman - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/services/graphman name: graphman + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/services/restman + name: restman + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-deployment-test-listen-port-bundle + name: ssg-deployment-test-listen-port-bundle - mountPath: /opt/docker/rc.d/003-parse-custom-files.sh name: ssg-deployment-test-parse-custom-files-script subPath: 003-parse-custom-files.sh - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/conf/sample.properties - name: config-override-secret - subPath: sample.properties - - mountPath: /opt/docker/test.properties - name: test-system-override - subPath: test.properties + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 + name: ssg-deployment-test-repository-bundle-dest - mountPath: /graphman/config.json name: ssg-deployment-test-repository-init-config subPath: config.json - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - name: ssg-deployment-test-repository-bundle-dest + - mountPath: /opt/docker/test.properties + name: test-system-override + subPath: test.properties dnsPolicy: ClusterFirst hostAliases: - hostnames: @@ -134,6 +134,10 @@ spec: topologyKey: testTopology whenUnsatisfiable: ScheduleAnyway volumes: + - name: config-override-secret + secret: + defaultMode: 444 + secretName: config-override-secret - name: gateway-license secret: defaultMode: 493 @@ -142,15 +146,15 @@ spec: path: license.xml optional: false secretName: gateway-license + - emptyDir: {} + name: graphman + - emptyDir: {} + name: restman - configMap: defaultMode: 493 name: ssg-deployment-test-listen-port-bundle optional: false name: ssg-deployment-test-listen-port-bundle - - emptyDir: {} - name: restman - - emptyDir: {} - name: graphman - configMap: defaultMode: 493 items: @@ -159,19 +163,15 @@ spec: name: ssg-deployment-test-gateway-files optional: false name: ssg-deployment-test-parse-custom-files-script - - name: config-override-secret - secret: - defaultMode: 444 - secretName: config-override-secret - - configMap: - defaultMode: 444 - name: test-system-override - optional: false - name: test-system-override + - emptyDir: {} + name: ssg-deployment-test-repository-bundle-dest - configMap: defaultMode: 493 name: ssg-deployment-test-repository-init-config optional: false name: ssg-deployment-test-repository-init-config - - emptyDir: {} - name: ssg-deployment-test-repository-bundle-dest + - configMap: + defaultMode: 444 + name: test-system-override + optional: false + name: test-system-override diff --git a/tests/e2e/gateway-deployment/00-install.yaml b/tests/e2e/gateway-deployment/00-install.yaml index d4f42212..24adaf77 100644 --- a/tests/e2e/gateway-deployment/00-install.yaml +++ b/tests/e2e/gateway-deployment/00-install.yaml @@ -18,13 +18,13 @@ kind: Gateway metadata: name: ssg-deployment-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycleHooks: postStart: diff --git a/tests/e2e/gateway-deployment/01-install.yaml b/tests/e2e/gateway-deployment/01-install.yaml index e2152ecc..3732f380 100644 --- a/tests/e2e/gateway-deployment/01-install.yaml +++ b/tests/e2e/gateway-deployment/01-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-deployment-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 2 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycleHooks: postStart: diff --git a/tests/e2e/gateway-externalhazelcast/00-assert.yaml b/tests/e2e/gateway-externalhazelcast/00-assert.yaml index 64e416b1..84a92d5c 100644 --- a/tests/e2e/gateway-externalhazelcast/00-assert.yaml +++ b/tests/e2e/gateway-externalhazelcast/00-assert.yaml @@ -17,7 +17,7 @@ spec: name: ssg-hazelcast-test - secretRef: name: ssg-hazelcast-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: {} name: gateway @@ -36,16 +36,16 @@ spec: - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml name: gateway-license subPath: license.xml - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-hazelcast-test-listen-port-bundle - name: ssg-hazelcast-test-listen-port-bundle - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/assertions/ExternalHazelcastSharedStateProviderAssertion/hazelcast-client.xml name: hazelcast-client subPath: hazelcast-client.xml + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-hazelcast-test-listen-port-bundle + name: ssg-hazelcast-test-listen-port-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 + name: ssg-hazelcast-test-repository-bundle-dest - mountPath: /graphman/config.json name: ssg-hazelcast-test-repository-init-config - subPath: config.json - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - name: ssg-hazelcast-test-repository-bundle-dest + subPath: config.json dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -62,11 +62,6 @@ spec: path: license.xml optional: false secretName: gateway-license - - configMap: - defaultMode: 493 - name: ssg-hazelcast-test-listen-port-bundle - optional: false - name: ssg-hazelcast-test-listen-port-bundle - configMap: defaultMode: 420 items: @@ -76,9 +71,14 @@ spec: name: hazelcast-client - configMap: defaultMode: 493 - name: ssg-hazelcast-test-repository-init-config + name: ssg-hazelcast-test-listen-port-bundle optional: false - name: ssg-hazelcast-test-repository-init-config + name: ssg-hazelcast-test-listen-port-bundle - emptyDir: {} name: ssg-hazelcast-test-repository-bundle-dest + - configMap: + defaultMode: 493 + name: ssg-hazelcast-test-repository-init-config + optional: false + name: ssg-hazelcast-test-repository-init-config diff --git a/tests/e2e/gateway-externalhazelcast/00-install.yaml b/tests/e2e/gateway-externalhazelcast/00-install.yaml index 2bb817d3..303f0140 100644 --- a/tests/e2e/gateway-externalhazelcast/00-install.yaml +++ b/tests/e2e/gateway-externalhazelcast/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-hazelcast-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent #serviceAccountName: ssg-serviceaccount management: diff --git a/tests/e2e/gateway-ingress/00-install.yaml b/tests/e2e/gateway-ingress/00-install.yaml index 2066bc17..fa975d3d 100644 --- a/tests/e2e/gateway-ingress/00-install.yaml +++ b/tests/e2e/gateway-ingress/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-ingress-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate diff --git a/tests/e2e/gateway-initcontainer/00-assert.yaml b/tests/e2e/gateway-initcontainer/00-assert.yaml index 187ea052..5451ab71 100644 --- a/tests/e2e/gateway-initcontainer/00-assert.yaml +++ b/tests/e2e/gateway-initcontainer/00-assert.yaml @@ -21,7 +21,7 @@ spec: name: ssg-initcontainer-test - secretRef: name: ssg-initcontainer-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: {} name: gateway @@ -50,7 +50,11 @@ spec: - env: - name: BOOTSTRAP_BASE value: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - image: docker.io/caapim/graphman-static-init:1.0.3 + - name: STATESTORE_CONFIG + value: /graphman/statestore-config/ + - name: STATESTORE_SECRET + value: /graphman/statestore-secret/ + image: docker.io/caapim/graphman-static-init:1.0.4 imagePullPolicy: IfNotPresent name: graphman-static-init restartPolicy: Always diff --git a/tests/e2e/gateway-initcontainer/00-install.yaml b/tests/e2e/gateway-initcontainer/00-install.yaml index f0de2c0f..847f499b 100644 --- a/tests/e2e/gateway-initcontainer/00-install.yaml +++ b/tests/e2e/gateway-initcontainer/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-initcontainer-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: diff --git a/tests/e2e/gateway-nodeselector/00-install.yaml b/tests/e2e/gateway-nodeselector/00-install.yaml index 916cac94..c462a376 100644 --- a/tests/e2e/gateway-nodeselector/00-install.yaml +++ b/tests/e2e/gateway-nodeselector/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-nodeselector-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: diff --git a/tests/e2e/gateway-prestopscript/00-install.yaml b/tests/e2e/gateway-prestopscript/00-install.yaml index c0d2278c..1edceca7 100644 --- a/tests/e2e/gateway-prestopscript/00-install.yaml +++ b/tests/e2e/gateway-prestopscript/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-lifecycle-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent #serviceAccountName: ssg-serviceaccount management: diff --git a/tests/e2e/gateway-secret/00-install.yaml b/tests/e2e/gateway-secret/00-install.yaml index a133507a..8b1ffd8e 100644 --- a/tests/e2e/gateway-secret/00-install.yaml +++ b/tests/e2e/gateway-secret/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-secret-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent updateStrategy: type: rollingUpdate diff --git a/tests/e2e/gateway-serviceaccounttoken/00-assert.yaml b/tests/e2e/gateway-serviceaccounttoken/00-assert.yaml index 57c53289..4aae8d33 100644 --- a/tests/e2e/gateway-serviceaccounttoken/00-assert.yaml +++ b/tests/e2e/gateway-serviceaccounttoken/00-assert.yaml @@ -21,7 +21,7 @@ spec: name: ssg-sa-test - secretRef: name: ssg-sa-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: {} name: gateway @@ -48,11 +48,11 @@ spec: subPath: update-service-account-token.xml - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-sa-test-listen-port-bundle name: ssg-sa-test-listen-port-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 + name: ssg-sa-test-repository-bundle-dest - mountPath: /graphman/config.json name: ssg-sa-test-repository-init-config subPath: config.json - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - name: ssg-sa-test-repository-bundle-dest dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -90,10 +90,10 @@ spec: name: ssg-sa-test-listen-port-bundle optional: false name: ssg-sa-test-listen-port-bundle + - emptyDir: {} + name: ssg-sa-test-repository-bundle-dest - configMap: defaultMode: 493 name: ssg-sa-test-repository-init-config optional: false - name: ssg-sa-test-repository-init-config - - emptyDir: {} - name: ssg-sa-test-repository-bundle-dest \ No newline at end of file + name: ssg-sa-test-repository-init-config \ No newline at end of file diff --git a/tests/e2e/gateway-serviceaccounttoken/00-install.yaml b/tests/e2e/gateway-serviceaccounttoken/00-install.yaml index a963d445..e2c22f39 100644 --- a/tests/e2e/gateway-serviceaccounttoken/00-install.yaml +++ b/tests/e2e/gateway-serviceaccounttoken/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-sa-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: diff --git a/tests/e2e/gateway-services/00-install.yaml b/tests/e2e/gateway-services/00-install.yaml index 1662eef0..c79a0e95 100644 --- a/tests/e2e/gateway-services/00-install.yaml +++ b/tests/e2e/gateway-services/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-service-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: diff --git a/tests/e2e/gateway-sidecars/00-assert.yaml b/tests/e2e/gateway-sidecars/00-assert.yaml index d3260762..07a2b008 100644 --- a/tests/e2e/gateway-sidecars/00-assert.yaml +++ b/tests/e2e/gateway-sidecars/00-assert.yaml @@ -21,7 +21,7 @@ spec: name: ssg-sidecar-test - secretRef: name: ssg-sidecar-test - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent lifecycle: {} name: gateway @@ -40,15 +40,15 @@ spec: - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml name: gateway-license subPath: license.xml - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-sidecar-test-listen-port-bundle - name: ssg-sidecar-test-listen-port-bundle - mountPath: /tmp name: simple-sidecar + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/ssg-sidecar-test-listen-port-bundle + name: ssg-sidecar-test-listen-port-bundle + - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 + name: ssg-sidecar-test-repository-bundle-dest - mountPath: /graphman/config.json name: ssg-sidecar-test-repository-init-config subPath: config.json - - mountPath: /opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/graphman/0 - name: ssg-sidecar-test-repository-bundle-dest - command: - sh - -c @@ -77,20 +77,20 @@ spec: path: license.xml optional: false secretName: gateway-license + - emptyDir: {} + name: simple-sidecar - configMap: defaultMode: 493 name: ssg-sidecar-test-listen-port-bundle optional: false name: ssg-sidecar-test-listen-port-bundle - emptyDir: {} - name: simple-sidecar + name: ssg-sidecar-test-repository-bundle-dest - configMap: defaultMode: 493 name: ssg-sidecar-test-repository-init-config optional: false name: ssg-sidecar-test-repository-init-config - - emptyDir: {} - name: ssg-sidecar-test-repository-bundle-dest status: replicas: 1 readyReplicas: 1 \ No newline at end of file diff --git a/tests/e2e/gateway-sidecars/00-install.yaml b/tests/e2e/gateway-sidecars/00-install.yaml index 2cdf52cd..0dcc6653 100644 --- a/tests/e2e/gateway-sidecars/00-install.yaml +++ b/tests/e2e/gateway-sidecars/00-install.yaml @@ -3,13 +3,13 @@ kind: Gateway metadata: name: ssg-sidecar-test spec: - version: "11.1.2" + version: "11.1.3" license: accept: true secretName: gateway-license app: replicas: 1 - image: docker.io/caapim/gateway:11.1.2 + image: docker.io/caapim/gateway:11.1.3 imagePullPolicy: IfNotPresent management: cluster: