Skip to content

Commit

Permalink
titus - alb UI support
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaslin committed Mar 16, 2018
1 parent 19aa4c8 commit 6f9bb06
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 1 deletion.
36 changes: 36 additions & 0 deletions loadBalancers/loadBalancerSelector.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="row">
<div class="col-md-12" ng-if="$ctrl.command.viewState.dirty.targetGroups">
<div class="alert alert-warning">
<p><i class="fa fa-exclamation-triangle"></i>
The following target groups could not be found in the selected account/region/VPC and were removed:
</p>
<ul>
<li ng-repeat="targetGroup in $ctrl.command.viewState.dirty.targetGroups">{{targetGroup}}</li>
</ul>
<p class="text-right">
<a class="btn btn-sm btn-default dirty-flag-dismiss" href ng-click="$ctrl.command.viewState.dirty.targetGroups = null">Okay</a>
</p>
</div>
</div>
<div class="form-group">
<div class="col-md-4 sm-label-right">
<b>Target Groups</b>
<help-field key="aws.loadBalancer.targetGroups"></help-field>
</div>
<div class="col-md-8">
<div class="form-control-static" ng-if="!$ctrl.command.backingData.filtered.targetGroups.length">
No target groups found in the selected account/region/VPC
</div>
<ui-select ng-if="$ctrl.command.backingData.filtered.targetGroups.length"
multiple
ng-model="$ctrl.command.targetGroups"
class="form-control input-sm">
<ui-select-match>{{$item}}</ui-select-match>
<ui-select-choices repeat="targetGroup in $ctrl.command.backingData.filtered.targetGroups | filter: $select.search">
<span ng-bind-html="targetGroup | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>

</div>
128 changes: 128 additions & 0 deletions loadBalancers/loadBalancerSelector.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {IController, IComponentOptions, module} from 'angular';

import {chain, flatten, intersection, xor} from 'lodash';

import {
AccountService,
CacheInitializerService,
IAccountDetails,
IAggregatedAccounts,
INFRASTRUCTURE_CACHE_SERVICE,
InfrastructureCacheService, LoadBalancerReader,
} from '@spinnaker/core';

import {Subscription} from 'rxjs/Subscription';
import {Subject} from 'rxjs/Subject';
import {IAmazonApplicationLoadBalancer, IAmazonLoadBalancer} from '@spinnaker/amazon';

class LoadBalancerSelectorController implements IController {
public command: any;

public refreshTime: number;
public refreshing = false;
public accountChanged: Subject<void>;
public regionChanged: Subject<void>;
public credentials: IAggregatedAccounts;
public loadBalancers: IAmazonLoadBalancer[];
private subscriptions: Subscription[];

constructor(private $q: ng.IQService,
private infrastructureCaches: InfrastructureCacheService,
private accountService: AccountService,
private cacheInitializer: CacheInitializerService,
private loadBalancerReader: LoadBalancerReader) {
'ngInject';

this.setLoadBalancerRefreshTime();
}

public $onInit(): void {
const credentialLoader: ng.IPromise<void> = this.accountService.getCredentialsKeyedByAccount('titus').then((credentials: IAggregatedAccounts) => {
this.credentials = credentials;
});
const loadBalancerLoader: ng.IPromise<void> = this.loadBalancerReader.listLoadBalancers('aws').then((loadBalancers: any[]) => {
this.loadBalancers = loadBalancers;
});
this.$q.all([credentialLoader, loadBalancerLoader]).then(() => this.configureLoadBalancerOptions());
this.subscriptions = [
this.accountChanged.subscribe(() => this.configureLoadBalancerOptions()),
this.regionChanged.subscribe(() => this.configureLoadBalancerOptions())
];
}

public $onDestroy(): void {
this.subscriptions.forEach(s => s.unsubscribe());
}

private getCredentials(): IAccountDetails {
return this.credentials[this.command.credentials];
}

private getAwsAccount(): string {
return this.getCredentials().awsAccount;
}

private getRegion(): string {
return this.command.region || (this.command.cluster ? this.command.cluster.region : null);
}

public getTargetGroupNames(): string[] {
const loadBalancersV2 = this.getLoadBalancerMap().filter((lb) => lb.loadBalancerType !== 'classic') as IAmazonApplicationLoadBalancer[];
const instanceTargetGroups = flatten(loadBalancersV2.map<any>((lb) => lb.targetGroups.filter((tg) => tg.targetType === 'ip')));
return instanceTargetGroups.map((tg) => tg.name).sort();
}

private getLoadBalancerMap(): IAmazonLoadBalancer[] {
return chain(this.loadBalancers)
.map('accounts')
.flattenDeep()
.filter({ name: this.getAwsAccount()})
.map('regions')
.flattenDeep()
.filter({ name: this.getRegion() })
.map<IAmazonLoadBalancer>('loadBalancers')
.flattenDeep<IAmazonLoadBalancer>()
.value()
}

public configureLoadBalancerOptions() {
const currentTargetGroups = this.command.targetGroups || [];
const allTargetGroups = this.getTargetGroupNames();

if (currentTargetGroups && this.command.targetGroups) {
const matched = intersection(allTargetGroups, currentTargetGroups);
const removedTargetGroups = xor(matched, currentTargetGroups);
this.command.targetGroups = intersection(allTargetGroups, matched);
this.command.removedTargetGroups = removedTargetGroups;
}
this.command.backingData.filtered.targetGroups = allTargetGroups;
}

public setLoadBalancerRefreshTime(): void {
this.refreshTime = this.infrastructureCaches.get('loadBalancers').getStats().ageMax;
}

public refreshLoadBalancers(): void {
this.cacheInitializer.refreshCache('loadBalancers').then(() => {
return this.loadBalancerReader.listLoadBalancers('aws').then((loadBalancers) => {
this.command.backingData.loadBalancers = loadBalancers;
this.refreshing = false;
this.configureLoadBalancerOptions();
});
});
}
}

export class LoadBalancerSelectorComponent implements IComponentOptions {
public bindings: any = {
command: '='
};
public controller: any = LoadBalancerSelectorController;
public templateUrl = require('./loadBalancerSelector.component.html');
}

export const TITUS_LOAD_BALANCER_SELECTOR = 'spinnaker.titus.serverGroup.configure.wizard.loadBalancers.selector.component';
module(TITUS_LOAD_BALANCER_SELECTOR, [
INFRASTRUCTURE_CACHE_SERVICE
])
.component('titusLoadBalancerSelector', new LoadBalancerSelectorComponent());
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

const angular = require('angular');
import {TITUS_SECURITY_GROUP_PICKER} from 'titus/securityGroup/securityGroupPicker.component';
import {TITUS_LOAD_BALANCER_SELECTOR} from 'titus/loadBalancers/loadBalancerSelector.component';


module.exports = angular.module('spinnaker.serverGroup.configure.titus.cloneServerGroup', [
require('@uirouter/angularjs').default,
TITUS_SECURITY_GROUP_PICKER
TITUS_SECURITY_GROUP_PICKER,
TITUS_LOAD_BALANCER_SELECTOR
])
.controller('titusCloneServerGroupCtrl', function($scope, $uibModalInstance, $q, $state,
serverGroupWriter, v2modalWizardService, taskMonitorBuilder,
Expand All @@ -16,6 +19,7 @@ module.exports = angular.module('spinnaker.serverGroup.configure.titus.cloneServ
basicSettings: require('./basicSettings.html'),
resources: require('./resources.html'),
capacity: require('./capacity/capacity.html'),
loadBalancers: require('./loadBalancers.html'),
securityGroups: require('./securityGroups.html'),
parameters: require('./parameters.html'),
};
Expand Down
3 changes: 3 additions & 0 deletions serverGroup/configure/wizard/loadBalancers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<titus-load-balancer-selector command="command"
account-changed="command.viewState.accountChangedStream"
region-changed="command.viewState.regionChangedStream"></titus-load-balancer-selector>
3 changes: 3 additions & 0 deletions serverGroup/configure/wizard/serverGroupWizard.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ <h3 us-spinner="{radius:30, width:8, length: 16}"></h3>
<v2-wizard-page key="capacity" label="Capacity">
<ng-include src="pages.capacity"></ng-include>
</v2-wizard-page>
<v2-wizard-page key="loadBalancers" label="Load Balancers" mandatory="false">
<ng-include src="pages.loadBalancers"></ng-include>
</v2-wizard-page>
<v2-wizard-page key="securityGroups" label="Security Groups" mandatory="false">
<ng-include src="pages.securityGroups"></ng-include>
</v2-wizard-page>
Expand Down

0 comments on commit 6f9bb06

Please sign in to comment.