-
Notifications
You must be signed in to change notification settings - Fork 141
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
OPTIONS for /api/providers #3
Conversation
@jntullo @abellotti PTAL |
.select { |param| param.starts_with?("ems_type") } # 'parameters with "ems_type" name | ||
.first.split('=').last # choosing only the first occuracne. | ||
ems_class = ExtManagementSystem.descendants.select { |ems| ems.ems_type == req_class_name }.first | ||
render :json => ems_class.respond_to?(:provider_settings) ? ems_class.provider_settings : {} |
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 you will want to use render_options(:providers, <your provider settings hash)
here. This will return all of the default options that are passed back from OPTIONS /providers
, and append your provider settings hash to it.
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.
@jntullo I changed to render_options
24a210d
to
9fb1dfc
Compare
.split('?').last.split('&') # '?' for query, '&' connects parameters | ||
.select { |param| param.starts_with?("ems_type") } # 'parameters with "ems_type" name | ||
.first.split('=').last # choosing only the first occuracne. | ||
ems_class = ExtManagementSystem.descendants.select { |ems| ems.ems_type == req_class_name }.first |
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.
missed this earlier, but you should be able to get the ems type from just params[:ems_type]. Then you can actually use ExtManagementSystem.descendant_get(params[:ems_type])
here. That will return the descendant. An example of its usage can be found https://github.com/ManageIQ/manageiq-api/blob/master/lib/services/api/authentication_service.rb#L4
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.
@jntullo I didn't know of descendant_get
before, but I am not sure it will help here because it will require sending the full class name (ie ManageIQ::Providers::Openshift::ContainerManager
) instead of the ems_type
reported by the providers. I will change to use params[:ems_type]
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.
@enoodle ah, gotcha! yeah, then descendant_get
won't work.
this is just nit but you could do ExtManagementSystem.descendants.find { |ems| ems.ems_type == params[:ems_type] }
9fb1dfc
to
c256d49
Compare
spec/requests/api/providers_spec.rb
Outdated
context "#options" do | ||
it "returns options for queried provider class" do | ||
api_basic_authorize | ||
ExtManagementSystem.descendants.select { |ems| ems.respond_to?(:provider_settings) }.each do |ems_type| |
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.
one last thing 😄 you can simplify the spec by using expect_options_results
, example here: https://github.com/ManageIQ/manageiq-api/blob/master/spec/requests/api/authentications_spec.rb#L480
c256d49
to
cfc7b9a
Compare
spec/requests/api/providers_spec.rb
Outdated
|
||
context "#options" do | ||
it "returns options for queried provider class" do | ||
api_basic_authorize |
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.
Doing an OPTIONS request shouldn't require authorization
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.
@imtayadeway I am not sure how to remove this requirement. I also see this in many other examples: cluster, hosts, authentications. How do you suggest solving this?
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 didn't realize this was still an issue.....I created #8 to resolve this
@@ -85,6 +85,11 @@ def import_vm_resource(type, id = nil, data = {}) | |||
end | |||
end | |||
|
|||
def options | |||
ems_class = ExtManagementSystem.descendants.find { |ems| ems.ems_type == params[:ems_type] } | |||
render_options(:providers, ems_class.respond_to?(:provider_settings) ? ems_class.provider_settings : {}) |
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.
It looks like you don't render anything when you don't provide the ems_type
param. Did you you consider rendering all the EMSs and their provider settings and leaving it to the client to figure out?
spec/requests/api/providers_spec.rb
Outdated
context "#options" do | ||
it "returns options for queried provider class" do | ||
api_basic_authorize | ||
ExtManagementSystem.descendants.select { |ems| ems.respond_to?(:provider_settings) }.each do |ems_type| |
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.
Your test logic here mirrors that of the implementation, so I'm wondering what value this test is providing? IMO, using literals to represent expected values is much clearer and will provide useful feedback in the case of breakages or false assumptions about the implementations.
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.
@imtayadeway doing so will force me to use specific providers names as this is only implemented for "ManageIQ::Providers::Kubernetes::ContainerManager" currently. I am afraid of breaking tests when things changes in another repo (ie someone will change the way options are saved there and tests here will be red). I also agree that the test logic is not super helpful but it helped me.
I will try to add a test with this provider and options that I don't think will change anytime soon.
fe1ba1f
to
af45586
Compare
af45586
to
1e2b12f
Compare
@@ -85,6 +85,21 @@ def import_vm_resource(type, id = nil, data = {}) | |||
end | |||
end | |||
|
|||
def options | |||
if params[:ems_type].blank? |
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 still have concerns over this param and its discoverability. At present AFAICT it is not discoverable, meaning it will have to be documented somewhere, and I'm not totally comfortable with adding complexity to OPTIONS calls. Is it needed?
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.
It is not a must, but I though it will be nice. I don't mind documenting it (where?) but I can also remove this.
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.
See also #3 (comment) for my explanation there - I think I'd prefer not including this unless there is a distinct need for it. If that is the case, I suspect OPTIONS might not be the right solution
if params[:ems_type].blank? | ||
all_options = Hash[ | ||
ExtManagementSystem.descendants.collect do |ems| | ||
[ems.ems_type, ems.respond_to?(:provider_settings) ? ems.provider_settings : {}] |
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.
Do provider settings come from the Settings
object? Could this information be got at through the settings API?
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.
No, they come from "per-provider" options, for example: ManageIQ/manageiq-providers-kubernetes#45
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.
Is there a reason that's not in here ?
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.
Yes, those options themselves are per provider instance.
What I am serving here are only their descriptions but belong there as they are static and not configurable.
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'm not sure I follow? I'd expect per-instance settings to be revealed via GETs to the collection member URI. We augment OPTIONS responses only as a limited way to reveal metadata - i.e. data about the resource itself in the abstract.
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.
Right. But here we are not serving the values of those options but the answer to the question "what per-provider options are for this provider type?". This is the static description of those options. please look at https://github.com/ManageIQ/manageiq-providers-kubernetes/pull/45/files#diff-47711b761083b6ce40dacb7d3ee68f8b for example
spec/requests/providers_spec.rb
Outdated
|
||
context "OPTIONS /api/providers" do | ||
it "returns options for all providers when no query" do | ||
api_basic_authorize |
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.
Now that #8 has been merged you can remove this and subsequent calls to api_basic_authorize
317ad45
to
7f6d4c0
Compare
@@ -85,6 +85,16 @@ def import_vm_resource(type, id = nil, data = {}) | |||
end | |||
end | |||
|
|||
def options | |||
all_options = Hash[ | |||
ExtManagementSystem.descendants.collect do |ems| |
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.
Prefer inject
or each_with_object
here
[ems.ems_type, ems.respond_to?(:provider_settings) ? ems.provider_settings : {}] | ||
end | ||
] | ||
all_options.delete(nil) |
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.
Which EMSs have an ems_type
of nil
?
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.
ExtManagementSystem.descendants.select { |ems| ems.ems_type == nil }.map { |ems| ems.name }
=> ["ManageIQ::Providers::BaseManager",
"ManageIQ::Providers::DatawarehouseManager",
"ManageIQ::Providers::MiddlewareManager",
"ManageIQ::Providers::NetworkManager",
"ManageIQ::Providers::ProvisioningManager",
"ManageIQ::Providers::AutomationManager",
"ManageIQ::Providers::CloudManager",
"ManageIQ::Providers::ContainerManager",
"ManageIQ::Providers::ConfigurationManager",
"ManageIQ::Providers::StorageManager",
"ManageIQ::Providers::InfraManager",
"ManageIQ::Providers::EmbeddedAutomationManager",
"ManageIQ::Providers::ExternalAutomationManager"]
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.
Will .leaf_subclasses
give you what you need?
7f6d4c0
to
accf865
Compare
@enoodle just one more suggestion in #3 (comment). Thanks! |
c5a6fe3
to
3150fdb
Compare
@imtayadeway PTAL |
@@ -85,6 +85,13 @@ def import_vm_resource(type, id = nil, data = {}) | |||
end | |||
end | |||
|
|||
def options | |||
all_options = ExtManagementSystem.leaf_subclasses.inject({}) do |ao, ems| | |||
ao.merge(ems.ems_type => ems.respond_to?(:provider_settings) ? ems.provider_settings : {}) |
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.
It's unfortunate that not all EMSs respond to this message. Though I think this if fine for now - do you think you could follow this up by trying to push this default down into the base class?
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.
Yes. I changed this to address leaf_subclasses
of ManageIQ::Providers::BaseManager
instead of ExtManagementSystem
and it will be easy to add
def self.provider_settings()
{}
end
to this class.
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.
spec/requests/providers_spec.rb
Outdated
it "returns options for all providers when no query" do | ||
run_options(providers_url) | ||
expect(response.parsed_body["data"].keys.count).to eq( | ||
ExtManagementSystem.leaf_subclasses.select { |ems| !ems.ems_type.blank? }.count |
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 there any leaf subclasses for which this is not true?
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.
No (that I know of), but if a new one will be created I think it will break this test. I will remove the select
.
3150fdb
to
44e7509
Compare
@imtayadeway PTAL |
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.
LGTM! Thanks @enoodle for your patience with my many questions.
Off to @abellotti
@miq-bot add_label wip |
@imtayadeway @abellotti with ManageIQ/manageiq#15799 being approved, can we merge this one? |
@@ -86,6 +86,13 @@ def import_vm_resource(type, id = nil, data = {}) | |||
end | |||
end | |||
|
|||
def options | |||
all_options = ManageIQ::Providers::BaseManager.leaf_subclasses.inject({}) do |ao, ems| | |||
ao.merge(ems.ems_type => ems.respond_to?(:options_description) ? ems.options_description : {}) |
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.
@enoodle if ManageIQ/manageiq#15799 is merged, can you remove this respond_to?
?
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.
Changed, tests here will only be green after ManageIQ/manageiq#15799 is merged
1aa3e25
to
87c533f
Compare
@enoodle can you attach sample output you're getting with OPTIONS /api/providers ? just the data part of the output is sufficient. Thanks. |
Output example from current masters: |
I wonder if there might be some common options we'd want to provide in the future for all providers, in which case we may want to nest the output one level down, i.e.
|
@abellotti Then you suggest to have the common options description under "provider_settings"? It will make for a more compact output, but will be more awkward to consume so I don't like it too much. |
@enoodle true, it is an extra level to fetch, but would keep the return signature future-proof. |
87c533f
to
37f3b81
Compare
@abellotti 👍 I added the "provider_settings" step. |
37f3b81
to
cb3b52c
Compare
Checked commit enoodle@cb3b52c with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 app/controllers/api/providers_controller.rb
|
Travis for this seems to be broken as it is testing the wrong commit. I will close this one to open a new PR. |
This is a migration of ManageIQ/manageiq#15660