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

Restructure longhorn UI proxy link to contain dynamic namespace #10263

Merged
merged 2 commits into from
Feb 29, 2024

Conversation

jordojordo
Copy link
Member

@jordojordo jordojordo commented Jan 12, 2024

Summary

Fixes #10259

The Longhorn frontend UI would fail to load as the namespace was hard-coded to longhorn-system. Although setting this namespace is the recommended approach when installing Longhorn with Helm, users may still determine their own namespace.

Occurred changes and/or fixed issues

This adds a computed property to find the Longhorn UI based on the label app=longhorn-ui which is defined in the Longhorn Helm chart.
If the service is found, the externalLinks will contain the correct namespace of this service in the link property.

Technical notes summary

I've also added a banner to display an error when no external links have been populated.

Screenshot/Video

longhorn-ui.mp4

@jordojordo jordojordo added this to the v2.9.0 milestone Jan 12, 2024
@jordojordo jordojordo self-assigned this Jan 12, 2024
async mounted() {
if ( this.$store.getters['cluster/schemaFor'](SERVICE) ) {
await this.$store.dispatch('cluster/findAll', { type: SERVICE });
Copy link
Member

Choose a reason for hiding this comment

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

There might be a large number of services, so for performance, we can use the label selector to look just for the longhorn one.

Copy link
Member Author

Choose a reason for hiding this comment

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

That was my original approach with:

  async mounted() {
    if ( this.$store.getters['cluster/schemaFor'](SERVICE) ) {
      const uiService = await this.$store.dispatch('cluster/findMatching', {
        type:     SERVICE,
        selector: 'app=longhorn-ui'
      });

      if ( !isEmpty(uiService) && uiService.metadata?.namespace ) {
        this.externalLinks = [
          {
            enabled:     true,
            iconSrc:     this.longhornImgSrc,
            label:       'longhorn.overview.linkedList.longhorn.label',
            description: 'longhorn.overview.linkedList.longhorn.description',
            link:        `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ uiService.metadata.namespace }/services/http:longhorn-frontend:80/proxy/`
          },
        ];
      }
    }
  },

The service is never found even when it exists. If I fetch all of the services with findAll, then run findMatching this will work but defeats the purpose. Am I using findMatching incorrectly?

longhorn-ui-2.mp4

Copy link
Member Author

@jordojordo jordojordo Jan 16, 2024

Choose a reason for hiding this comment

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

I looked further into this issue with findMatching and it seems that this is expected behavior. When findMatching is dispatched, it will return getters.matching which only has access to the resources that have already been stored within the getters.

Copy link
Member

Choose a reason for hiding this comment

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

You can supply force: true in the options to bypass that behaviour.

@jordojordo jordojordo requested a review from nwmac January 18, 2024 13:49
@nwmac
Copy link
Member

nwmac commented Jan 22, 2024

@jordojordo I had a look and the issue is that findMatching returns an array of matching services, not a single service which your code was looking for.

This worked for me:

  async mounted() {
    if ( this.$store.getters['cluster/schemaFor'](SERVICE) ) {
      await this.$store.dispatch('cluster/findAll', { type: SERVICE });

      const uiServices = await this.$store.dispatch('cluster/findMatching', { type: SERVICE, selector: 'app=longhorn-ui' });

      console.error(uiServices);

      if (uiServices && uiServices.length ===1 && uiServices[0].metadata?.namespace) {
        this.externalLinks = [
          {
            enabled:     true,
            iconSrc:     this.longhornImgSrc,
            label:       'longhorn.overview.linkedList.longhorn.label',
            description: 'longhorn.overview.linkedList.longhorn.description',
            link:        `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ uiServices[0].metadata.namespace }/services/http:longhorn-frontend:80/proxy/`
          },
        ];
      }
    }
  },

You might want to use fetch rather than mounted as with this, the red banner flicks up briefly before the service is found.

I would also suggest we use a vertical IconMessage rather than the error banner, eg:

image

Lastly, if we can avoid using lodash that would be great - generally I think we want to try and get that out of the code base, espcially for things like isEmpty (code above does not use that)

Copy link
Member

@nwmac nwmac left a comment

Choose a reason for hiding this comment

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

See comment

@jordojordo
Copy link
Member Author

jordojordo commented Jan 22, 2024

I updated this to use the fetch method rather than the mounted when fetching the services, converted the externalLinks into a computed property, and switched the Banner to an IconMessage component with a more specific message. Also updated the tests to fit this new structure.

longhorn.mp4

@jordojordo jordojordo requested a review from nwmac January 22, 2024 16:37
shell/pages/c/_cluster/longhorn/index.vue Outdated Show resolved Hide resolved
@jordojordo
Copy link
Member Author

Restructured this to use the findMatching action.

longhorn.mp4

@jordojordo jordojordo merged commit 983a70c into rancher:master Feb 29, 2024
21 checks passed
@jordojordo jordojordo deleted the longhorn-ns branch February 29, 2024 14:49
@enneitex
Copy link

Hey,

I know this is a bit late as this has been merged for a long time but this change means that users need mors RBAC than before to access longhorn UI. They need to be able to list services in every namespaces, this was not required before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Longhorn section in Rancher UI support for Longhorn installations in Namespaces other than longhorn-system
3 participants