-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Control API Architecture #59
Changes from all commits
8ab4ead
08f98d9
af5f93f
ec40239
729ea79
c6815b1
83e1762
e906c28
18d3542
a1d80bd
b4185a4
7363070
aa2c407
e040487
448cebd
a3f20e9
04192ca
8846521
87be13b
c0f4d58
501b491
eda5ff8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
= {controlapi}: Organization | ||
|
||
TIP: This resource implements the xref:references/functional-requirements.adoc#_feature_manage_organizations["Manage Organizations"] features. | ||
|
||
To circumvent the current limitation of the Kubernetes API to show filtered lists of cluster-scoped resources based on access rights, `Organization` is a virtual resource. | ||
|
||
It represents a filtered and formatted list of standard Kubernetes `Namespace` resources which have specific labels and annotations. | ||
|
||
It is assumed that the resource `appuio.io/v1/Organization` is used for all operations (create, list, read, update, delete). | ||
|
||
== Object | ||
|
||
.Virtual resource | ||
[source,yaml] | ||
---- | ||
apiVersion: appuio.io/v1 | ||
kind: Organization | ||
metadata: | ||
name: acme-corp <1> | ||
spec: | ||
displayName: Acme Corp. <2> | ||
---- | ||
<1> `metadata.name` from the `Namespace` without the `org`-prefix | ||
<2> Replicates `metadata.annotations.[organization.appuio.io/displayName]` from the `Namespace` | ||
|
||
.Original resource | ||
[source,yaml] | ||
---- | ||
apiVersion: v1 | ||
kind: Namespace | ||
metadata: | ||
name: org-acme-corp <1> | ||
labels: | ||
appuio.io/resource-type: organization <2> | ||
annotations: | ||
organization.appuio.io/displayName: Acme Corp. <3> | ||
---- | ||
<1> Prefixed (`org`) name to circumvent possible name collision (e.g. if a company is called "kube-system") | ||
<2> Identify resource type, used by the API server to filter for namespace representing organizations | ||
<3> Reflected in the organization object as `spec.displayName` | ||
|
||
== Labels and Annotations | ||
|
||
[cols="2,1,1,3",options="header"] | ||
|=== | ||
|Name | ||
|Type | ||
|Resource | ||
|Description | ||
|
||
|`appuio.io/resource-type` | ||
|label | ||
|`v1/Namespace` | ||
|Identifies the resource type in the scope of the {controlapi} | ||
|
||
|`organization.appuio.io/displayName` | ||
|annotation | ||
|`appuio.io/v1/Organization` | ||
|Display name of the organization | ||
|
||
|=== | ||
|
||
== Resource filter | ||
|
||
The virtual resource is a filtered view on `Namespaces`. | ||
The filter uses the following heuristic: | ||
|
||
* Resource kind = v1/Namespace | ||
* label[appuio.io/resource-type] = organization | ||
* subject is bound to one of the defined `ClusterRole` resources. | ||
|
||
== RBAC rules | ||
|
||
These are `ClusterRole` resources which are bound to a subject by a namespaced `RoleBinding`: | ||
|
||
`org-view`:: View (read only) access to an organization | ||
`org-admin`:: Admin (read / write) access to an organization | ||
|
||
Creating organizations can be done by all authenticated users. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
= {controlapi}: Team | ||
|
||
TIP: This resource implements the xref:references/functional-requirements.adoc#_feature_manage_teams["Manage Teams"] features. | ||
|
||
== Object | ||
|
||
[source,yaml] | ||
---- | ||
apiVersion: appuio.io/v1 | ||
kind: Team | ||
metadata: | ||
name: myteam1 | ||
namespace: org-acme-corp | ||
spec: | ||
userRefs: <1> | ||
- max-muster | ||
- demo-user | ||
---- | ||
<1> References to one or more `User` objects |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
= {controlapi}: User | ||
|
||
TIP: This resource implements the xref:references/functional-requirements.adoc#_feature_personal_settings_per_user["Personal Settings per User"] feature. | ||
|
||
== Object | ||
|
||
[source,yaml] | ||
---- | ||
apiVersion: appuio.io/v1 | ||
kind: User | ||
metadata: | ||
name: demo-max | ||
spec: | ||
defaultOrganizationRef: acme-corp <1> | ||
---- | ||
<1> Reference to an `Organization` object |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
= {controlapi}: Zone | ||
|
||
TIP: This resource implements the xref:references/functional-requirements.adoc#_feature_zones["Manage Zones"] features. | ||
|
||
== Object | ||
|
||
[source,yaml] | ||
---- | ||
apiVersion: appuio.io/v1 | ||
kind: Zone | ||
metadata: | ||
name: cloudscale-lpg-0 | ||
spec: | ||
displayName: cloudscale.ch LPG 0 <1> | ||
status: <2> | ||
features: | ||
openshift-version: "4.8" | ||
kubernetes-version: "1.21" | ||
sdn: OVN-Kubernetes | ||
console-url: https://console.cloudscale-lpg-0.appuio.cloud/ | ||
kubernetes-api-url: https://api.cloudscale-lpg-0.appuio.cloud:6443/ | ||
---- | ||
<1> {product} instance specific name | ||
<2> Provided by adapter, e.g. by https://syn.tools/[Project Syn Lieutenant] |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,78 @@ | ||||||
= {controlapi} Architecture | ||||||
|
||||||
This page describes the xref:references/glossary.adoc#_control_api[{controlapi}]. | ||||||
It adheres to the decision taken in xref:explanation/decisions/control-api.adoc[{controlapi}] and it follows the features asked in xref:references/functional-requirements.adoc[Functional Requirements]. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
== General Principles | ||||||
|
||||||
Kubernetes API:: | ||||||
The Control API is built upon the Kubernetes API and adheres to it's https://kubernetes.io/docs/reference/kubernetes-api/[design principles]. | ||||||
|
||||||
API object field: `.status`:: | ||||||
The `status` field (also called https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource["Status subresource"]) represents the current observed state and external information. | ||||||
It is read-only to the end-user. | ||||||
|
||||||
API object field: `.spec`:: | ||||||
The `spec` field contains the desired state for reconciliation. | ||||||
|
||||||
== Virtual vs. CRD based resources | ||||||
|
||||||
Some resources are not persisted to etcd and are only available _virtually_, others are persisted to etcd and are defined and represented via `CustomResourceDefinition` (CRDs). | ||||||
|
||||||
Virtual resources are accessible via an https://kubernetes.io/docs/tasks/extend-kubernetes/setup-extension-api-server/[API Server Extension]. | ||||||
These resources are similar to views in a relational database. | ||||||
The benefit of providing these resources instead of only using CRDs is that we can calculate access permissions dynamically for every request. | ||||||
The same concept is also used by OpenShift with its `Project` resource which represents RBAC filtered `Namespaces` (see https://github.com/openshift/kube-projects[kube-projects]). | ||||||
And we can also find it in https://github.com/loft-sh/kiosk[Kiosk] for example. | ||||||
|
||||||
== Authentication and Authorization | ||||||
|
||||||
Authentication against the API server is done by the {idp}. | ||||||
It's always the same subject (user) which is being used throughout the whole {product} ecosystem. | ||||||
|
||||||
For authorization, standard https://kubernetes.io/docs/reference/access-authn-authz/rbac/[Kubernetes RBAC] is being used. | ||||||
Kyverno policies can be used to implement enhanced policies, for example the number of resources of a specified kind a user is allowed to create. | ||||||
|
||||||
There are several layers of authorization: | ||||||
|
||||||
* Kubernetes RBAC | ||||||
* Kyverno policies | ||||||
* Virtual resources with filtering | ||||||
|
||||||
== Resource Scopes | ||||||
|
||||||
Resources on the Kubernetes API server can either be https://kubernetes.io/docs/reference/using-api/api-concepts/#standard-api-terminology[cluster scoped or namespace scoped]. | ||||||
|
||||||
Each {controlapi} instance is represented by one Kubernetes API server instance. | ||||||
This allows us to leverage the scoping concept of the Kubernetes API server to reflect the scopes in the {product} domain. | ||||||
Also, by doing it that way, standard Kubernetes RBAC rules can be used for permission handling on an organization level. | ||||||
|
||||||
{global} resources are available on the Kubernetes global scope (no namespace) whereas organization level resources are namespace scoped. | ||||||
|
||||||
Global:: Kubernetes cluster global resource. | ||||||
Organization:: Kubernetes namespaced resource. | ||||||
|
||||||
== Resources | ||||||
|
||||||
[cols="1,1,2",options="header"] | ||||||
|=== | ||||||
|Name | ||||||
|Scope | ||||||
|Type | ||||||
|
||||||
|xref:references/architecture/control-api-org.adoc[Organization] | ||||||
|Global | ||||||
|Virtual (represents filtered `Namespace` resources) | ||||||
|
||||||
|xref:references/architecture/control-api-user.adoc[User] | ||||||
|Global | ||||||
|CRD | ||||||
|
||||||
|xref:references/architecture/control-api-team.adoc[Team] | ||||||
|Organization | ||||||
|CRD | ||||||
|
||||||
|xref:references/architecture/control-api-zone.adoc[Zone] | ||||||
|Global | ||||||
|CRD | ||||||
|=== |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
= Functional Requirements | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This page already exists in |
||
|
||
This page discusses functional requirements. | ||
It currently mainly targets the Control API and the {product} Portal. | ||
|
||
== Feature: Authentication | ||
|
||
> As a xref:references/glossary.adoc#_user[User] + | ||
> I want to only login once to the {product} ecosystem + | ||
> So that I can use strong authentication methods and still get a good user experience | ||
|
||
*Scenarios* | ||
|
||
* Login | ||
* Logout | ||
|
||
== Feature: Manage Organizations | ||
|
||
> As a xref:references/glossary.adoc#_user[User] + | ||
> I want to manage organizations + | ||
> So that I can group resources under it | ||
|
||
*Scenarios* | ||
|
||
* Create Organization | ||
* List Organizations | ||
* Edit Organization | ||
* Delete Organization | ||
* Invite User to Organization | ||
* Join Organization | ||
|
||
_Implementation: xref:references/architecture/control-api-org.adoc[APPUiO Control API: Organization]._ | ||
|
||
== Feature: Manage Teams | ||
|
||
> As an xref:references/glossary.adoc#_organization-owner[Organization Owner] + | ||
> I want to manage teams in an organization + | ||
> So that I can group users under it for easier permission management | ||
|
||
*Scenarios* | ||
|
||
* Create Team | ||
* List Teams | ||
* Edit Team | ||
* Delete Team | ||
* Add User to Team | ||
* Remove User from Team | ||
|
||
_Implementation: xref:references/architecture/control-api-team.adoc[APPUiO Control API: Team]._ | ||
|
||
== Feature: Zones | ||
|
||
> As a xref:references/glossary.adoc#_user[User] + | ||
> I want to see all available {zone}s + | ||
> So that I know of them | ||
|
||
*Scenarios* | ||
|
||
* List {zone}s | ||
|
||
_Implementation: xref:references/architecture/control-api-zone.adoc[APPUiO Control API: Zone]._ | ||
|
||
== Feature: Personal Settings per User | ||
|
||
> As a xref:references/glossary.adoc#_user[User] + | ||
> I want to configure my personal settings + | ||
> So that I can have my defaults configured to my liking | ||
|
||
*Scenarios* | ||
|
||
* Default Organization | ||
|
||
_Implementation: xref:references/architecture/control-api-user.adoc[APPUiO Control API: User]._ | ||
|
||
== Feature: Branding | ||
|
||
> As an xref:references/glossary.adoc#_instance_owner[Instance Owner] + | ||
> I want to provide a familiar feeling to the user when using the web application | ||
> So that I can have a consistent feeling throughout my offering | ||
|
||
*Scenarios* | ||
|
||
* Logo | ||
* Colors | ||
* Navigation | ||
* Naming | ||
|
||
== Feature: Permissions | ||
|
||
> As a xref:references/glossary.adoc#_user[User] + | ||
> I want to only see what I can really do according to my permissions + | ||
> So that I don't get confused by actions which I'm not allowed to | ||
|
||
*Scenarios* | ||
|
||
* List resources | ||
* Create resources | ||
* Update resources | ||
* Delete resources |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,13 @@ | |
** xref:appuio-cloud:ROOT:references/architecture/namespace-ownership.adoc[Namespace ownership] | ||
** xref:appuio-cloud:ROOT:references/architecture/metering.adoc[Metering of resource usage] | ||
** xref:appuio-cloud:ROOT:references/architecture/metrics-of-interest.adoc[Metrics of interest] | ||
** xref:appuio-cloud:ROOT:references/architecture/control-api.adoc[Control API] | ||
*** xref:appuio-cloud:ROOT:references/architecture/control-api-org.adoc[Organization] | ||
*** xref:appuio-cloud:ROOT:references/architecture/control-api-user.adoc[User] | ||
*** xref:appuio-cloud:ROOT:references/architecture/control-api-team.adoc[Team] | ||
*** xref:appuio-cloud:ROOT:references/architecture/control-api-zone.adoc[Zone] | ||
|
||
* xref:appuio-cloud:ROOT:references/functional-requirements.adoc[Functional Requirements] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This link is probably also outdated |
||
|
||
* Functional Requirements | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are watches and patches not supported?