Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ COPY api/ api/
COPY common/ common/
COPY controllers/ controllers/
COPY version/ version/
COPY pkg/ pkg/

# Build
ARG LD_FLAGS
Expand Down
78 changes: 11 additions & 67 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ import (
"strings"

"github.com/argoproj/argo-cd/v3/util/env"
appsv1 "github.com/openshift/api/apps/v1"
configv1 "github.com/openshift/api/config/v1"
oauthv1 "github.com/openshift/api/oauth/v1"
routev1 "github.com/openshift/api/route/v1"
templatev1 "github.com/openshift/api/template/v1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client/config"
Expand All @@ -40,6 +34,7 @@ import (
"github.com/argoproj-labs/argocd-operator/common"
"github.com/argoproj-labs/argocd-operator/controllers/argocd"
"github.com/argoproj-labs/argocd-operator/controllers/argocdexport"
operatorscheme "github.com/argoproj-labs/argocd-operator/pkg/schema"

metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

Expand All @@ -52,13 +47,10 @@ import (
"go.uber.org/zap/zapcore"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

v1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1"
v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1"
"github.com/argoproj-labs/argocd-operator/version"
//+kubebuilder:scaffold:imports
Expand All @@ -69,14 +61,6 @@ var (
setupLog = ctrl.Log.WithName("setup")
)

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))

utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(v1beta1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

func printVersion() {
setupLog.Info(fmt.Sprintf("Go Version: %s", goruntime.Version()))
setupLog.Info(fmt.Sprintf("Go OS/Arch: %s/%s", goruntime.GOOS, goruntime.GOARCH))
Expand Down Expand Up @@ -190,65 +174,25 @@ func main() {

setupLog.Info("Registering Components.")

// Setup Scheme for all resources
if err := v1alpha1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
// Setup Scheme for all resources using the centralized scheme package
err1 := operatorscheme.SetupScheme(mgr.GetScheme(), operatorscheme.SchemeOptions{
EnablePrometheus: argocd.IsPrometheusAPIAvailable(),
EnableRoutes: argocd.IsRouteAPIAvailable(),
EnableVersion: argocd.IsVersionAPIAvailable(),
EnableKeycloak: argocd.CanUseKeycloakWithTemplate(),
})

if err := v1beta1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
if err1 != nil {
setupLog.Error(err, "failed to set up scheme: %v")
os.Exit(1)
}

// Setup Scheme for Prometheus if available.
if argocd.IsPrometheusAPIAvailable() {
if err := monitoringv1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
}

// Setup Scheme for OpenShift Routes if available.
if argocd.IsRouteAPIAvailable() {
if err := routev1.Install(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
}

// Set up the scheme for openshift config if available
if argocd.IsVersionAPIAvailable() {
if err := configv1.Install(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
}

// Setup Schemes for SSO if template instance is available.
if argocd.CanUseKeycloakWithTemplate() {
setupLog.Info("Keycloak instance can be managed using OpenShift Template")
if err := templatev1.Install(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
if err := appsv1.Install(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
if err := oauthv1.Install(mgr.GetScheme()); err != nil {
setupLog.Error(err, "")
os.Exit(1)
}
} else {
setupLog.Info("Keycloak instance cannot be managed using OpenShift Template, as DeploymentConfig/Template API is not present")
}

k8sClient, err := initK8sClient()
if err != nil {
setupLog.Error(err, "Failed to initialize Kubernetes client")
os.Exit(1)
}

if err = (&argocd.ReconcileArgoCD{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Expand Down
98 changes: 98 additions & 0 deletions pkg/schema/scheme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
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.
*/

// Package scheme provides centralized scheme registration for all API types
package schema

import (
appsv1 "github.com/openshift/api/apps/v1"
configv1 "github.com/openshift/api/config/v1"
oauthv1 "github.com/openshift/api/oauth/v1"
routev1 "github.com/openshift/api/route/v1"
templatev1 "github.com/openshift/api/template/v1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"

v1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1"
v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1"
)

var (
schemeLog = ctrl.Log.WithName("scheme")
)

// SchemeOptions provides toggles to register optional APIs.
type SchemeOptions struct {
EnablePrometheus bool
EnableRoutes bool
EnableVersion bool
EnableKeycloak bool
}

func SetupScheme(scheme *runtime.Scheme, opts SchemeOptions) error {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
registerArgoCDAPIs(scheme)
// Setup Scheme for Prometheus if enabled.
if opts.EnablePrometheus {
if err := monitoringv1.AddToScheme(scheme); err != nil {
schemeLog.Error(err, "Failed to register Prometheus API")
return err
}
}
// Setup Scheme for OpenShift Routes if enabled.
if opts.EnableRoutes {
if err := routev1.Install(scheme); err != nil {
schemeLog.Error(err, "Failed to register Route API")
return err
}
}
// Setup Scheme for OpenShift config if enabled.
if opts.EnableVersion {
if err := configv1.Install(scheme); err != nil {
schemeLog.Error(err, "Failed to register Version API")
return err
}
}
// Setup Schemes for SSO if template instance is available.
if opts.EnableKeycloak {
schemeLog.Info("Keycloak instance can be managed using OpenShift Template.")
if err := templatev1.Install(scheme); err != nil {
schemeLog.Error(err, "Failed to register Template API")
return err
}
if err := appsv1.Install(scheme); err != nil {
schemeLog.Error(err, "Failed to register DeploymentConfig API")
return err
}
if err := oauthv1.Install(scheme); err != nil {
schemeLog.Error(err, "Failed to register OAuth API")
return err
}
} else {
schemeLog.Info("Keycloak instance cannot be managed using OpenShift Template, as //DeploymentConfig/Template API is not present.")
}

schemeLog.Info("Scheme setup complete.")
return nil
}

func registerArgoCDAPIs(scheme *runtime.Scheme) {
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(v1beta1.AddToScheme(scheme))
}
73 changes: 73 additions & 0 deletions pkg/schema/scheme_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package schema

import (
"testing"

"github.com/argoproj-labs/argocd-operator/controllers/argocd"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func TestSetupScheme(t *testing.T) {
t.Run("SetupScheme should register all required schemes", func(t *testing.T) {
scheme := runtime.NewScheme()

// Call SetupScheme
SetupScheme(scheme, SchemeOptions{
EnablePrometheus: true,
EnableRoutes: true,
EnableVersion: true,
EnableKeycloak: true,
})

// Verify the scheme is not nil
assert.NotNil(t, scheme, "Scheme should not be nil")

// Verify that ArgoCD API schemes are registered
v1alpha1GVK := schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "ArgoCD"}
v1beta1GVK := schema.GroupVersionKind{Group: "argoproj.io", Version: "v1beta1", Kind: "ArgoCD"}
assert.True(t, scheme.Recognizes(v1alpha1GVK), "v1alpha1 ArgoCD scheme should be registered")
assert.True(t, scheme.Recognizes(v1beta1GVK), "v1beta1 ArgoCD scheme should be registered")

// Verify conditional schemes based on API availability
if argocd.IsPrometheusAPIAvailable() {
prometheusGVK := schema.GroupVersionKind{Group: "monitoring.coreos.com", Version: "v1", Kind: "Prometheus"}
assert.True(t, scheme.Recognizes(prometheusGVK), "Prometheus scheme should be registered when API is available")
}

if argocd.IsRouteAPIAvailable() {
routeGVK := schema.GroupVersionKind{Group: "route.openshift.io", Version: "v1", Kind: "Route"}
assert.True(t, scheme.Recognizes(routeGVK), "OpenShift Route scheme should be registered when API is available")
}

if argocd.IsVersionAPIAvailable() {
clusterVersionGVK := schema.GroupVersionKind{Group: "config.openshift.io", Version: "v1", Kind: "ClusterVersion"}
assert.True(t, scheme.Recognizes(clusterVersionGVK), "OpenShift Config scheme should be registered when API is available")
}

if argocd.CanUseKeycloakWithTemplate() {
templateGVK := schema.GroupVersionKind{Group: "template.openshift.io", Version: "v1", Kind: "Template"}
deploymentConfigGVK := schema.GroupVersionKind{Group: "apps.openshift.io", Version: "v1", Kind: "DeploymentConfig"}
oauthClientGVK := schema.GroupVersionKind{Group: "oauth.openshift.io", Version: "v1", Kind: "OAuthClient"}

assert.True(t, scheme.Recognizes(templateGVK), "OpenShift Template scheme should be registered when Keycloak can use templates")
assert.True(t, scheme.Recognizes(deploymentConfigGVK), "OpenShift DeploymentConfig scheme should be registered when Keycloak can use templates")
assert.True(t, scheme.Recognizes(oauthClientGVK), "OpenShift OAuth scheme should be registered when Keycloak can use templates")
}
})

t.Run("SetupScheme should not panic with empty scheme", func(t *testing.T) {
scheme := runtime.NewScheme()

// This should not panic
assert.NotPanics(t, func() {
SetupScheme(scheme, SchemeOptions{
EnablePrometheus: true,
EnableRoutes: true,
EnableVersion: true,
EnableKeycloak: true,
})
}, "SetupScheme should not panic with empty scheme")
})
}