From 7be76008a8b436e97b578215f2654bdbca83f4a7 Mon Sep 17 00:00:00 2001 From: duftler Date: Sun, 21 Feb 2016 09:11:44 -0500 Subject: [PATCH 1/2] Add support for GCE subnets. Move subnet reader from amazon to core. --- app/scripts/modules/amazon/aws.module.js | 2 +- .../amazon/cache/cacheConfigurer.service.js | 2 +- .../createLoadBalancer.controller.js | 2 +- .../serverGroupCommandBuilder.service.js | 2 +- .../serverGroupConfiguration.service.js | 2 +- app/scripts/modules/core/help/helpContents.js | 6 +++ .../{amazon => core}/subnet/subnet.module.js | 0 .../subnet/subnet.read.service.js | 11 +++- .../subnet/subnet.read.service.spec.js | 0 .../google/cache/cacheConfigurer.service.js | 15 +++++- .../details/instance.details.controller.js | 12 +++-- .../instance/details/instanceDetails.html | 2 + .../configure/ServerGroupCommandBuilder.js | 16 +++--- .../serverGroupConfiguration.service.js | 52 ++++++++++++++++--- .../configure/wizard/CloneServerGroupCtrl.js | 1 + .../ServerGroupBasicSettings.controller.js | 13 +++++ .../configure/wizard/basicSettings.html | 10 ++++ .../serverGroupDetails.gce.controller.js | 44 +++++++++------- .../details/serverGroupDetails.html | 8 ++- .../subnet/subnetSelectField.directive.html | 19 +++++++ .../subnet/subnetSelectField.directive.js | 24 +++++++++ 21 files changed, 196 insertions(+), 47 deletions(-) rename app/scripts/modules/{amazon => core}/subnet/subnet.module.js (100%) rename app/scripts/modules/{amazon => core}/subnet/subnet.read.service.js (70%) rename app/scripts/modules/{amazon => core}/subnet/subnet.read.service.spec.js (100%) create mode 100644 app/scripts/modules/google/subnet/subnetSelectField.directive.html create mode 100644 app/scripts/modules/google/subnet/subnetSelectField.directive.js diff --git a/app/scripts/modules/amazon/aws.module.js b/app/scripts/modules/amazon/aws.module.js index 5c1c48345c1..fd296bcedbf 100644 --- a/app/scripts/modules/amazon/aws.module.js +++ b/app/scripts/modules/amazon/aws.module.js @@ -22,6 +22,7 @@ module.exports = angular.module('spinnaker.aws', [ require('../core/pipeline/config/stages/resizeAsg/aws/awsResizeAsgStage.js'), require('../core/pipeline/config/stages/scaleDownCluster/aws/awsScaleDownClusterStage.js'), require('../core/pipeline/config/stages/shrinkCluster/aws/awsShrinkClusterStage.js'), + require('../core/subnet/subnet.module.js'), require('./serverGroup/details/serverGroup.details.module.js'), require('./serverGroup/serverGroup.transformer.js'), require('./serverGroup/configure/wizard/CloneServerGroup.aws.controller.js'), @@ -37,7 +38,6 @@ module.exports = angular.module('spinnaker.aws', [ require('./securityGroup/configure/EditSecurityGroupCtrl.js'), require('./securityGroup/securityGroup.transformer.js'), require('./securityGroup/securityGroup.reader.js'), - require('./subnet/subnet.module.js'), require('./validation/applicationName.validator.js'), require('./vpc/vpc.module.js'), require('./image/image.reader.js'), diff --git a/app/scripts/modules/amazon/cache/cacheConfigurer.service.js b/app/scripts/modules/amazon/cache/cacheConfigurer.service.js index bab61683c1f..9b513ed33a9 100644 --- a/app/scripts/modules/amazon/cache/cacheConfigurer.service.js +++ b/app/scripts/modules/amazon/cache/cacheConfigurer.service.js @@ -7,7 +7,7 @@ module.exports = angular.module('spinnaker.aws.cache.initializer', [ require('../../core/loadBalancer/loadBalancer.read.service.js'), require('../../core/instance/instanceTypeService.js'), require('../../core/securityGroup/securityGroup.read.service.js'), - require('../subnet/subnet.read.service.js'), + require('../../core/subnet/subnet.read.service.js'), require('../vpc/vpc.read.service.js'), ]) .factory('awsCacheConfigurer', function ($q, diff --git a/app/scripts/modules/amazon/loadBalancer/configure/createLoadBalancer.controller.js b/app/scripts/modules/amazon/loadBalancer/configure/createLoadBalancer.controller.js index 721a218e8e1..ebd81984797 100644 --- a/app/scripts/modules/amazon/loadBalancer/configure/createLoadBalancer.controller.js +++ b/app/scripts/modules/amazon/loadBalancer/configure/createLoadBalancer.controller.js @@ -11,7 +11,7 @@ module.exports = angular.module('spinnaker.loadBalancer.aws.create.controller', require('../../../core/securityGroup/securityGroup.read.service.js'), require('../../../core/modal/wizard/v2modalWizard.service.js'), require('../../../core/task/monitor/taskMonitorService.js'), - require('../../subnet/subnet.read.service.js'), + require('../../../core/subnet/subnet.read.service.js'), require('../../../core/cache/cacheInitializer.js'), require('../../../core/cache/infrastructureCaches.js'), require('../../../core/naming/naming.service.js'), diff --git a/app/scripts/modules/amazon/serverGroup/configure/serverGroupCommandBuilder.service.js b/app/scripts/modules/amazon/serverGroup/configure/serverGroupCommandBuilder.service.js index 0783cea71b1..91136de8509 100644 --- a/app/scripts/modules/amazon/serverGroup/configure/serverGroupCommandBuilder.service.js +++ b/app/scripts/modules/amazon/serverGroup/configure/serverGroupCommandBuilder.service.js @@ -5,7 +5,7 @@ let angular = require('angular'); module.exports = angular.module('spinnaker.aws.serverGroupCommandBuilder.service', [ require('exports?"restangular"!imports?_=lodash!restangular'), require('../../../core/account/account.service.js'), - require('../../subnet/subnet.read.service.js'), + require('../../../core/subnet/subnet.read.service.js'), require('../../../core/instance/instanceTypeService.js'), require('../../../core/naming/naming.service.js'), require('./serverGroupConfiguration.service.js'), diff --git a/app/scripts/modules/amazon/serverGroup/configure/serverGroupConfiguration.service.js b/app/scripts/modules/amazon/serverGroup/configure/serverGroupConfiguration.service.js index 25c22ad8de5..16250289602 100644 --- a/app/scripts/modules/amazon/serverGroup/configure/serverGroupConfiguration.service.js +++ b/app/scripts/modules/amazon/serverGroup/configure/serverGroupConfiguration.service.js @@ -7,8 +7,8 @@ module.exports = angular.module('spinnaker.aws.serverGroup.configure.service', [ require('../../../core/account/account.service.js'), require('../../../core/naming/naming.service.js'), require('../../../core/securityGroup/securityGroup.read.service.js'), + require('../../../core/subnet/subnet.read.service.js'), require('../../instance/awsInstanceType.service.js'), - require('../../subnet/subnet.read.service.js'), require('../../keyPairs/keyPairs.read.service.js'), require('../../../core/loadBalancer/loadBalancer.read.service.js'), require('../../../core/cache/cacheInitializer.js'), diff --git a/app/scripts/modules/core/help/helpContents.js b/app/scripts/modules/core/help/helpContents.js index 4f99190f957..555ad59b3ca 100644 --- a/app/scripts/modules/core/help/helpContents.js +++ b/app/scripts/modules/core/help/helpContents.js @@ -120,6 +120,12 @@ module.exports = angular.module('spinnaker.core.help.contents', []) 'gce.serverGroup.autoscaling.minVMs': 'The least number of VM instances the group will contain, even if the target is not met.', 'gce.serverGroup.autoscaling.maxVMs': 'The largest number of VM instances allowed, even if the target is exceeded.', 'gce.serverGroup.autoscaling.cooldown': 'How long to wait before collecting information from a new instance. This should be at least the time it takes to initialize the instance. To find the minimum, create an instance from the same image and note how long it takes to start.', + 'gce.serverGroup.subnet': 'Subnetworks allow you to regionally segment the network IP space into prefixes (subnets) and control which prefix a VM instance\'s internal IP address is allocated from. There are several types of GCE networks:' + + '', 'pipeline.config.checkPreconditions.failPipeline': '' + '

Checked - the overall pipeline will fail whenever this precondition is false.

' + '

Unchecked - the overall pipeline will continue executing but this particular branch will stop.

', diff --git a/app/scripts/modules/amazon/subnet/subnet.module.js b/app/scripts/modules/core/subnet/subnet.module.js similarity index 100% rename from app/scripts/modules/amazon/subnet/subnet.module.js rename to app/scripts/modules/core/subnet/subnet.module.js diff --git a/app/scripts/modules/amazon/subnet/subnet.read.service.js b/app/scripts/modules/core/subnet/subnet.read.service.js similarity index 70% rename from app/scripts/modules/amazon/subnet/subnet.read.service.js rename to app/scripts/modules/core/subnet/subnet.read.service.js index 54209d44a59..b9ad17ecb02 100644 --- a/app/scripts/modules/amazon/subnet/subnet.read.service.js +++ b/app/scripts/modules/core/subnet/subnet.read.service.js @@ -5,7 +5,7 @@ let angular = require('angular'); module.exports = angular .module('spinnaker.subnet.read.service', [ require('exports?"restangular"!imports?_=lodash!restangular'), - require('../../core/cache/infrastructureCaches.js') + require('../cache/infrastructureCaches.js') ]) .factory('subnetReader', function (Restangular, infrastructureCaches) { @@ -25,8 +25,15 @@ module.exports = angular }); } + function listSubnetsByProvider(cloudProvider) { + return Restangular.one('subnets', cloudProvider) + .withHttpConfig({cache: infrastructureCaches.subnets}) + .getList(); + } + return { - listSubnets: listSubnets + listSubnets: listSubnets, + listSubnetsByProvider: listSubnetsByProvider, }; }); diff --git a/app/scripts/modules/amazon/subnet/subnet.read.service.spec.js b/app/scripts/modules/core/subnet/subnet.read.service.spec.js similarity index 100% rename from app/scripts/modules/amazon/subnet/subnet.read.service.spec.js rename to app/scripts/modules/core/subnet/subnet.read.service.spec.js diff --git a/app/scripts/modules/google/cache/cacheConfigurer.service.js b/app/scripts/modules/google/cache/cacheConfigurer.service.js index 8fec4d7b680..2897d8d52dc 100644 --- a/app/scripts/modules/google/cache/cacheConfigurer.service.js +++ b/app/scripts/modules/google/cache/cacheConfigurer.service.js @@ -4,11 +4,14 @@ let angular = require('angular'); module.exports = angular.module('spinnaker.gce.cache.initializer', [ require('../../core/account/account.service.js'), - require('../../core/loadBalancer/loadBalancer.read.service.js'), require('../../core/instance/instanceTypeService.js'), + require('../../core/loadBalancer/loadBalancer.read.service.js'), + require('../../core/network/network.read.service.js'), require('../../core/securityGroup/securityGroup.read.service.js'), + require('../../core/subnet/subnet.read.service.js'), ]) - .factory('gceCacheConfigurer', function (accountService, instanceTypeService, loadBalancerReader) { + .factory('gceCacheConfigurer', function (accountService, instanceTypeService, loadBalancerReader, + networkReader, subnetReader) { let config = Object.create(null); @@ -24,5 +27,13 @@ module.exports = angular.module('spinnaker.gce.cache.initializer', [ initializers: [ () => loadBalancerReader.listLoadBalancers('gce') ], }; + config.networks = { + initializers: [ () => networkReader.listNetworksByProvider('gce') ], + }; + + config.subnets = { + initializers: [ () => subnetReader.listSubnetsByProvider('gce') ], + }; + return config; }); diff --git a/app/scripts/modules/google/instance/details/instance.details.controller.js b/app/scripts/modules/google/instance/details/instance.details.controller.js index 20bebf39df8..62fd8739ec9 100644 --- a/app/scripts/modules/google/instance/details/instance.details.controller.js +++ b/app/scripts/modules/google/instance/details/instance.details.controller.js @@ -132,6 +132,7 @@ module.exports = angular.module('spinnaker.instance.detail.gce.controller', [ $scope.instance.internalIpAddress = $scope.instance.networkInterfaces[0].networkIP; $scope.instance.externalIpAddress = $scope.instance.networkInterfaces[0].accessConfigs[0].natIP; $scope.instance.network = getNetwork(); + $scope.instance.subnet = getSubnet(); $scope.instance.sshLink = $scope.instance.selfLink.replace('www.googleapis.com/compute/v1', 'cloudssh.developers.google.com') + '?authuser=0&hl=en_US'; @@ -188,12 +189,13 @@ module.exports = angular.module('spinnaker.instance.detail.gce.controller', [ } function getNetwork() { - if ($scope.instance.networkInterfaces[0].network) { - var networkUrl = $scope.instance.networkInterfaces[0].network; + let networkUrl = _.get($scope.instance, 'networkInterfaces[0].network'); + return networkUrl ? _.last(networkUrl.split('/')) : null; + } - return _.last(networkUrl.split('/')); - } - return null; + function getSubnet() { + let subnetUrl = _.get($scope.instance, 'networkInterfaces[0].subnetwork'); + return subnetUrl ? _.last(subnetUrl.split('/')) : null; } this.canRegisterWithLoadBalancer = function() { diff --git a/app/scripts/modules/google/instance/details/instanceDetails.html b/app/scripts/modules/google/instance/details/instanceDetails.html index d72323a3fae..8aaaf02ece1 100644 --- a/app/scripts/modules/google/instance/details/instanceDetails.html +++ b/app/scripts/modules/google/instance/details/instanceDetails.html @@ -81,6 +81,8 @@

Network
{{instance.network || '(Unknown)'}}
+
Subnet
+
{{instance.subnet}}
diff --git a/app/scripts/modules/google/serverGroup/configure/ServerGroupCommandBuilder.js b/app/scripts/modules/google/serverGroup/configure/ServerGroupCommandBuilder.js index 938545ecfc9..2d469c04504 100644 --- a/app/scripts/modules/google/serverGroup/configure/ServerGroupCommandBuilder.js +++ b/app/scripts/modules/google/serverGroup/configure/ServerGroupCommandBuilder.js @@ -31,14 +31,13 @@ module.exports = angular.module('spinnaker.gce.serverGroupCommandBuilder.service } function extractNetworkName(serverGroup) { - if (_.has(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces')) { - var networkInterfaces = serverGroup.launchConfig.instanceTemplate.properties.networkInterfaces; - if (networkInterfaces.length === 1) { - var networkUrl = networkInterfaces[0].network; - return _.last(networkUrl.split('/')); - } - } - return null; + let networkUrl = _.get(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].network'); + return networkUrl ? _.last(networkUrl.split('/')) : null; + } + + function extractSubnetName(serverGroup) { + let subnetworkUrl = _.get(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].subnetwork'); + return subnetworkUrl ? _.last(subnetworkUrl.split('/')) : null; } function populateDisksFromExisting(disks, command) { @@ -271,6 +270,7 @@ module.exports = angular.module('spinnaker.gce.serverGroupCommandBuilder.service }, zone: serverGroup.zones[0], network: extractNetworkName(serverGroup), + subnet: extractSubnetName(serverGroup), instanceMetadata: [], tags: [], availabilityZones: [], diff --git a/app/scripts/modules/google/serverGroup/configure/serverGroupConfiguration.service.js b/app/scripts/modules/google/serverGroup/configure/serverGroupConfiguration.service.js index 807de728e40..40a715dbac2 100644 --- a/app/scripts/modules/google/serverGroup/configure/serverGroupConfiguration.service.js +++ b/app/scripts/modules/google/serverGroup/configure/serverGroupConfiguration.service.js @@ -8,12 +8,13 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati require('../../../core/cache/cacheInitializer.js'), require('../../../core/loadBalancer/loadBalancer.read.service.js'), require('../../../core/network/network.read.service.js'), + require('../../../core/subnet/subnet.read.service.js'), require('../../image/image.reader.js'), require('../../instance/gceInstanceTypeService.js'), ]) .factory('gceServerGroupConfigurationService', function(gceImageReader, accountService, securityGroupReader, gceInstanceTypeService, cacheInitializer, - $q, loadBalancerReader, networkReader, _) { + $q, loadBalancerReader, networkReader, subnetReader, _) { var persistentDiskTypes = [ 'pd-standard', @@ -57,6 +58,7 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati regionsKeyedByAccount: accountService.getRegionsKeyedByAccount('gce'), securityGroups: securityGroupReader.getAllSecurityGroups(), networks: networkReader.listNetworksByProvider('gce'), + subnets: subnetReader.listSubnetsByProvider('gce'), loadBalancers: loadBalancerReader.listLoadBalancers('gce'), packageImages: imageLoader, instanceTypes: gceInstanceTypeService.getAllTypesByRegion(), @@ -177,8 +179,18 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati } function configureZones(command) { - command.backingData.filtered.zones = + var result = { dirty: {} }; + var filteredData = command.backingData.filtered; + if (command.region === null) { + return result; + } + filteredData.zones = command.backingData.regionsKeyedByAccount[command.credentials].regions[command.region]; + if (!_(filteredData.zones).contains(command.zone)) { + command.zone = ""; + result.dirty.zone = true; + } + return result; } function getLoadBalancerNames(command) { @@ -231,6 +243,24 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati }); } + function configureSubnets(command) { + var result = { dirty: {} }; + var filteredData = command.backingData.filtered; + if (command.region === null) { + return result; + } + filteredData.subnets = _(command.backingData.subnets) + .filter({ account: command.credentials, network: command.network, region: command.region }) + .pluck('name') + .valueOf(); + + if (!_(filteredData.subnets).contains(command.subnet)) { + command.subnet = ""; + result.dirty.subnet = true; + } + return result; + } + function getSecurityGroups(command) { var newSecurityGroups = command.backingData.securityGroups[command.credentials] || { gce: {}}; newSecurityGroups = _.filter(newSecurityGroups.gce.global, function(securityGroup) { @@ -321,11 +351,10 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati command.regionChanged = function regionChanged() { var result = { dirty: {} }; var filteredData = command.backingData.filtered; + angular.extend(result.dirty, configureSubnets(command).dirty); if (command.region) { angular.extend(result.dirty, configureInstanceTypes(command).dirty); - - configureZones(command); - + angular.extend(result.dirty, configureZones(command).dirty); angular.extend(result.dirty, configureLoadBalancerOptions(command).dirty); angular.extend(result.dirty, configureImages(command).dirty); } else { @@ -334,7 +363,6 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati command.viewState.dirty = command.viewState.dirty || {}; angular.extend(command.viewState.dirty, result.dirty); - return result; }; @@ -370,6 +398,17 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati command.networkChanged = function networkChanged() { var result = { dirty: {} }; + command.viewState.autoCreateSubnets = _(command.backingData.networks) + .filter({ account: command.credentials, name: command.network }) + .pluck('autoCreateSubnets') + .head(); + + command.viewState.subnets = _(command.backingData.networks) + .filter({ account: command.credentials, name: command.network }) + .pluck('subnets') + .head(); + + angular.extend(result.dirty, configureSubnets(command).dirty); angular.extend(result.dirty, configureSecurityGroupOptions(command).dirty); command.viewState.dirty = command.viewState.dirty || {}; @@ -384,6 +423,7 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.configurati configureInstanceTypes: configureInstanceTypes, configureImages: configureImages, configureZones: configureZones, + configureSubnets: configureSubnets, configureLoadBalancerOptions: configureLoadBalancerOptions, refreshLoadBalancers: refreshLoadBalancers, refreshSecurityGroups: refreshSecurityGroups, diff --git a/app/scripts/modules/google/serverGroup/configure/wizard/CloneServerGroupCtrl.js b/app/scripts/modules/google/serverGroup/configure/wizard/CloneServerGroupCtrl.js index a3de83439cb..ea77f630c33 100644 --- a/app/scripts/modules/google/serverGroup/configure/wizard/CloneServerGroupCtrl.js +++ b/app/scripts/modules/google/serverGroup/configure/wizard/CloneServerGroupCtrl.js @@ -99,6 +99,7 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.cloneServer processCommandUpdateResult($scope.command.credentialsChanged()); processCommandUpdateResult($scope.command.regionChanged()); processCommandUpdateResult($scope.command.networkChanged()); + gceServerGroupConfigurationService.configureSubnets($scope.command); } function createResultProcessor(method) { diff --git a/app/scripts/modules/google/serverGroup/configure/wizard/ServerGroupBasicSettings.controller.js b/app/scripts/modules/google/serverGroup/configure/wizard/ServerGroupBasicSettings.controller.js index ffa704ea006..739a21b22b5 100644 --- a/app/scripts/modules/google/serverGroup/configure/wizard/ServerGroupBasicSettings.controller.js +++ b/app/scripts/modules/google/serverGroup/configure/wizard/ServerGroupBasicSettings.controller.js @@ -13,6 +13,7 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.basicSettin require('../../../gceRegionSelectField.directive.js'), require('../../../gceZoneSelectField.directive.js'), require('../../../gceNetworkSelectField.directive.js'), + require('../../../subnet/subnetSelectField.directive.js'), ]) .controller('gceServerGroupBasicSettingsCtrl', function($scope, $controller, $uibModalStack, $state, v2modalWizardService, rx, imageReader, namingService) { @@ -84,6 +85,18 @@ module.exports = angular.module('spinnaker.serverGroup.configure.gce.basicSettin } }; + this.getSubnetPlaceholder = () => { + if (!$scope.command.region) { + return '(Select an account)'; + } else if ($scope.command.viewState.autoCreateSubnets) { + return '(Subnet will be automatically selected)'; + } else if ($scope.command.viewState.autoCreateSubnets === null) { + return '(Subnets not supported)'; + } else { + return null; + } + }; + $scope.$watch('form.$valid', function(newVal) { if (newVal) { v2modalWizardService.markClean('location'); diff --git a/app/scripts/modules/google/serverGroup/configure/wizard/basicSettings.html b/app/scripts/modules/google/serverGroup/configure/wizard/basicSettings.html index 97da54c3dab..a44bcf03a7f 100644 --- a/app/scripts/modules/google/serverGroup/configure/wizard/basicSettings.html +++ b/app/scripts/modules/google/serverGroup/configure/wizard/basicSettings.html @@ -11,6 +11,16 @@ + +
diff --git a/app/scripts/modules/google/serverGroup/details/serverGroupDetails.gce.controller.js b/app/scripts/modules/google/serverGroup/details/serverGroupDetails.gce.controller.js index ae94ba48d09..703cde9792d 100644 --- a/app/scripts/modules/google/serverGroup/details/serverGroupDetails.gce.controller.js +++ b/app/scripts/modules/google/serverGroup/details/serverGroupDetails.gce.controller.js @@ -10,6 +10,7 @@ module.exports = angular.module('spinnaker.serverGroup.details.gce.controller', require('../../../core/serverGroup/serverGroup.read.service.js'), require('../../../core/serverGroup/details/serverGroupWarningMessage.service.js'), require('../../../core/confirmationModal/confirmationModal.service.js'), + require('../../../core/network/network.read.service.js'), require('../../../core/serverGroup/serverGroup.write.service.js'), require('../../../core/serverGroup/configure/common/runningExecutions.service.js'), require('../../../core/utils/lodash.js'), @@ -21,7 +22,7 @@ module.exports = angular.module('spinnaker.serverGroup.details.gce.controller', ]) .controller('gceServerGroupDetailsCtrl', function ($scope, $state, $templateCache, $interpolate, app, serverGroup, InsightFilterStateModel, gceServerGroupCommandBuilder, serverGroupReader, $uibModal, confirmationModalService, _, serverGroupWriter, - runningExecutionsService, serverGroupWarningMessageService) { + runningExecutionsService, serverGroupWarningMessageService, networkReader) { let application = app; @@ -71,6 +72,9 @@ module.exports = angular.module('spinnaker.serverGroup.details.gce.controller', }).compact().value(); } + $scope.serverGroup.network = getNetwork(); + retrieveSubnet(); + var pathSegments = $scope.serverGroup.launchConfig.instanceTemplate.selfLink.split('/'); var projectId = pathSegments[pathSegments.indexOf('projects') + 1]; $scope.serverGroup.logsLink = @@ -197,6 +201,27 @@ module.exports = angular.module('spinnaker.serverGroup.details.gce.controller', } } + function getNetwork() { + let networkUrl = _.get($scope.serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].network'); + return networkUrl ? _.last(networkUrl.split('/')) : null; + } + + function retrieveSubnet() { + networkReader.listNetworksByProvider('gce').then(function(networks) { + let autoCreateSubnets = _(networks) + .filter({ account: $scope.serverGroup.account, name: $scope.serverGroup.network }) + .pluck('autoCreateSubnets') + .head(); + + if (autoCreateSubnets) { + $scope.serverGroup.subnet = '(Auto-select)'; + } else { + let subnetUrl = _.get($scope.serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].subnetwork'); + $scope.serverGroup.subnet = subnetUrl ? _.last(subnetUrl.split('/')) : null; + } + }); + } + retrieveServerGroup().then(() => { // If the user navigates away from the view before the initial retrieveServerGroup call completes, // do not bother subscribing to the refresh @@ -393,22 +418,5 @@ module.exports = angular.module('spinnaker.serverGroup.details.gce.controller', } return null; }; - - this.getNetwork = function() { - if ($scope.serverGroup && - $scope.serverGroup.launchConfig && - $scope.serverGroup.launchConfig.instanceTemplate && - $scope.serverGroup.launchConfig.instanceTemplate.properties && - $scope.serverGroup.launchConfig.instanceTemplate.properties.networkInterfaces) { - var networkInterfaces = $scope.serverGroup.launchConfig.instanceTemplate.properties.networkInterfaces; - - if (networkInterfaces.length === 1) { - var networkUrl = networkInterfaces[0].network; - - return _.last(networkUrl.split('/')); - } - } - return null; - }; } ); diff --git a/app/scripts/modules/google/serverGroup/details/serverGroupDetails.html b/app/scripts/modules/google/serverGroup/details/serverGroupDetails.html index 063befd1b52..f440b239c3b 100644 --- a/app/scripts/modules/google/serverGroup/details/serverGroupDetails.html +++ b/app/scripts/modules/google/serverGroup/details/serverGroupDetails.html @@ -104,6 +104,10 @@

[SERVER GROUP IS DISABLED {{serverGroup.region}} +
Network
+
{{serverGroup.network}}
+
Subnet
+
{{serverGroup.subnet}}
Zone
    @@ -161,7 +165,9 @@

    [SERVER GROUP IS DISABLED

Network
-
{{ctrl.getNetwork()}}
+
{{serverGroup.network}}
+
Subnet
+
{{serverGroup.subnet}}
Startup Script
Show Startup Script
[none]
diff --git a/app/scripts/modules/google/subnet/subnetSelectField.directive.html b/app/scripts/modules/google/subnet/subnetSelectField.directive.html new file mode 100644 index 00000000000..ecc58d4c889 --- /dev/null +++ b/app/scripts/modules/google/subnet/subnetSelectField.directive.html @@ -0,0 +1,19 @@ +
+
+ Subnet + +
+
{{subnetPlaceholder}}
+
+ +

{{component[field]}}

+
+
diff --git a/app/scripts/modules/google/subnet/subnetSelectField.directive.js b/app/scripts/modules/google/subnet/subnetSelectField.directive.js new file mode 100644 index 00000000000..76bffdd4c3c --- /dev/null +++ b/app/scripts/modules/google/subnet/subnetSelectField.directive.js @@ -0,0 +1,24 @@ +'use strict'; + +let angular = require('angular'); + +module.exports = angular.module('spinnaker.google.subnet.subnetSelectField.directive', [ +]) + .directive('gceSubnetSelectField', function () { + return { + restrict: 'E', + templateUrl: require('./subnetSelectField.directive.html'), + scope: { + subnets: '=', + subnetPlaceholder: '=', + autoCreateSubnets: '=', + component: '=', + field: '@', + account: '=', + region: '=', + onChange: '&', + labelColumns: '@', + helpKey: '@', + }, + }; +}); From 17c76d2d5bbe8d4825bdb844c5ccea1b1f92d40d Mon Sep 17 00:00:00 2001 From: duftler Date: Sun, 21 Feb 2016 12:39:22 -0500 Subject: [PATCH 2/2] Fixup behavior of zone-based cluster selector when toggling. --- .../modules/core/forms/checkmap/checkmap.directive.js | 1 + .../core/widgets/accountZoneClusterSelector.component.js | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/app/scripts/modules/core/forms/checkmap/checkmap.directive.js b/app/scripts/modules/core/forms/checkmap/checkmap.directive.js index ca383282d3c..95cea9fbab9 100644 --- a/app/scripts/modules/core/forms/checkmap/checkmap.directive.js +++ b/app/scripts/modules/core/forms/checkmap/checkmap.directive.js @@ -73,6 +73,7 @@ module.exports = angular.module('spinnaker.core.forms.checkmap.checkmap.directiv scope.updateSelectedItems = updateSelectedItems; + scope.$watch('itemMap', initializeModelHolder); scope.$watch('selectedItems', initializeModelHolder); } }; diff --git a/app/scripts/modules/core/widgets/accountZoneClusterSelector.component.js b/app/scripts/modules/core/widgets/accountZoneClusterSelector.component.js index 2d3247d7fe8..8f892654ece 100644 --- a/app/scripts/modules/core/widgets/accountZoneClusterSelector.component.js +++ b/app/scripts/modules/core/widgets/accountZoneClusterSelector.component.js @@ -29,6 +29,15 @@ module.exports = angular let accountFilter = (cluster) => cluster.account === vm.component.credentials; let zoneList = appListExtractorService.getZonesByRegion([vm.application], accountFilter); vm.zones = Object.keys(zoneList).length ? zoneList : zones; + + // Deselect any zones that are not included in the filtered list. + let flattenedZoneList = _(vm.zones) + .map() + .flatten() + .value(); + vm.component.zones = _.filter(vm.component.zones, zone => { + return _.includes(flattenedZoneList, zone); + }); }; let setClusterList = () => {