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
4 changes: 2 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func main() {
setupLog.Info("detected operator namespace", "namespace", controllers.DetectOperatorNamespace())

// Create initial config map for gitops
err := createGitOpsConfigMap()
err := createPatternsOperatorConfigMap()
if err != nil {
setupLog.Error(err, "unable to create config map")
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func printVersion() {
// Creates the patterns operator configmap
// This will include configuration parameters that
// will allow operator configuration
func createGitOpsConfigMap() error {
func createPatternsOperatorConfigMap() error {
config, err := ctrl.GetConfig()
if err != nil {
return fmt.Errorf("failed to get config: %s", err)
Expand Down
2 changes: 1 addition & 1 deletion hack/operator-build-deploy.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -e -o pipefail

CATALOGSOURCE="test-pattern-operator"
CATALOGSOURCE="test-patterns-operator"
DEFAULT_NS="patterns-operator"
OPERATOR="patterns-operator"
VERSION="${VERSION:-6.6.6}"
Expand Down
29 changes: 19 additions & 10 deletions internal/controller/argo.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,19 @@ const (
ConsoleLinkResource = "consolelinks"
)

func newArgoCD(name, namespace string) *argooperator.ArgoCD {
argoPolicy := `g, system:cluster-admins, role:admin
g, cluster-admins, role:admin
g, admin, role:admin`
func newArgoCD(name, namespace string, patternsOperatorConfig PatternsOperatorConfig) *argooperator.ArgoCD {
argoPolicies := []string{
"g, system:cluster-admins, role:admin",
"g, cluster-admins, role:admin",
"g, admin, role:admin",
}
for argoAdmin := range strings.SplitSeq(patternsOperatorConfig.getValueWithDefault("gitops.additionalArgoAdmins"), ",") {
argoAdmin = strings.TrimSpace(argoAdmin)
if argoAdmin != "" {
argoPolicies = append(argoPolicies, "g, "+argoAdmin+", role:admin")
}
}
argoPolicy := strings.Join(argoPolicies, "\n")
defaultPolicy := "role:readonly"
argoScopes := "[groups,email]"
trueBool := true
Expand Down Expand Up @@ -403,8 +412,8 @@ func haveArgo(client dynamic.Interface, name, namespace string) bool {
return err == nil
}

func createOrUpdateArgoCD(client dynamic.Interface, fullClient kubernetes.Interface, name, namespace string) error {
argo := newArgoCD(name, namespace)
func createOrUpdateArgoCD(client dynamic.Interface, fullClient kubernetes.Interface, name, namespace string, patternsOperatorConfig PatternsOperatorConfig) error {
argo := newArgoCD(name, namespace, patternsOperatorConfig)
gvr := schema.GroupVersionResource{Group: ArgoCDGroup, Version: ArgoCDVersion, Resource: ArgoCDResource}

var err error
Expand Down Expand Up @@ -911,7 +920,7 @@ func newArgoApplication(p *api.Pattern) *argoapi.Application {
return targetApp
}

func newArgoGiteaApplication(p *api.Pattern) *argoapi.Application {
func newArgoGiteaApplication(p *api.Pattern, patternsOperatorConfig PatternsOperatorConfig) *argoapi.Application {
consoleHref := fmt.Sprintf("https://%s-%s.%s", GiteaRouteName, GiteaNamespace, p.Status.AppClusterDomain)
parameters := []argoapi.HelmParameter{
{
Expand All @@ -934,9 +943,9 @@ func newArgoGiteaApplication(p *api.Pattern) *argoapi.Application {
},
Project: "default",
Source: &argoapi.ApplicationSource{
RepoURL: PatternsOperatorConfig.getValueWithDefault("gitea.helmRepoUrl"),
TargetRevision: PatternsOperatorConfig.getValueWithDefault("gitea.chartVersion"),
Chart: PatternsOperatorConfig.getValueWithDefault("gitea.chartName"),
RepoURL: patternsOperatorConfig.getValueWithDefault("gitea.helmRepoUrl"),
TargetRevision: patternsOperatorConfig.getValueWithDefault("gitea.chartVersion"),
Chart: patternsOperatorConfig.getValueWithDefault("gitea.chartName"),
Helm: &argoapi.ApplicationSourceHelm{
Parameters: parameters,
},
Expand Down
90 changes: 55 additions & 35 deletions internal/controller/argo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,15 +824,17 @@ var _ = Describe("NewApplicationValues", func() {

var _ = Describe("NewArgoCD", func() {
var (
name string
namespace string
argoCD *argooperator.ArgoCD
name string
namespace string
argoCD *argooperator.ArgoCD
patternsOperatorConfig PatternsOperatorConfig
)

BeforeEach(func() {
name = "test-argocd"
namespace = "test-namespace"
argoCD = newArgoCD(name, namespace)
patternsOperatorConfig = DefaultPatternsOperatorConfig
argoCD = newArgoCD(name, namespace, patternsOperatorConfig)
})

Context("when creating a new ArgoCD object", func() {
Expand Down Expand Up @@ -962,10 +964,11 @@ var _ = Describe("haveArgo", func() {

var _ = Describe("CreateOrUpdateArgoCD", func() {
var (
dynamicClient dynamic.Interface
gvr schema.GroupVersionResource
name string
namespace string
dynamicClient dynamic.Interface
gvr schema.GroupVersionResource
name string
namespace string
patternsOperatorConfig PatternsOperatorConfig
)

BeforeEach(func() {
Expand All @@ -975,11 +978,12 @@ var _ = Describe("CreateOrUpdateArgoCD", func() {
})
name = argoName
namespace = argoNS
patternsOperatorConfig = DefaultPatternsOperatorConfig
})

Context("when the ArgoCD instance does not exist", func() {
It("should create a new ArgoCD instance", func() {
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace)
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace, patternsOperatorConfig)
Expect(err).ToNot(HaveOccurred())

argoCD, err := dynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
Expand Down Expand Up @@ -1007,7 +1011,7 @@ var _ = Describe("CreateOrUpdateArgoCD", func() {
})

It("should update the existing ArgoCD instance", func() {
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace)
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace, patternsOperatorConfig)
Expect(err).ToNot(HaveOccurred())

argoCD, err := dynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
Expand Down Expand Up @@ -1038,7 +1042,7 @@ var _ = Describe("CreateOrUpdateArgoCD", func() {
})

It("should propagate the error and not update the existing argocd", func() {
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace)
err := createOrUpdateArgoCD(dynamicClient, nil, name, namespace, patternsOperatorConfig)
Expect(err).To(HaveOccurred())

argoCD, err := dynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
Expand Down Expand Up @@ -1420,9 +1424,12 @@ var _ = Describe("getChildApplications", func() {

var _ = Describe("NewArgoGiteaApplication", func() {
var pattern *api.Pattern
var patternsOperatorConfig PatternsOperatorConfig
var app *argoapi.Application

BeforeEach(func() {
tmpFalse := false
PatternsOperatorConfig = DefaultPatternOperatorConfig
patternsOperatorConfig = DefaultPatternsOperatorConfig
pattern = &api.Pattern{
ObjectMeta: metav1.ObjectMeta{Name: "test-pattern", Namespace: defaultNamespace},
TypeMeta: metav1.TypeMeta{Kind: "Pattern", APIVersion: api.GroupVersion.String()},
Expand All @@ -1444,10 +1451,11 @@ var _ = Describe("NewArgoGiteaApplication", func() {
ClusterDomain: "hub-cluster.validatedpatterns.io",
},
}
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)

})

It("should create a gitea application with correct properties", func() {
app := newArgoGiteaApplication(pattern)
Expect(app).ToNot(BeNil())
Expect(app.Name).To(Equal(GiteaApplicationName))
Expect(app.Namespace).To(Equal(getClusterWideArgoNamespace()))
Expand Down Expand Up @@ -2001,6 +2009,8 @@ var _ = Describe("removeApplication", func() {

var _ = Describe("newArgoGiteaApplication", func() {
var pattern *api.Pattern
var patternsOperatorConfig PatternsOperatorConfig
var app *argoapi.Application

BeforeEach(func() {
tmpFalse := false
Expand Down Expand Up @@ -2028,37 +2038,37 @@ var _ = Describe("newArgoGiteaApplication", func() {
ClusterVersion: "4.14.0",
},
}
PatternsOperatorConfig = GitOpsConfig{}
patternsOperatorConfig = DefaultPatternsOperatorConfig
})

It("should create the Gitea application with correct name", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Name).To(Equal(GiteaApplicationName))
Expect(app.Namespace).To(Equal(getClusterWideArgoNamespace()))
})

It("should set the pattern label", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Labels).To(HaveKeyWithValue("validatedpatterns.io/pattern", "test-pattern"))
})

It("should set the destination namespace to GiteaNamespace", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.Destination.Namespace).To(Equal(GiteaNamespace))
})

It("should set destination to in-cluster", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.Destination.Name).To(Equal("in-cluster"))
})

It("should set the project to default", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.Project).To(Equal("default"))
})

It("should include helm parameters for gitea admin secret and console href", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.Source).ToNot(BeNil())
Expect(app.Spec.Source.Helm).ToNot(BeNil())

Expand All @@ -2074,90 +2084,100 @@ var _ = Describe("newArgoGiteaApplication", func() {
})

It("should have the foreground propagation finalizer", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(controllerutil.ContainsFinalizer(app, argoapi.ForegroundPropagationPolicyFinalizer)).To(BeTrue())
})

It("should set a sync policy when not manual sync", func() {
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.SyncPolicy).ToNot(BeNil())
Expect(app.Spec.SyncPolicy.Automated).ToNot(BeNil())
})

It("should have nil sync policy when manual sync is enabled", func() {
pattern.Spec.GitOpsConfig.ManualSync = true
app := newArgoGiteaApplication(pattern)
app = newArgoGiteaApplication(pattern, patternsOperatorConfig)
Expect(app.Spec.SyncPolicy).To(BeNil())
})
})

var _ = Describe("newArgoCD", func() {
var argo *argooperator.ArgoCD

It("should create an ArgoCD with the correct name and namespace", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Name).To(Equal("test-argo"))
Expect(argo.Namespace).To(Equal("test-ns"))
})

It("should have the argoproj.io/finalizer", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Finalizers).To(ContainElement("argoproj.io/finalizer"))
})

It("should have HA disabled", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.HA.Enabled).To(BeFalse())
})

It("should have monitoring disabled", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.Monitoring.Enabled).To(BeFalse())
})

It("should have notifications disabled", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.Notifications.Enabled).To(BeFalse())
})

It("should have SSO configured with Dex provider", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.SSO).ToNot(BeNil())
Expect(argo.Spec.SSO.Provider).To(Equal(argooperator.SSOProviderTypeDex))
Expect(argo.Spec.SSO.Dex).ToNot(BeNil())
Expect(argo.Spec.SSO.Dex.OpenShiftOAuth).To(BeTrue())
})

It("should have server route enabled with reencrypt TLS", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.Server.Route.Enabled).To(BeTrue())
Expect(argo.Spec.Server.Route.TLS).ToNot(BeNil())
Expect(argo.Spec.Server.Route.TLS.Termination).To(Equal(routev1.TLSTerminationReencrypt))
})

It("should have resource exclusions for tekton", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.ResourceExclusions).To(ContainSubstring("tekton.dev"))
Expect(argo.Spec.ResourceExclusions).To(ContainSubstring("TaskRun"))
Expect(argo.Spec.ResourceExclusions).To(ContainSubstring("PipelineRun"))
})

It("should have resource health checks for Subscription", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.ResourceHealthChecks).To(HaveLen(1))
Expect(argo.Spec.ResourceHealthChecks[0].Group).To(Equal("operators.coreos.com"))
Expect(argo.Spec.ResourceHealthChecks[0].Kind).To(Equal("Subscription"))
})

It("should have init containers for CA cert fetching", func() {
argo := newArgoCD("test-argo", "test-ns")
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.Repo.InitContainers).To(HaveLen(1))
Expect(argo.Spec.Repo.InitContainers[0].Name).To(Equal("fetch-ca"))
})

It("should have correct RBAC policy", func() {
argo := newArgoCD("test-argo", "test-ns")
It("should have correct RBAC policy with defaults", func() {
argo = newArgoCD("test-argo", "test-ns", DefaultPatternsOperatorConfig)
Expect(argo.Spec.RBAC.Policy).ToNot(BeNil())
Expect(*argo.Spec.RBAC.Policy).To(ContainSubstring("cluster-admins"))
})

It("should have correct RBAC policy with additional admin", func() {
argo = newArgoCD("test-argo", "test-ns", PatternsOperatorConfig{"gitops.additionalArgoAdmins": "test-admins"})
Expect(argo.Spec.RBAC.Policy).ToNot(BeNil())
Expect(*argo.Spec.RBAC.Policy).To(ContainSubstring("cluster-admins"))
Expect(*argo.Spec.RBAC.Policy).To(ContainSubstring("test-admins"))
})

})

var _ = Describe("commonSyncPolicy", func() {
Expand Down
31 changes: 15 additions & 16 deletions internal/controller/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,27 @@ const (
// Experimental Capabilities that can be enabled
// Currently none

var DefaultPatternOperatorConfig = map[string]string{
"gitops.catalogSource": GitOpsDefaultCatalogSource,
"gitops.channel": GitOpsDefaultChannel,
"gitops.sourceNamespace": GitOpsDefaultCatalogSourceNamespace,
"gitops.installApprovalPlan": GitOpsDefaultApprovalPlan,
"gitops.csv": GitOpsDefaultCSV,
"gitea.chartName": GiteaChartName,
"gitea.helmRepoUrl": GiteaHelmRepoUrl,
"gitea.chartVersion": GiteaDefaultChartVersion,
"analytics.enabled": "true",
"catalog.image": "",
var DefaultPatternsOperatorConfig = map[string]string{
"gitops.catalogSource": GitOpsDefaultCatalogSource,
"gitops.channel": GitOpsDefaultChannel,
"gitops.sourceNamespace": GitOpsDefaultCatalogSourceNamespace,
"gitops.installApprovalPlan": GitOpsDefaultApprovalPlan,
"gitops.csv": GitOpsDefaultCSV,
"gitops.additionalArgoAdmins": "",
"gitea.chartName": GiteaChartName,
"gitea.helmRepoUrl": GiteaHelmRepoUrl,
"gitea.chartVersion": GiteaDefaultChartVersion,
"analytics.enabled": "true",
"catalog.image": "",
}

type GitOpsConfig map[string]string
type PatternsOperatorConfig map[string]string

var PatternsOperatorConfig GitOpsConfig

func (g GitOpsConfig) getValueWithDefault(k string) string {
func (g PatternsOperatorConfig) getValueWithDefault(k string) string {
if v, present := g[k]; present {
return v
}
if defaultValue, present := DefaultPatternOperatorConfig[k]; present {
if defaultValue, present := DefaultPatternsOperatorConfig[k]; present {
return defaultValue
}
return ""
Expand Down
Loading