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

Fix for helm application filters, refactor topology utils #4778

Conversation

jeff-phillips-18
Copy link
Member

Fixes:
https://issues.redhat.com/browse/ODC-3280

Analysis / Root cause:
Workloads were being filtered out during data creation time and the helm workloads do not contain the application label so they were not being created.

Solution Description:
Updated the mechanism for application filtering to create all the nodes and hide those not in the filtered application.

Large refactor of the data creation functions to simplify parameters and to break it up into the different types (knative, helm, operators, base). Eventually this should be changed to use plugins for each to make it more extensible as more types are added.

Screen shots / Gifs for design review:
No visible changes

Unit test coverage report:
image

Browser conformance:

  • Chrome
  • Firefox
  • Safari
  • Edge

@openshift-ci-robot openshift-ci-robot added component/core Related to console core functionality component/dev-console Related to dev-console component/knative Related to knative-plugin component/shared Related to console-shared labels Mar 19, 2020
@jeff-phillips-18
Copy link
Member Author

/retest

@openshift-ci-robot openshift-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 20, 2020
@andrewballantyne
Copy link
Contributor

/kind bug
/kind cleanup

@openshift-ci-robot openshift-ci-robot added kind/bug Categorizes issue or PR as related to a bug. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. labels Mar 20, 2020
@openshift-ci-robot openshift-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 20, 2020
Copy link
Contributor

@andrewballantyne andrewballantyne left a comment

Choose a reason for hiding this comment

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

There are a lot of references from knative-plugin to dev-console ... which we need to make use of the plugin infrastructure. cc @christianvogt

You are also directly using Redux Store getState... which is not a great idea as this breaks the paradigm of Redux. Not sure your refactors in this case should be done. They appear to have used the proper connect statement which is the appropriate way to do it. There are hooks and HoCs that can be used to help streamline it likely, but we shouldn't do import store; store.getState();.

Comment on lines 62 to 64
resourceList.forEach((resource) => {
utils = [...utils, resource.properties.utils];
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
resourceList.forEach((resource) => {
utils = [...utils, resource.properties.utils];
});
utils = resourceList.map((resource) => resource.properties.utils);


export const getResourceUtils = (resList?: any): Function[] => {
let utils = [];
const state = store.getState();
Copy link
Contributor

Choose a reason for hiding this comment

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

This is deprecated. If you need the feature flags you'll have to provide it somehow. This is bad Redux and never should have been done in the first place by Console.

cc @christianvogt not sure if we have a better mechanism to getting the feature flags though 😞

Copy link
Contributor

Choose a reason for hiding this comment

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

global access to redux store is a no go. We need to use connect or hooks.

@@ -649,8 +671,11 @@ export class TransformResourceData {
});
};

public createDeploymentConfigItems = (deploymentConfigs: K8sResourceKind[]): OverviewItem[] => {
return _.map(deploymentConfigs, (dc) => {
public createDeploymentConfigItems = (
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll need to expand the tests for these 4 methods to cover the new param you added.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

TYPE_TRAFFIC_CONNECTOR,
} from '../const';
import { moveConnectionModal } from '../components/MoveConnectionModal';
} from '@console/knative-plugin/src/topology/const';
Copy link
Contributor

Choose a reason for hiding this comment

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

Please reorder the import and put with the rest of the package imports.

cc @christianvogt Do we have a better mechanism for getting constants than a direct import from a package?


const mapStateToProps = (state: RootState): StateProps => {
return {
serviceBinding: getServiceBindingStatus(state),
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure we can get rid of this imo. This is kind of important functionality of Redux.

@@ -1,4 +1,4 @@
@import '../../topology-utils';
@import '../../../../../dev-console/src/components/topology/topology-utils';
Copy link
Contributor

Choose a reason for hiding this comment

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

😕 I am not sure we have a plugin infrastructure for SCSS.

cc @christianvogt

@@ -9,7 +9,7 @@ import {
} from '@console/topology';
import { modelFor, referenceFor } from '@console/internal/module/k8s';
import { useAccessReview } from '@console/internal/components/utils';
import { getTopologyResourceObject } from '../../topology-utils';
import { getTopologyResourceObject } from '@console/dev-console/src/components/topology/topology-utils';
Copy link
Contributor

Choose a reason for hiding this comment

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

Definitely need a plugin infrastructure for utilities -- I do not currently see one in place.

cc @christianvogt

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. That is the longer term goal. This PR is a stepping stone towards that.

@@ -13,9 +13,12 @@ import {
createSvgIdUrl,
} from '@console/topology';
import { getKnativeEventSourceIcon } from '@console/knative-plugin';
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably doesn't need to be package referenced anymore.

TopologyDataResources,
} from '@console/dev-console/src/components/topology/topology-types';
import { addToTopologyDataModel } from '@console/dev-console/src/components/topology/data-transforms/transform-utils';
import { getOperatorBackedServiceKindMap, OperatorBackedServiceKindMap } from '@console/shared/src';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { getOperatorBackedServiceKindMap, OperatorBackedServiceKindMap } from '@console/shared/src';
import { getOperatorBackedServiceKindMap, OperatorBackedServiceKindMap } from '@console/shared';

@@ -0,0 +1,112 @@
import * as _ from 'lodash';
import { DeploymentKind, K8sResourceKind } from '@console/internal/module/k8s';
import { ClusterServiceVersionKind } from '@console/operator-lifecycle-manager/src';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { ClusterServiceVersionKind } from '@console/operator-lifecycle-manager/src';
import { ClusterServiceVersionKind } from '@console/operator-lifecycle-manager';

@jeff-phillips-18
Copy link
Member Author

The idea here was to simplify the calls and avoid passing state through to all the lower levels. Using store.getState() is not necessarily a bad thing and is used in other sections of console code. Currently we get the state from connect to pass it down and down and down until eventually needed. This seems worse to me as it just seems to be a continuously growing list of parameters.

The plan would be to follow up with a plugin mechanism but wanted to get the simplification in first to make that process easier.

@andrewballantyne
Copy link
Contributor

The idea here was to simplify the calls and avoid passing state through to all the lower levels. Using store.getState() is not necessarily a bad thing and is used in other sections of console code. Currently we get the state from connect to pass it down and down and down until eventually needed. This seems worse to me as it just seems to be a continuously growing list of parameters.

The plan would be to follow up with a plugin mechanism but wanted to get the simplification in first to make that process easier.

Let's put aside what console code already does... there were a lot of early learning problems they have yet to correct. Getting access to store state directly is bad form as you're not subscribing for changes. Sure, in your case, it doesn't matter a ton as you're just asking at a "point in time" what the feature flag states are... but the functions you use it in are no longer testable (eg. pure functions).

You're doing impure things inside a function for convenience, this is a poor model to grow code on. Passing variables down as they are relevant is perfectly fine for a functional programming methodology. If your path is growing in design and needs the world of params, that's likely an indication that it should be broken up / address from a different angle; like computed in parts and combined in another.

In this case you've removed a simple "get me the state of a single feature flag" and a few threading of the variable to making an impure method that every time it's invoked can result in a different outcome. I don't think we should give up good design for convenience... what is short term gains will hurt us in the long run.

For the case of using plugins as well, we have developed hooks for this that were added in #3383. We should be able to keep a proper plugin infrastructure and redux connectivity without resorting to impure global accessors.

Copy link
Contributor

@christianvogt christianvogt left a comment

Choose a reason for hiding this comment

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

Lots of good changes here.
I think grouping related files (ie data transformers, components, utils etc) in a single folder such as helm, knative, operator-backed, etc... would be good in future to better support an extension model.

const nodeSorter = (node1: ColaNode, node2: ColaNode) =>
getNodeTimeStamp(node1) > getNodeTimeStamp(node2) ? -1 : 1;

export const getColaLayoutConstraints = (
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 rename file to layoutConstraints instead.

import KnativeService from './components/groups/KnativeService';
import { nodeContextMenu } from '@console/dev-console/src/components/topology/nodeContextMenu';
import RevisionNode from './components/nodes/RevisionNode';
import TrafficLink from '@console/dev-console/src/components/topology/components/edges/TrafficLink';
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this move to the knative plugin as well?

application: string = ALL_APPLICATIONS_KEY,
filters?: TopologyFilters,
): Model => {
const groupNodes: NodeModel[] = dataModel.graph.groups.map((d) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should look to remove the intermediate data model and handle groups as nodes in the future. Probably too much to do as part of this refactor.

Comment on lines +85 to +100
if (!knativeComponentFactoryRef.current) {
knativeComponentFactoryRef.current = new KnativeComponentFactory(serviceBinding);
}
if (!helmComponentFactoryRef.current) {
helmComponentFactoryRef.current = new HelmComponentFactory(serviceBinding);
}
if (!operatorsComponentFactoryRef.current) {
operatorsComponentFactoryRef.current = new OperatorsComponentFactory(serviceBinding);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious. I think you can just do React.useRef<Type>(new MyItem(value)). I think that achieves the same net result.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jeff-phillips-18 any consideration to the above? It'll save you the use of the if statements.

@@ -260,10 +296,13 @@ const Topology: React.FC<TopologyProps> = ({ data, serviceBinding, filters, acti
);
};

const getServiceBindingStatus = ({ FLAGS }: RootState): boolean => FLAGS.get(ALLOW_SERVICE_BINDING);
Copy link
Contributor

Choose a reason for hiding this comment

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

Last I reviewed (forgot to mention this - recalled when i saw this line) this exists already. Can you do a quick search for ALLOW_SERVICE_BINDING and see if it's implemented multiple times. Think we can probably reuse here.

}) =>
render({
}) => {
return render({
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume a debugging refactor? Not sure this change is needed, but no skin off my nose to leave it.

/>
</Firehose>
);
};

const getServiceBindingStatus = ({ FLAGS }: RootState): boolean => FLAGS.get(ALLOW_SERVICE_BINDING);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I wonder if this is the one I saw... Can we find a common spot for these?

@import '~@patternfly/patternfly/sass-utilities/colors';
@import '../../../../../../../node_modules/@patternfly/patternfly/sass-utilities/colors';
Copy link
Contributor

Choose a reason for hiding this comment

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

Yikes... what happened here? Is this really required? This looks horrible lol.

Copy link
Member Author

Choose a reason for hiding this comment

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

not sure how that happened, works fine the original way. Sorry I missed that.

Copy link
Contributor

@andrewballantyne andrewballantyne left a comment

Choose a reason for hiding this comment

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

Okay, my eyes hurt... but I think I am done. Just a couple disjointed comments I have posted above. Feel free to mark our conversations resolved when you are good with them @jeff-phillips-18 might be easier to re-review after the last set of changes (I think) you need.

@openshift-ci-robot openshift-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 26, 2020
Copy link
Contributor

@andrewballantyne andrewballantyne left a comment

Choose a reason for hiding this comment

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

/lgtm

Big refactor, let's try to get it merged and iterate over it.

@andrewballantyne
Copy link
Contributor

More conflicts 🙈

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Mar 26, 2020
@openshift-ci-robot openshift-ci-robot removed lgtm Indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Mar 27, 2020
@andrewballantyne
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Mar 27, 2020
@christianvogt
Copy link
Contributor

/approve

@christianvogt
Copy link
Contributor

@jeff-phillips-18 rebase

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 27, 2020
@openshift-ci-robot openshift-ci-robot removed the lgtm Indicates that a PR is ready to be merged. label Mar 27, 2020
@andrewballantyne
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Mar 27, 2020
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: andrewballantyne, christianvogt, jeff-phillips-18

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 26a372a into openshift:master Mar 27, 2020
@spadgett spadgett added this to the v4.5 milestone Mar 31, 2020
@jeff-phillips-18 jeff-phillips-18 deleted the refactor-topology-utils branch December 2, 2020 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. component/core Related to console core functionality component/dev-console Related to dev-console component/knative Related to knative-plugin component/shared Related to console-shared kind/bug Categorizes issue or PR as related to a bug. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants