Skip to content

Commit

Permalink
refactor(controller)!: remove option to borrow credentials from argo …
Browse files Browse the repository at this point in the history
…cd (akuity#1483)

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>
  • Loading branch information
krancour authored Feb 16, 2024
1 parent 0b0d148 commit 06daf18
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 272 deletions.
33 changes: 16 additions & 17 deletions charts/kargo/README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion charts/kargo/templates/argocd/role-binding.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.controller.argocd.integrationEnabled (or .Values.controller.argocd.watchArgocdNamespaceOnly .Values.controller.argocd.enableCredentialBorrowing) }}
{{- if and .Values.controller.argocd.integrationEnabled .Values.controller.argocd.watchArgocdNamespaceOnly }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
Expand Down
14 changes: 1 addition & 13 deletions charts/kargo/templates/argocd/role.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.controller.argocd.integrationEnabled (or .Values.controller.argocd.watchArgocdNamespaceOnly .Values.controller.argocd.enableCredentialBorrowing) }}
{{- if and .Values.controller.argocd.integrationEnabled .Values.controller.argocd.watchArgocdNamespaceOnly }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
Expand All @@ -8,7 +8,6 @@ metadata:
{{- include "kargo.labels" . | nindent 4 }}
{{- include "kargo.controller.labels" . | nindent 4 }}
rules:
{{- if or .Values.controller.argocd.watchArgocdNamespaceOnly }}
- apiGroups:
- argoproj.io
resources:
Expand All @@ -19,14 +18,3 @@ rules:
- patch
- watch
{{- end }}
{{- if .Values.controller.argocd.enableCredentialBorrowing }}
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
{{- end }}
{{- end }}
1 change: 0 additions & 1 deletion charts/kargo/templates/controller/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ data:
ARGOCD_KUBECONFIG: /etc/kargo/kubeconfigs/argocd-kubeconfig.yaml
{{- end }}
ARGOCD_NAMESPACE: {{ .Values.controller.argocd.namespace }}
ARGOCD_ENABLE_CREDENTIAL_BORROWING: {{ quote .Values.controller.argocd.enableCredentialBorrowing }}
ARGOCD_WATCH_ARGOCD_NAMESPACE_ONLY: {{ quote .Values.controller.argocd.watchArgocdNamespaceOnly }}
{{- end }}
ROLLOUTS_INTEGRATION_ENABLED: {{ quote .Values.controller.rollouts.integrationEnabled }}
Expand Down
2 changes: 0 additions & 2 deletions charts/kargo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ controller:
namespace: argocd
## @param controller.argocd.watchArgocdNamespaceOnly Specifies whether the reconciler that watches Argo CD Applications for the sake of forcing related Stages to reconcile should only watch Argo CD Application resources residing in Argo CD's own namespace. Note: Older versions of Argo CD only supported Argo CD Application resources in Argo CD's own namespace, but newer versions support Argo CD Application resources in any namespace. This should usually be left as `false`.
watchArgocdNamespaceOnly: false
## @param controller.argocd.enableCredentialBorrowing Specifies whether Kargo may borrow repository credentials (specially formatted and specially annotated Secrets) from Argo CD.
enableCredentialBorrowing: true

## All settings relating to the use of Argo Rollouts AnalysisTemplates and
## AnalysisRuns as a means of verifying Stages after a Promotion.
Expand Down
8 changes: 0 additions & 8 deletions cmd/controlplane/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/metrics/server"

Expand Down Expand Up @@ -248,15 +247,8 @@ func newControllerCommand() *cobra.Command {
log.Info("Argo Rollouts integration is disabled")
}

var argocdClientForCreds client.Client
if types.MustParseBool(
os.GetEnv("ARGOCD_ENABLE_CREDENTIAL_BORROWING", "false"),
) && argocdMgr != nil {
argocdClientForCreds = argocdMgr.GetClient()
}
credentialsDB := credentials.NewKubernetesDatabase(
kargoMgr.GetClient(),
argocdClientForCreds,
credentials.KubernetesDatabaseConfigFromEnv(),
)

Expand Down
5 changes: 1 addition & 4 deletions internal/controller/promotion/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import (
func TestNewMechanisms(t *testing.T) {
promoMechs := NewMechanisms(
fake.NewClientBuilder().Build(),
credentials.NewKubernetesDatabase(
nil,
nil, credentials.KubernetesDatabaseConfig{},
),
credentials.NewKubernetesDatabase(nil, credentials.KubernetesDatabaseConfig{}),
)
require.IsType(t, &compositeMechanism{}, promoMechs)
}
Expand Down
160 changes: 45 additions & 115 deletions internal/credentials/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,9 @@ import (
)

const (
// authorizedProjectsAnnotationKey is the key for an annotation used by owners
// of Secrets in Argo CD's namespace to indicate consent to be borrowed by
// specific Kargo projects.
authorizedProjectsAnnotationKey = "kargo.akuity.io/authorized-projects"

// kargoSecretTypeLabelKey is the key for a label used to identify the type
// of credentials stored in a Secret.
kargoSecretTypeLabelKey = "kargo.akuity.io/secret-type" // nolint: gosec
// argoCDSecretTypeLabelKey is the key for a label used to identify the type
// of credentials stored in a Secret within Argo CD's namespace.
argoCDSecretTypeLabelKey = "argocd.argoproj.io/secret-type" // nolint: gosec
// repositorySecretTypeLabelValue denotes that a secret contains credentials
// for a repository that is an exact match on the normalized URL.
repositorySecretTypeLabelValue = "repository"
Expand Down Expand Up @@ -71,15 +63,13 @@ type Database interface {
// utilizes a Kubernetes controller runtime client to retrieve credentials
// stored in Kubernetes Secrets.
type kubernetesDatabase struct {
kargoClient client.Client
argocdClient client.Client // nil if credential borrowing is not enabled
cfg KubernetesDatabaseConfig
kargoClient client.Client
cfg KubernetesDatabaseConfig
}

// KubernetesDatabaseConfig represents configuration for a Kubernetes based
// implementation of the Database interface.
type KubernetesDatabaseConfig struct {
ArgoCDNamespace string `envconfig:"ARGOCD_NAMESPACE" default:"argocd"`
GlobalCredentialsNamespaces []string `envconfig:"GLOBAL_CREDENTIALS_NAMESPACES" default:""`
}

Expand All @@ -94,13 +84,11 @@ func KubernetesDatabaseConfigFromEnv() KubernetesDatabaseConfig {
// retrieve Credentials stored in Kubernetes Secrets.
func NewKubernetesDatabase(
kargoClient client.Client,
argocdClient client.Client,
cfg KubernetesDatabaseConfig,
) Database {
return &kubernetesDatabase{
kargoClient: kargoClient,
argocdClient: argocdClient,
cfg: cfg,
kargoClient: kargoClient,
cfg: cfg,
}
}

Expand Down Expand Up @@ -129,57 +117,13 @@ func (k *kubernetesDatabase) Get(
); err != nil {
return creds, false, err
}
// Found creds in namespace
if secret != nil {
return secretToCreds(secret), true, nil
}

// Check namespace for credentials template
if secret, err = getCredentialsSecret(
ctx,
k.kargoClient,
namespace,
labels.Set(map[string]string{
kargoSecretTypeLabelKey: repoCredsSecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
true, // repoURL is a prefix
); err != nil {
return creds, false, err
}

// Found template creds in namespace
if secret != nil {
return secretToCreds(secret), true, nil
}

// Check global credentials namespaces for credentials
for _, globalCredsNamespace := range k.cfg.GlobalCredentialsNamespaces {
// Check shared creds namespace for credentials
if secret, err = getCredentialsSecret(
ctx,
k.kargoClient,
globalCredsNamespace,
labels.Set(map[string]string{
kargoSecretTypeLabelKey: repositorySecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
false, // repoURL is not a prefix
); err != nil {
return creds, false, err
}
// Found creds in global creds namespace
if secret != nil {
return secretToCreds(secret), true, nil
}

// Check shared creds namespace for credentials template
if secret == nil {
// Check namespace for credentials template
if secret, err = getCredentialsSecret(
ctx,
k.kargoClient,
globalCredsNamespace,
namespace,
labels.Set(map[string]string{
kargoSecretTypeLabelKey: repoCredsSecretTypeLabelValue,
}).AsSelector(),
Expand All @@ -189,68 +133,54 @@ func (k *kubernetesDatabase) Get(
); err != nil {
return creds, false, err
}

if secret != nil {
return secretToCreds(secret), true, nil
}
}

if k.argocdClient == nil {
// We cannot borrow creds from from Argo CD
return creds, false, nil
}

// Check Argo CD's namespace for credentials
if secret, err = getCredentialsSecret(
ctx,
k.argocdClient,
k.cfg.ArgoCDNamespace,
labels.Set(map[string]string{
argoCDSecretTypeLabelKey: repositorySecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
false, // repoURL is not a prefix
); err != nil {
return creds, false, err
}

if secret == nil {
// Check Argo CD's namespace for credentials template
if secret, err = getCredentialsSecret(
ctx,
k.argocdClient,
k.cfg.ArgoCDNamespace,
labels.Set(map[string]string{
argoCDSecretTypeLabelKey: repoCredsSecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
true, // repoURL is a prefix
); err != nil || secret == nil {
return creds, false, err
// Check global credentials namespaces for credentials
for _, globalCredsNamespace := range k.cfg.GlobalCredentialsNamespaces {
// Check shared creds namespace for credentials
if secret, err = getCredentialsSecret(
ctx,
k.kargoClient,
globalCredsNamespace,
labels.Set(map[string]string{
kargoSecretTypeLabelKey: repositorySecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
false, // repoURL is not a prefix
); err != nil {
return creds, false, err
}
if secret != nil {
break
}

// Check shared creds namespace for credentials template
if secret, err = getCredentialsSecret(
ctx,
k.kargoClient,
globalCredsNamespace,
labels.Set(map[string]string{
kargoSecretTypeLabelKey: repoCredsSecretTypeLabelValue,
}).AsSelector(),
credType,
repoURL,
true, // repoURL is a prefix
); err != nil {
return creds, false, err
}
if secret != nil {
break
}
}
}

if secret == nil {
return creds, false, nil
}

// This Secret represents credentials borrowed from Argo CD. We need to look
// at its annotations to see if this is authorized by the Secret's owner.
// If it's not annotated properly, we'll treat it as we didn't find it.
allowedProjectsStr, ok := secret.Annotations[authorizedProjectsAnnotationKey]
if !ok {
return creds, false, nil
}
allowedProjects := strings.Split(allowedProjectsStr, ",")
for _, allowedProject := range allowedProjects {
if strings.TrimSpace(allowedProject) == namespace {
return secretToCreds(secret), true, nil
}
}

return creds, false, nil
return secretToCreds(secret), true, nil
}

func getCredentialsSecret(
Expand Down
Loading

0 comments on commit 06daf18

Please sign in to comment.