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

Use API to get block storage manager for volumes #861

Closed

Conversation

gberginc
Copy link
Contributor

Instead of using instance variables to pass the list of available block storage managers to the form we are exploiting the capabilities of the API to return the list of storage managers supporting block_storage.

This patch removes the logic from the ruby controller and adds the required API calls to the JS controller. In order to deal with the asynchronous nature of data retrieval, this patch also changes how afterGet is set to ensure that all the required information is in place.

A video showing the form for creating new cloud volumes: http://x.k00.fr/ha2qj.

It first shows how the form behaves when cloud volumes are created for a specific block storage manager and then also how it behaves when creating a volume from the list of volumes from all block storage managers.

@miq-bot add_label storage,refactoring
@miq-bot assign @AparnaKarve

/cc @miha-plesko Could be useful with regards to #651.

@@ -269,13 +269,8 @@ def new
assert_privileges("cloud_volume_new")
@volume = CloudVolume.new
@in_a_form = true
@storage_manager_choices = {}
if params[:storage_manager_id]
@storage_manager_id = params[:storage_manager_id]
Copy link
Contributor

@AparnaKarve AparnaKarve Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gberginc This line seems to be causing the Hakiri Security issue.
Is there any other way we could retrieve the Storage Manager id here without directly assigning params[:storage_manager_id] ?

I guess an alternate approach (somewhat roundabout route) would be to loop through all EMSes that have supports_block_storage? = true and look for the one that matches params[:storage_manager_id]

@gberginc gberginc force-pushed the use_api_in_cloud_volume_controller branch from 9c64c59 to b5c1027 Compare March 31, 2017 04:16
@gberginc
Copy link
Contributor Author

@AparnaKarve I have added two commits, one passing Hakiri, the other surprisingly not...

First will query the DB and look for the storage manager with that specific ID. It will then store the whole storage manager into an instance variable. I am not completely sure what you meant by looping through all EMSes, but I guess this is something similar.

Second commit fails. I am more in favour of this one because I think it is safe and we only ever use the ID. But Hakiri doesn't agree. It basically ensures the given storage_manager_id is an Integer and passes it to the form - if it's not an integer, it will be set to nil due to exception in Integer(params[:storage_manager]). For example, http://localhost:3000/cloud_volume/new?storage_manager_id=abrakadabra will result in storage_manager_id = nil. The only consequence of this is that the select will not be pre-populated (check screenshot).

screen shot 2017-03-31 at 06 22 34

However, since I am nowhere near being an expert in XSS, I have no idea if someone can exploit something like this.

Can you please check if any of the two commits works for you and I'll then remove the other one?

@gberginc
Copy link
Contributor Author

Nah, even rubocop doesn't like my proposal 😄.

@@ -180,5 +177,19 @@ ManageIQ.angular.app.controller('cloudVolumeFormController', ['$scope', 'miqServ
}
};

var formOptions = function() {
API.get("/api/providers?expand=resources&attributes=id,name&filter[]=supports_block_storage?=true").then(function(data) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does every StorageManager that supports :block_storage feature also supports creation of new cloud volumes? At the moment this seems to be true (since only OpenStack and Amazon support object storage), but will it always be true? When someone implements inventory (e.g. for Azure) it will appear on this list even if creating new volumes is not implemented yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This code is currently only replacing the existing logic which filtered with supports_block_storage?. In EBS, supports_create? is only available in the CloudVolume so I am not sure how to check for that or even if it makes sense at this point.

@gberginc gberginc force-pushed the use_api_in_cloud_volume_controller branch 2 times, most recently from f9f058e to c87754f Compare March 31, 2017 07:50
@gberginc
Copy link
Contributor Author

@AparnaKarve @miha-plesko has suggested the use of ERB::Util.escape which I did in c87754f, but Hakiri still complains. Pure logic tells me that the second commit should be sufficient, but I am no longer sure.

@AparnaKarve
Copy link
Contributor

@gberginc Probably all you need is this:

@storage_manager = find_record_with_rbac(ExtManagementSystem, params[:storage_manager_id])

and this:

ManageIQ.angular.app.value('storageManagerId', '#{@storage_manager.try(:id)}');

Can you give that a try?

@gberginc gberginc force-pushed the use_api_in_cloud_volume_controller branch 2 times, most recently from 8d5325f to 8a5ab64 Compare March 31, 2017 18:01
@gberginc
Copy link
Contributor Author

@AparnaKarve that was similar to the first proposed solution. If it's ok with you, it is also ok with me. If an illegal storage_manager_id, it will (check screenshot):

screen shot 2017-03-31 at 20 03 42

@AparnaKarve
Copy link
Contributor

@gberginc Yes, very similar to your first try.

Why would storage_manager_id ever be invalid?

@gberginc
Copy link
Contributor Author

@AparnaKarve only is the user would alter the ID :-D

Instead of using instance variables to pass the list of available block
storage managers to the form we are exploiting the capabilities of the
API to return the list of storage managers supporting `block_storage`.

This patch removes the logic from the ruby controller and adds the
required API calls to the JS controller. In order to deal with the
asynchronous nature of data retrieval, this patch also changes how
`afterGet` is set to ensure that all the required information is in
place.
@gberginc gberginc force-pushed the use_api_in_cloud_volume_controller branch from 8a5ab64 to 93dd8e0 Compare March 31, 2017 18:50
@miq-bot
Copy link
Member

miq-bot commented Mar 31, 2017

Checked commit gberginc@93dd8e0 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
1 file checked, 0 offenses detected
Everything looks good. 🍪

@AparnaKarve
Copy link
Contributor

only is the user would alter the ID :-D

Ok, in that case, nothing to worry about :)

miqService.sparkleOff();
});
};

Copy link
Contributor

@AparnaKarve AparnaKarve Mar 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gberginc Can you add a .catch block here to catch failures?

We typically write API.get like this --

API.get(url)
  .then(getData)
  .catch(miqService.handleFailure);

The .catch did not work before (one of the reasons why I didn't suggest using it before), but it has been fixed now.

@AparnaKarve
Copy link
Contributor

Other than the above comment, LGTM.

@gberginc
Copy link
Contributor Author

gberginc commented Apr 6, 2017

@AparnaKarve Closing in favour of #950. It turned out that just the changes in this PR did not suffice for a more general approach to show the proper edit form.

@gberginc gberginc closed this Apr 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants