Skip to content

Commit b069649

Browse files
Proposal for Cluster identity (#204)
1 parent cad9972 commit b069649

File tree

1 file changed

+186
-0
lines changed

1 file changed

+186
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
---
2+
title: Cluster Level Identity(aka Multitenancy support)
3+
authors:
4+
- "@shyamradhakrishnan"
5+
- "@joekr"
6+
reviewers:
7+
creation-date: 2023-01-18
8+
last-updated: 2023-01-18
9+
status: implementable
10+
see-also:
11+
- https://github.com/oracle/cluster-api-provider-oci/issues/203
12+
replaces: []
13+
---
14+
15+
## Summary
16+
17+
Cluster API Provider for OCI(CAPOCI) supports a single OCI User Principal currently. This
18+
User Principal is [defined during installation][user-principal] and will be refreshed when the CAPOCI pod is
19+
restarted.
20+
Some of the customer scenarios requires support for OCI User Principal defined per cluster. This will help
21+
customers create workload clusters using different OCI User Principals such that a single management cluster can
22+
support a multitenanted architecture.
23+
24+
## Goals
25+
26+
1. To enable OCICluster resources reconciliation use a cluster specific OCI user principal.
27+
2. To maintain backwards compatibility and cause no impact for users who don't intend to make use of
28+
this capability
29+
## Non-goals
30+
31+
1. This proposal does not solve multitenancy across a single cluster, for example, control plane in Tenant A worker
32+
nodes in Tenant B.
33+
34+
## Proposal
35+
36+
### User Stories
37+
38+
#### Story 1 - Use a Cluster specific OCI user principal
39+
40+
A large organization typically consists of many smaller OCI tenancies and compartments. Such a large organization
41+
may run a single Cluster API management cluster in a managed service model by a single team, let us call as Cluster
42+
Ops team. The Cluster Ops team will have their own api or tools for customers to create and operate workload clusters.
43+
Cluster Ops team will want to make sure that individual teams use OCI user principal specific to their organization to
44+
create the workload clusters so that the OCI resources are created in the correct tenancy/compartment and individual
45+
team are not able to create clusters in tenancies or compartments in which they do not have access. In order to achieve
46+
this goal, the Cluster Ops team will not use a single user principal to create all workload clusters, instead, the
47+
individual workload clusters has to be created using OCI user principals tied to individual workload clusters.
48+
49+
### Custom Resource Changes
50+
51+
The following fields will be added to OCIClusterSpec custom resource.
52+
53+
```go
54+
// OCIClusterSpec defines the desired state of OciCluster
55+
type OCIClusterSpec struct {
56+
// IdentityRef is a reference to an identity(principal) to be used when reconciling this cluster
57+
// +optional
58+
IdentityRef *corev1.ObjectReference `json:"identityRef,omitempty"`
59+
}
60+
```
61+
The following custom resources will be added.
62+
63+
```go
64+
65+
type PrincipalType string
66+
67+
const (
68+
// UserPrincipal represents a user princpal.
69+
UserPrincipal PrincipalType = "UserPrincipal"
70+
)
71+
72+
// OCIClusterIdentitySpec defines the parameters that are used to create an OCIIdentity.
73+
type OCIClusterIdentitySpec struct {
74+
// Type is the type of OCI Principal used.
75+
// UserPrincipal is the only supported value
76+
Type PrincipalType `json:"type"`
77+
78+
// PrincipalSecret is a secret reference which contains the authentication credentials for the principal.
79+
// +optional
80+
PrincipalSecret corev1.SecretReference `json:"clientSecret,omitempty"`
81+
82+
// AllowedNamespaces is used to identify the namespaces the clusters are allowed to use the identity from.
83+
// Namespaces can be selected either using an array of namespaces or with label selector.
84+
// An empty allowedNamespaces object indicates that OCIClusters can use this identity from any namespace.
85+
// If this object is nil, no namespaces will be allowed (default behaviour, if this field is not provided)
86+
// A namespace should be either in the NamespaceList or match with Selector to use the identity.
87+
//
88+
// +optional
89+
// +nullable
90+
AllowedNamespaces *AllowedNamespaces `json:"allowedNamespaces"`
91+
}
92+
93+
// AllowedNamespaces defines the namespaces the clusters are allowed to use the identity from
94+
// NamespaceList takes precedence over the Selector.
95+
type AllowedNamespaces struct {
96+
// A nil or empty list indicates that OCICluster cannot use the identity from any namespace.
97+
//
98+
// +optional
99+
// +nullable
100+
NamespaceList []string `json:"list"`
101+
102+
// Selector is a selector of namespaces that OCICluster can
103+
// use this Identity from. This is a standard Kubernetes LabelSelector,
104+
// a label query over a set of resources. The result of matchLabels and
105+
// matchExpressions are ANDed.
106+
//
107+
// A nil or empty selector indicates that OCICluster cannot use this
108+
// OCIClusterIdentity from any namespace.
109+
// +optional
110+
Selector *metav1.LabelSelector `json:"selector"`
111+
}
112+
113+
// OCIClusterIdentityStatus defines the observed state of OCIClusterIdentity.
114+
type OCIClusterIdentityStatus struct {
115+
// Conditions defines current service state of the OCIClusterIdentity.
116+
// +optional
117+
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
118+
}
119+
120+
type OCIClusterIdentity struct {
121+
metav1.TypeMeta `json:",inline"`
122+
metav1.ObjectMeta `json:"metadata,omitempty"`
123+
124+
Spec OCIClusterIdentitySpec `json:"spec,omitempty"`
125+
Status OCIClusterIdentityStatus `json:"status,omitempty"`
126+
}
127+
128+
```
129+
130+
131+
### Example Cluster template
132+
133+
```yaml
134+
---
135+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
136+
kind: OCICluster
137+
spec:
138+
identityRef:
139+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
140+
kind: OCIClusterIdentity
141+
name: <test-identity>
142+
namespace: <test>
143+
---
144+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
145+
kind: OCIClusterIdentity
146+
metadata:
147+
name: test-identity
148+
namespace: test
149+
spec:
150+
type: UserPrincipal
151+
clientSecret:
152+
name: user-credentials
153+
namespace: secret-namespace
154+
allowedNamespaces:
155+
list:
156+
- test
157+
---
158+
apiVersion: v1
159+
kind: Secret
160+
metadata:
161+
name: user-credentials
162+
namespace: secret-namespace
163+
type: Opaque
164+
data:
165+
tenancy: <>
166+
user: <>
167+
passphrase: <> -> optional
168+
key: <>
169+
fingerprint: <>
170+
---
171+
```
172+
173+
### Implementation Details
174+
175+
#### Controller changes
176+
177+
Cluster and machine controller will lookup if the cluster has an associated identity. If an identity exists
178+
OCI clients will be created using the corresponding identity principals. If identity does not exist
179+
the old behaviour of using the CAPOCI pod level OCI identity principals will still be used.
180+
181+
#### Webhook changes
182+
183+
OCICluster validation webhook will be enhanced to add the necessary validations such that
184+
the identityRef kind object is only of supported types(currently only OCIClusterIdentity)
185+
186+
[user-principal]: https://oracle.github.io/cluster-api-provider-oci/gs/install-cluster-api.html#user-principal

0 commit comments

Comments
 (0)