Cloud credentials support and UI built in implementation for phoenixNAP node driver (#4380)

* Cloud credentials support for phoenixNAP driver.

* space added

* code formatting

* init function removed, name param removed from the arrays that populate
dropdowns

Co-authored-by: pavlej <pavlej@NSDT-PAVLEJ.ccbill-hq.local>
This commit is contained in:
pajuga 2021-01-13 20:57:13 +01:00 committed by GitHub
parent 960da87b24
commit eb1abb00f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 299 additions and 6 deletions

View File

@ -20,15 +20,18 @@ const cloudCredential = Resource.extend({
isDo: notEmpty('digitaloceancredentialConfig'),
isLinode: notEmpty('linodecredentialConfig'),
isOCI: notEmpty('ocicredentialConfig'),
isPNAP: notEmpty('pnapcredentialConfig'),
isVMware: notEmpty('vmwarevspherecredentialConfig'),
displayType: computed('amazonec2credentialConfig', 'azurecredentialConfig', 'digitaloceancredentialConfig', 'linodecredentialConfig', 'ocicredentialConfig', 'vmwarevspherecredentialConfig', function() {
displayType: computed('amazonec2credentialConfig', 'azurecredentialConfig', 'digitaloceancredentialConfig', 'linodecredentialConfig', 'ocicredentialConfig', 'pnapcredentialConfig', 'vmwarevspherecredentialConfig', function() {
const {
isAmazon,
isAzure,
isDo,
isLinode,
isOCI,
isPNAP,
isVMware
} = this;
@ -42,6 +45,8 @@ const cloudCredential = Resource.extend({
return 'Linode';
} else if (isOCI) {
return 'OCI';
} else if (isPNAP) {
return 'phoenixNAP';
} else if (isVMware) {
return 'VMware vSphere';
}

View File

@ -4,7 +4,7 @@ import Resource from '@rancher/ember-api-store/models/resource';
import C from 'ui/utils/constants';
import { parseExternalId } from 'ui/utils/parse-externalid';
export const BUILT_IN_UI = ['amazonec2', 'digitalocean', 'azure', 'exoscale', 'packet', 'rackspace', 'vmwarevsphere', 'aliyunecs', 'oci'];
export const BUILT_IN_UI = ['amazonec2', 'digitalocean', 'azure', 'exoscale', 'packet', 'pnap', 'rackspace', 'vmwarevsphere', 'aliyunecs', 'oci'];
export const BUILT_IN_ICON_ONLY = ['openstack', 'otc'];
function displayUrl(url) {

View File

@ -103,6 +103,10 @@
background-image: url('images/providers/packet.svg');
}
@mixin pnap {
background-image: url('images/providers/pnap.svg');
}
@mixin rackspace {
background-image: url('images/providers/rackspace.svg');
}

View File

@ -199,6 +199,7 @@ $badge-partner: $warning;
&.openstack { @include openstack; }
&.other { @include other; }
&.packet { @include packet; }
&.pnap { @include pnap; }
&.rackspace { @include rackspace; }
&.rancherdo { @include rancherdo;}
&.vmwarevsphere { @include vmwarevsphere; }

View File

@ -56,6 +56,7 @@
&.oci { @include oci; }
&.openstack { @include openstack; }
&.packet { @include packet; }
&.pnap { @include pnap; }
&.rackspace { @include rackspace; }
&.vmwarevsphere { @include vmwarevsphere; }
&.other { @include other; }

View File

@ -33,6 +33,12 @@ const CRED_CONFIG_CHOICES = [
driver: 'oci',
configField: 'ocicredentialConfig',
},
{
name: 'pnap',
displayName: 'phoenixNAP',
driver: 'pnap',
configField: 'pnapcredentialConfig',
},
{
name: 'linode',
displayName: 'Linode',
@ -110,7 +116,7 @@ export default Component.extend(ViewNewEdit, {
},
},
config: computed('cloudCredentialType', 'model.{amazonec2credentialConfig,azurecredentialConfig,digitaloceancredentialConfig,linodecredentialConfig,ocicredentialConfig,vmwarevspherecredentialConfig}', function() {
config: computed('cloudCredentialType', 'model.{amazonec2credentialConfig,azurecredentialConfig,digitaloceancredentialConfig,linodecredentialConfig,ocicredentialConfig,pnapcredentialConfig,vmwarevspherecredentialConfig}', function() {
const { model } = this;
const configField = this.getConfigField();
@ -145,6 +151,7 @@ export default Component.extend(ViewNewEdit, {
case 'linode':
return 'modalAddCloudKey.saving.validating';
case 'oci':
case 'pnap':
case 'azure':
case 'vmware':
default:

View File

@ -258,6 +258,37 @@
</div>
{{else if (eq cloudCredentialType "pnap")}}
<div class="row">
<div class="col span-6">
<label class="acc-label" for="pnap-client-identifier">
{{t "modalAddCloudKey.pnap.clientIdentifier.label"}}{{field-required}}
</label>
{{input
type="text"
value=config.clientIdentifier
classNames="form-control"
id="pnap-client-identifier"
placeholder=(t "modalAddCloudKey.pnap.clientIdentifier.placeholder")
}}
</div>
<div class="col span-6">
<label class="acc-label" for="pnap-client-secret">
{{t "modalAddCloudKey.pnap.clientSecret.label"}}{{field-required}}
</label>
{{input
type="password"
value=config.clientSecret
classNames="form-control"
id="pnap-client-secret"
placeholder=(t "modalAddCloudKey.pnap.clientSecret.placeholder")
}}
<p class="text-info">
{{t "modalAddCloudKey.pnap.clientSecret.help" htmlSafe=true}}
</p>
</div>
</div>
{{else if (eq cloudCredentialType "vmware")}}
<div class="row">
<div class="col span-6">

View File

@ -0,0 +1,86 @@
import { alias } from '@ember/object/computed';
import { get, set } from '@ember/object';
import Component from '@ember/component';
import NodeDriver from 'shared/mixins/node-driver';
import layout from './template';
import { inject as service } from '@ember/service';
const DRIVER = 'pnap';
const CONFIG = 'pnapConfig';
const LOCATION_CHOICES = [
{ value: 'PHX' },
{ value: 'ASH' }
];
const OS_CHOICES = [
{ value: 'ubuntu/bionic' },
{ value: 'centos/centos7' }
];
const TYPE_CHOICES = [
{ value: 's1.c1.small' },
{ value: 's1.c1.medium' },
{ value: 's1.c2.medium' },
{ value: 's1.c2.large' },
{ value: 'd1.c1.small' },
{ value: 'd1.c1.medium' },
{ value: 'd1.c1.large' },
{ value: 'd1.m1.medium' }
];
export default Component.extend(NodeDriver, {
intl: service(),
layout,
driverName: DRIVER,
locationChoices: LOCATION_CHOICES,
osChoices: OS_CHOICES,
typeChoices: TYPE_CHOICES,
model: null,
config: alias(`model.${ CONFIG }`),
actions: {
finishAndSelectCloudCredential(credential) {
set(this, 'model.cloudCredentialId', get(credential, 'id'))
}
},
bootstrap() {
let config = get(this, 'globalStore').createRecord({
type: CONFIG,
serverLocation: 'PHX',
serverType: 's1.c1.medium',
serverOs: 'ubuntu/bionic',
serverHostname: 'host'
});
set(this, `model.${ CONFIG }`, config);
},
validate() {
this._super();
let errors = get(this, 'errors') || [];
if ( !get(this, 'model.name') ) {
errors.push(this.intl.t('nodeDriver.nameError'));
}
if (!this.validateCloudCredentials()) {
errors.push(this.intl.t('nodeDriver.cloudCredentialError'))
}
if (errors.length) {
set(this, 'errors', errors.uniq());
return false;
}
return true;
},
});

View File

@ -0,0 +1,112 @@
{{#accordion-list showExpandAll=false as | al expandFn |}}
<div class="over-hr">
<span>
{{driverOptionsTitle}}
</span>
</div>
{{#accordion-list-item
title=(t "nodeDriver.pnap.access.title")
detail=(t "nodeDriver.pnap.access.detail")
expandAll=expandAll
expand=(action expandFn)
expandOnInit=true
}}
{{form-auth-cloud-credential
driverName=driverName
parseAndCollectErrors=(action "errorHandler")
primaryResource=primaryResource
cloudCredentials=cloudCredentials
finishAndSelectCloudCredential=(action "finishAndSelectCloudCredential")
progressStep=(action "finishAndSelectCloudCredential")
cancel=(action "cancel")
hideSave=true
}}
{{/accordion-list-item}}
{{#accordion-list-item
title=(t "nodeDriver.pnap.serverDetails.title")
detail=(t "nodeDriver.pnap.serverDetails.detail")
expandAll=expandAll
expand=(action expandFn)
expandOnInit=true
}}
<div class="row">
<div class="col span-6">
<label class="acc-label">
{{t "nodeDriver.pnap.location.label"}}
</label>
{{new-select
classNames="form-control"
content=locationChoices
optionLabelPath="value"
value=config.serverLocation
}}
</div>
<div class="col span-6">
<label class="acc-label">
{{t "nodeDriver.pnap.type.label"}}
</label>
{{new-select
classNames="form-control"
content=typeChoices
optionLabelPath="value"
value=config.serverType
}}
</div>
</div>
<div class="row">
<div class="col span-6">
<label class="acc-label">
{{t "nodeDriver.pnap.os.label"}}
</label>
{{new-select
classNames="form-control"
content=osChoices
optionLabelPath="value"
value=config.serverOs
}}
</div>
</div>
{{/accordion-list-item}}
<div class="over-hr">
<span>
{{templateOptionsTitle}}
</span>
</div>
{{form-name-description
model=model
nameRequired=true
rowClass="row mb-10"
}}
{{form-user-labels
initialLabels=labelResource.labels
setLabels=(action "setLabels")
expand=(action expandFn)
}}
{{form-node-taints
model=model
expand=(action expandFn)
}}
{{form-engine-opts
machine=model
showEngineUrl=showEngineUrl
}}
{{top-errors
errors=errors
}}
{{save-cancel
save=(action "save")
cancel=(action "cancel")
editing=editing
}}
{{/accordion-list}}

View File

@ -0,0 +1 @@
export { default } from 'nodes/components/driver-pnap/component';

View File

@ -79,6 +79,10 @@ function _initBuiltInSizes() {
driver: 'packet',
keyOrKeysToWatch: 'config.plan',
},
{
driver: 'pnap',
keyOrKeysToWatch: 'config.serverType',
},
{
driver: 'rackspace',
keyOrKeysToWatch: 'config.flavorId',
@ -135,6 +139,10 @@ function _initBuiltInLocations() {
driver: 'packet',
keyOrKeysToWatch: 'config.facilityCode',
},
{
driver: 'pnap',
keyOrKeysToWatch: 'config.serverLocation',
},
{
driver: 'rackspace',
keyOrKeysToWatch: 'config.region',
@ -270,6 +278,11 @@ export default Mixin.create(NewOrEdit, ManageLabels, {
return cc;
}
break;
case 'pnap':
if (get(cc, 'isPNAP')) {
return cc;
}
break;
case 'vmwarevsphere':
if (get(cc, 'isVMware')) {
return cc;
@ -336,7 +349,7 @@ export default Mixin.create(NewOrEdit, ManageLabels, {
},
validateCloudCredentials() {
const driversToValidate = ['amazonec2', 'azure', 'digitalocean', 'linode', 'vmwarevsphere'];
const driversToValidate = ['amazonec2', 'azure', 'digitalocean', 'linode', 'pnap', 'vmwarevsphere'];
let { driverName } = this;
let { cloudCredentialId } = this.model;
let valid = false;

View File

@ -0,0 +1 @@
<svg id="pnap" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><g id="Logo_Globe_Color" data-name="Logo Globe Color"><rect id="bg" width="100" height="100" style="fill:none"/><path id="Path_2569" data-name="Path 2569" d="M73.87,26.76h-.53a49.2,49.2,0,0,0-11.72,1.42,6.49,6.49,0,0,0-1-1.63A48.26,48.26,0,0,1,67,21a27.26,27.26,0,0,1,6.86,5.8M44,63.21a5.59,5.59,0,0,0-3,1.41,47.64,47.64,0,0,1-6.38-8.24,6.41,6.41,0,0,0,1.29-9,6.12,6.12,0,0,0-.72-.8A50.88,50.88,0,0,1,51,34a5.26,5.26,0,0,0,.79,1.08A55.58,55.58,0,0,0,44,63.21m7.75-46.75a28.72,28.72,0,0,1,13.61,3.42,50.35,50.35,0,0,0-6.12,5.47,5.85,5.85,0,0,0-3-.86,6.18,6.18,0,0,0-6.07,6.29,6.55,6.55,0,0,0,.21,1.52,52.57,52.57,0,0,0-16.6,13.28,5.53,5.53,0,0,0-4.29-.38A56.82,56.82,0,0,1,26.8,30.35,29.74,29.74,0,0,1,51.72,16.46m-26.5,16.7a55.91,55.91,0,0,0,2.57,12.75A6.42,6.42,0,0,0,25,51.17a6.32,6.32,0,0,0,2,4.61,51.21,51.21,0,0,0-2.1,4.88,31.75,31.75,0,0,1-3-13.39,32.14,32.14,0,0,1,3.35-14.11M26,62.83a54.7,54.7,0,0,1,2.52-6,6,6,0,0,0,2.62.65A7.05,7.05,0,0,0,33,57.19,50,50,0,0,0,39.78,66a6.4,6.4,0,0,0-1,3.48,6.19,6.19,0,0,0,6.07,6.29c.16,0,.32-.06.47-.06l.47,1.95A30.09,30.09,0,0,1,26,62.83M47.69,77.91c-.27-.87-.47-1.74-.68-2.6a5.87,5.87,0,0,0,2.3-1.63,54.37,54.37,0,0,0,7.86,4,30.61,30.61,0,0,1-5.4.54,32.68,32.68,0,0,1-4.08-.33m12.56-1a48.85,48.85,0,0,1-10-4.78,6.75,6.75,0,0,0,.63-2.76,6.21,6.21,0,0,0-5.19-6.19,53.57,53.57,0,0,1,7.44-27.06,5.62,5.62,0,0,0,3,.86,6.19,6.19,0,0,0,6.08-6.29,5.77,5.77,0,0,0-.11-.92,48.52,48.52,0,0,1,11.26-1.3c.68,0,1.36.05,2,.05a31.54,31.54,0,0,1,6.18,18.72A30.76,30.76,0,0,1,60.25,76.94" style="fill:#006ca8"/><path id="Path_2570" data-name="Path 2570" d="M81.39,33.46a34.87,34.87,0,0,1,3,14.27c0,18.77-14.73,34.09-32.89,34.09S18.6,66.55,18.6,47.72,33.34,13.63,51.5,13.63a25.32,25.32,0,0,1,2.89.16A37.9,37.9,0,0,0,50,13.52C30.61,13.52,14.85,29.9,14.85,50S30.61,86.48,50,86.48,85.14,70.1,85.14,50A36.92,36.92,0,0,0,81.4,33.45" style="fill:#c52127"/></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -8036,7 +8036,15 @@ modalAddCloudKey:
authRegion:
label: Region
help: Any region your tenancy is subscribed to authenticate your credentials.
pnap:
clientIdentifier:
label: Client ID
placeholder: Your Client ID
clientSecret:
label: Client Secret
placeholder: Your Client Secret
help:
From <a href="https://bmc.phoenixnap.com/applications/" target="_blank" rel="nofollow noreferrer noopener">phoenixNAP BMC Portal</a> Application Credentials
vmwarevsphere:
password:
@ -8642,6 +8650,7 @@ nodeDriver:
otccce: Open Telekom Cloud CCE
packet: Packet
pinganyunecs: Pinganyun ECS
pnap: phoenixNAP
rackspace: RackSpace
rancherkubernetesengine: RKE
softlayer: SoftLayer
@ -9338,7 +9347,29 @@ nodeDriver:
region:
label: Region
placeholder: 'select cloud credential to populate options...'
pnap:
access:
title: Account Access
detail: API Credentials will be used to launch phoenixNAP servers.
serverDetails:
title: Server Details
detail: Select details of the instances that will be created by this template.
location:
label: Location
placeholder: 'Please select server location.'
os:
label: OS
placeholder: 'Please select Operating System.'
type:
label: Type
placeholder: 'Please select type of server to provision.'
errors:
typeRequired: Server type is required.
osRequired: Operating System is required.
locationRequired: Location is required.
hostnameRequired: Hostname is required.
clientIDRequired: Client ID is required.
clientSecretRequired: Client Secret is required.
zstack:
access:
title: 1. Account Access