Skip to content

Commit

Permalink
Merge branch 'master' into kubesaw170_restart
Browse files Browse the repository at this point in the history
  • Loading branch information
fbm3307 authored Sep 13, 2024
2 parents da57803 + 1fbffd4 commit aeef8de
Show file tree
Hide file tree
Showing 31 changed files with 294 additions and 595 deletions.
23 changes: 17 additions & 6 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ NAME USERNAME COMPLETE REASON COMPLIANTUSERNAME
```
The first column is the name of the `UserSignup` resource.

To look-up a UserSignup resource from the user's email address, run:
To look up a UserSignup resource from the user's email address, run:
in Linux:
```
ksctl get -t host usersignups -l toolchain.dev.openshift.com/email-hash=`echo -n <email_address> | md5sum | cut -d ' ' -f 1`
Expand All @@ -71,7 +71,7 @@ ksctl get -t host usersignups -l toolchain.dev.openshift.com/email-hash=`echo -n

=== Approving a user

To approve user, either use the user's email:
To approve a user, either use the user's email:
```
$ ksctl approve --email <user_email>
```
Expand All @@ -81,7 +81,7 @@ or <<find_usersignup_name,get the UserSignup name>>, and then run:
$ ksctl approve --name <usersignup_name>
```

WARNING: By default, the `approve` command checks if the user already initiated the phone verification process. To skip this check for the users or environments where the a phone verification is not required, use the `--skip-phone-check` flag.
WARNING: By default, the `approve` command checks if the user has already initiated the phone verification process. To skip this check for the users or environments where the phone verification is not required, use the `--skip-phone-check` flag.

The command will print out additional information about the `UserSignup` resource to be approved and it will also ask for a confirmation.

Expand Down Expand Up @@ -110,17 +110,17 @@ The command will print out additional information about the `UserSignup` resourc

=== Banning a user

To ban a user so the account is deprovisioned and the user is not able to sign up again, use the `ban` command. First <<find_usersignup_name,get the UserSignup name>>, then run:
To ban a user which in turn de-provisions the account and doesn't allow the user to sign up again, use the `ban` command. First <<find_usersignup_name,get the UserSignup name>>, second <<reason of the ban>>, then run:

```
$ ksctl ban <usersignup_name>
$ ksctl ban <usersignup_name> <ban_reason>
```

The command will print out additional information about the `UserSignup` resource to be banned and it will also ask for a confirmation.

=== Creating an Event

Social Events are a feature allowing users to sign up without having to go through the phone verification process. This is useful when running labs or workshops, as it lets attendees get up and running quickly without having to fulfil all the requirements of the standard signup process.
Social Events are a feature allowing users to sign up without having to go through the phone verification process. This is useful when running labs or workshops, as it lets attendees to get up and run it quickly without having to fulfill all the requirements of the standard sign up process.

Social Events are temporary in nature; creating an event will produce a unique activation code that may be used for a predefined period of time, after which the code will no longer work.

Expand Down Expand Up @@ -197,6 +197,17 @@ serviceAccounts:

For each ServiceAccount defined in this section, the `ksctl generate cli-configs` generates a separate `ksctl.yaml` file with the corresponding cluster configuration and tokens. As an administrator of the clusters, run this command and distribute securely the generated `ksctl.yaml` files to other team members.

====== Testing the `ksctl generate cli-configs` command locally
1. Run `make install`
2. Create `kubesaw-admins.yaml` (as an example, check link:test-resources/dummy.openshiftapps.com/kubesaw-admins.yaml[kubesaw-admins.yaml])
3. Run `ksctl generate admin-manifests --kubesaw-admins <path>/kubesaw-admins.yaml --out-dir <admin-manifests-out-dir-path>`
4. Create resources from the `<admin-manifests-out-dir-path>` of the previous command. Please, note that you will need to create some namespaces manually (`oc create ns <namespace-name>`), such as `sandbox-sre-host`, `first-component`, `second-component`, `some-component`, `sandbox-sre-member`, and `crw`, for example.
- Run `oc apply -k <admin-manifests-out-dir-path>/host`
- Run `oc apply -k <admin-manifests-out-dir-path>/member`
- Run `oc apply -k <admin-manifests-out-dir-path>/member-3`
5. Run `ksctl generate cli-configs -k <kubeconfig-path> -c <path>/kubesaw-admins.yaml`


==== Users

The `ksctl` command can generate The `users` section contains definition for users, identities, and the permissions granted to them.
Expand Down
4 changes: 2 additions & 2 deletions cmd/user-identity-mapper/user_identity_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ func CreateUserIdentityMappings(ctx context.Context, logger *log.Logger, cl runt
logger.Info("listing users...")
users := &userv1.UserList{}
if err := cl.List(ctx, users, runtimeclient.MatchingLabels{
"provider": "sandbox-sre",
"provider": "ksctl",
}); err != nil {
return fmt.Errorf("unable to list users: %w", err)
}
for _, user := range users.Items {
logger.Info("listing identities", "username", user.Name)
identities := userv1.IdentityList{}
if err := cl.List(ctx, &identities, runtimeclient.MatchingLabels{
"provider": "sandbox-sre",
"provider": "ksctl",
"username": user.Name,
}); err != nil {
return fmt.Errorf("unable to list identities: %w", err)
Expand Down
16 changes: 8 additions & 8 deletions cmd/user-identity-mapper/user_identity_mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func TestUserIdentityMapper(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "user1",
Labels: map[string]string{
"provider": "sandbox-sre",
"provider": "ksctl",
},
},
}
identity1 := &userv1.Identity{
ObjectMeta: metav1.ObjectMeta{
Name: "identity1",
Labels: map[string]string{
"provider": "sandbox-sre",
"provider": "ksctl",
"username": "user1",
},
},
Expand All @@ -46,30 +46,30 @@ func TestUserIdentityMapper(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "user2",
Labels: map[string]string{
"provider": "sandbox-sre",
"provider": "ksctl",
},
},
}
identity2 := &userv1.Identity{
ObjectMeta: metav1.ObjectMeta{
Name: "identity2",
Labels: map[string]string{
"provider": "sandbox-sre",
"provider": "ksctl",
"username": "user2",
},
},
}
user3 := &userv1.User{
ObjectMeta: metav1.ObjectMeta{
Name: "user3",
// not managed by sandbox-sre
// not managed by ksctl
},
}
identity3 := &userv1.Identity{
ObjectMeta: metav1.ObjectMeta{
Name: "identity3",
Labels: map[string]string{
"provider": "sandbox-sre",
"provider": "ksctl",
"username": "user3",
},
},
Expand All @@ -88,7 +88,7 @@ func TestUserIdentityMapper(t *testing.T) {
require.NoError(t, err)
assert.NotContains(t, out.String(), "unable to list identities")
uim := &userv1.UserIdentityMapping{}
// `user1` and `user2` are not managed by sandbox (ie, labelled with `provider: sandbox-sre`), hence the `UserIdentityMappings` exist
// `user1` and `user2` are not managed by ksctl (ie, labelled with `provider: ksctl`), hence the `UserIdentityMappings` exist
require.NoError(t, cl.Get(context.TODO(), types.NamespacedName{Name: identity1.Name}, uim))
assert.Equal(t, identity1.Name, uim.Identity.Name)
assert.Equal(t, user1.Name, uim.User.Name)
Expand All @@ -111,7 +111,7 @@ func TestUserIdentityMapper(t *testing.T) {
// then
require.NoError(t, err)
assert.NotContains(t, out.String(), "unable to list identities")
// `user3` is not managed by sandbox (ie, not labelled with `provider: sandbox-sre`), , hence the `UserIdentityMappings` does not exist
// `user3` is not managed by ksctl (ie, not labelled with `provider: ksctl`), , hence the `UserIdentityMappings` does not exist
require.EqualError(t, cl.Get(context.TODO(), types.NamespacedName{Name: identity3.Name}, &userv1.UserIdentityMapping{}), `useridentitymappings.user.openshift.io "identity3" not found`)
})

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/kubesaw/ksctl
go 1.20

require (
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded
github.com/codeready-toolchain/toolchain-common v0.0.0-20240911094752-38ba816bff59
github.com/ghodss/yaml v1.0.0
github.com/mitchellh/go-homedir v1.1.0
// using latest commit from 'github.com/openshift/api branch release-4.12'
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27 h1:uEH8HAM81QZBccuqQpGKJUoJQe28+DFSYi/mRKZDYrA=
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a h1:o18wLp3eT4HdH8TvDqtLWiC47WY/kaTp9p54exux/MU=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a/go.mod h1:aIbki5CFsykeqZn2/ZwvUb3Krx2f2Tbq58R6MGnk6H8=
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded h1:AZdMwBPoT96Sze2AMR7N10dXIAMVxuM8CMuCSZxjQOY=
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240911094752-38ba816bff59 h1:/Z5NNPZvHKg0Zzyj6fdQjQNtKrgXkY91tWiHr7XgAEQ=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240911094752-38ba816bff59/go.mod h1:kENp9EMqJaoZNvM3BLTk/i+CEteHKrJRAAm0H7L8Z+A=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
Expand Down
7 changes: 5 additions & 2 deletions pkg/assets/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ objects:
metadata:
name: get-catalogsources
labels:
provider: sandbox-sre
provider: ksctl
rules:
- apiGroups:
- operators.coreos.com
Expand All @@ -47,7 +47,7 @@ objects:
metadata:
name: get-deployments
labels:
provider: sandbox-sre
provider: ksctl
rules:
- apiGroups:
- apps
Expand Down Expand Up @@ -110,6 +110,9 @@ func TestGetKubeSawAdmins(t *testing.T) {
assert.NotEmpty(t, member.API)
}

assert.Equal(t, "host-sre-namespace", kubeSawAdmins.DefaultServiceAccountsNamespace.Host)
assert.Equal(t, "member-sre-namespace", kubeSawAdmins.DefaultServiceAccountsNamespace.Member)

assert.NotEmpty(t, kubeSawAdmins.ServiceAccounts)
for _, sa := range kubeSawAdmins.ServiceAccounts {
assert.NotEmpty(t, sa.Name)
Expand Down
14 changes: 11 additions & 3 deletions pkg/assets/sandbox_config.go → pkg/assets/kubesaw-admins.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package assets

type KubeSawAdmins struct {
Clusters Clusters `yaml:"clusters"`
ServiceAccounts []ServiceAccount `yaml:"serviceAccounts"`
Users []User `yaml:"users"`
Clusters Clusters `yaml:"clusters"`
ServiceAccounts []ServiceAccount `yaml:"serviceAccounts"`
Users []User `yaml:"users"`
DefaultServiceAccountsNamespace DefaultServiceAccountsNamespace `yaml:"defaultServiceAccountsNamespace"`
}

type Clusters struct {
Expand All @@ -24,6 +25,13 @@ type ClusterConfig struct {
API string `yaml:"api"`
}

// DefaultServiceAccountsNamespace defines the names of the default namespaces where the ksctl SAs should be created.
// If not specified, then the names kubesaw-admins-host and kubesaw-admins-member are used.
type DefaultServiceAccountsNamespace struct {
Host string `yaml:"host"`
Member string `yaml:"member"`
}

type ServiceAccount struct {
Name string `yaml:"name"`
Namespace string `yaml:"namespace,omitempty"`
Expand Down
10 changes: 5 additions & 5 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,14 @@ func TestCreate(t *testing.T) {
namespacedName := commontest.NamespacedName("openshift-customer-monitoring", "openshift-customer-monitoring")
fakeClient := commontest.NewFakeClient(t)
term := NewFakeTerminalWithResponse("Y")
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "sandbox-sre"})
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "ksctl"})

// when
err := client.Create(term, fakeClient, operatorGroup)

// then
require.NoError(t, err)
AssertOperatorGroupHasLabels(t, fakeClient, namespacedName, map[string]string{"provider": "sandbox-sre"})
AssertOperatorGroupHasLabels(t, fakeClient, namespacedName, map[string]string{"provider": "ksctl"})
output := term.Output()
assert.Contains(t, output, "The 'openshift-customer-monitoring/openshift-customer-monitoring' OperatorGroup has been created")
})
Expand All @@ -370,7 +370,7 @@ func TestCreate(t *testing.T) {
namespacedName := commontest.NamespacedName("openshift-customer-monitoring", "openshift-customer-monitoring")
fakeClient := commontest.NewFakeClient(t, newOperatorGroup(namespacedName, map[string]string{"provider": "osd"}))
term := NewFakeTerminalWithResponse("Y")
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "sandbox-sre"})
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "ksctl"})

// when
err := client.Create(term, fakeClient, operatorGroup)
Expand All @@ -390,7 +390,7 @@ func TestCreate(t *testing.T) {
}
term := NewFakeTerminalWithResponse("Y")
namespacedName := commontest.NamespacedName("openshift-customer-monitoring", "openshift-customer-monitoring")
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "sandbox-sre"})
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "ksctl"})

// when
err := client.Create(term, fakeClient, operatorGroup)
Expand All @@ -408,7 +408,7 @@ func TestCreate(t *testing.T) {
}
term := NewFakeTerminalWithResponse("Y")
namespacedName := commontest.NamespacedName("openshift-customer-monitoring", "openshift-customer-monitoring")
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "sandbox-sre"})
operatorGroup := newOperatorGroup(namespacedName, map[string]string{"provider": "ksctl"})

// when
err := client.Create(term, fakeClient, operatorGroup)
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions pkg/cmd/adm/must_gather_namespace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestMustGatherNamespaceCmd(t *testing.T) {
t.Run("ok", func(t *testing.T) {
t.Run("create the dest-dir on-the-fly", func(t *testing.T) {
// given
baseDir, err := os.MkdirTemp("", "sandbox-sre-out-")
baseDir, err := os.MkdirTemp("", "ksctl-out-")
require.NoError(t, err)
destDir := filepath.Join(baseDir, "test-dev")

Expand All @@ -51,7 +51,7 @@ func TestMustGatherNamespaceCmd(t *testing.T) {

t.Run("dest-dir already exists and is empty", func(t *testing.T) {
// given
baseDir, err := os.MkdirTemp("", "sandbox-sre-out-")
baseDir, err := os.MkdirTemp("", "ksctl-out-")
require.NoError(t, err)
destDir := filepath.Join(baseDir, "test-dev")
err = os.Mkdir(destDir, 0755)
Expand All @@ -71,7 +71,7 @@ func TestMustGatherNamespaceCmd(t *testing.T) {

t.Run("dest-dir already exists but is not empty", func(t *testing.T) {
// given
baseDir, err := os.MkdirTemp("", "sandbox-sre-out-")
baseDir, err := os.MkdirTemp("", "ksctl-out-")
require.NoError(t, err)
destDir := filepath.Join(baseDir, "test-dev")
err = os.Mkdir(destDir, 0755)
Expand Down
15 changes: 8 additions & 7 deletions pkg/cmd/ban.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import (

func NewBanCmd() *cobra.Command {
return &cobra.Command{
Use: "ban <usersignup-name>",
Short: "Ban a user for the given UserSignup resource",
Use: "ban <usersignup-name> <ban-reason>",
Short: "Ban a user for the given UserSignup resource and reason of the ban",
Long: `Ban the given UserSignup resource. There is expected
only one parameter which is the name of the UserSignup to be used for banning`,
Args: cobra.ExactArgs(1),
only two parameters which the first one is the name of the UserSignup to be used for banning
and the second one the reason of the ban`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
term := ioutils.NewTerminal(cmd.InOrStdin, cmd.OutOrStdout)
ctx := clicontext.NewCommandContext(term, client.DefaultNewClient)
Expand All @@ -29,7 +30,7 @@ only one parameter which is the name of the UserSignup to be used for banning`,
}

func Ban(ctx *clicontext.CommandContext, args ...string) error {
return CreateBannedUser(ctx, args[0], func(userSignup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return CreateBannedUser(ctx, args[0], args[1], func(userSignup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
if _, exists := bannedUser.Labels[toolchainv1alpha1.BannedUserPhoneNumberHashLabelKey]; !exists {
ctx.Printlnf("\nINFO: The UserSignup doesn't have the label '%s' set, so the resulting BannedUser resource won't have this label either.\n",
toolchainv1alpha1.BannedUserPhoneNumberHashLabelKey)
Expand All @@ -46,7 +47,7 @@ func Ban(ctx *clicontext.CommandContext, args ...string) error {
})
}

func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName string, confirm func(*toolchainv1alpha1.UserSignup, *toolchainv1alpha1.BannedUser) (bool, error)) error {
func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName, banReason string, confirm func(*toolchainv1alpha1.UserSignup, *toolchainv1alpha1.BannedUser) (bool, error)) error {
cfg, err := configuration.LoadClusterConfig(ctx, configuration.HostName)
if err != nil {
return err
Expand All @@ -66,7 +67,7 @@ func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName string, con
return err
}

bannedUser, err := banneduser.NewBannedUser(userSignup, ksctlConfig.Name)
bannedUser, err := banneduser.NewBannedUser(userSignup, ksctlConfig.Name, banReason)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit aeef8de

Please sign in to comment.