Skip to content

Commit

Permalink
Merge bb449d3 into be52fd0
Browse files Browse the repository at this point in the history
  • Loading branch information
valaparthvi authored Jun 7, 2022
2 parents be52fd0 + bb449d3 commit bcb426e
Show file tree
Hide file tree
Showing 13 changed files with 556 additions and 154 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: odo remove binding
---

## Description
The `odo remove binding` command removes the link created between the component and a service via Service Binding.

## Running the Command
Running this command removes the reference from the devfile, but does not necessarily remove it from the cluster. To remove the ServiceBinding from the cluster, you must run `odo dev`, or `odo deploy`.

The command takes a required `--name` flag that points to the name of the Service Binding to be removed.
```shell
odo remove binding --name <ServiceBinding_name>
```

## Examples
```shell
$ odo remove binding --name redis-service-my-nodejs-app
```

There is no interactive mode for this command at the moment.
83 changes: 83 additions & 0 deletions pkg/binding/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package binding

import (
"fmt"

"github.com/devfile/library/pkg/devfile/parser"
sboApi "github.com/redhat-developer/service-binding-operator/apis/binding/v1alpha1"
"gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

backendpkg "github.com/redhat-developer/odo/pkg/binding/backend"
"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/libdevfile"
)

// ValidateAddBinding calls Validate method of the adequate backend
func (o *BindingClient) ValidateAddBinding(flags map[string]string) error {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.Validate(flags)
}

func (o *BindingClient) SelectServiceInstance(flags map[string]string, serviceMap map[string]unstructured.Unstructured) (string, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.SelectServiceInstance(flags[backendpkg.FLAG_SERVICE], serviceMap)
}

func (o *BindingClient) AskBindingName(serviceName, componentName string, flags map[string]string) (string, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
defaultBindingName := fmt.Sprintf("%v-%v", componentName, serviceName)
return backend.AskBindingName(defaultBindingName, flags)
}

func (o *BindingClient) AskBindAsFiles(flags map[string]string) (bool, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.AskBindAsFiles(flags)
}

func (o *BindingClient) AddBinding(bindingName string, bindAsFiles bool, unstructuredService unstructured.Unstructured, obj parser.DevfileObj, componentContext string) (parser.DevfileObj, error) {
service, err := o.kubernetesClient.NewServiceBindingServiceObject(unstructuredService, bindingName)
if err != nil {
return obj, err
}

deploymentName := fmt.Sprintf("%s-app", obj.GetMetadataName())
deploymentGVR, err := o.kubernetesClient.GetDeploymentAPIVersion()
if err != nil {
return obj, err
}

serviceBinding := kclient.NewServiceBindingObject(bindingName, bindAsFiles, deploymentName, deploymentGVR, []sboApi.Mapping{}, []sboApi.Service{service})

// Note: we cannot directly marshal the serviceBinding object to yaml because it doesn't do that in the correct k8s manifest format
serviceBindingUnstructured, err := kclient.ConvertK8sResourceToUnstructured(serviceBinding)
if err != nil {
return obj, err
}
yamlDesc, err := yaml.Marshal(serviceBindingUnstructured.UnstructuredContent())
if err != nil {
return obj, err
}

return libdevfile.AddKubernetesComponentToDevfile(string(yamlDesc), serviceBinding.Name, obj)
}
73 changes: 2 additions & 71 deletions pkg/binding/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
bindingApi "github.com/redhat-developer/service-binding-operator/apis/binding/v1alpha1"
specApi "github.com/redhat-developer/service-binding-operator/apis/spec/v1alpha3"

"github.com/devfile/library/pkg/devfile/parser"
devfilefs "github.com/devfile/library/pkg/testingutil/filesystem"
"gopkg.in/yaml.v2"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

devfilev1alpha2 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/pkg/devfile/parser"
parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common"
devfilefs "github.com/devfile/library/pkg/testingutil/filesystem"

"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/binding/asker"
Expand Down Expand Up @@ -56,75 +56,6 @@ func (o *BindingClient) GetFlags(flags map[string]string) map[string]string {
return bindingFlags
}

// Validate calls Validate method of the adequate backend
func (o *BindingClient) Validate(flags map[string]string) error {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.Validate(flags)
}

func (o *BindingClient) SelectServiceInstance(flags map[string]string, serviceMap map[string]unstructured.Unstructured) (string, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.SelectServiceInstance(flags[backendpkg.FLAG_SERVICE], serviceMap)
}

func (o *BindingClient) AskBindingName(serviceName, componentName string, flags map[string]string) (string, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
defaultBindingName := fmt.Sprintf("%v-%v", componentName, serviceName)
return backend.AskBindingName(defaultBindingName, flags)
}

func (o *BindingClient) AskBindAsFiles(flags map[string]string) (bool, error) {
var backend backendpkg.AddBindingBackend
if len(flags) == 0 {
backend = o.interactiveBackend
} else {
backend = o.flagsBackend
}
return backend.AskBindAsFiles(flags)
}

func (o *BindingClient) AddBinding(bindingName string, bindAsFiles bool, unstructuredService unstructured.Unstructured, obj parser.DevfileObj, componentContext string) (parser.DevfileObj, error) {
service, err := o.kubernetesClient.NewServiceBindingServiceObject(unstructuredService, bindingName)
if err != nil {
return obj, err
}

deploymentName := fmt.Sprintf("%s-app", obj.GetMetadataName())
deploymentGVR, err := o.kubernetesClient.GetDeploymentAPIVersion()
if err != nil {
return obj, err
}

serviceBinding := kclient.NewServiceBindingObject(bindingName, bindAsFiles, deploymentName, deploymentGVR, []bindingApi.Mapping{}, []bindingApi.Service{service})

// Note: we cannot directly marshal the serviceBinding object to yaml because it doesn't do that in the correct k8s manifest format
serviceBindingUnstructured, err := kclient.ConvertK8sResourceToUnstructured(serviceBinding)
if err != nil {
return obj, err
}
yamlDesc, err := yaml.Marshal(serviceBindingUnstructured.UnstructuredContent())
if err != nil {
return obj, err
}

return libdevfile.AddKubernetesComponentToDevfile(string(yamlDesc), serviceBinding.Name, obj)
}

func (o *BindingClient) GetServiceInstances() (map[string]unstructured.Unstructured, error) {
// Get the BindableKinds/bindable-kinds object
bindableKind, err := o.kubernetesClient.GetBindableKinds()
Expand Down
28 changes: 18 additions & 10 deletions pkg/binding/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,38 @@ package binding

import (
"github.com/devfile/library/pkg/devfile/parser"
"github.com/redhat-developer/odo/pkg/api"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"github.com/redhat-developer/odo/pkg/api"
)

type Client interface {
// GetFlags gets the necessary flags for binding
GetFlags(flags map[string]string) map[string]string
// Validate returns error if the backend failed to validate; mainly useful for flags backend
Validate(flags map[string]string) error
// GetServiceInstances returns a map of bindable instance name with its unstructured.Unstructured object, and an error
GetServiceInstances() (map[string]unstructured.Unstructured, error)
// GetBindingsFromDevfile returns the bindings defined in the devfile with the status extracted from cluster
GetBindingsFromDevfile(devfileObj parser.DevfileObj, context string) ([]api.ServiceBinding, error)
// GetBindingFromCluster returns information about a binding in the cluster (either from group binding.operators.coreos.com or servicebinding.io)
GetBindingFromCluster(name string) (api.ServiceBinding, error)

// add_binding.go

// ValidateAddBinding returns error if the backend failed to validate; mainly useful for flags backend
ValidateAddBinding(flags map[string]string) error
// SelectServiceInstance returns the service to bind to the component
SelectServiceInstance(flags map[string]string, serviceMap map[string]unstructured.Unstructured) (string, error)
// AskBindingName returns the name to be set for the binding
AskBindingName(serviceName, componentName string, flags map[string]string) (string, error)
// AskBindAsFiles asks if the service should be bound as files
AskBindAsFiles(flags map[string]string) (bool, error)

// AddBinding adds the ServiceBinding manifest to the devfile
AddBinding(bindingName string, bindAsFiles bool, unstructuredService unstructured.Unstructured, obj parser.DevfileObj, componentContext string) (parser.DevfileObj, error)
// GetServiceInstances returns a map of bindable instance name with its unstructured.Unstructured object, and an error
GetServiceInstances() (map[string]unstructured.Unstructured, error)

// GetBindingsFromDevfile returns the bindings defined in the devfile with the status extracted from cluster
GetBindingsFromDevfile(devfileObj parser.DevfileObj, context string) ([]api.ServiceBinding, error)
// remove_binding.go

// GetBindingFromCluster returns information about a binding in the cluster (either from group binding.operators.coreos.com or servicebinding.io)
GetBindingFromCluster(name string) (api.ServiceBinding, error)
// ValidateRemoveBinding validates if the command has adequate arguments/flags
ValidateRemoveBinding(flags map[string]string) error
// RemoveBinding removes the binding from devfile
RemoveBinding(bindingName string, obj parser.DevfileObj) (parser.DevfileObj, error)
}
Loading

0 comments on commit bcb426e

Please sign in to comment.