Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Use ServiceAccountName for impersonation #180

Merged
merged 3 commits into from
Nov 20, 2020
Merged
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: 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