diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ac128b3f..31e6cda17 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,6 +26,15 @@ jobs: with: go-version: ${{ env.GO_VERSION }} + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Remove rhel9 suffix from images.go uses: jacobtomlinson/gha-find-replace@v3 with: @@ -109,7 +118,7 @@ jobs: run: cat controllers/constants/images.go - name: Build operator container - run: IMG=ttl.sh/securesign/secure-sign-operator:1h make docker-build docker-push + run: IMG=ttl.sh/securesign/secure-sign-operator-${GITHUB_SHA}:1h make docker-build docker-push test-kind: name: Test kind deployment @@ -123,7 +132,16 @@ jobs: uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - + + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Log in to registry.redhat.io uses: redhat-actions/podman-login@9184318aae1ee5034fbfbacc0388acf12669171f # v1 with: @@ -147,7 +165,8 @@ jobs: kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=90s - name: Deploy operator container - run: IMG=ttl.sh/securesign/secure-sign-operator:1h make deploy + run: | + IMG=ttl.sh/securesign/secure-sign-operator-${GITHUB_SHA}:1h OPENSHIFT=false make deploy - name: Wait for operator to be ready run: | @@ -227,6 +246,15 @@ jobs: with: go-version: ${{ env.GO_VERSION }} + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Install eksctl run: | ARCH=amd64 @@ -252,7 +280,7 @@ jobs: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml - name: Deploy operator container - run: IMG=ttl.sh/securesign/secure-sign-operator:1h make deploy + run: IMG=ttl.sh/securesign/secure-sign-operator-${GITHUB_SHA}:1h make deploy - name: Wait for operator to be ready run: | diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade.yml index f99cf73a5..da7ce2a4f 100644 --- a/.github/workflows/upgrade.yml +++ b/.github/workflows/upgrade.yml @@ -31,6 +31,15 @@ jobs: with: go-version: ${{ env.GO_VERSION }} + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Log in to registry.redhat.io uses: redhat-actions/podman-login@9184318aae1ee5034fbfbacc0388acf12669171f # v1 with: @@ -223,5 +232,5 @@ jobs: run: go install github.com/sigstore/cosign/v2/cmd/cosign@v2.2.2 - name: Run tests - run: TEST_BASE_CATALOG=registry.redhat.io/redhat/redhat-operator-index:v4.14 TEST_TARGET_CATALOG=$CATALOG_IMG go test ./e2e/... -tags=upgrade -timeout 20m + run: TEST_BASE_CATALOG=registry.redhat.io/redhat/redhat-operator-index:v4.14 TEST_TARGET_CATALOG=$CATALOG_IMG OPENSHIFT=false go test ./e2e/... -tags=upgrade -timeout 20m diff --git a/Makefile b/Makefile index 12165e5c7..a71776905 100644 --- a/Makefile +++ b/Makefile @@ -77,6 +77,8 @@ endif SHELL = /usr/bin/env bash -o pipefail .SHELLFLAGS = -ec +OPENSHIFT ?= true + .PHONY: all all: build @@ -183,6 +185,9 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} $(KUSTOMIZE) build config/default | kubectl apply -f - + @if [ "$(OPENSHIFT)" == "false" ]; then \ + kubectl patch deploy -n openshift-rhtas-operator -p '{"spec": {"template": {"spec": {"containers": [{"name": "manager","env": [{"name": "OPENSHIFT","value":"false"}]}]}}}}' rhtas-operator-controller-manager; \ + fi .PHONY: undeploy undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. diff --git a/bundle/manifests/rhtas-operator.clusterserviceversion.yaml b/bundle/manifests/rhtas-operator.clusterserviceversion.yaml index 7d80c79fc..e0ce47fee 100644 --- a/bundle/manifests/rhtas-operator.clusterserviceversion.yaml +++ b/bundle/manifests/rhtas-operator.clusterserviceversion.yaml @@ -192,7 +192,7 @@ metadata: ] capabilities: Seamless Upgrades containerImage: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:1988280e920b5832f6c9b71f3ef3ea9c618c83046113db8738dffece44ecaecf - createdAt: "2024-06-19T13:25:03Z" + createdAt: "2024-06-25T09:02:55Z" features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "false" features.operators.openshift.io/csi: "false" @@ -204,7 +204,7 @@ metadata: features.operators.openshift.io/token-auth-azure: "false" features.operators.openshift.io/token-auth-gcp: "false" operators.openshift.io/valid-subscription: '["Red Hat Trusted Artifact Signer"]' - operators.operatorframework.io/builder: operator-sdk-v1.34.1 + operators.operatorframework.io/builder: operator-sdk-v1.34.2 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/securesign/secure-sign-operator support: Red Hat @@ -737,6 +737,9 @@ spec: - --leader-elect command: - /manager + env: + - name: OPENSHIFT + value: "true" image: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:1988280e920b5832f6c9b71f3ef3ea9c618c83046113db8738dffece44ecaecf livenessProbe: httpGet: diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index c7e90df90..30e25cc1a 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -1,3 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + # Adds namespace to all resources. namespace: openshift-rhtas-operator @@ -12,7 +15,7 @@ namePrefix: rhtas- #commonLabels: # someName: someValue -bases: +resources: - ../crd - ../rbac - ../manager @@ -24,6 +27,12 @@ bases: # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus +patches: + - path: manager_openshift_patch.yaml + target: + kind: Deployment + name: operator-controller-manager + patchesStrategicMerge: # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics diff --git a/config/default/manager_openshift_patch.yaml b/config/default/manager_openshift_patch.yaml new file mode 100644 index 000000000..2ca4aa907 --- /dev/null +++ b/config/default/manager_openshift_patch.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: operator-controller-manager +spec: + template: + spec: + containers: + - name: manager + env: + - name: OPENSHIFT + value: "true" diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index f289523f8..1a4d6afbf 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -77,6 +77,7 @@ spec: capabilities: drop: - "ALL" + env: [] livenessProbe: httpGet: path: /healthz diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 713937132..74099798c 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization # These resources constitute the fully configured set of manifests # used to generate the 'manifests/' directory in a bundle. resources: diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml index 50cd2d084..c6b1b11e1 100644 --- a/config/scorecard/kustomization.yaml +++ b/config/scorecard/kustomization.yaml @@ -1,16 +1,17 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization resources: - bases/config.yaml -patchesJson6902: +patches: - path: patches/basic.config.yaml target: group: scorecard.operatorframework.io - version: v1alpha3 kind: Configuration name: config + version: v1alpha3 - path: patches/olm.config.yaml target: group: scorecard.operatorframework.io - version: v1alpha3 kind: Configuration name: config -#+kubebuilder:scaffold:patchesJson6902 + version: v1alpha3 diff --git a/controllers/clidownload/component.go b/controllers/clidownload/component.go index 9d1f4a617..2a0c7882e 100644 --- a/controllers/clidownload/component.go +++ b/controllers/clidownload/component.go @@ -60,7 +60,7 @@ func (c *Component) Start(ctx context.Context) error { } obj = append(obj, ingress) - if kubernetes.IsOpenShift(c.Client) { + if kubernetes.IsOpenShift() { protocol := "http://" if len(ingress.Spec.TLS) > 0 { protocol = "https://" diff --git a/controllers/common/utils/flag_or_env.go b/controllers/common/utils/flag_or_env.go index b457bc1f6..85ab2d5c7 100644 --- a/controllers/common/utils/flag_or_env.go +++ b/controllers/common/utils/flag_or_env.go @@ -3,9 +3,10 @@ package utils import ( "flag" "os" + "strconv" ) -// stringFlagOrEnv defines a string flag which can be set by an environment variable. +// StringFlagOrEnv defines a string flag which can be set by an environment variable. // Precedence: flag > env var > default value. func StringFlagOrEnv(p *string, name string, envName string, defaultValue string, usage string) { envValue := os.Getenv(envName) @@ -14,3 +15,13 @@ func StringFlagOrEnv(p *string, name string, envName string, defaultValue string } flag.StringVar(p, name, defaultValue, usage) } + +// BoolFlagOrEnv defines a bool flag which can be set by an environment variable. +// Precedence: flag > env var > default value. +func BoolFlagOrEnv(p *bool, name string, envName string, defaultValue bool, usage string) { + envValue := os.Getenv(envName) + if envName != "" { + defaultValue, _ = strconv.ParseBool(envValue) + } + flag.BoolVar(p, name, defaultValue, usage) +} diff --git a/controllers/common/utils/kubernetes/common.go b/controllers/common/utils/kubernetes/common.go index d6e083289..7f72e4a13 100644 --- a/controllers/common/utils/kubernetes/common.go +++ b/controllers/common/utils/kubernetes/common.go @@ -3,17 +3,12 @@ package kubernetes import ( "context" "fmt" - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" "os" "path/filepath" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - "strconv" - "sync" "time" v13 "github.com/openshift/api/operator/v1" - "k8s.io/apimachinery/pkg/runtime/schema" + "github.com/securesign/operator/controllers/constants" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -75,47 +70,12 @@ func ContainerMode() (bool, error) { return false, nil } -var onceIsOpenshift sync.Once -var isOpenshift bool - -func IsOpenShift(client client.Client) bool { - // atomic - onceIsOpenshift.Do(func() { - log := ctrllog.Log.WithName("IsOpenshift") - isOpenshift = checkIsOpenshift(client, log) - log.Info(strconv.FormatBool(isOpenshift)) - }) - - return isOpenshift -} - -func checkIsOpenshift(client client.Client, logger logr.Logger) bool { - - _, err := client.RESTMapper().ResourceFor(schema.GroupVersionResource{ - Group: "security.openshift.io", - Resource: "SecurityContextConstraints", - }) - - for i := 0; i < openshiftCheckLimit; i++ { - if err != nil { - if meta.IsNoMatchError(err) { - // continue with non-ocp standard - return false - } - - logger.Info("failed to identify", "retry", fmt.Sprintf("%d/%d", i, openshiftCheckLimit)) - logger.V(1).Info(err.Error()) - time.Sleep(time.Duration(i) * openshiftCheckDelay) - continue - } - return true - } - - return false +func IsOpenShift() bool { + return constants.Openshift } func CalculateHostname(ctx context.Context, client client.Client, svcName, ns string) (string, error) { - if IsOpenShift(client) { + if IsOpenShift() { ctrl := &v13.IngressController{} if err := client.Get(ctx, types.NamespacedName{Namespace: "openshift-ingress-operator", Name: "default"}, ctrl); err != nil { return "", err diff --git a/controllers/common/utils/kubernetes/ingress.go b/controllers/common/utils/kubernetes/ingress.go index a397775b1..2e8f2529d 100644 --- a/controllers/common/utils/kubernetes/ingress.go +++ b/controllers/common/utils/kubernetes/ingress.go @@ -16,7 +16,7 @@ func CreateIngress(ctx context.Context, cli client.Client, svc v12.Service, conf var tlsConfig []networkingv1.IngressTLS var annotations map[string]string - if IsOpenShift(cli) { + if IsOpenShift() { annotations = map[string]string{"route.openshift.io/termination": "edge"} // ocp is able to autogenerate TLS tlsConfig = []networkingv1.IngressTLS{ diff --git a/controllers/constants/config.go b/controllers/constants/config.go index 34195642b..e82022a79 100644 --- a/controllers/constants/config.go +++ b/controllers/constants/config.go @@ -1,7 +1,6 @@ package constants - - var ( CreateTreeDeadline int64 = 1200 + Openshift bool ) diff --git a/controllers/trillian/actions/db/deployment.go b/controllers/trillian/actions/db/deployment.go index d3484ff47..36efd0dfd 100644 --- a/controllers/trillian/actions/db/deployment.go +++ b/controllers/trillian/actions/db/deployment.go @@ -40,7 +40,7 @@ func (i deployAction) Handle(ctx context.Context, instance *rhtasv1alpha1.Trilli updated bool openshift bool ) - openshift = kubernetes.IsOpenShift(i.Client) + openshift = kubernetes.IsOpenShift() labels := constants.LabelsFor(actions.DbComponentName, actions.DbDeploymentName, instance.Name) db, err := trillianUtils.CreateTrillDb(instance, actions.DbDeploymentName, actions.RBACName, openshift, labels) diff --git a/e2e/upgrade_test.go b/e2e/upgrade_test.go index 9fede4105..85d8eb88e 100644 --- a/e2e/upgrade_test.go +++ b/e2e/upgrade_test.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "os" + "strconv" "strings" "time" @@ -51,6 +52,7 @@ var _ = Describe("Operator upgrade", Ordered, func() { rtuf *tasv1alpha.Tuf oidcToken string prevImageName, newImageName string + openshift bool ) AfterEach(func() { @@ -79,6 +81,7 @@ var _ = Describe("Operator upgrade", Ordered, func() { baseCatalogImage = os.Getenv("TEST_BASE_CATALOG") targetedCatalogImage = os.Getenv("TEST_TARGET_CATALOG") + openshift, _ = strconv.ParseBool(os.Getenv("OPENSHIFT")) namespace = support.CreateTestNamespace(ctx, cli) DeferCleanup(func() { @@ -130,6 +133,14 @@ var _ = Describe("Operator upgrade", Ordered, func() { CatalogSourceNamespace: namespace.Name, Package: "rhtas-operator", Channel: "stable", + Config: &v1alpha1.SubscriptionConfig{ + Env: []v1.EnvVar{ + { + Name: "OPENSHIFT", + Value: strconv.FormatBool(openshift), + }, + }, + }, }, Status: v1alpha1.SubscriptionStatus{}, } diff --git a/main.go b/main.go index 29cae3fd7..4fd8b79c5 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ package main import ( "flag" "os" + "strconv" consolev1 "github.com/openshift/api/console/v1" v1 "github.com/openshift/api/operator/v1" @@ -86,6 +87,7 @@ func main() { "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") flag.Int64Var(&constants.CreateTreeDeadline, "create-tree-deadline", constants.CreateTreeDeadline, "The time allowance (in seconds) for the create tree job to run before failing.") + utils.BoolFlagOrEnv(&constants.Openshift, "openshift", "OPENSHIFT", false, "Enable to ensures the operator applies OpenShift specific configurations.") utils.StringFlagOrEnv(&constants.TrillianLogSignerImage, "trillian-log-signer-image", "TRILLIAN_LOG_SIGNER_IMAGE", constants.TrillianLogSignerImage, "The image used for trillian log signer.") utils.StringFlagOrEnv(&constants.TrillianServerImage, "trillian-log-server-image", "TRILLIAN_LOG_SERVER_IMAGE", constants.TrillianServerImage, "The image used for trillian log server.") utils.StringFlagOrEnv(&constants.TrillianDbImage, "trillian-db-image", "TRILLIAN_DB_IMAGE", constants.TrillianDbImage, "The image used for trillian's database.") @@ -208,6 +210,8 @@ func main() { os.Exit(1) } + setupLog.WithName("IsOpenshift").Info(strconv.FormatBool(constants.Openshift)) + setupLog.Info("starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { setupLog.Error(err, "problem running manager")