Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(provider/aws): Functions (listing and searching) #7536

Merged
merged 11 commits into from
Oct 25, 2019

Conversation

sidmuls
Copy link
Contributor

@sidmuls sidmuls commented Oct 16, 2019

Issue: https://github.com/spinnaker/spinnaker/issues/4921Issue
Summary:
Add functions support to Spinnaker UI. This is a net functionality that we've been working on for almost a year to this point. The initial backend work was done like three months back.
From then we've worked on creating the UI components with guidance from the Netflix UX team.

Cloud Provider(s): provider/AWS
Environment:
This worked on user's local environment and also through deploying docker images to kubernetes cluster.

Feature Area: @spinnaker/ui-ux-team
Description:
CRUD functionality for managing lambda functions, With this new we must be able to create, update and delete lambda lambda functions through Spinnaker UI
We must also be able to attach target groups to lambda functions using Spinnaker UI.
Additional Details:
Clouddriver backend details: https://github.com/spinnaker/clouddriver/tree/master/clouddriver-lambda

@spinnakerbot
Copy link
Contributor

The following commits need their title changed:

  • c7d0768: .

  • b340011: feat(provider/aws):Function listing and searching functionality

Please format your commit title into the form:

<type>(<scope>): <subject>, e.g. fix(kubernetes): address NPE in status check

This allows us to easily generate changelogs & determine semantic version numbers when cutting releases. You can read more about commit conventions here.

This change adds a new tab for functions and facilitates listing existing functions and searching functions listed.
Corresponding provider specific changes are included in this change for AWS.

Authors: @sidmuls and @nabebe
This change adds a new tab for functions and facilitates listing existing functions and searching functions listed.
Corresponding provider specific changes are included in this change for AWS.

Authors: @sidmuls and @nabebe
functionName: string;
publish: boolean;
description: string;
tags: [{}];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use a more explicit type or generics for the tags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had thought of having tags: [{[key: string] : string}]
But since tags can be empty, the following error is thrown:

Property '0' is missing in type '[]' but required in type '[{ [key: string]: string; }]'.

Could you please suggest a better way?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like {} is also equiavalent to { [key: string]: any }, so {} may be the best option unless there is a constant, explicit type when there is a tag present

tags: [{}];
memorySize: number;
timeout: number;
envVariables: {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If envVariables will not be empty it would be stronger to make the type { [key: string]: any }.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can be empty if no env vars are set on the function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, then feel free to leave it as is.

functionDef: IFunction;
}

export class Function extends React.Component<IFunctionProps> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this a functional component since it is stateless and presentational only?

export interface IFunctionDetailsProps extends IOverridableProps {}

@Overridable('function.details')
export class FunctionDetails extends React.Component<IFunctionDetailsProps> {

This comment was marked as outdated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it looks like our @Overridable annotation can only decorate class components.

https://github.com/spinnaker/deck/blob/master/app/scripts/modules/core/src/overrideRegistry/Overridable.tsx#L36-L40

At least in its current form. 😞

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. A PureComponent could be a viable alternative in the current form, I would have to look at the differences between the two interfaces in react.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine as-is. This component is effectively a placeholder and hopefully never gets rendered.


export class Functions extends React.Component<IFunctionsProps, IFunctionsState> {
private groupsUpdatedListener: Subscription;
private functionsRefreshUnsubscribe: () => any;

This comment was marked as outdated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the definition of that function maps to

this.functionsRefreshUnsubscribe = app
      .getDataSource('functions')
      .onRefresh(null, () => this.updateFunctionGroups());

the onRefresh returns any

};

public render(): React.ReactElement<Functions> {
const groupings = this.state.initialized ? (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Groupings should be its own component, especially since it has already been abstracted away from the rest of the presentational layer.

…tion component.

This is a refactoring change as requested by reviewer @caseyhebebrand

Author: @sidmuls
This change is for refactoring requested by reviewer @caseyhebebrand.

Author: @sidmuls
super(props);

const { groups } = props;
this.state = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just directly use the props instead of assigning groups to the state. Especially since you are never mutating the groups within the component. It will re-render anyway if the groups in props are updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed the change :)

@caseyhebebrand
Copy link
Contributor

LGTM, thanks for addressing the comments

Copy link
Contributor

@christopherthielen christopherthielen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good! I just have a few requests and questions.

description?: string;
name?: string;
functionName?: string;
provider?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is provider?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some providers may add the 'cloud provider' field with the key 'provider'
it was to accomodate for that discrepancy from the backend.
but we can probably remove it and enforce the filed key to be 'cloudProvider'
I have removed it in the next push.

export interface IFunctionDetailsProps extends IOverridableProps {}

@Overridable('function.details')
export class FunctionDetails extends React.Component<IFunctionDetailsProps> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine as-is. This component is effectively a placeholder and hopefully never gets rendered.


constructor() {
this.asFilterModel = FilterModelService.configureFilterModel(this as any, filterModelConfig);
FilterModelService.registerRouterHooks(this.asFilterModel, '**.application.insight.loadBalancers.**');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'**.application.insight.loadBalancers.**'

this doesn't seem right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for pointing this out :)
fixed in the next push.


constructor() {}

private addSearchFields(functionDef: IFunction): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this should be done in the transformer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this fits here because it is specific to filtering.
I used loadbalancer module as reference.


// sort groups in place so Angular doesn't try to update the world
FunctionState.filterModel.asFilterModel.groups.sort((a, b) => {
if (a.heading < b.heading) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return a.heading.localeCompare(b.heading)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

const functions = this.filterFunctionsForDisplay(application.functions.data);
const grouped = groupBy(functions, 'account');

forOwn(grouped, (group, account) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would love to see this section extracted to a pure function, then some tests written against it. It's difficult to read and the intentions are not completely clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in the next push.

.value();
}

private diffSubgroups(oldGroups: IFunctionGroup[], newGroups: IFunctionGroup[]): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would like to see some tests for this function

Copy link
Contributor Author

@sidmuls sidmuls Oct 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured we don't need this method altogether.
removed it in next push.

public loadFunctions(applicationName: string): IPromise<IFunctionSourceData[]> {
return API.one('applications', applicationName)
.all('functions')
.withParams({ region: 'us-west-2' })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard coded region

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed in next push :)

(applicationStateProvider: ApplicationStateProvider, stateConfigProvider: StateConfigProvider) => {
const functionDetails: INestedState = {
name: 'functionDetails',
url: '/functionDetails/:provider/:account/:region/:vpcId/:name',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't uniquely target a function without a vpcId?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can. removed it in my next push. Thank you for pointing this out :)


private normalizeFunction(functionDef: IFunctionSourceData): IPromise<IFunction> {
return this.functionTransformer.normalizeFunction(functionDef).then((fn: IFunction) => {
fn.cloudProvider = fn.cloudProvider || 'aws';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the backend ever return functions without a cloudProvider field? This seems a little odd since I assume the backend always returns 'aws' for Lambdas?

name: $stateParams.name,
accountId: $stateParams.account,
region: $stateParams.region,
vpcId: $stateParams.vpcId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this line

Copy link
Contributor

@christopherthielen christopherthielen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor things to address, but those can be in a subsequent pr.

@christopherthielen christopherthielen added the ready to merge Reviewed and ready for merge label Oct 25, 2019
@mergify mergify bot added the auto merged Merged automatically by a bot label Oct 25, 2019
@mergify mergify bot merged commit 86a365b into spinnaker:master Oct 25, 2019
plumpy added a commit that referenced this pull request Oct 25, 2019
mergify bot pushed a commit that referenced this pull request Oct 25, 2019
christopherthielen added a commit to christopherthielen/deck that referenced this pull request Oct 28, 2019
d71daa5 fix(core/pipeline): fully re-render list of trigger configs after a delete (spinnaker#7571)
629a98f fix(core/pipeline): make revision dropdown usable, layout tweaks (spinnaker#7569)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
114303a fix(kubernetes): disable project cluster filtration by stack/detail (spinnaker#7562)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
6236a9f fix(core/pipeline): make UX less bad when a pipeline stage never happened (spinnaker#7563)
christopherthielen added a commit to christopherthielen/deck that referenced this pull request Oct 28, 2019
c2bbf20 feat(rosco): Allow roscoMode per stage/execution (spinnaker#7564)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
christopherthielen added a commit that referenced this pull request Oct 28, 2019
d71daa5 fix(core/pipeline): fully re-render list of trigger configs after a delete (#7571)
629a98f fix(core/pipeline): make revision dropdown usable, layout tweaks (#7569)
ca176fc feat(provider/aws): Functions (listing and searching) (#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (#7536)" (#7567)
114303a fix(kubernetes): disable project cluster filtration by stack/detail (#7562)
86a365b feat(provider/aws): Functions (listing and searching) (#7536)
6236a9f fix(core/pipeline): make UX less bad when a pipeline stage never happened (#7563)
christopherthielen added a commit that referenced this pull request Oct 28, 2019
c2bbf20 feat(rosco): Allow roscoMode per stage/execution (#7564)
ca176fc feat(provider/aws): Functions (listing and searching) (#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (#7536)" (#7567)
86a365b feat(provider/aws): Functions (listing and searching) (#7536)
Jammy-Louie pushed a commit to pivotal/deck that referenced this pull request Nov 8, 2019
Jammy-Louie pushed a commit to pivotal/deck that referenced this pull request Nov 8, 2019
d71daa5 fix(core/pipeline): fully re-render list of trigger configs after a delete (spinnaker#7571)
629a98f fix(core/pipeline): make revision dropdown usable, layout tweaks (spinnaker#7569)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
114303a fix(kubernetes): disable project cluster filtration by stack/detail (spinnaker#7562)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
6236a9f fix(core/pipeline): make UX less bad when a pipeline stage never happened (spinnaker#7563)
Jammy-Louie pushed a commit to pivotal/deck that referenced this pull request Nov 8, 2019
c2bbf20 feat(rosco): Allow roscoMode per stage/execution (spinnaker#7564)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
yunzhangit pushed a commit to yunzhangit/deck that referenced this pull request Mar 28, 2021
* .

* feat(provider/aws): Function listing and searching functionality

This change adds a new tab for functions and facilitates listing existing functions and searching functions listed.
Corresponding provider specific changes are included in this change for AWS.

Authors: @sidmuls and @nabebe

* feat(provider/aws): Function listing and searching functionality

This change adds a new tab for functions and facilitates listing existing functions and searching functions listed.
Corresponding provider specific changes are included in this change for AWS.

Authors: @sidmuls and @nabebe

* refactor(provider/aws): Converting Function class component into function component.

This is a refactoring change as requested by reviewer @caseyhebebrand

Author: @sidmuls

* refactor(provider/aws): Refactoring groupings into a separate component.

This change is for refactoring requested by reviewer @caseyhebebrand.

Author: @sidmuls

* refactor(provider/aws): Removing unnecessary state from FunctionGroupings.

This change is a refactoring requested by @caseyhebebrand

Author: @sidmuls

*  refactor(provider/aws): removing extra line. Tthis is actually for retrying tests on TravisCI

* refactor(provider/aws): Adding tests for FunctionFilterService and changes as requested by @christopherthielen

Author: @sidmuls

* refactor(provider/aws): removing unnecessary field from IFunction
yunzhangit pushed a commit to yunzhangit/deck that referenced this pull request Mar 28, 2021
yunzhangit pushed a commit to yunzhangit/deck that referenced this pull request Mar 28, 2021
d71daa5 fix(core/pipeline): fully re-render list of trigger configs after a delete (spinnaker#7571)
629a98f fix(core/pipeline): make revision dropdown usable, layout tweaks (spinnaker#7569)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
114303a fix(kubernetes): disable project cluster filtration by stack/detail (spinnaker#7562)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
6236a9f fix(core/pipeline): make UX less bad when a pipeline stage never happened (spinnaker#7563)
yunzhangit pushed a commit to yunzhangit/deck that referenced this pull request Mar 28, 2021
c2bbf20 feat(rosco): Allow roscoMode per stage/execution (spinnaker#7564)
ca176fc feat(provider/aws): Functions (listing and searching) (spinnaker#7568)
e49ffaf Revert "feat(provider/aws): Functions (listing and searching) (spinnaker#7536)" (spinnaker#7567)
86a365b feat(provider/aws): Functions (listing and searching) (spinnaker#7536)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto merged Merged automatically by a bot ready to merge Reviewed and ready for merge target-release/1.17
Projects
None yet
5 participants