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

Automatically provision personal namespace #95

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gbenhaim
Copy link
Member

Extend Workspace manager to support automatic provisioning of personal namespaces.

The name of the namespace to create will be calculated from the user name, which is expected to be an email address.

The user that namespace is created for will get konflux-admin permissions on the namespace.

The implementation is idempotent.

This feature should be turned on using environment variables.

This change also adds an additional test suite. In order to run it at the same time with the existing test suite (the default of go test), allow to use different ports for workspace-manager.

In order to use the fakeclient provided by controller-runtime, its version was updated.

Extend Workspace manager to support automatic provisioning
of personal namespaces.

The name of the namespace to create will be calculated from the
user name, which is expected to be an email address.

The user that namespace is created for will get konflux-admin
permissions on the namespace.

The implementation is idempotent.

This feature should be turned on using environment variables.

This change also adds an additional test suite. In order to run
it at the same time with the existing test suite (the default of
go test), allow to use different ports for workspace-manager.

In order to use the fakeclient provided by controller-runtime,
its version was updated.

Signed-off-by: gbenhaim <[email protected]>
@gbenhaim
Copy link
Member Author

@filariow this is a temporary solution until it would be possible to create namespace through the UI. It would be removed when the UI adds support for creating namespaces.
It's needed by the Fedora Konflux deployment where there was a request to create a namespace for each user that logs in.


func normalizeEmail(email string) string {
ret := strings.Replace(email, "@", "-", -1)
ret = strings.Replace(ret, "+", "-", -1)
Copy link
Member

Choose a reason for hiding this comment

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

Any concern that users with different emails will get the same normalized email? e.g. [email protected] and [email protected] (or users with very long emails that start the same)

Choose a reason for hiding this comment

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

I agree that this may be a concern long term. The alternatives I can think of to avoid collisions will lead to ugly namespace names and/or break idempotency, like appending a kubernetes generated suffix or using IdP's user Id.

What if we allow the user to define the namespace name instead? We'll break idempotency, but we'll also avoid collisions. We should also implement a quota mechanism, that can be very simple for now: we can store the user email (or email hash to be RFC1123 compliant) in an annotation/label. In the create endpoint we can check that the user has not already created a namespace by checking this annotation/label on existing namespaces.

UserIdAnnotation string = "konflux-ci.dev/requester-user-id"
)

func normalizeEmail(email string) string {
Copy link
Member

Choose a reason for hiding this comment

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

I think the function name is misleading. It returns the namespace name rather than just normalizing the email.


err = nsp.k8sClient.Create(c.Request().Context(), rb)
if errors.IsAlreadyExists(err) {
c.Logger().Warn("Role binding for the initial admin already exists.")
Copy link
Member

Choose a reason for hiding this comment

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

Suppose that 2 users share the same normalized email, the second user will get no access to the workspace (which is good), but will also not get indication for that. I think this might not be an issue, but maybe we should take a note of that or something.

)

var _ = DescribeTable(
"Test CheckNSExistHandler",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Test CheckNSExistHandler",
"Test CreateNSHandler",

Comment on lines +216 to +219
port := "5000"
if val, ok := os.LookupEnv("WM_HTTP_PORT"); ok {
port = val
}

Choose a reason for hiding this comment

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

If you like this can be simplified as

Suggested change
port := "5000"
if val, ok := os.LookupEnv("WM_HTTP_PORT"); ok {
port = val
}
// import "cmp"
// const defaultHttpPort = "5000"
port := cmp.Or(os.Getenv("WM_HTTP_PORT"), defaultHttpPort)

Comment on lines +6 to +7
var NotSignedUp SignupStatusReason = "NotSignedUp"
var UnknownSignUpStatus SignupStatusReason = "Unknown"

Choose a reason for hiding this comment

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

If I'm not mistaken we could use const here

Suggested change
var NotSignedUp SignupStatusReason = "NotSignedUp"
var UnknownSignUpStatus SignupStatusReason = "Unknown"
const NotSignedUp SignupStatusReason = "NotSignedUp"
const UnknownSignUpStatus SignupStatusReason = "Unknown"


func normalizeEmail(email string) string {
ret := strings.Replace(email, "@", "-", -1)
ret = strings.Replace(ret, "+", "-", -1)

Choose a reason for hiding this comment

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

I agree that this may be a concern long term. The alternatives I can think of to avoid collisions will lead to ugly namespace names and/or break idempotency, like appending a kubernetes generated suffix or using IdP's user Id.

What if we allow the user to define the namespace name instead? We'll break idempotency, but we'll also avoid collisions. We should also implement a quota mechanism, that can be very simple for now: we can store the user email (or email hash to be RFC1123 compliant) in an annotation/label. In the create endpoint we can check that the user has not already created a namespace by checking this annotation/label on existing namespaces.

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.

3 participants