Odo: Research and define how can services be linked to components

Created on 20 Aug 2018  Â·  35Comments  Â·  Source: openshift/odo

With https://github.com/redhat-developer/odo/pull/413 odo can create services.
But odo doesn't have an easy way to configure component so it is able to connect to the service.

  • Research what is the standard way to connect to services created from a service catalog and how we can implement it.
  • Define commands that will be used to connect services and components. We should use odo link command for it. Ideally, it should be as simple as running odo link mysql and odo link mysql --component mycomponent
backlog

Most helpful comment

I also agree on @geoand's s proposition.

Remark : We need a technical document referencing the use cases that we would like to address with the link command like also to discuss the syntax to be adopted for the command or k8s modificitions

All 35 comments

This is an interesting command odo link that you propose to use to update the supervisord's deploymentConfig in order to add as EnvFrom the secret containing the parameters of a serviceInstance

We have implemented successfully this use case with the function MountSecretAsEnvFrom( - see

From a functional point of view we do :

  • Search and get the DeploymentConfig to be enhanced
  • Add `EnvFrom <- Secret generated during service binding
  • Rollout the DeploymentConfig to have the Env vars available within the pod

The parameters that you should know will be the secretName created during binding step and the name of the deploymentconfig to be enhanced and optionally the namespace

So the command could be

odo component link <name_of_the_component> --secret <secretName>

Additional question:

What should be the strategy that we will propose to add a config/secret to a component (= DeploymentConfig ) ?

  • EnvFrom using as reference the name of the configMap/Secret (= default approach proposed by Openshift UI - see screen add to application)
  • Volume mounted

Command developed and code implemented to check if a secret exists like the component and next to add the envFrom to the container of the application

see - https://github.com/redhat-developer/odo/pull/723/files#diff-6025e9b620e9321c03c11bf29e5c4dbdR1435

So the command could be

odo link <name_of_the_component> --secret <secretName>

The user doesn't have to know that it is a secret. From a users point of view, it should look like linking component to the service.
This might be better
odo link <component_name> --service <service_name>
On the background, it will be the same - finding the right Secret and injecting it to the component's DeploymentConfig.

We should also modify current odo link command that allows linking two components as odo link <component_name_1> <component_name_2> to odo link <component_name_1> --component <component_name_2>.

In general odo link command will have a following form odo link <target_component> --<link_type> <source_component>. Target component is optional and if not specified current component will be used.

Thoughts? @cmoulliard @jorgemoralespou

As the information which is needed to link the secret to an application is available from the serviceBinding resource

 oc get servicebinding/dh-postgresql-apb -o yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  finalizers:
  - kubernetes-incubator/service-catalog
  generation: 1
  name: dh-postgresql-apb
  namespace: cmoullia
apb
  uid: 91ee39ba-c19f-11e8-98df-0a580a800110
spec:
  externalID: 91ee3941-c19f-11e8-98df-0a580a800110
  instanceRef:
    name: dh-postgresql-apb // NAME OF THE SERVICE INSTANCE TO LOOK FOR
  parameters:
    postgresql_database: my_data
    postgresql_password: secret
    postgresql_user: luke
    postgresql_version: "9.6"
  secretName: dh-postgresql-apb // NAME OF THE SECRET TO USE TO CREATE ENVFROM IN DC

, then we can adopt your proposition

odo link <component_name> --service <service_name>

@kadel
What --<link_type> do you envision?

Also, AFAIK:

We should also modify current odo link command that allows linking two components as odo link to odo link --component

This is how it is defined now, not?

Usage:
  odo link <target component> --component [source component] [flags]

Examples:
  # Link current component to a component 'mariadb'
  odo link mariadb

  # Link 'mariadb' component to 'nodejs' component
  odo link mariadb --component nodejs

What --<link_type> do you envision?

for now --component and --service

This is how it is defined now, not?

Kind of, but I described it in the other way. (Changed source and target component)
In the current implementation, the env variables are injected into the source component.
In my comment, I expected that variables will be injected into <component_name_1> and<target_component>.

Now as I'm looking at this again, I'm a little bit worried that it might be a little bit confusing.
We are not doing a good job describing what is happening in link command, and what I'm describing might be even worse :-(
In all other components, we use --component flag to change a component that command is operation on (from the current one to something else). But what I described in link syntax is using this flag to select the component that information is taken from.

@kadel, not sure what is your concern. In odo everything we do without a specific "qualifier" should be in the context of the current component, hence current naming makes sense IMHO:

  • odo link --service bla means link current component to service bla.
  • odo link --service bla --component foo means link foo component to service bla.

Semantically is what/how you would read it. We could maybe change the --service for --to-service to make it more clear.

Maybe I'm missing the point.

I think that the natural way to read the syntax of the command is from something to something else where the qualifier gives an indication about the type of info to be injected within the Deployment or DeploymentConfig

  • odo link --component bla --component foo : add service foo address to component bla -> component-bla.service-foo.svc
  • odo link --secret bla --component foo : add secret bla to component foo
  • odo link --service bla --component foo : add secret bla as enfFrom of the service instance bla to component foo

@kadel, not sure what is your concern. In odo everything we do without a specific "qualifier" should be in the context of the current component, hence current naming makes sense IMHO:

@jorgemoralespou
My concern is how to specify when you want to link two components when you don't want to use the current component.

@cmoulliard showed that in his comment

odo link --component bla --component foo : add service foo address to component bla -> component-bla.service-foo.svc

This command doesn't make sense. We wouldn't be to detect "direction" of the link.

We could assume that by default `odo linkz operates on components.
That would mean following:

  • odo link foo - create a link in the current component that points to foo component
  • odo link --service foo - create a link in the current component that points to foo service
  • odo link foo --component bar - create a link in bar component that points to foo component
  • odo link --service foo --component bar - create a link in bar component that points to foo service

But that looks a bit weird :-(

What if we use --to-component and --to-service

  • odo link --to-component foo - create a link in the current component that points to foo component
  • odo link --to-service foo - create a link in the current component that points to foo service
  • odo link --to-component foo --component bar - create a link in bar component that points to foo component
  • odo link --to-service foo --component bar - create a link in bar component that points to foo

It makes it longer but on the other hand, it makes it clear what is a direction of the link.

I see now.
To me your first implementation doesn't look weird, as the tool is to develop the innercycle or local iterative cycle, which means that a component is the center and front of the tool and everything works on the scope of a component as there is where you'll be putting your code, etc...

We're sometimes biassed by what can be done with openshift, but I think it's important to constrain what we're doing to the current scope, meaning that it's not a deployment tool, it's not an architecture tool, it is a tool to work on code in an interative way. Which means that this use case should be the simpler one.

In any case, I'm fine with other's point of view. I wouldn't reject the second notation, but to me, that one looks more complex/weird :-D

@marekjelen @gshipley do you guys want to comment?

I like the 2nd one - clarity beats length - though, I would use from rather then to, or specifically

  • odo link --from-service mysql - links mysql to current component
  • odo link --from-service mysql --to-component wordpress - links mysql to wordpress component

odo link --from-service/--from-component=source [--to-service/--to-component=target]

@marekjelen what is from and to? which one is the consumer side and which one is the producer side? In your example, from means the producer side, while in @kadel example to means the producer side, which means that this notation could be confusing, IMHO

And what about consistency with all the other commands. Isn't that important?

@jorgemoralespou every time when there is to/from involved it can be confusing ;) Also what's a producer side? The side getting the credentials? If it gets credentials shouldn't it be receiver and so the side providing the credentials to be a producer?

The function of the link command can be understood in two ways

  • linking something to my component (e.g. from mysql to my wordpress component)
  • linking my component to something (e.g. from my wordpress to mysql)

producer is the one that provides the capability, in this case, the database. consumer is the one that uses the capability, in this case wordpress.
The ambiguity is the main reason why I would rather avoid using from and to, and just stick to what we're using in the other components.

The ambiguity is the main reason why I would rather avoid using from and to, and just stick to what we're using in the other components.

I agree with you. In other commands, we use current component, or component specified by --component flag. And we should follow that here.

The problem is that we have two types of link. One that link component to component and one that links component to service (and in future, there might be more).
For me, the question is how to translate those two types into the link command.
I think that we should have flags that determine if we are linking with service or component.

This is why I proposed --to-service and --to-component. We can try to find better names, something that doesn't have to or from. But we can't use simply --service or --component as --component is already there.

Can you then provide some examples like a definition of the syntax of the command proposed including latest remarks such --to-service, --to-component ? @kadel

@kadel I think it makes sense, although I've always advocated for minimal syntax, I think that the most common use scenario will be to link to services, as it's not possible to link to components currently :-D

Yes, I know we've hacked that example in the initial implementation of odo, but as we should rely on service catalog's functionality for linking, we will most likely always link services into components.

We could do one of the following:

  • Don't have --to-service or --to-component and have odo internally discover whether the parameter is a service or a component. This would be nice from usability PoV, but maybe too complex.
  • Have service as the default, which is what will most likely be and not support linking to a component.
  • Have a flag that does decoration on what the argument means (default --as-service, but with --as-component as option). e.g. `odo link mydb [--as-service|--as-component]. Not nice naming and not natural speech.
  • Introduce the --to-service and --to-component parameters, and the command should not accept a . Without defaults, in this case, to avoid confusion.

I think that from all of them the last one is the less error prone but the first one is the most easier.

@jorgemoralespou one more point to your list - you can have 2 verbs to separate the use-cases ... e.g. link for services and bridge for components

@jorgemoralespou

  • Don't have --to-service or --to-component and have odo internally discover whether the parameter is a service or a component. This would be nice from usability PoV, but maybe too complex.

This shouldn't be that hard to do, but I'm a little bit afraid that it might be a little bit too magical for the user. There is also one small corner case that we would have to handle. What if there is a component with the same name as a service?

  • Have service as the default, which is what will most likely be and not support linking to a component.

I haven't considered that, but it would make sense. We don't really need linking between two components. Odo is by default creating Service for each component. All we have to do is properly explain in our docs how to find the internal hostname for the component. We can, for example, display this in odo describe.

This might be the best solution.

My 2 cents:

I believe that linking a component to a service should be the only option. As a new comer to odo but as a developer who has been banging with k8s / openshift for quite a while, I find it surprising to have a 'link' between 2 components - Kubernetes Services should play this role.

So I would propose:

odo link foo - Links the current component to the foo service
odo link foo --component bar - Links the bar component to the foo service.

@kadel I agree with @geoand and I think that until there is a standard way to define how a component could be linked to another component, we should go this route.

In the future, I would expect though, to be able to define a way to connect to a component, like a binding in a service, and then be able to link to that component by injecting the binding to my component. Sadly, that's not possible today.

I wouldn't go that far as it doesn't make sense, as I think it does, but we should also be aware of the technical challenges.

Maybe we should think a way of creating the binding, so that we can either link to a service and to a component, as if they were a service anyways, as to be honest, linking what it does is injecting a binging into a deployment. We might need to think how to create a binding from a component.

OK, It makes sense.
Let's do it this way. Let's change odo link to link component with service only.

Cool! I will do that as part of #723 if you don't mind

On Mon, Oct 15, 2018, 14:27 Tomas Kral notifications@github.com wrote:

OK, It makes sense.
Let's do it this way. Let's change odo link to link component with
service only.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/redhat-developer/odo/issues/652#issuecomment-429813904,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AELBv1Ae4nuLgPGKOeQON1kIkLN4SFkQks5ulHEQgaJpZM4WDw_H
.

I also agree on @geoand's s proposition.

Remark : We need a technical document referencing the use cases that we would like to address with the link command like also to discuss the syntax to be adopted for the command or k8s modificitions

just a thought in my mind:

rather than, odo link <service> --component <component>, odo service link <service> --component <component>
would be much cleaner.
But considering current situation, since all odo <verb> deal with components.
I think it should be,

odo link <component> --service <service>

and also I think one component can consume mulitple services, so user can do

odo link component --service service1
odo link component --service service2

WDYT @kadel ?

current @geoand 's implementation also looks good to me though :smile:
(maybe future or when we refactor )

@geoand @kadel I'm still skeptical that we're getting the right syntax here, but the truth is that by using whatever we do we'll be able to understand how it fits into the developer workflow.

odo service link <service> --component <component> to me would read as link <service> to the current service in component <component> as that would be the consistent behavior/understanding from the rest of the CLI.

Linking something to a component needs to happen in the context of the component, like everything else we do, so odo link is a must.

I would think that maybe we should do:

odo link --to-component componentA [--component componentB]
odo link --to-service serviceA  [--component componentB]

And not have an odo link <anything> option as that is what seems to be misleading.

This way we can link any component or service to current/any component.

What should happen when odo link --to-component <componentA> is what I've been thinking through, and I think we should do the following:

  • When we create a component, we should also create a secret with the host (k8s service name) and port to connect to this component.
  • When we link, this secret would be injected into my component underlying definition, so that the connection details are available to my component.
  • We need to augment the odo link signature to support mapping of key names from the secret to the env vars in the DC. I've thought a flag like --map <secret-key-name>:<component-key-name> (But maybe this one should need a follow up issue, @geoand @kadel WDYT to defer this?)

An example of all this would be:

odo create wildfly backend --binary=target/ROOT.war
odo push
odo create nodejs frontend
odo push
odo link --to-component backend --map host:BACKEND_HOST
odo url create

By default, the secret created for a component would add some "standardized variables`, to be properly defined, but taking some existing services as references:

port
uri    # MAYBE???
username   # MAYBE???
password   # MAYBE???

The last 3 maybe should be something the user could create later in some way. The first 2 seem required.

I really like this proposal since it unifies the approach and also feels like the proper k8s solution!
Furthermore I agree that the first pass should perhaps exclude the --map, although it should definitely be added later on.
I'm going through the existing odo code ( since I am still new to this codebase :) ) to see what's required to implement it, but so far I don't see any pain points arising

+1

Yes, let's not complicate the first iteration with --map, it would be better to add that later on.

I started playing with this and seems straightforward.
The only complication I see is with the case where the service exposes
multiple ports.
Hopefully I will have something pretty complete on Monday so we can discuss
on something concrete.

On Fri, Oct 19, 2018, 16:23 Tomas Kral notifications@github.com wrote:

+1

Yes, let's not complicate the first iteration with --map, it would be
better to add that later on.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/redhat-developer/odo/issues/652#issuecomment-431361670,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AELBvyI5dcnHwg7XXKvnmnXcB0z3ghbkks5umdJmgaJpZM4WDw_H
.

The only complication I see is with the case where the service exposes multiple ports.

Ah, completly fogot about that. That might get a little bit tricky.

Do we really need to store port in the Secret?
The user will know what port should be used (it is displayed during component creation, and we should show it in odo describe). The user then can use odo config to create an environment variable with that information.
But I guess this is not that user friendly :-(

Or we could add optional --port flag for odo link. New Secret would be created for each component port. --port would control which secret will be injected.
--port would be only required if the component that we are linking to has multiple ports.

Example:

odo create java backend --port 8080,9090
# two secrets created (for example backend-8080 and backend-9090)

odo create nodejs frontend
odo link --to-component backend --port 8080
# injects Secret backend-8080 to the frontend component

I really like the --port idea!

We can even fail the command when the port is not part of the s2i image.

I propose we proceed with that idea

On Fri, Oct 19, 2018, 21:18 Tomas Kral notifications@github.com wrote:

The only complication I see is with the case where the service exposes
multiple ports.

Ah, completly fogot about that. That might get a little bit tricky.

Do we really need to store port in the Secret?
The user will know what port should be used (it is displayed during
component creation, and we should show it in odo describe). The user then
can use odo config to create an environment variable with that
information.
But I guess this is not that user friendly :-(

Or we could add optional --port flag for odo link. New Secret would be
created for each component port. --port would control which secret will
be injected.
--port would be only required if the component that we are linking to has
multiple ports.

Example:

odo create java backend --port 8080,9090

two secrets created (for example backend-8080 and backend-9090)

odo create nodejs frontend
odo link --to-component backend --port 8080

injects Secret backend-8080 to the frontend component

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/redhat-developer/odo/issues/652#issuecomment-431452720,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AELBv4Wp1rQ7RalGfru38BMREJlN9YQ-ks5umhd6gaJpZM4WDw_H
.

which secret

Remark: this is not a base64 string which is injected from a k8s secret key but instead a string which is associated to an Env variable [1]. That should be clear and well documented for the developer although this is not the case if you look to the output of the odo link -h command.
I propose to mention that we inject the object's value (where object could be a port, service, ...) as an env variable. Why, developers must know how their code could then use/consume such info.

[1] https://goo.gl/AGz8jo

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kadel picture kadel  Â·  8Comments

prietyc123 picture prietyc123  Â·  3Comments

maysunfaisal picture maysunfaisal  Â·  8Comments

dharmit picture dharmit  Â·  6Comments

prietyc123 picture prietyc123  Â·  7Comments