---
tags: work, problems, spike
---
# Join Namespace Network Policy
## Problem Statement
* At the moment, we are using api to ansible tower to perform the join namespace whenever the plan requested to do so.
* Join namespace is performed in bi-directional way. That would means when we requested `namespace-a` to join `namespace-b` we called ansible tower two times, to create the following network policy (ingress) :
* `allow-from-namespace-b` network policy in `namespace-a`
* `allow-from-namespace-a` network policy in `namespace-b`
* This causes us massive creation of network policy that never get cleaned up on the long lived namespace.
* For example, we have `namspace-a` that many other namespace has needs to join here, let's say `namespace-1` to `namespace-n`. This would means there will be `allow-from-namespace-1` to `allow-from-namespace-n` in `namespace-a`.
* When we deleted `namespace-1` to `namespace-n` the network policies that gets deleted only those under the deleted namespace, the long lived namespace would never get cleaned up its obsoleted network policy
### Additional information
* There are few default network policy created when we create namespace in the cluster
* default-deny
* allow-from-same-namespace
* allow-from-global-namespace
* We are using kubernetes network policy, its not external CRD. So everything in kubernetes example should be applicable.
```yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny
namespace: da-saas-alfonz-test
```
* Below is the example of the current network policy definitions.
```yaml
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
name: da-saas-non-prod-c7f9b7fac9154c44a88003dba6902194
policyTypes:
- Ingress
```
* We have the following network policy by the time we created the service group via provisioning service
* `allow-from-global-namespace`
```yaml
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
system-network-namespace: 'true'
policyTypes:
- Ingress
```
* `allow-from-same-namespace`
```yaml
spec:
podSelector: {}
ingress:
- from:
- podSelector: {}
policyTypes:
- Ingress
```
* `default-deny`
```yaml
spec:
podSelector: {}
policyTypes:
- Ingress
```
## Solution & Options
* Provisioning service to have a strategy to join the namespace
* managed by **ANSIBLE_TOWER**
* Use existing implementation, in which the join namespace can be bidirectional/uni-directional depending on current configuration
* managed by **OPENSHIFT**
* Creating new object into the namespace to apply network policy during join namespace
* We will still create 2 network policy, one is from the short lived namespace and another one in the long lived namespace
* On the creation of network policy, the main policy should be from the shorter lived namespace.
* Provisioning service will track the joined namespace
* Refer to the following policy example to be autogenerated by provisioning service on the source namespace of join namespace
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: da-saas-dev
egress:
- to:
- namespaceSelector:
matchLabels:
name: da-saas-dev
```
* When the namespace get deleted, the network policy will also be deleted naturally.
## Appendix
### Example of NetworkPolicy
```yaml=
apiVersion: v1
kind: Namespace
metadata:
name: dono-test-1
labels:
networking/name: dono-test-1
---
apiVersion: v1
kind: Pod
metadata:
name: app-1
namespace: dono-test-1
labels:
name: app-1
spec:
containers:
- name: app-1
image: joshrosso/nginx-curl:v2
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "128Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: app-1
namespace: dono-test-1
spec:
ports:
- port: 80
targetPort: 80
name: http
protocol: TCP
selector:
name: app-1
```
```yaml=
apiVersion: v1
kind: Namespace
metadata:
name: dono-test-2
labels:
networking/name: dono-test-2
---
apiVersion: v1
kind: Pod
metadata:
name: app-2
namespace: dono-test-2
labels:
name: app-2
spec:
containers:
- name: app-2
image: joshrosso/nginx-curl:v2
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "128Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: app-2
namespace: dono-test-2
spec:
ports:
- port: 80
targetPort: 80
name: http
protocol: TCP
selector:
name: app-2
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-interaction-to-dono-test-1
namespace: dono-test-2
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: dono-test-1
egress:
- to:
- namespaceSelector:
matchLabels:
name: dono-test-1
```