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): Setup create storage system wizard #9438

Merged

Conversation

afreen23
Copy link
Contributor

@afreen23 afreen23 commented Jul 7, 2021

The PR covers the following:

Testing Pr:
Use the following URL to see the Storage System wizard.

http://localhost:9000/k8s/ns/openshift-storage/operators.coreos.com~v1alpha1~ClusterServiceVersion/ocs-operator.v4.7.2/odf.openshift.io~v1alpha1~StorageSystem/~new

Screenshots:
Screenshot from 2021-07-08 01-29-25
Screenshot from 2021-07-08 01-28-32
Screenshot from 2021-07-08 00-55-21
Screenshot from 2021-07-08 01-24-41
Screenshot from 2021-07-08 00-55-41
Screenshot from 2021-07-08 00-55-32
Screenshot from 2021-07-08 03-53-44

@openshift-ci openshift-ci bot requested review from bipuladh and cloudbehl July 7, 2021 20:32
@openshift-ci openshift-ci bot added component/ceph Related to ceph-storage-plugin kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jul 7, 2021
@afreen23 afreen23 force-pushed the feat-implement-wizard branch 4 times, most recently from 92b28f0 to 86c9c39 Compare July 7, 2021 22:56
@afreen23
Copy link
Contributor Author

afreen23 commented Jul 8, 2021

/assign @vbnrh

@@ -0,0 +1,10 @@
export type ExternalProvider = {
Copy link
Contributor

Choose a reason for hiding this comment

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

this could be moved inside ceph-storage-plugin/src/types instead of a separate dir.
the dir odf-external-providers seems odd to be sitting at the root of the plugin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file and folder is to allow external providers to add their components e.g flash system.
I am keeping it separate so that I can add more details to it and maintain separate components for the external system.

import { ExternalProvider } from './types';
import { RHCS, StorageClusterIdentifier } from '../constants/create-storage-system';

export const ODF_EXTERNAL_PROVIDERS: ExternalProvider[] = [
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, these constants could be moved to ceph-storage-plugin/src/constants/create-storage-system.ts. Doesn't seem like this needs a separate place.

Copy link
Contributor Author

@afreen23 afreen23 Jul 8, 2021

Choose a reason for hiding this comment

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

@vbnrh we don't want to do that.
This file and folder is to allow external providers to add their components e.g flash system.
I am keeping it separate so that I can add more details to it and maintain separate components for the external system.

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 ditch the dir and keep the files like external-provider.ts, external-provider-types ? Should accomplish the same unless you're trying to add lot of more files in later PRs into the dir

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah we want to add support for each of providers to have their own folder and add their dedicated step.

frontend/packages/ceph-storage-plugin/src/models.ts Outdated Show resolved Hide resolved
nonRhcsExternalProviderStep,
{
canJumpTo: count >= 3,
...commonSteps.reviewAndCreate,
Copy link
Contributor

Choose a reason for hiding this comment

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

small confusion, if storagecluster is already there, we are just showing the step for creating storageclass and then moving to review and create ?

Is it just to create FlashSystem CR ?

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 the same be applicable to other cases if storagecluster exists or not ?

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 is Storage system creation, if OCS Storage System is already there we do not want to create that one.
RHCS itself uses Storage Cluster - an OCS Storage System, hence its only for external vendors

currentStep: StepState;
backingStorage: {
type: BackingStorageType;
externalProvider: string;
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
externalProvider: string;
externalProvider?: string;

Optional right ?

Copy link
Contributor Author

@afreen23 afreen23 Jul 8, 2021

Choose a reason for hiding this comment

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

It's the state of the component. it's set by the external storage dropdown.
By default one external Provider will always be set.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok makes sense :)

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
externalProvider: string;
externalProvider: RHCS | IBM_FLASH;

Reduce the scope of values that can be assigned to external providers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Expect some of changes in another PR.
Otherwise it will increase the scope. the next PR will standardize contribution mechanism for plugins.

@afreen23
Copy link
Contributor Author

afreen23 commented Jul 9, 2021

I have added an error handling HOC that can be used for each step:
In case of loading:
Screenshot from 2021-07-09 20-16-26
In case of error, will display -"An error has occurred: {errorMessage}"
Screenshot from 2021-07-09 20-02-32

cc @vbnrh @yuvalgalanti

currentStep: StepState;
backingStorage: {
type: BackingStorageType;
externalProvider: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

ok makes sense :)

import { ExternalProvider } from './types';
import { RHCS, StorageClusterIdentifier } from '../constants/create-storage-system';

export const ODF_EXTERNAL_PROVIDERS: ExternalProvider[] = [
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 ditch the dir and keep the files like external-provider.ts, external-provider-types ? Should accomplish the same unless you're trying to add lot of more files in later PRs into the dir

currentStep: StepState;
backingStorage: {
type: BackingStorageType;
externalProvider: string;
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
externalProvider: string;
externalProvider: RHCS | IBM_FLASH;

Reduce the scope of values that can be assigned to external providers

@vbnrh
Copy link
Contributor

vbnrh commented Jul 12, 2021

I have added an error handling HOC that can be used for each step:
In case of loading:
Screenshot from 2021-07-09 20-16-26
In case of error, will display -"An error has occurred: {errorMessage}"
Screenshot from 2021-07-09 20-02-32

cc @vbnrh @yuvalgalanti

Looks good although i'd prefer if the spinner is centered vertically and horizontally on the page. It looks a bit above center mark. Please check if you have time otherwise we can move on :-)

@afreen23 afreen23 force-pushed the feat-implement-wizard branch 2 times, most recently from 3f8e73d to d84001a Compare July 13, 2021 05:31
@afreen23
Copy link
Contributor Author

afreen23 commented Jul 13, 2021

Looks good although i'd prefer if the spinner is centered vertically and horizontally on the page. It looks a bit above center mark. Please check if you have time otherwise we can move on :-)

I also wanted that, but this is rendered inside the div rendered by PF wizard. In order to center this , we need to center the wizard body which will then mess with other flows where we we do not want to do that.
I can also do something like

className={(!ssLoaded || !!ssLoadError) && 'odf-create-storage-system-wizard-body'}

But the issue with that one is, I need to maintain error states for the different steps in the parent component.
I would not do this much effort for the loading UIs. Open to other suggestions.

@vbnrh
Copy link
Contributor

vbnrh commented Jul 13, 2021

I just tested the PR, Couple of issues i noticed

  1. StorageClass Dropdown is way too narrow and all the items are squeezed up. We need to make it wider

Screenshot from 2021-07-13 14-21-02

  1. Next button is wider than the back, cancel. We have to keep them the same size

Screenshot from 2021-07-13 14-21-58

  1. An error is thrown when selecting No default StorageClass from dropdown

Screenshot from 2021-07-13 14-24-10

  1. The dropdown items are not rendered with the correct design. The design looks off ?

Screenshot from 2021-07-13 14-25-49

  1. Additional margin/padding is required in between the breadcrumbs, title, wizard and it should show "Openshift Container Storage" as link instead of the ocs version.

Screenshot from 2021-07-13 14-27-40

Screenshot from 2021-07-13 14-35-49

Reference to how it is rendered on BucketClass creation page

Screenshot from 2021-07-13 14-36-09

@afreen23
Copy link
Contributor Author

afreen23 commented Jul 13, 2021

I just tested the PR, Couple of issues i noticed

1. StorageClass Dropdown is way too narrow and all the items are squeezed up. We need to make it wider
  1. Thats the optimum width we are using since previous releases
1. Additional margin/padding is required in between the breadcrumbs, title, wizard and it should show "Openshift Container Storage" as link instead of the ocs version.
  1. If you check the code , I have added this intentionally. Too much space on header is making wizard smaller.

The dropdown items are not rendered with the correct design. The design looks off ?

  1. Patternfly css https://www.patternfly.org/v4/components/form-select

Additional margin/padding is required in between the breadcrumbs, title, wizard and it should show "Openshift Container Storage" as link instead of the ocs version.

It takes in the name of resource you passing the url. If you check the previous version of code, you can see.
I have hardcoded it to be OpenShift Data Foundation for now to be consistent with other views

Rest I have fixed @vbnrh

@vbnrh
Copy link
Contributor

vbnrh commented Jul 13, 2021

I just tested the PR, Couple of issues i noticed

1. StorageClass Dropdown is way too narrow and all the items are squeezed up. We need to make it wider
  1. Thats the optimum width we are using since previous releases
1. Additional margin/padding is required in between the breadcrumbs, title, wizard and it should show "Openshift Container Storage" as link instead of the ocs version.
  1. If you check the code , I have added this intentionally. Too much space on header is making wizard smaller.
  1. Hmm, looks bit too narrow.. Screen has plenty of space i feel it should be stretched out

  2. I feel the wider spacing makes it look cleaner but UX may know best. Also we need to have consistent design with the other wizards

  3. Why is FormSelect needed when we could use a normal Dropdrown ? Are there any particular advantages ? As per design guidelines
    A form select embeds browser native select lists into a form.
    If your use case only calls for simple selects, you may opt to use a form select as an field inside a form.

I see we are only selecting a couple of static items but using a browser native list makes it inconsistent with dropdowns in the same page and other wizard pages .

@yuvalgalanti Thoughts ?

@afreen23
Copy link
Contributor Author

afreen23 commented Jul 13, 2021

3. Why is FormSelect needed when we could use a normal Dropdrown ? Are there any particular advantages ? As per design guidelines
   `A form select embeds browser native select lists into a form.`
   `If your use case only calls for simple selects, you may opt to use a form select as an field inside a form. `

I see we are only selecting a couple of static items but using a browser native list makes it inconsistent with dropdowns in the same page and other wizard pages .

We should not be choosing components purely based on aesthetics. We should consider the components which are semantically applicable for a UI element. Its is actually a select list option hence makes sense to use it here. Dropdown just renders the <button> . Additionally , you can add CSS to any component and get the same effect.
I would like to change Storage class as well, its in my todos.

@vbnrh
Copy link
Contributor

vbnrh commented Jul 13, 2021

3. Why is FormSelect needed when we could use a normal Dropdrown ? Are there any particular advantages ? As per design guidelines
   `A form select embeds browser native select lists into a form.`
   `If your use case only calls for simple selects, you may opt to use a form select as an field inside a form. `

I see we are only selecting a couple of static items but using a browser native list makes it inconsistent with dropdowns in the same page and other wizard pages .

We should not be choosing components purely based on aesthetics. We should consider the components which are semantically applicable for a UI element. Its is actually a select list option hence makes sense to use it here. Dropdown just renders the <button> . Additionally , you can add CSS to any component and get the same effect.
I would like to change Storage class as well, its in my todos.

Do we have any other places where FormSelect is being used ? if so we can proceed with it otherwise we better change it or make it look like the above dropdown. As more external providers are added, the design will only look more glaringly different over time.

I agree with your notion of using the proper component but Openshift team has always valued design consistency over what is logical which is why we have always made sure of all the text, capitalisation, colours, looks.

@afreen23
Copy link
Contributor Author

Do we have any other places where FormSelect is being used ? if so we can proceed with it otherwise we better change it or make it look like the above dropdown. As more external providers are added, the design will only look more glaringly different over time.

I agree with your notion of using the proper component but Openshift team has always valued design consistency over what is logical which is why we have always made sure of all the text, capitalisation, colours, looks.

Yep! I can see it used over a couple of places.

@vbnrh
Copy link
Contributor

vbnrh commented Jul 13, 2021

/approve

/assign @bipuladh @cloudbehl for the lgtm

@afreen23 afreen23 force-pushed the feat-implement-wizard branch 2 times, most recently from 2d06224 to c772153 Compare July 13, 2021 13:57
/* name is a unique identifier that will be used in naming StorageSystems and sub-StorageSystems
e.g `odf-<name>-storage-system`.
*/
id: ExternalProviderId;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need both id and kind?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For nicer names and ease in reference. Its only the reference point for a provider
kind I have kept but it can be dropped further since it can be constructed easily from apiVersion, apiGroup and kind.

const onStorageClassSelect = (sc: StorageClassResourceKind) =>
dispatch({
type: 'wizard/setStorageClass',
payload: { name: sc?.metadata?.name, provisioner: sc?.provisioner },
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
payload: { name: sc?.metadata?.name, provisioner: sc?.provisioner },
payload: { name: sc.metadata.name, provisioner: sc.provisioner },

These are always defined, right? If a user selects a storage class then the object is present.

Copy link
Contributor Author

@afreen23 afreen23 Jul 14, 2021

Choose a reason for hiding this comment

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

Not really, there is an option for no default storage/ no stoarge class class which is an empty object.

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 in that case as well the sc.provisioner will be added after figuring out the default storage class from the backend.

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 meant no storage class, updated!

Copy link
Contributor Author

@afreen23 afreen23 Jul 14, 2021

Choose a reason for hiding this comment

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

Y'all can check @vbnrh 's comment, he posted the error as well.
#9438 (comment)

@afreen23 afreen23 force-pushed the feat-implement-wizard branch 2 times, most recently from 0fce634 to 1a40cf9 Compare July 14, 2021 06:00
frontend/packages/ceph-storage-plugin/package.json Outdated Show resolved Hide resolved
const onStorageClassSelect = (sc: StorageClassResourceKind) =>
dispatch({
type: 'wizard/setStorageClass',
payload: { name: sc?.metadata?.name, provisioner: sc?.provisioner },
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 in that case as well the sc.provisioner will be added after figuring out the default storage class from the backend.

return validateBackingStorageStep(type, storageClass, externalProvider);
case StepsId.CreateLocalVolumeSet:
case StepsId.CapacityAndNodes:
case StepsId.ConnectionDetails:
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
case StepsId.ConnectionDetails:
case StepsId.ConnectionDetails:

How are providers supposed to add their validation logic here?

Copy link
Contributor Author

@afreen23 afreen23 Jul 14, 2021

Choose a reason for hiding this comment

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

Its for RHCS. RHCS has a very different view compared to external vendors.

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 external vendors only use create storage class step, that only we will be standardizing.


return (
<>
{showErrorAlert && (
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
{showErrorAlert && (
{!_.isEmpty(requestError) && (

We only need one state.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or simply requestError && (

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Check the code below:
actionClose={<AlertActionCloseButton onClose={() => setShowErrorAlert(false)} />}
The state is for close button on alert and also using it to show alert.

} from '@patternfly/react-core';
import './create-storage-system.scss';

export const CreateStorageSystemHeader: React.FC<CreateStorageSystemHeaderProps> = ({ url, t }) => (
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 use PageHeading here.

Copy link
Contributor Author

@afreen23 afreen23 Jul 14, 2021

Choose a reason for hiding this comment

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

PageHeading is a very heavy component , and also not certain whether its part of sdk or not.(when I was coding this)
Plus, as per the recent changes, it would be the case that we can drop this header when the new operand extension would come.

Copy link
Contributor

@bipuladh bipuladh Jul 14, 2021

Choose a reason for hiding this comment

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

I suggest we use PageHeading Operand Extension is going to take time. Page heading is going to be part of the SDK. As dashboards can't exist without PageHeading. The other reason to use PageHeading and an important one is to maintain style consistency across Pages with headers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PageHeading itself wont be required with the operand extension.

- Adds Backing Storage step
- implements a wizard with [incrementally enabled steps](https://www.patternfly.org/v4/components/wizard/#incrementally-enabled-steps)
- This step creates the Storage System for an external Provider other than RHCS on clicking Next.
- This step otherwise, allow choosing the backing storage for Storage Cluster. The Storage Cluster is hidden from UI but it is created internally by wizard flow. The creation of storage cluster happens in the last step.
- https://issues.redhat.com/browse/ODFE-83

Signed-off-by: Afreen Rahman <afrahman@redhat.com>
Copy link
Contributor

@bipuladh bipuladh left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jul 14, 2021
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jul 14, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: afreen23, bipuladh, cloudbehl, vbnrh

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 6427450 into openshift:master Jul 14, 2021
@spadgett spadgett added this to the v4.9 milestone Jul 14, 2021
@yuvalgalanti
Copy link

I just tested the PR, Couple of issues i noticed

  1. StorageClass Dropdown is way too narrow and all the items are squeezed up. We need to make it wider

Screenshot from 2021-07-13 14-21-02

  1. Next button is wider than the back, cancel. We have to keep them the same size

Screenshot from 2021-07-13 14-21-58

  1. An error is thrown when selecting No default StorageClass from dropdown

Screenshot from 2021-07-13 14-24-10

  1. The dropdown items are not rendered with the correct design. The design looks off ?

Screenshot from 2021-07-13 14-25-49

  1. Additional margin/padding is required in between the breadcrumbs, title, wizard and it should show "Openshift Container Storage" as link instead of the ocs version.

Screenshot from 2021-07-13 14-27-40

Screenshot from 2021-07-13 14-35-49

Reference to how it is rendered on BucketClass creation page

Screenshot from 2021-07-13 14-36-09

point 1: you are totally right lets make this filed wider
point 4: you right doesn't look like the PF$ dropdown
point 5: the padding you added looks good. lets see that its the same padding we have in other places as well.

@afreen23
Copy link
Contributor Author

afreen23 commented Jul 15, 2021

point 1: you are totally right lets make this filed wider

this is fixed

point 4: you right doesn't look like the PF$ dropdown

this is a pf form select -> https://www.patternfly.org/v4/components/form-select
We should check why its css is so different with PF folks and fix then.

point 5: the padding you added looks good. lets see that its the same padding we have in other places as well.

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/ceph Related to ceph-storage-plugin kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated 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

7 participants