-
Notifications
You must be signed in to change notification settings - Fork 243
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
Add support for unlinking component from service #3651
Add support for unlinking component from service #3651
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3651 +/- ##
==========================================
- Coverage 44.27% 44.22% -0.05%
==========================================
Files 139 139
Lines 13405 13420 +15
==========================================
Hits 5935 5935
- Misses 6888 6903 +15
Partials 582 582
Continue to review full report at Codecov.
|
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kadel The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -301,6 +301,17 @@ func (esi *EnvSpecificInfo) DeleteURL(parameter string) error { | |||
return esi.writeToFile() | |||
} | |||
|
|||
func (esi *EnvSpecificInfo) DeleteLink(parameter string) error { | |||
for i, link := range *esi.componentSettings.Link { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you shouldn't change the Link
while you are looping though it. better just do
index := -1
...
if link.Name == parameter {
index = i
break
}
...
if index != -1 {
s := *esi.componentSettings.Link
s = append(s[:index], s[index+1:]...)
esi.componentSettings.Link = &s
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't *esi.componentSettings.Link
need to be checked to make sure it's not == nil
as well? Looks like a null pointer error waiting to happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cdrage there is a check to validate that a link exists before we reach this function. Here's how it looks when executed:
$ cat .odo/env/env.yaml
ComponentSettings:
Name: node-todo
Namespace: myproject
AppName: app
RunMode: run
$ odo unlink EtcdCluster/example
✗ failed to unlink the service "EtcdCluster/example" since it's not linked with the component "node-todo"
pkg/odo/cli/component/common_link.go
Outdated
} | ||
|
||
o.serviceType, o.serviceName, err = svc.IsOperatorServiceNameValid(suppliedName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if o.operationName == "unlink" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better to make this a const string?
pkg/odo/cli/component/common_link.go
Outdated
@@ -172,6 +177,19 @@ func (o *commonLinkOptions) validate(wait bool) (err error) { | |||
return fmt.Errorf("Couldn't find service named %q. Refer %q to see list of running services", svcFullName, "odo service list") | |||
} | |||
|
|||
if o.operationName == "unlink" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
pkg/odo/cli/component/common_link.go
Outdated
@@ -228,6 +246,24 @@ func (o *commonLinkOptions) validate(wait bool) (err error) { | |||
|
|||
func (o *commonLinkOptions) run() (err error) { | |||
if experimental.IsExperimentalModeEnabled() { | |||
if o.operationName == "unlink" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we actually using anything from the common_link
code? seems quite disjoint to me?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed this over the call so not touching this part.
pkg/odo/cli/component/common_link.go
Outdated
if o.operationName == "unlink" { | ||
sbrName := getSBRName(o.EnvSpecificInfo.GetName(), o.serviceType, o.serviceName) | ||
svcFullName := getSvcFullName(sbrKind, sbrName) | ||
err = svc.DeleteOperatorService(o.KClient, svcFullName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should unlink actually delete the service?
} | ||
|
||
// getSBRName creates a name to be used for creation/deletion of SBR during link/unlink operations | ||
func getSBRName(componentName, serviceType, serviceName string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am losing track of such helper functions, are we sure we are reusing them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed on call, I create a helper only when it's used at least twice.
stdOut = helper.CmdShouldFail("odo", "link", "EtcdCluster/example") | ||
Expect(stdOut).To(ContainSubstring("already linked with the service")) | ||
|
||
stdOut = helper.CmdShouldPass("odo", "unlink", "EtcdCluster/example") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we check if the secrets were actually removed? or if the SBR was deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to do this by adding oc get sbr
in the test. But it takes some time for the SBR to disappear from the output. I'll have to add a few seconds' timeout to be able to validate this.
/retest |
unit test seems to be failing on golint
|
@@ -301,6 +301,17 @@ func (esi *EnvSpecificInfo) DeleteURL(parameter string) error { | |||
return esi.writeToFile() | |||
} | |||
|
|||
func (esi *EnvSpecificInfo) DeleteLink(parameter string) error { | |||
for i, link := range *esi.componentSettings.Link { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't *esi.componentSettings.Link
need to be checked to make sure it's not == nil
as well? Looks like a null pointer error waiting to happen.
pkg/odo/cli/component/common_link.go
Outdated
return fmt.Errorf("failed to unlink the service %q since it's not linked with the component %q", svcFullName, componentName) | ||
} | ||
|
||
//verify if the underlying service binding request actually exists |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add space to comment & capitalize :)
pkg/odo/cli/component/common_link.go
Outdated
return err | ||
} | ||
if !sbrExists { | ||
// this could have happened if the service binding request was deleted outside odo workflow (eg: oc delete sbr/<sbr-name>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capitalize
|
||
linked := isComponentLinked(sbrName, links) | ||
if !linked { | ||
// user's trying to unlink a service that's not linked with the component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capitalize :)
if err != nil { | ||
return fmt.Errorf("component's link with %q has been deleted outside odo; unable to delete odo's state of the link", svcFullName) | ||
} | ||
return fmt.Errorf("component's link with %q has been deleted outside odo", svcFullName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
components
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think component's
is just right here since we're talking about a specific component. ☕ 😉
return strings.Join([]string{componentName, strings.ToLower(serviceType), serviceName}, "-") | ||
} | ||
|
||
func isComponentLinked(sbrName string, links []envinfo.EnvInfoLink) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments maybe?
/lgtm |
Looks like an unrelated failure:
/test v4.5-integration-e2e |
/lgtm |
What type of PR is this?
/kind feature
What does this PR do / why we need it:
Adds support for unlinking a component from an Operator backed service with
odo unlink
commandWhich issue(s) this PR fixes:
Fixes #3563
PR acceptance criteria:
Unit test
Integration test
Documentation
How to test changes / Special notes to the reviewer:
Install "Service Binding Operator" on the OpenShift cluster.
Create a
nodejs
component using https://github.com/akashshinde/node-todo. Use this devfile for things to work fine:Create a URL for it using
odo url create
. Hit the URL and see that it's showing a loading animation. That's because it needs to be connected to an EtcdCluster.Create an EtcdCluster using
odo service create etcdoperator.v0.9.4-clusterwide --crd EtcdCluster
(exact command depends upon the etcd Operator you've installed in the namesapce).Link the two by doing
odo link EtcdCluster/example
(follows theodo link <servicetype>/<servicename>
syntax since it's perfectly valid to create different kinds of service with same name when working with Operator Hub. Refer Support link command for devfile #2920 (comment).Check the contents of
.odo/env/env.yaml
.Do an
odo push
to make sure that link is applied. We didn't requireodo push
when linking with Service Catalog backed services but require it for Operator backed service. Refer: Support link command for devfile #2920 (comment).Now load the URL created in earlier step again. The app should now be ready to take items. Play around with this ToDo app to make sure things work.
Doing
odo unlink EtcdCluster/example
for the component would delete "ServiceBindingRequest" that binds the component with the Operator backed service and also delete theLink
information from.odo/env/env.yaml
.Example shell flow: