Skip to content

Commit

Permalink
refactor(kubernetes): exclude manifest from infrastructure interfaces (
Browse files Browse the repository at this point in the history
…#8438)

* refactor(kubernetes): exclude manifest from IKubernetesLoadBalancer

As part of ongoing Kubernetes performance improvements, Clouddriver will stop caching the entire Kubernetes resource YAML. In the immediate term, we will stop returning the manifest as part of top-level /loadBalancers, /serverGroups, and /securityGroups endpoints. Let's instead block LB details view loading on a separate /manifests request, and use that to hydrate the template.

* fix(kubernetes): fix alignment of Host Rules and Ingress sections

* refactor(kubernetes): exclude manifest from IKubernetesServerGroup

Also refactors ManifestTrafficService to check for associated services in the `loadBalancers` field of a server group rather than check the server group's manifest's annotations, and removes unnecessary extractEntityTags method which is just re-setting entityTags on the same serverGroup from which it was reading it.

* refactor(kubernetes): exclude manifest from IKubernetesServerGroupManager

* refactor(kubernetes): remove manifest from IKubernetesInstance

* refactor(kubernetes): exclude manifest from IKubernetesSecurityGroup

Also add `account` to interface, because unlike the other infra types, the base type does not include `account` (but we are always getting this back from Clouddriver for Kubernetes SGs).

* fix(kubernetes): include manifest as $interpolation context for annotation-driven UI

The Kubernetes [annotation-driven UI](https://spinnaker.io/guides/user/kubernetes-v2/annotations-ui/) expects the full manifest to be available to hydrate custom UI sections specfied as annotations. Since we already have access to the full manifest in this component off of which we read each annotation, simply include it as part of the context we pass to $interpolate.

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
maggieneterval and mergify[bot] committed Jul 29, 2020
1 parent e47310c commit ef176f0
Show file tree
Hide file tree
Showing 18 changed files with 270 additions and 317 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export interface IKubernetesInstance extends IInstance {
humanReadableName: string;
displayName: string;
apiVersion: string;
manifest: any;
namespace: string;
moniker: IMoniker;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { IController, IPromise, IQService, IScope, module } from 'angular';
import { IModalService } from 'angular-ui-bootstrap';
import { flattenDeep } from 'lodash';
import { StateService } from '@uirouter/angularjs';

import { Application, InstanceReader, RecentHistoryService, IManifest, ILoadBalancer } from '@spinnaker/core';
import {
Application,
InstanceReader,
RecentHistoryService,
IManifest,
ILoadBalancer,
ManifestReader,
} from '@spinnaker/core';

import { IKubernetesInstance } from './IKubernetesInstance';
import { KubernetesManifestService } from '../../manifest/manifest.service';
import { ManifestWizard } from '../../manifest/wizard/ManifestWizard';
import { KubernetesManifestCommandBuilder } from '../../manifest/manifestCommandBuilder.service';

Expand Down Expand Up @@ -34,43 +41,22 @@ class KubernetesInstanceDetailsController implements IController {
public manifest: IManifest;
public consoleOutputInstance: IConsoleOutputInstance;

public static $inject = ['instance', '$uibModal', '$q', '$scope', 'app'];
public static $inject = ['instance', '$uibModal', '$q', '$scope', 'app', '$state'];
constructor(
instance: InstanceFromStateParams,
private $uibModal: IModalService,
private $q: IQService,
private $scope: IScope,
private app: Application,
private $state: StateService,
) {
this.app
.ready()
.then(() => this.retrieveInstance(instance))
.then(instanceDetails => {
this.instance = instanceDetails;
this.consoleOutputInstance = {
account: instanceDetails.account,
region: instanceDetails.region,
id: instanceDetails.humanReadableName,
provider: instanceDetails.provider,
};

const unsubscribe = KubernetesManifestService.makeManifestRefresher(
this.app,
{
account: this.instance.account,
location: this.instance.namespace,
name: this.instance.name,
},
this,
);
this.$scope.$on('$destroy', () => {
unsubscribe();
});
this.state.loading = false;
.then(() => {
this.extractInstance(instance);
this.app.onRefresh(this.$scope, () => this.extractInstance(instance));
})
.catch(() => {
this.state.loading = false;
});
.catch(() => this.autoClose());
}

public deleteInstance(): void {
Expand All @@ -93,14 +79,37 @@ class KubernetesInstanceDetailsController implements IController {
public editInstance(): void {
KubernetesManifestCommandBuilder.buildNewManifestCommand(
this.app,
this.instance.manifest,
this.manifest.manifest,
this.instance.moniker,
this.instance.account,
).then(builtCommand => {
ManifestWizard.show({ title: 'Edit Manifest', application: this.app, command: builtCommand });
});
}

private extractInstance(instanceFromState: InstanceFromStateParams): void {
this.retrieveInstance(instanceFromState).then((instance: IKubernetesInstance) => {
if (!instance) {
return this.autoClose();
}
ManifestReader.getManifest(instance.account, instance.namespace, instance.name).then((manifest: IManifest) => {
this.instance = {
...instance,
apiVersion: manifest.manifest.apiVersion,
displayName: manifest.manifest.metadata.name,
};
this.manifest = manifest;
this.consoleOutputInstance = {
account: this.instance.account,
region: this.instance.region,
id: this.instance.humanReadableName,
provider: this.instance.provider,
};
this.state.loading = false;
});
});
}

private retrieveInstance(instanceFromState: InstanceFromStateParams): IPromise<IKubernetesInstance> {
const instanceLocatorPredicate = (dataSource: InstanceManager) => {
return dataSource.instances.some(possibleMatch => possibleMatch.id === instanceFromState.instanceId);
Expand Down Expand Up @@ -132,11 +141,7 @@ class KubernetesInstanceDetailsController implements IController {
RecentHistoryService.addExtraDataToLatest('instances', recentHistoryExtraData);
return InstanceReader.getInstanceDetails(instanceManager.account, instanceManager.region, instance.name).then(
(instanceDetails: IKubernetesInstance) => {
instanceDetails.account = instanceManager.account;
instanceDetails.namespace = instanceDetails.manifest.metadata.namespace;
instanceDetails.displayName = instanceDetails.manifest.metadata.name;
instanceDetails.kind = instanceDetails.manifest.kind;
instanceDetails.apiVersion = instanceDetails.manifest.apiVersion;
instanceDetails.namespace = instanceDetails.region;
instanceDetails.id = instance.id;
instanceDetails.name = instance.name;
instanceDetails.provider = 'kubernetes';
Expand All @@ -147,6 +152,15 @@ class KubernetesInstanceDetailsController implements IController {
return this.$q.reject();
}
}

private autoClose(): void {
if (this.$scope.$$destroyed) {
return;
} else {
this.$state.params.allowModalToStayOpen = true;
this.$state.go('^', null, { location: 'replace' });
}
}
}

export const KUBERNETES_INSTANCE_DETAILS_CTRL = 'spinnaker.kubernetes.instanceDetails.controller';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>
<dt>Kind</dt>
<dd>{{ctrl.instance.kind}}</dd>
<dt>QOS Class</dt>
<dd><kubernetes-manifest-qos manifest="ctrl.instance.manifest"></kubernetes-manifest-qos></dd>
<dd><kubernetes-manifest-qos manifest="ctrl.manifest.manifest"></kubernetes-manifest-qos></dd>
<dt>Logs</dt>
<dd>
<console-output-link instance="ctrl.consoleOutputInstance" uses-multi-output="true"></console-output-link>
Expand All @@ -65,7 +65,7 @@ <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>
</collapsible-section>

<kubernetes-annotation-custom-sections
manifest="ctrl.instance.manifest"
manifest="ctrl.manifest.manifest"
resource="ctrl.instance"
></kubernetes-annotation-custom-sections>

Expand All @@ -75,13 +75,13 @@ <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>

<collapsible-section heading="Resources" expanded="true">
<kubernetes-manifest-resources
manifest="ctrl.instance.manifest"
manifest="ctrl.manifest.manifest"
metrics="ctrl.manifest.metrics"
></kubernetes-manifest-resources>
</collapsible-section>

<collapsible-section heading="Labels" expanded="true">
<kubernetes-manifest-labels manifest="ctrl.instance.manifest"></kubernetes-manifest-labels>
<kubernetes-manifest-labels manifest="ctrl.manifest.manifest"></kubernetes-manifest-labels>
</collapsible-section>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ export interface IKubernetesLoadBalancer extends ILoadBalancer {
kind: string;
displayName: string;
apiVersion: string;
manifest: any;
namespace: string;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { copy, IController, IScope, module } from 'angular';
import { IController, IScope, module } from 'angular';
import { IModalService } from 'angular-ui-bootstrap';
import { StateService } from '@uirouter/angularjs';

import { Application, ILoadBalancer, IManifest } from '@spinnaker/core';
import { Application, ILoadBalancer, IManifest, ManifestReader } from '@spinnaker/core';

import { IKubernetesLoadBalancer } from './IKubernetesLoadBalancer';
import { KubernetesManifestService } from '../../manifest/manifest.service';
import { KubernetesManifestCommandBuilder } from '../../manifest/manifestCommandBuilder.service';
import { ManifestWizard } from '../../manifest/wizard/ManifestWizard';

Expand All @@ -18,7 +17,6 @@ interface ILoadBalancerFromStateParams {
class KubernetesLoadBalancerDetailsController implements IController {
public state = { loading: true };
public manifest: IManifest;
private loadBalancerFromParams: ILoadBalancerFromStateParams;
public loadBalancer: IKubernetesLoadBalancer;

public static $inject = ['$uibModal', '$state', '$scope', 'loadBalancer', 'app'];
Expand All @@ -29,25 +27,14 @@ class KubernetesLoadBalancerDetailsController implements IController {
loadBalancer: ILoadBalancerFromStateParams,
private app: Application,
) {
this.loadBalancerFromParams = loadBalancer;
this.app
.getDataSource('loadBalancers')
const dataSource = this.app.getDataSource('loadBalancers');
dataSource
.ready()
.then(() => {
this.extractLoadBalancer();
const unsubscribe = KubernetesManifestService.makeManifestRefresher(
this.app,
{
account: this.loadBalancerFromParams.accountId,
location: this.loadBalancerFromParams.region,
name: this.loadBalancerFromParams.name,
},
this,
);
this.$scope.$on('$destroy', () => {
unsubscribe();
});
});
this.extractLoadBalancer(loadBalancer);
dataSource.onRefresh(this.$scope, () => this.extractLoadBalancer(loadBalancer));
})
.catch(() => this.autoClose());
}

public deleteLoadBalancer(): void {
Expand All @@ -57,9 +44,9 @@ class KubernetesLoadBalancerDetailsController implements IController {
controllerAs: 'ctrl',
resolve: {
coordinates: {
name: this.loadBalancerFromParams.name,
namespace: this.loadBalancerFromParams.region,
account: this.loadBalancerFromParams.accountId,
name: this.loadBalancer.name,
namespace: this.loadBalancer.namespace,
account: this.loadBalancer.account,
},
application: this.app,
manifestController: (): string => null,
Expand All @@ -70,35 +57,33 @@ class KubernetesLoadBalancerDetailsController implements IController {
public editLoadBalancer(): void {
KubernetesManifestCommandBuilder.buildNewManifestCommand(
this.app,
this.loadBalancer.manifest,
this.manifest.manifest,
this.loadBalancer.moniker,
this.loadBalancer.account,
).then(builtCommand => {
ManifestWizard.show({ title: 'Edit Manifest', application: this.app, command: builtCommand });
});
}

private extractLoadBalancer(): void {
private extractLoadBalancer({ accountId, name, region }: ILoadBalancerFromStateParams): void {
const rawLoadBalancer = this.app.getDataSource('loadBalancers').data.find((test: ILoadBalancer) => {
return (
test.name === this.loadBalancerFromParams.name &&
test.account === this.loadBalancerFromParams.accountId &&
test.region === this.loadBalancerFromParams.region
);
return test.name === name && test.account === accountId && test.region === region;
});

if (rawLoadBalancer) {
this.state.loading = false;
this.loadBalancer = copy(rawLoadBalancer) as IKubernetesLoadBalancer;
this.loadBalancer.namespace = rawLoadBalancer.region;
this.loadBalancer.displayName = rawLoadBalancer.manifest.metadata.name;
this.loadBalancer.kind = rawLoadBalancer.manifest.kind;
this.loadBalancer.apiVersion = rawLoadBalancer.manifest.apiVersion;

this.app.getDataSource('loadBalancers').onRefresh(this.$scope, () => this.extractLoadBalancer());
} else {
this.autoClose();
if (!rawLoadBalancer) {
return this.autoClose();
}

ManifestReader.getManifest(accountId, region, name).then((manifest: IManifest) => {
this.manifest = manifest;
this.loadBalancer = {
...rawLoadBalancer,
apiVersion: manifest.manifest.apiVersion,
displayName: manifest.manifest.metadata.name,
namespace: rawLoadBalancer.region,
};
this.state.loading = false;
});
}

private autoClose(): void {
Expand Down
Loading

0 comments on commit ef176f0

Please sign in to comment.