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

Bug 1759051: Ensure that pre-labelled nodes are not re-labelled #3326

Merged
merged 1 commit into from Nov 27, 2019

Conversation

parthdhanjal
Copy link
Contributor

@openshift-ci-robot openshift-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Nov 11, 2019
@openshift-ci-robot
Copy link
Contributor

Hi @parthdhanjal. Thanks for your PR.

I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@openshift-ci-robot openshift-ci-robot added component/ceph Related to ceph-storage-plugin component/shared Related to console-shared labels Nov 11, 2019
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
Copy link
Contributor

Choose a reason for hiding this comment

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

use resourcePathFromModel

Copy link
Contributor

Choose a reason for hiding this comment

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

@bipuladh We need ocs.openshift.io~v1~StorageCluster here, hence referenceForModel is being used. Output of resourcePathFromModel is /k8s/all-namespaces/ocs.openshift.io~v1~StorageCluster which is not needed here

Copy link
Contributor

Choose a reason for hiding this comment

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

resourcePathFromModel would replace the whole of the line and you can specify the namespace as per your need as well as the appName.

Copy link
Member

Choose a reason for hiding this comment

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

@bipuladh resourcePathFromModel would not give us the the same path. I do feel like maybe the path used here might actually be a bug. The path to k8s resources should be standardized, and this appears at first glance to be different from the usual format.

Comment on lines 281 to 284
return k8sPatch(NodeModel, node, patch);
}
});
promises.push(selectedNodes);
Copy link
Contributor

Choose a reason for hiding this comment

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

You are creating an array containing an array of promises. ([][])
I would do something in the lines of:

const promise = k8sPatch(NodeMode,node,patch);
promises.push(promise);

Comment on lines 345 to 349
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
);
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 it would be easier for you to use resourcePathFromModel.

Comment on lines 322 to 355
if (promises) {
Promise.all(promises)
.then(() => {
k8sCreate(OCSServiceModel, ocsObj)
.then(() => {
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
);
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
} else {
k8sCreate(OCSServiceModel, ocsObj)
.then(() => {
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
);
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

no need for if else. Use finally

Copy link
Member

Choose a reason for hiding this comment

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

No need to use finally here either. Promise.all() will resolve if passed an empty array. You can remove all of the conditional logic around this, and it should work fine.

Comment on lines 284 to 285
promises.push(selectedNodes);
return promises;
Copy link
Contributor

Choose a reason for hiding this comment

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

You are creating an array of array.

value: '',
},
];
return k8sPatch(NodeModel, node, patch);
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
return k8sPatch(NodeModel, node, patch);
const promise = k8sPatch(NodeModel, node, patch);
promises.push(promise);

Copy link
Member

Choose a reason for hiding this comment

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

Creating a "const" array then pushing to it is a bit counterintuitive since constants should be immutable. I don't know why js allows this, but I think it's better practice to use a 'pure' approach like a reducer here:

  const makeLabelNodesRequest = (selectedNodes: NodeKind[]): Promise<NodeKind>[] =>
    _.reduce(selectedNodes, (accumulator, node) => {
      // patch could actually be defined as a constant at the top level scope since it is static.
      const patch = [
        {
          op: 'add',
          path: '/metadata/labels/cluster.ocs.openshift.io~1openshift-storage',
          value: '',
        },
      ];
      return isLabelPresent(node) ? accumulator : [
        ...accumulator,
        k8sPatch(NodeModel, node, patch)
      ];
    }, []);

@TheRealJon TheRealJon changed the title Ensure that pre-labelled nodes are not re-labelled Bug 1759051: Ensure that pre-labelled nodes are not re-labelled Nov 11, 2019
@openshift-ci-robot
Copy link
Contributor

@parthdhanjal: This pull request references Bugzilla bug 1759051, which is valid. The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

Bug 1759051: Ensure that pre-labelled nodes are not re-labelled

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@openshift-ci-robot openshift-ci-robot added the bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. label Nov 11, 2019
Copy link
Member

@TheRealJon TheRealJon left a comment

Choose a reason for hiding this comment

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

As @bipuladh pointed out, I think there is some flawed logic in makeLabelNodesRequest. You are returning a 2D array (which I don't think is the intention). See my comments on how this function could be improved. There are also a few "not new" things in node-list.tsx that I think should probably be addressed in a follow on at some point. I'll leave a separate comment for that.

value: '',
},
];
return k8sPatch(NodeModel, node, patch);
Copy link
Member

Choose a reason for hiding this comment

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

Creating a "const" array then pushing to it is a bit counterintuitive since constants should be immutable. I don't know why js allows this, but I think it's better practice to use a 'pure' approach like a reducer here:

  const makeLabelNodesRequest = (selectedNodes: NodeKind[]): Promise<NodeKind>[] =>
    _.reduce(selectedNodes, (accumulator, node) => {
      // patch could actually be defined as a constant at the top level scope since it is static.
      const patch = [
        {
          op: 'add',
          path: '/metadata/labels/cluster.ocs.openshift.io~1openshift-storage',
          value: '',
        },
      ];
      return isLabelPresent(node) ? accumulator : [
        ...accumulator,
        k8sPatch(NodeModel, node, patch)
      ];
    }, []);

Comment on lines 322 to 355
if (promises) {
Promise.all(promises)
.then(() => {
k8sCreate(OCSServiceModel, ocsObj)
.then(() => {
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
);
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
} else {
k8sCreate(OCSServiceModel, ocsObj)
.then(() => {
history.push(
`/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
ocsProps.clusterServiceVersion.metadata.name
}/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
);
})
.catch((err) => {
setProgress(false);
setError(err.message);
});
}
Copy link
Member

Choose a reason for hiding this comment

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

No need to use finally here either. Promise.all() will resolve if passed an empty array. You can remove all of the conditional logic around this, and it should work fine.

@TheRealJon
Copy link
Member

"Not new" issues that should probably be addressed at some point in a follow on.


node-list.tsx [line 313-315] unnecessary spread operator:

const promises = [];

promises.push(...makeLabelNodesRequest(selectedData));	

Should just be:

const promises = makeLabelNodesRequest(selectedData);

node-list.tsx [line 319-320] Mutating deep object properties:

Instead of creating a static ocsObj, cloning, then mutating it, we should just use a function to build the object we need:

export const getOCSRequestData = (storageClassName: string): K8sResourceKind => ({
  apiVersion: 'ocs.openshift.io/v1',
  kind: 'StorageCluster',
  metadata: {
    name: 'ocs-storagecluster',
    namespace: 'openshift-storage',
  },
  spec: {
    managedNodes: false,
    storageDeviceSets: [
      {
        name: 'ocs-deviceset',
        count: 3,
        resources: {},
        placement: {},
        portable: true,
        dataPVCTemplate: {
          spec: {
            storageClassName,
            accessModes: ['ReadWriteOnce'],
            volumeMode: 'Block',
            resources: {
              requests: {
                storage: '1Ti',
              },
            },
          },
        },
      },
    ],
  },
});

Tainting logic that is commented out should not be in master
Use a single TODO comment, and save the logic in another branch. We shouldn't have commented code like this in master.

@gnehapk
Copy link
Contributor

gnehapk commented Nov 12, 2019

@TheRealJon
node-list.tsx [line 319-320] Mutating deep object properties: - This is a constant request data that needs to be send out while creating ocs service, expect one field which will be updated. Since there are not many fields getting updated, IMO its better to create a constant here instead of writing a separate method to do that.

},
];
return k8sPatch(NodeModel, node, patch);
const promises = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

@parthdhanjal makeLabelNodesRequest definition should be like this -

const makeLabelNodesRequest = (selectedNodes: NodeKind[]): Promise<NodeKind>[] => {
    return selectedNodes.map((node: NodeKind) => {
      const nodeLabel = isLabelPresent(node, ocsLabel);
      if (!nodeLabel) {
        const patch = [
          {
            op: 'add',
            path: '/metadata/labels/cluster.ocs.openshift.io~1openshift-storage',
            value: '',
          },
        ];
        return k8sPatch(NodeModel, node, patch);
      }
    });
  };

No need to create a promise array here and pass the ocs label explicitly so that isLabelPresent function should be generic.

setError(err.message);
});

if (promises) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@parthdhanjal

Promise.all(promises)
      .then(() => {
        return k8sCreate(OCSServiceModel, ocsObj);
      })
      .then(() => {
        history.push(
          `/k8s/ns/${ocsProps.namespace}/clusterserviceversions/${
            ocsProps.clusterServiceVersion.metadata.name
          }/${referenceForModel(OCSServiceModel)}/${ocsObj.metadata.name}`,
        );
      })
      .catch((err) => {
        setProgress(false);
        setError(err.message);
      });

No need of if else and no need to write separate catch for both scenarios. It can be done in one like I have mentioned above.

@@ -18,6 +18,9 @@ export const getNodeRoles = (node: NodeKind): string[] => {
);
};

export const isLabelPresent = (node: NodeKind) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

@parthdhanjal

export const isLabelPresent = (node: NodeKind, label: string) : boolean =>
  _.has(node, ['metadata', 'labels', label]);

Copy link
Member

Choose a reason for hiding this comment

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

I would also argue that this function probably belongs in frontend/packages/console-shared/src/selectors/common.ts. Labels are common to all k8s resources, so this could be reused elsewhere. Also, I think 'hasLabel' is probably a more concise and accurate name.

export const hasLabel = <A extends K8sResourceKind = K8sResourceKind>(value: A, label: string) : boolean =>
  _.has(value, ['metadata', 'labels', label]);

@openshift-ci-robot openshift-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Nov 12, 2019
@cloudbehl
Copy link
Contributor

/ok-to-test
/kind bug

@openshift-ci-robot openshift-ci-robot added kind/bug Categorizes issue or PR as related to a bug. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Nov 12, 2019
@gnehapk
Copy link
Contributor

gnehapk commented Nov 12, 2019

@parthdhanjal Frontend tests are failing. Can you please check?

@TheRealJon
Copy link
Member

TheRealJon commented Nov 12, 2019

@TheRealJon
node-list.tsx [line 319-320] Mutating deep object properties: - This is a constant request data that needs to be send out while creating ocs service, expect one field which will be updated. Since there are not many fields getting updated, IMO its better to create a constant here instead of writing a separate method to do that.

@gnehapk I have to disagree with this. If you need to change part of the object when you use it, then by definition it is not constant. The number of fields being updated doesn't matter. The important thing is that we are generating a dynamic object in a reusable way. The best way to do that is with a function.

@openshift-ci-robot openshift-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Nov 13, 2019
@gnehapk
Copy link
Contributor

gnehapk commented Nov 13, 2019

/test images
/test e2e-gcp-console

@openshift-ci-robot openshift-ci-robot removed the lgtm Indicates that a PR is ready to be merged. label Nov 25, 2019
@parthdhanjal
Copy link
Contributor Author

/test e2e-gcp-console

@parthdhanjal
Copy link
Contributor Author

/retest

@gnehapk
Copy link
Contributor

gnehapk commented Nov 26, 2019

/test e2e-gcp-console

const patch = [
{
op: 'add',
path: '/metadata/labels/cluster.ocs.openshift.io~1openshift-storage',
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiousity, where does '/metadata/labels/cluster.ocs.openshift.io~1openshift-storage' come from? the ~1openshift-storage seems a little strange to me.

@benjaminapetersen
Copy link
Contributor

/lgtm

I believe @TheRealJon is going to create a few follow-up chores in Jira to address some of the items he mentioned above.

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 26, 2019
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: benjaminapetersen, cloudbehl, gnehapk, parthdhanjal, TheRealJon

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-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 26, 2019
@benjaminapetersen
Copy link
Contributor

/retest

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

11 similar comments
@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-merge-robot openshift-merge-robot merged commit 84e1a85 into openshift:master Nov 27, 2019
@openshift-ci-robot
Copy link
Contributor

@parthdhanjal: All pull requests linked via external trackers have merged. Bugzilla bug 1759051 has been moved to the MODIFIED state.

In response to this:

Bug 1759051: Ensure that pre-labelled nodes are not re-labelled

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@openshift-cherrypick-robot

@spadgett: new pull request created: #3591

In response to this:

/cherrypick release-4.3

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

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. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. component/ceph Related to ceph-storage-plugin component/shared Related to console-shared kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet