Skip to content

Commit

Permalink
Merge pull request #180 from fluxcd/sa
Browse files Browse the repository at this point in the history
Use ServiceAccountName for impersonation
  • Loading branch information
stefanprodan authored Nov 20, 2020
2 parents 41a8a7e + 8f7f0d8 commit 59b1134
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 116 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ jobs:
kubectl -n kustomize-system apply -k ./config/testdata/sops
kubectl -n kustomize-system wait kustomizations/sops --for=condition=ready --timeout=4m
kubectl -n test2 get secrets/test --template={{.data.password}} | base64 -d | grep test
- name: Run impersonation tests
run: |
kubectl -n impersonation apply -f ./config/testdata/impersonation
kubectl -n impersonation wait kustomizations/podinfo --for=condition=ready --timeout=4m
- name: Logs
run: |
kubectl -n kustomize-system logs deploy/source-controller
Expand Down
17 changes: 4 additions & 13 deletions api/v1beta1/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type KustomizationSpec struct {
Interval metav1.Duration `json:"interval"`

// The KubeConfig for reconciling the Kustomization on a remote cluster.
// When specified, KubeConfig takes precedence over ServiceAccountName.
// +optional
KubeConfig *KubeConfig `json:"kubeConfig,omitempty"`

Expand All @@ -66,9 +67,10 @@ type KustomizationSpec struct {
// +optional
HealthChecks []CrossNamespaceObjectReference `json:"healthChecks,omitempty"`

// The Kubernetes service account used for applying the kustomization.
// The name of the Kubernetes service account to impersonate
// when reconciling this Kustomization.
// +optional
ServiceAccount *ServiceAccount `json:"serviceAccount,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty"`

// Reference of the source where the kustomization file is.
// +required
Expand Down Expand Up @@ -99,17 +101,6 @@ type KustomizationSpec struct {
Validation string `json:"validation,omitempty"`
}

// ServiceAccount defines a reference to a Kubernetes service account.
type ServiceAccount struct {
// Name is the name of the service account being referenced.
// +required
Name string `json:"name"`

// Namespace is the namespace of the service account being referenced.
// +required
Namespace string `json:"namespace"`
}

// Decryption defines how decryption is handled for Kubernetes manifests.
type Decryption struct {
// Provider is the name of the decryption engine.
Expand Down
20 changes: 0 additions & 20 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 6 additions & 16 deletions config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ spec:
type: string
kubeConfig:
description: The KubeConfig for reconciling the Kustomization on a
remote cluster.
remote cluster. When specified, KubeConfig takes precedence over
ServiceAccountName.
properties:
secretRef:
description: SecretRef holds the name to a secret that contains
Expand All @@ -140,21 +141,10 @@ spec:
prune:
description: Prune enables garbage collection.
type: boolean
serviceAccount:
description: The Kubernetes service account used for applying the
kustomization.
properties:
name:
description: Name is the name of the service account being referenced.
type: string
namespace:
description: Namespace is the namespace of the service account
being referenced.
type: string
required:
- name
- namespace
type: object
serviceAccountName:
description: The name of the Kubernetes service account to impersonate
when reconciling this Kustomization.
type: string
sourceRef:
description: Reference of the source where the kustomization file
is.
Expand Down
66 changes: 66 additions & 0 deletions config/testdata/impersonation/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
apiVersion: v1
kind: Namespace
metadata:
name: impersonation
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gotk-reconciler
namespace: impersonation
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gotk-reconciler
namespace: impersonation
rules:
- apiGroups: ['*']
resources: ['*']
verbs: ['*']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gotk-reconciler
namespace: impersonation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gotk-reconciler
subjects:
- kind: ServiceAccount
name: gotk-reconciler
namespace: impersonation
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
namespace: impersonation
spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
tag: "5.0.3"
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: podinfo
namespace: impersonation
spec:
targetNamespace: impersonation
serviceAccountName: gotk-reconciler
interval: 5m
path: "./kustomize"
prune: true
sourceRef:
kind: GitRepository
name: podinfo
validation: client
healthChecks:
- kind: Deployment
name: podinfo
namespace: impersonation
timeout: 2m
10 changes: 5 additions & 5 deletions controllers/kustomization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,8 @@ func (r *KustomizationReconciler) getKubeConfig(kustomization kustomizev1.Kustom

func (r *KustomizationReconciler) getServiceAccountToken(kustomization kustomizev1.Kustomization) (string, error) {
namespacedName := types.NamespacedName{
Namespace: kustomization.Spec.ServiceAccount.Namespace,
Name: kustomization.Spec.ServiceAccount.Name,
Namespace: kustomization.Namespace,
Name: kustomization.Spec.ServiceAccountName,
}

var serviceAccount corev1.ServiceAccount
Expand All @@ -656,8 +656,8 @@ func (r *KustomizationReconciler) getServiceAccountToken(kustomization kustomize
}

secretName := types.NamespacedName{
Namespace: kustomization.Spec.ServiceAccount.Namespace,
Name: kustomization.Spec.ServiceAccount.Name,
Namespace: kustomization.Namespace,
Name: kustomization.Spec.ServiceAccountName,
}

for _, secret := range serviceAccount.Secrets {
Expand Down Expand Up @@ -700,7 +700,7 @@ func (r *KustomizationReconciler) apply(kustomization kustomizev1.Kustomization,
cmd = fmt.Sprintf("%s --kubeconfig=%s", cmd, kubeConfig)
} else {
// impersonate SA
if kustomization.Spec.ServiceAccount != nil {
if kustomization.Spec.ServiceAccountName != "" {
saToken, err := r.getServiceAccountToken(kustomization)
if err != nil {
return "", fmt.Errorf("service account impersonation failed: %w", err)
Expand Down
67 changes: 12 additions & 55 deletions docs/api/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ KubeConfig
</td>
<td>
<em>(Optional)</em>
<p>The KubeConfig for reconciling the Kustomization on a remote cluster.</p>
<p>The KubeConfig for reconciling the Kustomization on a remote cluster.
When specified, KubeConfig takes precedence over ServiceAccountName.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -163,16 +164,15 @@ bool
</tr>
<tr>
<td>
<code>serviceAccount</code><br>
<code>serviceAccountName</code><br>
<em>
<a href="#kustomize.toolkit.fluxcd.io/v1beta1.ServiceAccount">
ServiceAccount
</a>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>The Kubernetes service account used for applying the kustomization.</p>
<p>The name of the Kubernetes service account to impersonate
when reconciling this Kustomization.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -555,7 +555,8 @@ KubeConfig
</td>
<td>
<em>(Optional)</em>
<p>The KubeConfig for reconciling the Kustomization on a remote cluster.</p>
<p>The KubeConfig for reconciling the Kustomization on a remote cluster.
When specified, KubeConfig takes precedence over ServiceAccountName.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -596,16 +597,15 @@ bool
</tr>
<tr>
<td>
<code>serviceAccount</code><br>
<code>serviceAccountName</code><br>
<em>
<a href="#kustomize.toolkit.fluxcd.io/v1beta1.ServiceAccount">
ServiceAccount
</a>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>The Kubernetes service account used for applying the kustomization.</p>
<p>The name of the Kubernetes service account to impersonate
when reconciling this Kustomization.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -779,49 +779,6 @@ Snapshot
</table>
</div>
</div>
<h3 id="kustomize.toolkit.fluxcd.io/v1beta1.ServiceAccount">ServiceAccount
</h3>
<p>
(<em>Appears on:</em>
<a href="#kustomize.toolkit.fluxcd.io/v1beta1.KustomizationSpec">KustomizationSpec</a>)
</p>
<p>ServiceAccount defines a reference to a Kubernetes service account.</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>name</code><br>
<em>
string
</em>
</td>
<td>
<p>Name is the name of the service account being referenced.</p>
</td>
</tr>
<tr>
<td>
<code>namespace</code><br>
<em>
string
</em>
</td>
<td>
<p>Namespace is the namespace of the service account being referenced.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="kustomize.toolkit.fluxcd.io/v1beta1.Snapshot">Snapshot
</h3>
<p>
Expand Down
4 changes: 3 additions & 1 deletion docs/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ of the frontend app was deployed and if the deployment is healthy, no matter the
The reconciliation process can be defined with a Kubernetes custom resource
that describes a pipeline such as:
- **check** if depends-on conditions are meet
- **fetch** manifests from Git repository X
- **fetch** manifests from source-controller (Git repository or S3 bucket)
- **generate** a kustomization if needed
- **build** the manifest using kustomization X
- **decrypt** Kubernetes secrets using Mozilla SOPS
- **validate** the resulting objects
- **impersonate** Kubernetes account
- **apply** the objects
- **prune** the objects removed from source
- **verify** the deployment status
Expand Down Expand Up @@ -76,6 +77,7 @@ The API design of the controller can be found at [kustomize.toolkit.fluxcd.io/v1
| Plain Kubernetes manifests sync | :heavy_check_mark: | :heavy_check_mark: |
| Kustomize build sync | :heavy_check_mark: | :heavy_check_mark: |
| Garbage collection | :heavy_check_mark: | :heavy_check_mark: |
| Secrets decryption | :heavy_check_mark: | :heavy_check_mark: |
| Container image updates | :x: | :heavy_check_mark: |
| Generate manifests with shell scripts | :x: | :heavy_check_mark: |

Expand Down
1 change: 1 addition & 0 deletions docs/spec/v1beta1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ of Kubernetes objects generated with Kustomize.
+ [Health assessment](kustomization.md#health-assessment)
+ [Kustomization dependencies](kustomization.md#kustomization-dependencies)
+ [Role-based access control](kustomization.md#role-based-access-control)
+ [Targeting remote clusters](kustomization.md#remote-clusters--cluster-api)
+ [Secrets decryption](kustomization.md#secrets-decryption)
+ [Status](kustomization.md#status)

Expand Down
Loading

0 comments on commit 59b1134

Please sign in to comment.