提交 2f02d624 编写于 作者: U urcan

deploy using settings directive is implemented

上级 d6c3b563
......@@ -17,8 +17,8 @@ limitations under the License.
<div layout="column" layout-padding layout-align="center center">
<md-whiteframe class="kd-deploy-whiteframe md-whiteframe-5dp" flex flex-gt-md>
<h3 class="md-headline">Deploy a Containerized App</h3>
<form ng-submit="ctrl.deploy()">
<md-input-container>
<form ng-submit="ctrl.deployBySelection()">
<md-input-container class="md-block">
<label>App name</label>
<input ng-model="ctrl.name" required>
</md-input-container>
......@@ -30,50 +30,21 @@ limitations under the License.
Upload a YAML or JSON file
</md-radio-button>
</md-radio-group>
<md-input-container>
<label>Container image</label>
<input ng-model="ctrl.containerImage" required>
</md-input-container>
<md-input-container>
<label>Number of pods</label>
<input ng-model="ctrl.replicas" type="number" required min="1">
</md-input-container>
<div layout="row" ng-repeat="portMapping in ctrl.portMappings">
<md-input-container flex>
<label>Port</label>
<input ng-model="portMapping.port" type="number" min="0">
</md-input-container>
<md-input-container flex>
<label>Target port</label>
<input ng-model="portMapping.targetPort" type="number" min="0">
</md-input-container>
<md-input-container flex="none">
<label>Protocol</label>
<md-select ng-model="portMapping.protocol" required>
<md-option ng-repeat="protocol in ctrl.protocols" ng-value="protocol">
{{protocol}}
</md-option>
</md-select>
</md-input-container>
</div>
<md-input-container>
<label>Namespace</label>
<md-select ng-model="ctrl.namespace" required>
<md-option ng-repeat="namespace in ctrl.namespaces" ng-value="namespace">
{{namespace}}
</md-option>
<md-option ng-click="ctrl.handleNamespaceDialog($event)">
Create a new namespace...
</md-option>
</md-select>
</md-input-container>
<md-switch ng-model="ctrl.isExternal" class="md-primary">
Expose service externally
</md-switch>
<md-input-container>
<label>Description (optional)</label>
<textarea ng-model="ctrl.description"></textarea>
</md-input-container>
<deploy-from-settings name="ctrl.name"
namespace="ctrl.namespace"
detail="ctrl.detail">
</deploy-from-settings>
<md-input-container class="md-block">
<label>Namespace</label>
<md-select ng-model="ctrl.namespace" required>
<md-option ng-repeat="namespace in ctrl.namespaces" ng-value="namespace">
{{namespace}}
</md-option>
<md-option ng-click="ctrl.handleNamespaceDialog($event)">
Create a new namespace...
</md-option>
</md-select>
</md-input-container>
<md-button class="md-raised md-primary" type="submit" ng-disabled="ctrl.isDeployDisabled()">
Deploy
</md-button>
......
......@@ -13,7 +13,6 @@
// limitations under the License.
import {stateName as zerostate} from 'zerostate/zerostate_state';
import {stateName as replicasetliststate} from 'replicasetlist/replicasetlist_state';
import showNamespaceDialog from 'deploy/createnamespace_dialog';
/**
......@@ -34,25 +33,6 @@ export default class DeployController {
/** @export {string} */
this.name = '';
/** @export {string} */
this.containerImage = '';
/** @export {number} */
this.replicas = 1;
/** @export {string} */
this.description = '';
/**
* List of supported protocols.
* TODO(bryk): Do not hardcode the here, move to backend.
* @const @export {!Array<string>}
*/
this.protocols = ['TCP', 'UDP'];
/** @export {!Array<!backendApi.PortMapping>} */
this.portMappings = [this.newEmptyPortMapping_(this.protocols[0])];
/**
* List of available namespaces.
* @export {!Array<string>}
......@@ -65,9 +45,6 @@ export default class DeployController {
*/
this.namespace = this.namespaces.length > 0 ? this.namespaces[0] : undefined;
/** @export {boolean} */
this.isExternal = false;
/** @private {!angular.$resource} */
this.resource_ = $resource;
......@@ -82,42 +59,23 @@ export default class DeployController {
/** @private {boolean} */
this.isDeployInProgress_ = false;
/**
* Contains the selected directive's controller which has its own deploy logic
*
* @export {{deploy:function()}}
*/
this.detail = {deploy: function() {}};
}
/**
* Deploys the application based on the sate of the controller.
* Notifies the child scopes to call their deploy methods.
*
* @export
*/
deploy() {
// TODO(bryk): Validate input data before sending to the server.
/** @type {!backendApi.AppDeploymentSpec} */
let appDeploymentSpec = {
containerImage: this.containerImage,
isExternal: this.isExternal,
name: this.name,
description: this.description,
portMappings: this.portMappings.filter(this.isPortMappingEmpty_),
replicas: this.replicas,
namespace: this.namespace,
};
/** @type {!angular.Resource<!backendApi.AppDeploymentSpec>} */
let resource = this.resource_('/api/appdeployments');
deployBySelection() {
this.isDeployInProgress_ = true;
resource.save(
appDeploymentSpec,
(savedConfig) => {
this.isDeployInProgress_ = false;
this.log_.info('Successfully deployed application: ', savedConfig);
this.state_.go(replicasetliststate);
},
(err) => {
this.isDeployInProgress_ = false;
this.log_.error('Error deploying application:', err);
});
this.detail.deploy().finally(() => { this.isDeployInProgress_ = false; });
}
/**
......@@ -157,25 +115,4 @@ export default class DeployController {
* @export
*/
cancel() { this.state_.go(zerostate); }
/**
* @param {string} defaultProtocol
* @return {!backendApi.PortMapping}
* @private
*/
newEmptyPortMapping_(defaultProtocol) {
return {
port: null,
targetPort: null,
protocol: defaultProtocol,
};
}
/**
* Returns true when the given port mapping hasn't been filled by the user, i.e., is empty.
* @param {!backendApi.PortMapping} portMapping
* @return {boolean}
* @private
*/
isPortMappingEmpty_(portMapping) { return !!portMapping.port && !!portMapping.targetPort; }
}
......@@ -13,6 +13,7 @@
// limitations under the License.
import stateConfig from './deploy_state';
import deployFromSettingsDirective from './deployfromsettings_directive';
/**
* Angular module for the deploy view.
......@@ -25,4 +26,5 @@ export default angular.module(
'ngMaterial',
'ui.router',
])
.config(stateConfig);
.config(stateConfig)
.directive('deployFromSettings', deployFromSettingsDirective);
<!--
Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-input-container class="md-block">
<label>Container image</label>
<input ng-model="ctrl.containerImage" required>
</md-input-container>
<md-input-container class="md-block">
<label>Number of pods</label>
<input ng-model="ctrl.replicas" type="number" required min="1">
</md-input-container>
<div layout="row" ng-repeat="portMapping in ctrl.portMappings">
<md-input-container flex>
<label>Port</label>
<input ng-model="portMapping.port" type="number" min="0">
</md-input-container>
<md-input-container flex>
<label>Target port</label>
<input ng-model="portMapping.targetPort" type="number" min="0">
</md-input-container>
<md-input-container flex="none">
<label>Protocol</label>
<md-select ng-model="portMapping.protocol" required>
<md-option ng-repeat="protocol in ctrl.protocols" ng-value="protocol">
{{protocol}}
</md-option>
</md-select>
</md-input-container>
</div>
<md-switch ng-model="ctrl.isExternal" class="md-primary">
Expose service externally
</md-switch>
<md-input-container>
<label>Description (optional)</label>
<textarea ng-model="ctrl.description"></textarea>
</md-input-container>
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {stateName as replicasetliststate} from 'replicasetlist/replicasetlist_state';
/**
* Controller for the deploy from settings directive.
*
* @final
*/
export default class DeployFromSettingsController {
/**
* @param {!angular.$log} $log
* @param {!ui.router.$state} $state
* @param {!angular.$resource} $resource
* @param {!angular.$q} $q
* @ngInject
*/
constructor($log, $state, $resource, $q) {
/**
* It initializes the scope output parameter
*
* @export {!DeployFromSettingsController}
*/
this.detail = this;
/** @private {!angular.$q} */
this.q_ = $q;
/** @private {!angular.$resource} */
this.resource_ = $resource;
/** @private {!angular.$log} */
this.log_ = $log;
/** @private {!ui.router.$state} */
this.state_ = $state;
/** @export {string} */
this.containerImage = '';
/** @export {number} */
this.replicas = 1;
/** @export {string} */
this.description = '';
/**
* List of supported protocols.
* TODO(bryk): Do not hardcode the here, move to backend.
* @const @export {!Array<string>}
*/
this.protocols = ['TCP', 'UDP'];
/** @export {!Array<!backendApi.PortMapping>} */
this.portMappings = [this.newEmptyPortMapping_(this.protocols[0])];
/** @export {boolean} */
this.isExternal = false;
}
/**
* Deploys the application based on the state of the controller.
*
* @export
* @return {angular.$q.Promise}
*/
deploy() {
// TODO(bryk): Validate input data before sending to the server.
/** @type {!backendApi.AppDeploymentSpec} */
let appDeploymentSpec = {
containerImage: this.containerImage,
isExternal: this.isExternal,
name: this.name,
description: this.description,
portMappings: this.portMappings.filter(this.isPortMappingEmpty_),
replicas: this.replicas,
namespace: this.namespace,
};
let defer = this.q_.defer();
/** @type {!angular.Resource<!backendApi.AppDeploymentSpec>} */
let resource = this.resource_('/api/appdeployments');
resource.save(
appDeploymentSpec,
(savedConfig) => {
defer.resolve(savedConfig); // Progress ends
this.log_.info('Successfully deployed application: ', savedConfig);
this.state_.go(replicasetliststate);
},
(err) => {
defer.reject(err); // Progress ends
this.log_.error('Error deploying application:', err);
});
return defer.promise;
}
/**
* @param {string} defaultProtocol
* @return {!backendApi.PortMapping}
* @private
*/
newEmptyPortMapping_(defaultProtocol) {
return {port: null, targetPort: null, protocol: defaultProtocol};
}
/**
* Returns true when the given port mapping hasn't been filled by the user, i.e., is empty.
* @param {!backendApi.PortMapping} portMapping
* @return {boolean}
* @private
*/
isPortMappingEmpty_(portMapping) { return !!portMapping.port && !!portMapping.targetPort; }
}
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import DeployFromSettingsController from './deployfromsettings_controller';
/**
* Returns directive definition object for the deploy from settings directive.
* @return {!angular.Directive}
*/
export default function deployFromSettingsDirective() {
return {
scope: {},
bindToController: {
name: '=',
namespace: '=',
detail: '=',
},
controller: DeployFromSettingsController,
controllerAs: 'ctrl',
templateUrl: 'deploy/deployfromsettings.html',
};
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册