Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 8 additions & 0 deletions locales/cluster/bind/active.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ one = 'Binding %v with %v app succeeded'
[cluster.serviceBinding.status.message]
one = 'Binding "%v" with "%v" app'

[cluster.serviceBinding.operatorMissing]
one = '''
Operator is not available on the current cluster.
Please remove --force-operator=true if you wish to create resource without operator
Error:
'''

[cluster.serviceBinding.usingOperator]
one = 'Using ServiceBinding Operator to perform binding'
6 changes: 6 additions & 0 deletions locales/cmd/cluster/bind/active.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ services with.
Bind command detects Kubernetes deployments and inject managed services credentials to them.
For information about what credentials are injected please refer to individual services
Command will inject credentials as files into `/bindings` folder inside your application.

Bind command will create volume inside your deployment or
ServiceBindingOperator resource if you have it installed on your cluster
'''

[cluster.bind.cmd.example]
Expand All @@ -26,5 +29,8 @@ $ rhoas cluster bind --namespace=ns --app-name=myapp
[cluster.bind.flag.appName]
one = '''Name of the kubernetes deployment to bind'''

[cluster.bind.flag.onlyOperator.description]
one = '''Use ServiceBindingOperator only and fail if Operator is not installed'''

[cluster.bind.error.emptyResponse]
one = '''Server returned empty response for service'''
30 changes: 27 additions & 3 deletions pkg/cluster/serviceBinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/redhat-developer/app-services-cli/pkg/logging"
sboContext "github.com/redhat-developer/service-binding-operator/pkg/reconcile/pipeline/context"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"os"
Expand All @@ -33,7 +34,9 @@ type KubernetesClients struct {

var deploymentResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}

func ExecuteServiceBinding(logger logging.Logger, serviceName string, ns string, appName string, forceCreationWithoutAsk bool) error {
// TODO extract arguments
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have this almost there - moving arguments to structure.

func ExecuteServiceBinding(logger logging.Logger, serviceName string, ns string, appName string,
forceCreationWithoutAsk bool, forceUseOperator bool) error {
clients, err := client()
if err != nil {
return err
Expand Down Expand Up @@ -90,7 +93,7 @@ func ExecuteServiceBinding(logger logging.Logger, serviceName string, ns string,
}

// Execute binding
err = performBinding(serviceName, appName, ns, clients)
err = performBinding(serviceName, appName, ns, clients, forceUseOperator, logger)
if err != nil {
return err
}
Expand All @@ -99,7 +102,8 @@ func ExecuteServiceBinding(logger logging.Logger, serviceName string, ns string,
return nil
}

func performBinding(serviceName string, appName string, ns string, clients *KubernetesClients) error {
func performBinding(serviceName string, appName string, ns string, clients *KubernetesClients,
forceUseOperator bool, logger logging.Logger) error {
serviceRef := v1alpha1.Service{
NamespacedRef: v1alpha1.NamespacedRef{
Ref: v1alpha1.Ref{
Expand Down Expand Up @@ -134,6 +138,26 @@ func performBinding(serviceName string, appName string, ns string, clients *Kube
}
sb.SetGroupVersionKind(v1alpha1.GroupVersionKind)

// Check of operator is installed
_, err := clients.dynamicClient.Resource(v1alpha1.GroupVersionResource).Namespace(ns).
List(context.TODO(), metav1.ListOptions{Limit: 1})

if err != nil {
if forceUseOperator {
return errors.New(localizer.MustLocalizeFromID("cluster.serviceBinding.operatorMissing") + err.Error())
}
logger.Debug("Service binding Operator not available. Will use SDK")
} else {
logger.Info(localizer.MustLocalizeFromID("cluster.serviceBinding.usingOperator"))
sbData, err := runtime.DefaultUnstructuredConverter.ToUnstructured(sb)
unstructuredSB := unstructured.Unstructured{Object: sbData}
_, err = clients.dynamicClient.Resource(v1alpha1.GroupVersionResource).Namespace(ns).
Create(context.TODO(), &unstructuredSB, metav1.CreateOptions{})

return err
}

// Use SDK instead of operatort
restMapper, err := apiutil.NewDynamicRESTMapper(clients.restConfig)
if err != nil {
return err
Expand Down
5 changes: 4 additions & 1 deletion pkg/cmd/cluster/bind/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Options struct {
ignoreContext bool
appName string
selectedKafka string
useOperator bool
}

func NewBindCommand(f *factory.Factory) *cobra.Command {
Expand Down Expand Up @@ -69,6 +70,7 @@ func NewBindCommand(f *factory.Factory) *cobra.Command {
cmd.Flags().BoolVarP(&opts.forceCreationWithoutAsk, "yes", "y", false, localizer.MustLocalizeFromID("cluster.common.flag.yes.description"))
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", localizer.MustLocalizeFromID("cluster.common.flag.namespace.description"))
cmd.Flags().BoolVarP(&opts.ignoreContext, "ignore-context", "", false, localizer.MustLocalizeFromID("cluster.common.flag.ignoreContext.description"))
cmd.Flags().BoolVarP(&opts.useOperator, "force-operator", "", false, localizer.MustLocalizeFromID("cluster.bind.flag.onlyOperator.description"))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@pmuir We assume to use Operator by default when installed. If this flag is added and CLI fails to detect operator it will fail. Otherwise if operator is not detected SDK is used.

Would you prefer to have more complex flags like:

--useOperator=true
--useSDK=true

Additionally we should provide name override for the service binding (as it is currently generated which might look bad)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like --force-operator - it's clear what's it's doing :-D What about --force-sdk as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. Adding SDK here will be easy. I was hoping to have single flag but that is not possible due to this fallback logic


return cmd
}
Expand Down Expand Up @@ -116,7 +118,8 @@ func runBind(opts *Options) error {
err = cluster.ExecuteServiceBinding(logger, *kafkaInstance.Name,
opts.namespace,
opts.appName,
opts.forceCreationWithoutAsk)
opts.forceCreationWithoutAsk,
opts.useOperator)

return err
}