Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
Allow passing username & password as flags to broker register
Browse files Browse the repository at this point in the history
This fix adds username and password as optional parameters to
broker register command. If passed the kubernetes secret is auto
created and used for broker register

fixes: #2479
Signed-off-by: Anmol Babu <anmolbudugutta@gmail.com>
  • Loading branch information
anmolbabu committed Mar 2, 2021
1 parent 18c0d73 commit 03f1071
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 3 deletions.
46 changes: 44 additions & 2 deletions cmd/svcat/broker/register_cmd.go
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package broker

import (
"encoding/base64"
"fmt"
"os"
"strings"
Expand All @@ -27,6 +28,7 @@ import (
"github.com/kubernetes-sigs/service-catalog/pkg/apis/servicecatalog/v1beta1"
servicecatalog "github.com/kubernetes-sigs/service-catalog/pkg/svcat/service-catalog"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand All @@ -38,6 +40,8 @@ type RegisterCmd struct {

BasicSecret string
BearerSecret string
UserName string
UserPassword string
BrokerName string
CAFile string
ClassRestrictions []string
Expand Down Expand Up @@ -66,6 +70,8 @@ func NewRegisterCmd(cxt *command.Context) *cobra.Command {
}
cmd.Flags().StringVar(&registerCmd.URL, "url", "",
"The broker URL (Required)")
cmd.Flags().StringVarP(&registerCmd.UserName, "username", "u", "", "User name to create kubernetes secret with")
cmd.Flags().StringVarP(&registerCmd.UserPassword, "password", "p", "", "Password to create kubernetes secret with")
cmd.MarkFlagRequired("url")
cmd.Flags().StringVar(&registerCmd.BasicSecret, "basic-secret", "",
"A secret containing basic auth (username/password) information to connect to the broker")
Expand Down Expand Up @@ -97,8 +103,24 @@ func (c *RegisterCmd) Validate(args []string) error {
}
c.BrokerName = args[0]

if c.BasicSecret != "" && c.BearerSecret != "" {
return fmt.Errorf("cannot use both basic auth and bearer auth")
var isAuthParamSet bool

if c.UserName != "" && c.UserPassword != "" {
isAuthParamSet = true
}

if c.BasicSecret != "" {
if isAuthParamSet {
return fmt.Errorf("cannot have more than one authentication parameter passed. Please pass either basic-secret or bearer-secret or username and password")
}
isAuthParamSet = true
}

if c.BearerSecret != "" {
if isAuthParamSet {
return fmt.Errorf("cannot have more than one authentication parameter passed. Please pass either basic-secret or bearer-secret or username and password")
}
isAuthParamSet = true
}

if c.CAFile != "" {
Expand All @@ -118,6 +140,26 @@ func (c *RegisterCmd) Validate(args []string) error {

// Run creates the broker and then displays the broker details
func (c *RegisterCmd) Run() error {
if c.UserName != "" && c.UserPassword != "" {
secret, err := c.Context.App.CreateSecret(
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: c.BrokerName,
Namespace: c.Namespace,
},
Data: map[string][]byte{
"username": []byte(base64.StdEncoding.EncodeToString([]byte(c.UserName))),
"password": []byte(base64.StdEncoding.EncodeToString([]byte(c.UserPassword))),
},
Type: corev1.SecretTypeBasicAuth,
},
)
if err != nil {
return err
}

c.BasicSecret = secret.Name
}
opts := &servicecatalog.RegisterOptions{
BasicSecret: c.BasicSecret,
BearerSecret: c.BearerSecret,
Expand Down
45 changes: 44 additions & 1 deletion cmd/svcat/broker/register_cmd_test.go
Expand Up @@ -111,7 +111,7 @@ var _ = Describe("Register Command", func() {
}
err := cmd.Validate([]string{"bananabroker", "http://bananabroker.com", "--basic-secret", basicSecret, "--bearer-secret", bearerSecret})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("cannot use both basic auth and bearer auth"))
Expect(err.Error()).To(ContainSubstring("cannot have more than one authentication parameter passed"))
})
It("errors if a provided CA file does not exist", func() {
cmd := RegisterCmd{
Expand Down Expand Up @@ -250,6 +250,49 @@ var _ = Describe("Register Command", func() {
Expect(output).To(ContainSubstring(brokerName))
Expect(output).To(ContainSubstring(brokerURL))
})
It("Passes in the uesrname and password", func() {
// userName := "foobar"
// password := "foobar"

brokerToReturn.Spec.AuthInfo.Basic = &v1beta1.ClusterBasicAuthConfig{
SecretRef: &v1beta1.ObjectReference{
Name: brokerToReturn.Name,
},
}

outputBuffer := &bytes.Buffer{}
fakeApp, _ := svcat.NewApp(nil, nil, namespace)
fakeSDK := new(servicecatalogfakes.FakeSvcatClient)
fakeSDK.RegisterReturns(brokerToReturn, nil)
fakeApp.SvcatClient = fakeSDK
cxt := svcattest.NewContext(outputBuffer, fakeApp)
cmd := RegisterCmd{
BasicSecret: brokerToReturn.Name,
BrokerName: brokerName,
Namespaced: command.NewNamespaced(cxt),
Scoped: command.NewScoped(),
Waitable: command.NewWaitable(),
URL: brokerURL,
}
cmd.Namespaced.ApplyNamespaceFlags(&pflag.FlagSet{})
cmd.Waitable.ApplyWaitFlags()
err := cmd.Run()

Expect(err).NotTo(HaveOccurred())
Expect(fakeSDK.RegisterCallCount()).To(Equal(1))
returnedName, returnedURL, returnedOpts, _ := fakeSDK.RegisterArgsForCall(0)
Expect(returnedName).To(Equal(brokerName))
Expect(returnedURL).To(Equal(brokerURL))
opts := servicecatalog.RegisterOptions{
Namespace: namespace,
BasicSecret: brokerToReturn.Name,
}
Expect(*returnedOpts).To(Equal(opts))

output := outputBuffer.String()
Expect(output).To(ContainSubstring(brokerName))
Expect(output).To(ContainSubstring(brokerURL))
})
It("Passes in the bearer secret", func() {
bearerSecret := "foobarsecret"
brokerToReturn.Spec.AuthInfo.Basic = nil
Expand Down
8 changes: 8 additions & 0 deletions cmd/svcat/testdata/output/completion-bash.txt
Expand Up @@ -1226,6 +1226,10 @@ _svcat_register()
two_word_flags+=("--namespace")
two_word_flags+=("-n")
local_nonpersistent_flags+=("--namespace=")
flags+=("--password=")
two_word_flags+=("--password")
two_word_flags+=("-p")
local_nonpersistent_flags+=("--password=")
flags+=("--plan-restrictions=")
two_word_flags+=("--plan-restrictions")
local_nonpersistent_flags+=("--plan-restrictions=")
Expand All @@ -1246,6 +1250,10 @@ _svcat_register()
flags+=("--url=")
two_word_flags+=("--url")
local_nonpersistent_flags+=("--url=")
flags+=("--username=")
two_word_flags+=("--username")
two_word_flags+=("-u")
local_nonpersistent_flags+=("--username=")
flags+=("--wait")
local_nonpersistent_flags+=("--wait")
flags+=("--context=")
Expand Down
8 changes: 8 additions & 0 deletions cmd/svcat/testdata/output/completion-zsh.txt
Expand Up @@ -1360,6 +1360,10 @@ _svcat_register()
two_word_flags+=("--namespace")
two_word_flags+=("-n")
local_nonpersistent_flags+=("--namespace=")
flags+=("--password=")
two_word_flags+=("--password")
two_word_flags+=("-p")
local_nonpersistent_flags+=("--password=")
flags+=("--plan-restrictions=")
two_word_flags+=("--plan-restrictions")
local_nonpersistent_flags+=("--plan-restrictions=")
Expand All @@ -1380,6 +1384,10 @@ _svcat_register()
flags+=("--url=")
two_word_flags+=("--url")
local_nonpersistent_flags+=("--url=")
flags+=("--username=")
two_word_flags+=("--username")
two_word_flags+=("-u")
local_nonpersistent_flags+=("--username=")
flags+=("--wait")
local_nonpersistent_flags+=("--wait")
flags+=("--context=")
Expand Down
1 change: 1 addition & 0 deletions pkg/svcat/service-catalog/sdk.go
Expand Up @@ -83,6 +83,7 @@ type SvcatClient interface {
RetrievePlanByID(string, ScopeOptions) (Plan, error)

RetrieveSecretByBinding(*apiv1beta1.ServiceBinding) (*apicorev1.Secret, error)
CreateSecret(secret *apicorev1.Secret) (*apicorev1.Secret, error)

ServerVersion() (*version.Info, error)
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/svcat/service-catalog/secret.go
Expand Up @@ -42,3 +42,8 @@ func (sdk *SDK) RetrieveSecretByBinding(binding *v1beta1.ServiceBinding) (*corev

return secret, nil
}

// CreateSecret creates a secret
func (sdk *SDK) CreateSecret(secret *corev1.Secret) (*corev1.Secret, error) {
return sdk.Core().Secrets(secret.Namespace).Create(context.Background(), secret, metav1.CreateOptions{})
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 03f1071

Please sign in to comment.