Skip to content
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

Support Groups as Subject Kind for Tenant Namespace RoleBindings created by Capsule #71

Merged

Conversation

MaxFedotov
Copy link
Collaborator

This PR closes #70 and adds additional configuration parameter use-groups-as-tenant-owner which allows Tenant Namespace RoleBindings to be created with "Kind": "Group"

It's completely backward-compatible, as default is set to false.

@bsctl
Copy link
Member

bsctl commented Aug 27, 2020

@MaxFedotov thanks for your interest in Capsule and for pushing this PR.

Should we consider to have a more general approach for the Tenant Ownership.
What about to leave the cluster admin to set the Subject.Kind of the owner by tenant instead of a general setting?

I mean something like this:

apiVersion: capsule.clastix.io/v1alpha1
kind: Tenant
metadata:
  name: oil
spec:
...
 subjectOwner:
   kind: Group
   name: foo

Where the kind can be User, Group, and ServiceAccount too. The latter case can be useful if the tenant owner needs be an application.

Not sure if technically feasible. @prometherion @MaxFedotov what do you think?

@prometherion
Copy link
Member

The main concern I have is upon Namespace creation, since we're using an indexer to speed up the Owner lookup at webhook level.

I need to investigate and check if it's feasible or not, since we have to lookup also per Kind rather than just the name.

@MaxFedotov
Copy link
Collaborator Author

MaxFedotov commented Aug 28, 2020

@prometherion
Copy link
Member

prometherion commented Aug 28, 2020

Exactly, that's a field indexer provided by the related struct

@MaxFedotov
Copy link
Collaborator Author

MaxFedotov commented Aug 28, 2020

@prometherion

I need to investigate and check if it's feasible or not, since we have to lookup also per Kind rather than just the name.

There is a way to do it - kubernetes-sigs/controller-runtime#612 (comment)

in our case we can use function like

func getValue(tenant) string {
   return tenant.Spec.SubjectOwner.Kind+":"+tenant.Spec.SubjectOwner.Name
}

But there is another problem, when https://github.com/clastix/capsule/blob/0f935d53b7acb17379e749a2d64e2f631adb6779/pkg/webhook/owner_reference/patching.go#L84-L93
is called, there is no way to get from req admission.Requestan information about a Kind of TenantOwner.
So first we need get TenantList for User:req.UserInfo.Groups and then if len(req.UserInfo.Groups) > 0 loop through it and for each group try to find TenantList which match Group:group_name and append them.

Btw, according to https://github.com/clastix/capsule/blob/0f935d53b7acb17379e749a2d64e2f631adb6779/pkg/webhook/owner_reference/patching.go#L92

we do not event need to find all tenants, just first one returned (which seems like a bit strange logic, so the namespace is actually assigned to a random tenant, within an owner)

Another way, is to enable by default force-tenant-prefix, which will make looking for TenantList match easier, as we can just get tenant name from Namespace name :)

Or we can combine these two approaches:

  • if force-tenant-prefix is enabled, extract tenantName from Namespace name and do simple lookup. But in this case we need to apply pattern for TenantName, so it doesn't allow -, as it is a separator between TenantName-NamespaceName. And as it is impossible to do via kubebuilder annotations, as Name goes from metav1.ObjectMeta imported struct, so may be we should create a validating webhook which will enforce pattern: ^[a-z0-9]([a-z0-9]*[a-z0-9])?$ for Tenant Name field.
  • if not - find first matching tenant either from User or from Group kind

But my personal vote is for enabling force-tenant-prefix by default, as it will make code more simple and also enforcing naming conventions is obviously a good thing :)

@MaxFedotov
Copy link
Collaborator Author

@prometherion
So what i've done in last commit:

  • Updated Capsule CRD to add support for new struct
type OwnerSpec struct {
	Name string `json:"name"`
	Kind Kind   `json:"kind"`
}
  • Rewritten indexer to support complex Owner field like
tenant.Spec.Owner.Kind.String() + ":" + tenant.Spec.Owner.Name
  • Updated owner_reference webhook with a logic, that I proposed in previous comment

if force-tenant-prefix is enabled, extract tenantName from Namespace name and do simple lookup.
if not - find first matching tenant either from User or from Group kind

  • Added tenant name validation webhook in order to restrict tenant names to only alphanumeric characters, so we will be able to extract tenant from namespace name in owner_reference webhook
  • Created new tests and updated existing to support these changes
  • Updated docs

@prometherion
Copy link
Member

Thanks @MaxFedotov, can't wait for take a look to it.

@bsctl do you think we should version a new API since this breaking change in the contract?

IMO, no need since we haven't yet released a stable version :)

e2e/ingress_class_test.go Show resolved Hide resolved
e2e/force_tenant_prefix_test.go Show resolved Hide resolved
e2e/selecting_tenant_no_label_test.go Outdated Show resolved Hide resolved
e2e/tenant_name_webhook_test.go Show resolved Hide resolved
e2e/tenant_resources_test.go Outdated Show resolved Hide resolved
e2e/utils_test.go Outdated Show resolved Hide resolved
pkg/webhook/owner_reference/patching.go Outdated Show resolved Hide resolved
Copy link
Member

@prometherion prometherion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some typos and more details requests

pkg/webhook/tenant_name/validating.go Outdated Show resolved Hide resolved
pkg/webhook/tenant_name/validating.go Outdated Show resolved Hide resolved
pkg/webhook/tenant_name/validating.go Outdated Show resolved Hide resolved
pkg/webhook/router.go Outdated Show resolved Hide resolved
pkg/webhook/owner_reference/patching.go Outdated Show resolved Hide resolved
e2e/tenant_resources_test.go Outdated Show resolved Hide resolved
@MaxFedotov MaxFedotov force-pushed the user_groups_for_tenant_owners branch from d7dd352 to 9d845b3 Compare September 2, 2020 11:59
@MaxFedotov
Copy link
Collaborator Author

@prometherion
I moved logic of getting Tenant for Namespace from owner_reference webhook to utils package to simplify it's refactoring with #76

@prometherion
Copy link
Member

@MaxFedotov this rebase will be painful, I know :(
If you don't mind, we could try to work on this together: eager to get it merged.

modify crd to support owner struct. add tenant name validation webhook. rewrite owner_reference hook logic. update and add new e2e tests

apply review notes

fix typo in timeout interval

apply review notes

move GetNamespaceTenant logic to utils from webhook

rebase on master. update tests. implement new tenant selection logic for namespace
@MaxFedotov MaxFedotov force-pushed the user_groups_for_tenant_owners branch from 1666f21 to 8e241d0 Compare September 10, 2020 14:07
Copy link
Member

@prometherion prometherion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just check why tests are not green: could be flaky

@prometherion prometherion merged commit 303fc4d into projectcapsule:master Sep 10, 2020
@bsctl bsctl mentioned this pull request Sep 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Group as RoleBinding.Subject.Kind created by Capsule
3 participants