Skip to content
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
2 changes: 1 addition & 1 deletion examples/set-namespace-imperative/.expected/config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
testType: eval
image: gcr.io/kpt-fn/set-namespace:unstable
args:
namespace: example-ns
namespace: new-ns
10 changes: 5 additions & 5 deletions examples/set-namespace-imperative/.expected/diff.patch
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
diff --git a/app.yaml b/app.yaml
index 1f8aeee..33e42da 100644
index d67a0d2..bf55161 100644
--- a/app.yaml
+++ b/app.yaml
@@ -9,7 +9,7 @@ apiVersion: v1
kind: Service
metadata:
name: the-service
- namespace: the-namespace
+ namespace: example-ns
- namespace: example
+ namespace: new-ns
spec:
ports:
- name: etcd-server-ssl
@@ -21,4 +21,4 @@ spec:
@@ -34,4 +34,4 @@ spec:
apiVersion: v1
kind: Namespace
metadata:
- name: example
+ name: example-ns
+ name: new-ns
9 changes: 5 additions & 4 deletions examples/set-namespace-imperative/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

### Overview

This examples shows how to set namespace in the `.metadata.namespace` field on
all resources by running [`set-namespace`] function imperatively. Resources that
are known to be cluster-scoped will be skipped.
This examples shows how to replace KRM resources' namespace fields by matching
the namespace with the namespace object's `metadata.name`.
The example uses `kpt fn eval` to run the function imperatively.

### Fetch the example package

Expand All @@ -27,6 +27,7 @@ The desired namespace is provided after `--` and it will be converted to

### Expected result

Check all resources have `metadata.namespace` set to `example-ns`:
Only the namespace fields which match the `namespace` "example" object has the value updated to
`new-ns`:

[`set-namespace`]: https://catalog.kpt.dev/set-namespace/v0.1/
15 changes: 14 additions & 1 deletion examples/set-namespace-imperative/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,20 @@ apiVersion: v1
kind: Service
metadata:
name: the-service
namespace: the-namespace
namespace: example
spec:
ports:
- name: etcd-server-ssl
port: 2380
- name: etcd-client-ssl
port: 2379
publishNotReadyAddresses: true
---
apiVersion: v1
kind: Service
metadata:
name: the-service
namespace: not-match-example
spec:
ports:
- name: etcd-server-ssl
Expand Down
136 changes: 91 additions & 45 deletions functions/go/set-namespace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,68 +17,114 @@ Namespaces are often used in the following scenarios:

## Usage

This function can be used with any KRM function orchestrators (e.g. kpt).

- If the resource is `Namespace`, `set-namespace` updates the `metadata.name` field.
- If the resource is `RoleBinding` or `ClusterRoleBinding` resource, the function updates
the namespace field in the `subjects` element whose name is `default`.
- If the resource is `CustomResourceDefinition` (CRD), `set-namespace` updates the
`spec/conversion/webhook/clientConfig/service/namespace` field.
- If the resource is `APIService`, `set-namespace` updates the
`spec/service/namespace` field.
- If there is a [`depends-on`] annotation for a namespaced resource, the namespace
section of the annotation will be updated if the referenced resource is also
declared in the package.
This function replaces the KRM resources existing namespace to a new value.

### Target KRM resources

- This function updates all namespace-scoped KRM resources `metadata.namespace` fields.
We determine whether a KRM resource is namespace scoped by checking if it has `metadata.namespace` set and matches the "oldNamespace"
If not, this function won't add new namespace.
- This function updates `RoleBinding` and `ClusterRoleBinding` resources `subjects` element whose kind is `ServiceAccount`
and the subject's `namespace` is set and matches the "oldNamespace".
- This function updates `CustomResourceDefinition` (CRD) `spec/conversion/webhook/clientConfig/service/namespace` field
if the field is set and matches the "oldNamespace"
- This function updates `APIService` `spec/service/namespace` field if the field is set and matches the "oldNamespace"
- This function updates the KRM resources annotation `config.kubernetes.io/depends-on` if this annotation contains the
matching namespace.

### FunctionConfig

This function supports the default `ConfigMap` as function config and a custom `SetNamespace`. See below examples

`ConfigMap` as functionConfig
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa
namespace: example
annotations:
config.kubernetes.io/depends-on: /namespaces/example/ServiceAccount/foo # <= this will NOT be updated (resource not declared)
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
...
annotations:
config.kubernetes.io/depends-on: /namespaces/example/ServiceAccount/sa # <== this will be updated (resource declared)
subjects:
- kind: ServiceAccount
name: default # <================== name default is used
namespace: example # <================== this will be updated
roleRef:
kind: Role
name: confluent-operator
apiGroup: rbac.authorization.k8s.io
kind: ConfigMap
data:
namespace: newNamespace # required
namespaceMatcher: example # update namespace whose value is "example" to "newNamespace"
```

This function can be used both declaratively and imperatively.
`SetNamespace` as functionConfig
```yaml
apiVersion: fn.kpt.dev/v1alpha1
kind: SetNamespace
namespace: newNamespace # required
namespaceMatcher: example # update namespace whose value is "example" to "newNamespace"
```

### FunctionConfig

There are 2 kinds of `functionConfig` supported by this function:
### Three updating modes

- `ConfigMap`
- A custom resource of kind `SetNamespace`
This function supports three modes to flexibly choose and update the target namespaces.

To use a `ConfigMap` as the `functionConfig`, the desired namespace must be
specified in the `data.namespace` field.
##### Restrict Mode
All target KRM resources namespace has to have the same value. All namespace will be updated to the new value.

To add a namespace `staging` to all resources, we use the
following `functionConfig`:
`ConfigMap` as functionConfig
```yaml
apiVersion: v1
kind: ConfigMap
data:
namespace: newNamespace # update all namespace fields to "newNamespace"
```

##### DefaultNamespace Mode

The input `resourcelist.items` contains one and only one `Namespace` object. The function matches the namespace `metadata.name`
with all other KRM resources, and only update the namespace if it matches the `Namespace` object.
If more than one `Namespace` objects are found, raise errors;

```yaml
kind: ResourceList
functionConfig:
apiVersion: v1
kind: ConfigMap
data:
namespace: newNs
items:
- apiVersion: v1
kind: Namespace
metadata:
name: example # updated to "newNs"
- apiVersion: v1
kind: Service
metadata:
name: the-service1
namespace: example # updated to "newNs"
- apiVersion: v1
kind: Service
metadata:
name: the-service2
namespace: irrelevant # skip since namespace does not match "example".
```

##### Matcher Mode

Only updates the namespace which matches a given value. The "oldNamespace" refers to the argument in FunctionConfig

`ConfigMap` as functionConfig
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
namespace: staging
namespace: newNamespace
namespaceMatcher: example # update namespace whose value is "example" to "newNamespace"
```

`SetNamespace` as functionConfig
```yaml
apiVersion: fn.kpt.dev/v1alpha1
kind: SetNamespace
namespace: newNamespace
namespaceMatcher: example # update namespace whose value is "example" to "newNamespace"
```

### DependsOn annotation

DependsOn annotation is a [kpt feature](https://kpt.dev/reference/annotations/depends-on/). This function updates the
namespace segment in a depends-on annotation if the namespace matches the `Namespace` object or `namespaceMatcher` field.

<!--mdtogo-->

[namespace]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
Expand Down
130 changes: 83 additions & 47 deletions functions/go/set-namespace/generated/docs.go

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

Loading