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

OSD-19729: Enables ocm backplane login to provide default namespace as an argument #374

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ In this example, we will login to a cluster with id `123456abcdef` in production
- Run `oc` command to access the target cluster.
```
$ oc whoami
system:serviceaccount:openshift-backplane-srep:1234567
system:serviceaccount:default:1234567
```

- To login to the Management cluster for HyperShift (or) the managing Hive shard of normal OSD/ROSA cluster
Expand Down
32 changes: 28 additions & 4 deletions cmd/ocm-backplane/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"strings"

"github.com/golang-jwt/jwt/v4"
Expand All @@ -33,9 +34,10 @@ const EnvPs1 = "KUBE_PS1_CLUSTER_FUNCTION"

var (
args struct {
multiCluster bool
kubeConfigPath string
pd string
multiCluster bool
kubeConfigPath string
pd string
defaultNamespace string
}

globalOpts = &globalflags.GlobalOptions{}
Expand Down Expand Up @@ -92,6 +94,14 @@ func init() {
"",
"Login using PagerDuty incident id or html_url.",
)
flags.StringVarP(
&args.defaultNamespace,
"namespace",
"n",
"default",
"The default namespace for a user to execute commands in",
)

}

func runLogin(cmd *cobra.Command, argv []string) (err error) {
Expand Down Expand Up @@ -324,7 +334,14 @@ func runLogin(cmd *cobra.Command, argv []string) (err error) {

targetContext.AuthInfo = targetUserNickName
targetContext.Cluster = clusterName
targetContext.Namespace = "default"

if isValidKubernetesNamespace(args.defaultNamespace) {
logger.Debugln("Validating argument passed as namespace")
targetContext.Namespace = args.defaultNamespace
} else {
return fmt.Errorf("%v is not a valid namespace", args.defaultNamespace)
}

targetContextNickName := getContextNickname(targetContext.Namespace, targetContext.Cluster, targetContext.AuthInfo)

// Put user, cluster, context into rawconfig
Expand Down Expand Up @@ -494,3 +511,10 @@ func getBackplaneCNAME(backplaneURL string) (string, error) {
}
return resolution, nil
}

// isValidNamespace validates the input string against Kubernetes namespace rules.( RFC 1123 )
func isValidKubernetesNamespace(namespace string) bool {
// RFC 1123 compliant regex pattern)
pattern := `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
return regexp.MustCompile(pattern).MatchString(namespace)
}
29 changes: 25 additions & 4 deletions cmd/ocm-backplane/login/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import (
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"

cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"

"github.com/openshift/backplane-cli/pkg/backplaneapi"
backplaneapiMock "github.com/openshift/backplane-cli/pkg/backplaneapi/mocks"
"github.com/openshift/backplane-cli/pkg/cli/config"
Expand All @@ -26,6 +22,8 @@ import (
"github.com/openshift/backplane-cli/pkg/ocm"
ocmMock "github.com/openshift/backplane-cli/pkg/ocm/mocks"
"github.com/openshift/backplane-cli/pkg/utils"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
)

func MakeIoReader(s string) io.ReadCloser {
Expand Down Expand Up @@ -257,6 +255,29 @@ var _ = Describe("Login command", func() {
Expect(cfg.Contexts["default/test123/anonymous"].Namespace).To(Equal("default"))
})

It("when the namespace of the context is passed as an argument", func() {
err := utils.CreateTempKubeConfig(nil)
args.defaultNamespace = "default"
Expect(err).To(BeNil())
mockOcmInterface.EXPECT().GetOCMEnvironment().Return(ocmEnv, nil).AnyTimes()
mockOcmInterface.EXPECT().GetTargetCluster(testClusterID).Return(trueClusterID, testClusterID, nil)
mockOcmInterface.EXPECT().IsClusterHibernating(gomock.Eq(trueClusterID)).Return(false, nil).AnyTimes()
mockOcmInterface.EXPECT().GetOCMAccessToken().Return(&testToken, nil)
mockClientUtil.EXPECT().MakeRawBackplaneAPIClientWithAccessToken(backplaneAPIURI, testToken).Return(mockClient, nil)
mockClient.EXPECT().LoginCluster(gomock.Any(), gomock.Eq(trueClusterID)).Return(fakeResp, nil)

err = runLogin(nil, []string{testClusterID})

Expect(err).To(BeNil())

cfg, err := utils.ReadKubeconfigRaw()
Expect(err).To(BeNil())
Expect(cfg.CurrentContext).To(Equal("default/test123/anonymous"))
Expect(len(cfg.Contexts)).To(Equal(1))
Expect(cfg.Contexts["default/test123/anonymous"].Cluster).To(Equal(testClusterID))
Expect(cfg.Contexts["default/test123/anonymous"].Namespace).To(Equal(args.defaultNamespace))
})

It("Should fail when trying to find a non existent cluster", func() {
mockOcmInterface.EXPECT().GetOCMEnvironment().Return(ocmEnv, nil).AnyTimes()
mockOcmInterface.EXPECT().GetOCMAccessToken().Return(&testToken, nil).AnyTimes()
Expand Down
2 changes: 1 addition & 1 deletion docs/PS1-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ You can use the below methods to set the shell prompt, so you can learn which cl
[user@user ~ (⎈ |stg/user-test-1.zlob.s1:default)]$ date
Tue Sep 7 17:40:35 CST 2021
[user@user ~ (⎈ |stg/user-test-1.zlob.s1:default)]$ oc whoami
system:serviceaccount:openshift-backplane-srep:xxxxxxxxxxxx
system:serviceaccount:default:xxxxxxxxxxxx
~~~

## Bash
Expand Down
2 changes: 1 addition & 1 deletion docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ When executing `ocm backplane login <cluster-id>`, it will:
- Create a script file in `$HOME/.kube/ocm-token` for later use. As backplane uses OCM token for authentication, the `ocm-token` script will call `ocm token` to get a fresh access token, and feed to the `oc` command.
- Create cluster in `kubeconfig`. The `server` of the cluster points to the proxy url just received.
- Create user in `kubeconfig`. The user has an [ExecConfig](https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig) pointing to the script just created.
- Create a context using the cluster & user just created, and set it to current context.
- Create a context using the cluster, namespace passed as an argument( default: default ) & user just created, and set it to current context.

### Logout

Expand Down