-
Notifications
You must be signed in to change notification settings - Fork 356
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
CRUD for embedded Ansible credentials #641
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
ManageIQ.angular.app.component('ansibleCredentialOptions', { | ||
bindings: { | ||
model: '=', | ||
options: '<', | ||
type: '<', | ||
}, | ||
|
||
controllerAs: 'vm', | ||
|
||
controller: ['$scope', function($scope) { | ||
$scope.__ = __; | ||
|
||
this.setOptions = function() { | ||
this.current_options = this.options[this.type]; | ||
}; | ||
|
||
this.$onInit = function() { | ||
this.setOptions(); | ||
}; | ||
|
||
this.$onChanges = function(changes) { | ||
this.setOptions(); | ||
}; | ||
}], | ||
|
||
template: [ | ||
'<div class="form-group" ng-repeat="(name, attr) in vm.current_options.attributes">', | ||
'<label class="control-label col-md-2">', | ||
'{{ __(attr.label) }}', | ||
'</label>', | ||
'<div ng-switch="attr.type" class="text">', | ||
// password | ||
'<div ng-switch-when="password" class="col-md-8">', | ||
'<input type="password" class="form-control" title="{{ __(attr.help_text) }}" ng-model="vm.model[name]">', | ||
'</div>', | ||
// select | ||
'<div ng-switch-when="choice" class="col-md-8">', | ||
'<select pf-select ng-options="opt as opt for opt in attr.choices" class="form-control" ng-model="vm.model[name]" />', | ||
'</div>', | ||
// text | ||
'<div ng-switch-when="string" class="col-md-8">', | ||
'<input type="text" class="form-control" title="{{ __(attr.help_text) }}" maxlength="{{ attr.max_length }}" ng-model="vm.model[name]">', | ||
'</div>', | ||
// default (text) | ||
'<div ng-switch-default class="col-md-8">', | ||
'<input type="text" class="form-control" title="{{ __(attr.help_text) }}" ng-model="vm.model[name]">', | ||
'</div>', | ||
'</div>', | ||
'</div>', | ||
].join('\n') | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
ManageIQ.angular.app.controller('ansibleCredentialsFormController', ['$window', 'credentialId', 'miqService', 'API', function($window, credentialId, miqService, API) { | ||
var vm = this; | ||
|
||
var init = function() { | ||
vm.credentialModel = { | ||
id: null, | ||
name: '', | ||
type: '', | ||
}; | ||
|
||
vm.credential_options = {}; | ||
vm.select_options = []; | ||
|
||
vm.newRecord = credentialId === 'new'; | ||
vm.afterGet = false; | ||
vm.model = 'credentialModel'; | ||
ManageIQ.angular.scope = vm; | ||
vm.saveable = miqService.saveable; | ||
|
||
miqService.sparkleOn(); | ||
|
||
// get credential specific options for all supported credential types | ||
API.options('/api/authentications') | ||
.then(getCredentialOptions) | ||
.catch(miqService.handleFailure); | ||
|
||
if (credentialId !== 'new') { | ||
API.get('/api/authentications/' + credentialId) | ||
.then(getCredentialFormData) | ||
.catch(miqService.handleFailure); | ||
} else { | ||
vm.select_options.push({'label':__('<Choose>'), 'value': ''}); | ||
// FIXME: this should go away once https://github.com/ManageIQ/manageiq/pull/14483 is merged | ||
vm.credentialModel.organization = 1; // work-around, organization id needs to be filled in automatically by the backend | ||
|
||
// credential creation requires manager_resource | ||
API.get('/api/providers?collection_class=ManageIQ::Providers::EmbeddedAutomationManager') | ||
.then(setManagerResource) | ||
.catch(miqService.handleFailure); | ||
|
||
vm.afterGet = true; | ||
vm.modelCopy = angular.copy( vm.credentialModel ); | ||
miqService.sparkleOff(); | ||
} | ||
}; | ||
|
||
vm.cancelClicked = function(angularForm) { | ||
if (credentialId === 'new') { | ||
getBack(__("Creation of new Credential was canceled by the user."), true); | ||
} else { | ||
getBack(sprintf(__("Edit of Credential \"%s\" was canceled by the user."), vm.credentialModel.name), true); | ||
} | ||
}; | ||
|
||
vm.resetClicked = function(angularForm) { | ||
vm.credentialModel = angular.copy( vm.modelCopy ); | ||
angularForm.$setPristine(true); | ||
miqService.miqFlash("warn", __("All changes have been reset")); | ||
}; | ||
|
||
vm.saveClicked = function(angularForm) { | ||
API.put('/api/authentications/' + credentialId, vm.credentialModel) | ||
.then(getBack(sprintf(__("Modification of Credential \"%s\" has been successfully queued."), vm.credentialModel.name), false)) | ||
.catch(miqService.handleFailure); | ||
}; | ||
|
||
vm.addClicked = function(angularForm) { | ||
addCredentialKind(); | ||
API.post('/api/authentications/', vm.credentialModel) | ||
.then(getBack(sprintf(__("Add of Credential \"%s\" has been successfully queued."), vm.credentialModel.name))) | ||
.catch(miqService.handleFailure); | ||
}; | ||
|
||
function getCredentialOptions(response) { | ||
Object.assign(vm.credential_options, response.data.credential_types.embedded_ansible_credential_types); | ||
|
||
for (var opt in vm.credential_options) { | ||
vm.select_options.push({'value': opt, 'label': vm.credential_options[opt].label}); | ||
} | ||
} | ||
|
||
function getCredentialFormData(response) { | ||
vm.credentialModel.id = response.id; | ||
vm.credentialModel.name = response.name; | ||
vm.credentialModel.type = response.type; | ||
|
||
// we need to merge options and vm.credentialModel | ||
for (var opt in response.options) { | ||
var item = vm.credential_options[vm.credentialModel.type]['attributes'][opt]; | ||
|
||
// void the password fields first | ||
if (item.hasOwnProperty('type') && item['type'] === 'password') { | ||
vm.credentialModel[opt] = ''; | ||
} else { | ||
vm.credentialModel[opt] = response.options[opt]; | ||
} | ||
} | ||
|
||
vm.modelCopy = angular.copy( vm.credentialModel ); | ||
vm.afterGet = true; | ||
miqService.sparkleOff(); | ||
} | ||
|
||
function getBack(message, warning = false, error = false) { | ||
var url = '/ansible_credential/show_list' + '?flash_msg=' + message + '&escape=true'; | ||
|
||
if (warning) { | ||
url += '&flash_warning=true&flash_error=false'; | ||
} else if (error) { | ||
url += '&flash_warning=false&flash_error=true'; | ||
} | ||
|
||
$window.location.href = url; | ||
} | ||
|
||
function setManagerResource(response) { | ||
vm.credentialModel.manager_resource = { "href": response.resources[0].href }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm aware that the credential API backend changes are still not complete in many respects, and some of the code here is subject to change... So why set the Does this need to be a dropdown that the user can pick a value from during credential creation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No dropdown. The concept is that there will be one embedded Ansible provider (that's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not sure I understand this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point of embedded ansible is that it's embedded in the appliance, so there's only one, ever. The API returns a list because it's the API and we want it consistent with all the other API calls, but AFAIK there can't ever be more than one embedded ansible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
And that's the clarification I was looking for. Thanks @himdel There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mzazrivec Agreed... I was thinking out loud here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jameswnl There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if I understand the needs of
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jameswnl I actually meant the We do need the It seems only logical to send the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding is that the convention for |
||
} | ||
|
||
// FIXME: this should go away once https://github.com/ManageIQ/manageiq/pull/14483 is merged | ||
// For creation, we need to send json like: {"kind": "scm", "type": "ManageIQ::Providers::EmbeddedAnsible::AutomationManager::ScmCredential"} | ||
function addCredentialKind() { | ||
vm.credentialModel.kind = vm.credential_options[vm.credentialModel.type].type; | ||
} | ||
|
||
init(); | ||
}]); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class ApplicationHelper::Toolbar::AnsibleCredentialCenter < ApplicationHelper::Toolbar::Basic | ||
button_group('ansible_repository', [ | ||
select( | ||
:ansible_credential_configuration, | ||
'fa fa-cog fa-lg', | ||
t = N_('Configuration'), | ||
t, | ||
:items => [ | ||
button( | ||
:embedded_automation_manager_credentials_edit, | ||
'pficon pficon-edit fa-lg', | ||
t = N_('Edit this Credential'), | ||
t, | ||
:url => "/edit"), | ||
button( | ||
:embedded_automation_manager_credentials_delete, | ||
'pficon pficon-delete fa-lg', | ||
t = N_('Remove this Credential'), | ||
t, | ||
:url_parms => "&refresh=y", | ||
:confirm => N_("Warning: The selected Credential will be permanently removed!")), | ||
] | ||
), | ||
]) | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
class ApplicationHelper::Toolbar::AnsibleCredentialsCenter < ApplicationHelper::Toolbar::Basic | ||
button_group('embedded_ansible_credentials', [ | ||
select( | ||
:embedded_ansible_credentials_configuration, | ||
'fa fa-cog fa-lg', | ||
t = N_('Configuration'), | ||
t, | ||
:items => [ | ||
button( | ||
:embedded_automation_manager_credentials_add, | ||
'pficon pficon-edit fa-lg', | ||
t = N_('Add New Credential'), | ||
t, | ||
:url_parms => "new_div"), | ||
button( | ||
:embedded_automation_manager_credentials_edit, | ||
'pficon pficon-edit fa-lg', | ||
t = N_('Edit this Credential'), | ||
t, | ||
:enabled => false, | ||
:onwhen => "1", | ||
:url_parms => "edit_div"), | ||
button( | ||
:embedded_automation_manager_credentials_delete, | ||
'pficon pficon-delete fa-lg', | ||
t = N_('Remove selected Credentials'), | ||
t, | ||
:url_parms => "delete_div", | ||
:enabled => false, | ||
:onwhen => "1+", | ||
:confirm => N_("Warning: The selected Credentials will be permanently removed!")), | ||
] | ||
) | ||
]) | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
%br | ||
.form-horizontal | ||
%form#form_div{'name' => 'angularForm', | ||
'ng-controller' => 'ansibleCredentialsFormController as vm', | ||
'ng-show' => 'vm.afterGet', | ||
'ng-cloak' => '', | ||
'miq-form' => true, | ||
'model' => 'vm.credentialModel', | ||
'model-copy' => 'vm.modelCopy', | ||
'novalidate' => true} | ||
= render :partial => "layouts/flash_msg" | ||
.form-group{"ng-class" => "{'has-error': angularForm.name.$invalid}"} | ||
%label.col-md-2.control-label | ||
= _('Name') | ||
.col-md-8 | ||
%input.form-control{:type => "text", | ||
:name => "name", | ||
"id" => "name", | ||
'ng-model' => "vm.credentialModel.name", | ||
:maxlength => MAX_NAME_LEN, | ||
:required => true, | ||
:checkchange => true, | ||
"auto-focus" => ""} | ||
%span.help-block{"ng-show" => "angularForm.name.$error.required"} | ||
= _("Required") | ||
.form-group | ||
%label.col-md-2.control-label | ||
= _('Credential type') | ||
- if @id == 'new' # we don't allow changing auth. type when editing a resource | ||
.col-md-8 | ||
%select{'ng-model' => 'vm.credentialModel.type', | ||
'ng-options' => 'cred.value as cred.label for cred in vm.select_options', | ||
'required' => 'true', | ||
'pf-select' => 'true'} | ||
- else | ||
.col-md-8 | ||
{{ vm.credential_options[vm.credentialModel.type].label }} | ||
|
||
%ansible-credential-options{:model => 'vm.credentialModel', | ||
:options => 'vm.credential_options', | ||
:type => 'vm.credentialModel.type'} | ||
|
||
= render :partial => 'layouts/angular/generic_form_buttons' | ||
|
||
:javascript | ||
ManageIQ.angular.app.value('credentialId', '#{@id}'); | ||
miq_bootstrap('#form_div'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#main_div | ||
= render :partial => 'credential_form', :locals => {:newRecord => false} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#main_div | ||
= render :partial => 'credential_form', :locals => {:newRecord => 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.
After #783 merge, the
.catch
will now catch the API failures, but those need to be visible to the user as flash messages.Created a PR #805 that will display the error message flash.