Skip to content
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

I3S - Simplify login to i3s through oneview client #166

Closed
marikrg opened this issue Feb 8, 2017 · 17 comments
Closed

I3S - Simplify login to i3s through oneview client #166

marikrg opened this issue Feb 8, 2017 · 17 comments

Comments

@marikrg
Copy link

marikrg commented Feb 8, 2017

Scenario/Intent

As far as I can see, currently I'm able to authenticate on Image Streamer only using a token
I have tried to access with an username/password and I got the error: Must set token option

From the tools point of view, may be better for some of them authenticate with username/password. The token expires frequently and the tools doesn't provide (and I believe it shouldn't) a way to generate it.

Then, it shouldn't be supported by ImageStreamer client?

Environment Details

  • OneView SDK Version: current master repo
  • OneView Appliance Version: OneView 3.0 (Synergy)
  • OneView Client API Version: 300
  • Ruby Version: Any
  • Platform: Any

Steps to Reproduce

  1. Define username/password instead of token
  2. Instantiate the ImageStreamer Client.
  3. Error Must set token option is raised.

Expected Result

Possible solution:

  1. Define username/password instead of a token
  2. Instantiate the ImageStreamer Client.
  3. Authenticate against OneView appliance and uses the generated token for ImageStreamer rest calls (as a single sign-on).

Actual Result

[What actually happens after the steps above? Include error output or a link to a gist.]

@marikrg marikrg changed the title [Question] Authenticate with either token or username/password on Image Streamer [Question] Authenticate with either token or username/password (Image Streamer Client) Feb 8, 2017
@jsmartt
Copy link
Collaborator

jsmartt commented Feb 8, 2017

@marikrg , I think the reason this was done is because I3S doesn't have an endpoint to login itself; it just uses the token provided from OneView. So you'd have to create a OneView client, then copy that into an I3S client. It seems like it could make sense to roll that all into 1, but then the client would hold 2 separate URLs (1 for OV & 1 for I3S). That seems strange/wrong to implement to me, so although it's a little strange, I think the current solution is the best way (as long as I3S doesn't have a login endpoint itself). @aalexmonteiro , do you have anything to add/correct about that?

@aalexmonteiro
Copy link
Contributor

@jsmartt , exactly. The #167, which was done by you, client attributes can be updated and the token can be set again when it expires. Looks good for me.

@fgbulsoni
Copy link
Contributor

@jsmartt @aalexmonteiro So, if I'm running many operations, like one of our devops tools could, our expected design is to always assume my token has expired and invoke the refresh before any operation? Because I'm guessing it would be expiring constantly and we'd have no way to actually be sure if it is working.

@aalexmonteiro
Copy link
Contributor

@fgbulsoni , It's strange the token is expiring so fast. @jsmartt , has implemented a refresh_login here on client.rb, which updates the token. I think you can use this method to get the new token before each operation and set the new token on the i3s client. I can't think of another solution at the moment.

@jsmartt
Copy link
Collaborator

jsmartt commented Feb 9, 2017

I've never had an issue with it, even after pretty long runs using a single token. It looks like by default, tokens expire 24-hrs after creation. It looks like a session can be extended as well, but I kept getting 401 unauthorized responses after trying to extend my own session. I'm sure we can figure something out if need be, but I think until OneView allows persistent tokens, most users will use a username/password to log in at the beginning of the execution and never run into issues.

One possible solution I thought of would be to keep track of when the session was created & how long it would be valid, so that any time a rest call was made after it is expected to expire, we can automatically refresh the token. But again, I don't see it as a problem that needs to be solved at this point

@fgbulsoni
Copy link
Contributor

@marikrg Would you mind sharing how this was implemented on the Python SDK, for comparison purposes?
Are we supporting both the usage of tokens and username/password or just username/password there?
I'm trying to see if it would be worth putting any effort into having both of these ways implemented vs what we have now. Do you expect to run into issues with what @jsmartt has just mentioned?

@marikrg
Copy link
Author

marikrg commented Feb 9, 2017

The Python SDK authentication is based on the OneView / Image Streamer UI:

  1. Login into OneView.
  2. If you log in successfully, you will be able to access Image Streamer tool.

In the Python SDK, first of all, the user needs to create the OneViewClient:

oneview_client = OneViewClient.from_json_file(EXAMPLE_CONFIG_FILE)

You can check an example of json config file at: https://github.com/HewlettPackard/python-hpOneView/blob/master/examples/config-rename.json

Then, to create the ImageStreamerClient, you must call the create_image_streamer_client method from the previously created OneViewClient instance.

image_streamer_client = oneview_client.create_image_streamer_client()

@marikrg
Copy link
Author

marikrg commented Feb 9, 2017

In addition, in the Python SDK the user can provide either an username/password or a token.

@jsmartt
Copy link
Collaborator

jsmartt commented Feb 10, 2017

I like the create_image_streamer_client method. Perhaps that's something we can add.

@fgbulsoni
Copy link
Contributor

I like the create_image_streamer_client method.

I like it as well, and another plus side of this approach is that since it acts similarly to the way the GUI handles the authentication, it might be the way a customer would expect it to be done.

@aalexmonteiro
Copy link
Contributor

The way it was done in python is interesting. But I have some thoughts on this:

1-In Ruby we will have to remove the inheritance between oneview client and i3s client and use composition, this will imply code duplication. In python it has a bit of replication (I do not see problems),
But in the case of ruby, this replication would be slightly larger.

2-Although interesting, somehow we have two instance variables for each type of client.

Current code.

client = client = OneviewSDK::Client.new(params)
client_i3s = OneviewSDK::ImageStreamer::Client.new(client.token)

Proposed code

client = OneviewSDK::Client.new
client_i3s = client.create_i3s_client

I do not see any great advantage to change, since we will lose code reuse. That is my opinion, but that does not mean that I am right.

@tmiotto
Copy link
Contributor

tmiotto commented Feb 13, 2017

@aalexmonteiro

The idea is to make this token not visible to the end user, like in the proposed code.

I cannot see why it will be necessary to remove the inheritance, and if removing would cause code duplication.

Also, it would be easier for the tools to have a creation method passing both data in the params:
e.g.

def initialize(options = {})
  @token = if options[:oneview_client]
             @oneview_client = OneviewSDK::Client.new(options[:oneview_client])
             @oneview_client.token
           else
             options[:token] || ENV['I3S_TOKEN']
  [...]
end

Also, I noticed the initialize in the ImageStreamer::Client is almost completely duplicated, we have a lot of room for improvements there.

@aalexmonteiro
Copy link
Contributor

@tmiotto , I got it. Now that seems clear for me.

@ricardogpsf
Copy link
Member

I agree with @tmiotto about to pass data for initialize method of ImageStreamer::Client.
And more, I think so the options[:token] is unecessary and just options[:oneview_client] is necessary (or just an client instance of OneviewSDK::Client).
The end user should not know about token or about passing token.

@jsmartt
Copy link
Collaborator

jsmartt commented Feb 13, 2017

I think it's still good for the I3S client initialize method to have all the options that it has now, but it would be nice for the OV client to have the ov_client.new_i3s_client method to abstract those options where they are not needed. That way we can still have the flexibility of all the options, but the simplicity of a single method call. Plus, it's less typing than OneviewSDK::ImageStreamer::Client.new(oneview_client: ov_client).
I can see the method in discussion looking something like:

def new_i3s_client(opts = {})
  OneviewSDK::ImageStreamer::Client.new(opts.merge(token: @token))
end

And usage:

i3s_client = ov_client.new_i3s_client
# or
i3s_client = ov_client.new_i3s_client(api_ver: 300)

Simple, yet flexible

@tmiotto
Copy link
Contributor

tmiotto commented Feb 14, 2017

Yeah... this is a resonable solution, in the code it would look like:

@ov_client = OneviewSDK::Client.new(
  url: 'https://xxx.xxx.xxx.xxx',
  user: 'Admin',
  password: 'admin',
  ssl_enabled: true,
  api_version: 300
)

@i3s_client = @ov_client.new_i3s_client(
  url: 'https://yyy.yyy.yyy.yyy',
  ssl_enabled: true,
  api_version: 300
)

@fgbulsoni fgbulsoni changed the title [Question] Authenticate with either token or username/password (Image Streamer Client) Simplify login to i3s through oneview client Feb 14, 2017
@fgbulsoni
Copy link
Contributor

fgbulsoni commented Feb 14, 2017

Changing tittle since it seems we've all agreed it would be good/important to have this feature implemented.

@fgbulsoni fgbulsoni changed the title Simplify login to i3s through oneview client I3S - Simplify login to i3s through oneview client Feb 14, 2017
@aalexmonteiro aalexmonteiro self-assigned this Feb 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants