diff --git a/pkg/epinio/config/epinio.ts b/pkg/epinio/config/epinio.ts index 2cdb74b66c..3a1f1e23c7 100644 --- a/pkg/epinio/config/epinio.ts +++ b/pkg/epinio/config/epinio.ts @@ -13,7 +13,8 @@ export function init($plugin: any, store: any) { headers, configureType, spoofedType, - weightType + weightType, + weightGroup } = $plugin.DSL(store, $plugin.name); const isEpinioSingleProduct = process.env.rancherEnv === 'epinio'; @@ -93,6 +94,34 @@ export function init($plugin: any, store: any) { customRoute: createEpinioRoute('c-cluster-resource', { resource: EPINIO_TYPES.CONFIGURATION }), }); + const SERVICE_GROUP = 'Services'; + + weightGroup(SERVICE_GROUP, 1, true); + + // Service Instance + weightType(EPINIO_TYPES.SERVICE_INSTANCE, 151, true); + configureType(EPINIO_TYPES.SERVICE_INSTANCE, { + isCreatable: false, + isEditable: false, + isRemovable: false, + showState: true, + showAge: false, + canYaml: false, + customRoute: createEpinioRoute('c-cluster-resource', { resource: EPINIO_TYPES.SERVICE_INSTANCE }), + }); + + // Catalog Service + weightType(EPINIO_TYPES.CATALOG_SERVICE, 150, true); + configureType(EPINIO_TYPES.CATALOG_SERVICE, { + isCreatable: false, + isEditable: false, + isRemovable: false, + showState: false, + showAge: false, + canYaml: false, + customRoute: createEpinioRoute('c-cluster-resource', { resource: EPINIO_TYPES.CATALOG_SERVICE }), + }); + // Namespace resource weightType(EPINIO_TYPES.NAMESPACE, 100, true); configureType(EPINIO_TYPES.NAMESPACE, { @@ -106,8 +135,14 @@ export function init($plugin: any, store: any) { showListMasthead: false // Disable default masthead because we provide a custom one. }); + basicType([ + EPINIO_TYPES.SERVICE_INSTANCE, + EPINIO_TYPES.CATALOG_SERVICE, + ], SERVICE_GROUP); + basicType([ EPINIO_TYPES.APP, + SERVICE_GROUP, EPINIO_TYPES.NAMESPACE, EPINIO_TYPES.CONFIGURATION ]); @@ -250,4 +285,32 @@ export function init($plugin: any, store: any) { sort: ['configuration.user'], }, ]); + + headers(EPINIO_TYPES.SERVICE_INSTANCE, [ + STATE, + SIMPLE_NAME, + { // This will be a link once the service instance detail / create / edit pages are created + name: 'catalog_service', + labelKey: 'epinio.serviceInstance.tableHeaders.service', + value: 'catalog_service', + sort: ['catalog_service'], + }, + + ]); + + headers(EPINIO_TYPES.CATALOG_SERVICE, [ + SIMPLE_NAME, + { + name: 'short_description', + labelKey: 'epinio.catalogService.tableHeaders.shortDesc', + value: 'short_description', + sort: ['short_description'], + }, + { + name: 'description', + labelKey: 'epinio.catalogService.tableHeaders.desc', + value: 'description', + sort: ['description'], + }, + ]); } diff --git a/pkg/epinio/l10n/en-us.yaml b/pkg/epinio/l10n/en-us.yaml index b762de90e1..17d04423d7 100644 --- a/pkg/epinio/l10n/en-us.yaml +++ b/pkg/epinio/l10n/en-us.yaml @@ -19,6 +19,16 @@ typeLabel: one { Configurations } other { Configurations } } + "catalog-service": |- + {count, plural, + one { Service Catalog } + other { Catalog } + } + "service-instance": |- + {count, plural, + one { Service Instances } + other { Instances } + } epinio: label: Epinio tableHeaders: @@ -177,5 +187,12 @@ epinio: createBy: Created By promptRemove: unbind: Unbind from applications before deleting + serviceInstance: + tableHeaders: + service: Service + catalogService: + tableHeaders: + shortDesc: Headline + desc: Description warnings: noNamespace: There are no namespaces. Please create one before proceeding \ No newline at end of file diff --git a/pkg/epinio/models/applications.js b/pkg/epinio/models/applications.js index 02892881f2..4b6759659a 100644 --- a/pkg/epinio/models/applications.js +++ b/pkg/epinio/models/applications.js @@ -2,7 +2,7 @@ import { APPLICATION_MANIFEST_SOURCE_TYPE, EPINIO_PRODUCT_NAME, EPINIO_TYPES } f import { createEpinioRoute } from '../utils/custom-routing'; import { formatSi } from '@shell/utils/units'; import { classify } from '@shell/plugins/dashboard-store/classify'; -import EpinioResource from './epinio-resource'; +import EpinioNamespacedResource from './epinio-namespaced-resource'; import { downloadFile } from '@shell/utils/download'; // See https://github.com/epinio/epinio/blob/00684bc36780a37ab90091498e5c700337015a96/pkg/api/core/v1/models/app.go#L11 @@ -22,7 +22,7 @@ const STATES_MAPPED = { unknown: 'unknown', }; -export default class EpinioApplication extends EpinioResource { +export default class EpinioApplication extends EpinioNamespacedResource { buildCache = {}; get details() { @@ -317,28 +317,6 @@ export default class EpinioApplication extends EpinioResource { }; } - // ------------------------------------------------------------------ - // Methods here are required for generic components to handle `namespaced` concept - - set metadata(metadata) { - this.meta = { - namespace: metadata.namespace, - name: metadata.name, - }; - } - - get metadata() { - return this.meta || {}; - } - - get namespaceLocation() { - return createEpinioRoute(`c-cluster-resource-id`, { - cluster: this.$rootGetters['clusterId'], - resource: EPINIO_TYPES.NAMESPACE, - id: this.meta.namespace, - }); - } - // ------------------------------------------------------------------ trace(text, ...args) { diff --git a/pkg/epinio/models/catalog-service.js b/pkg/epinio/models/catalog-service.js new file mode 100644 index 0000000000..6cd0e0b2df --- /dev/null +++ b/pkg/epinio/models/catalog-service.js @@ -0,0 +1,24 @@ +import EpinioNamespacedResource from './epinio-namespaced-resource'; + +export default class EpinioCatalogService extends EpinioNamespacedResource { + get links() { + return { + update: this.getUrl(), + self: this.getUrl(), + remove: this.getUrl(), + create: this.getUrl(null), // ensure name is null + }; + } + + getUrl(name = this.meta?.name) { + // Add baseUrl in a generic way + return this.$getters['urlFor'](this.type, this.id, { url: `/api/v1/services/${ name || '' }` }); + } + + get metadata() { + return this.meta || { + name: this.name, + namespace: this.namespace + }; + } +} diff --git a/pkg/epinio/models/configurations.js b/pkg/epinio/models/configurations.js index 56c3933b79..5b9b447b5b 100644 --- a/pkg/epinio/models/configurations.js +++ b/pkg/epinio/models/configurations.js @@ -1,11 +1,10 @@ import { EPINIO_TYPES } from '../types'; -import { createEpinioRoute } from '../utils/custom-routing'; -import EpinioResource from './epinio-resource'; +import EpinioNamespacedResource from './epinio-namespaced-resource'; // POST - {"name":"my-service","data":{"foo":"bar"}} // GET - { "boundapps": null, "name": "my-service" } -export default class EpinioConfiguration extends EpinioResource { +export default class EpinioConfiguration extends EpinioNamespacedResource { get links() { return { update: this.getUrl(), @@ -37,28 +36,6 @@ export default class EpinioConfiguration extends EpinioResource { return Object.keys(this.configuration?.details || {}).length; } - // ------------------------------------------------------------------ - // Methods here are required for generic components to handle `namespaced` concept - - set metadata(metadata) { - this.meta = { - namespace: metadata.namespace, - name: metadata.name, - }; - } - - get metadata() { - return this.meta; - } - - get namespaceLocation() { - return createEpinioRoute(`c-cluster-resource-id`, { - cluster: this.$rootGetters['clusterId'], - resource: EPINIO_TYPES.NAMESPACE, - id: this.meta.namespace, - }); - } - // ------------------------------------------------------------------ trace(text, ...args) { diff --git a/pkg/epinio/models/epinio-namespaced-resource.js b/pkg/epinio/models/epinio-namespaced-resource.js new file mode 100644 index 0000000000..7f45122a76 --- /dev/null +++ b/pkg/epinio/models/epinio-namespaced-resource.js @@ -0,0 +1,23 @@ +import { createEpinioRoute } from '~/pkg/epinio/utils/custom-routing'; +import EpinioResource from './epinio-resource'; + +export default class EpinioNamespacedResource extends EpinioResource { + set metadata(metadata) { + this.meta = { + namespace: metadata.namespace, + name: metadata.name, + }; + } + + get metadata() { + return this.meta; + } + + get namespaceLocation() { + return createEpinioRoute(`c-cluster-resource-id`, { + cluster: this.$rootGetters['clusterId'], + resource: this.schema.id, + id: this.meta.namespace, + }); + } +} diff --git a/pkg/epinio/models/service-instance.js b/pkg/epinio/models/service-instance.js new file mode 100644 index 0000000000..e53d15a07a --- /dev/null +++ b/pkg/epinio/models/service-instance.js @@ -0,0 +1,33 @@ +import EpinioNamespacedResource from './epinio-namespaced-resource'; + +export default class EpinioServiceInstance extends EpinioNamespacedResource { + get links() { + return { + update: this.getUrl(), + self: this.getUrl(), + remove: this.getUrl(), + create: this.getUrl(this.meta?.namespace, null), // ensure name is null + }; + } + + getUrl(namespace = 'from-ui', name = this.meta?.name) { + // getUrl(namespace = this.meta?.namespace, name = this.meta?.name) { + // Add baseUrl in a generic way + return this.$getters['urlFor'](this.type, this.id, { url: `/api/v1/namespaces/${ namespace }/services/${ name || '' }` }); + } + + // ------------------------------------------------------------------ + + set metadata(metadata) { + this.name = metadata.name; + this.namespace = metadata.namespace; + } + + get metadata() { + return { // TODO: See https://github.com/epinio/ui/issues/97#issuecomment-1124880156 + name: this.name, + namespace: this.namespace, + state: this.status + }; + } +} diff --git a/pkg/epinio/store/epinio-store/actions.ts b/pkg/epinio/store/epinio-store/actions.ts index fba054e4a1..a7c2d55d89 100644 --- a/pkg/epinio/store/epinio-store/actions.ts +++ b/pkg/epinio/store/epinio-store/actions.ts @@ -104,7 +104,8 @@ export default { if ( opt.responseType ) { return res; } else { - const out = res.data || {}; + const preOut = res.data || {}; + const out = preOut.services || preOut.catalog_services || preOut;// TODO: See https://github.com/epinio/ui/issues/97#issuecomment-1124880156 const schema = getters.schemaFor(type); if (Array.isArray(out)) { @@ -184,6 +185,19 @@ export default { type: 'schema', links: { collection: '/api/v1/namespaces' }, collectionMethods: ['get', 'post'], + }, { + product: EPINIO_PRODUCT_NAME, + id: EPINIO_TYPES.CATALOG_SERVICE, + type: 'schema', + links: { collection: '/api/v1/services' }, + collectionMethods: ['get', 'post'], + }, { + product: EPINIO_PRODUCT_NAME, + id: EPINIO_TYPES.SERVICE_INSTANCE, + type: 'schema', + links: { collection: '/api/v1/namespaces/from-ui/services' }, + collectionMethods: ['get', 'post'], + attributes: { namespaced: true } }, { product: EPINIO_PRODUCT_NAME, id: EPINIO_TYPES.APP_INSTANCE, diff --git a/pkg/epinio/types.ts b/pkg/epinio/types.ts index 47ee15cf95..78de92ee21 100644 --- a/pkg/epinio/types.ts +++ b/pkg/epinio/types.ts @@ -7,13 +7,15 @@ export const EPINIO_STANDALONE_CLUSTER_NAME = 'default'; export const EPINIO_TYPES = { // From API - APP: 'applications', - NAMESPACE: 'namespaces', - CONFIGURATION: 'configurations', + APP: 'applications', + NAMESPACE: 'namespaces', + CONFIGURATION: 'configurations', + CATALOG_SERVICE: 'catalog-service', + SERVICE_INSTANCE: 'service-instance', // Internal - INSTANCE: 'instance', - APP_ACTION: 'application-action', - APP_INSTANCE: 'application-instance', + INSTANCE: 'instance', + APP_ACTION: 'application-action', + APP_INSTANCE: 'application-instance', }; // // https://github.com/epinio/epinio/blob/7eb93b6dc735f8a6db26b8a242ae62a34877014c/pkg/api/core/v1/models/models.go#L96 diff --git a/shell/components/form/NameNsDescription.vue b/shell/components/form/NameNsDescription.vue index a4508806c6..aadb11592d 100644 --- a/shell/components/form/NameNsDescription.vue +++ b/shell/components/form/NameNsDescription.vue @@ -96,6 +96,10 @@ export default { type: Boolean, default: false }, + namespacesOverride: { + type: Array, + default: null, + }, descriptionLabel: { type: String, default: 'nameNsDescription.description.label', @@ -132,7 +136,7 @@ export default { horizontal: { type: Boolean, default: true, - }, + } }, data() {