Merge pull request #356 from vincent99/master

Remove API versions from everything
This commit is contained in:
Vincent Fiduccia 2020-03-11 09:38:28 -07:00 committed by GitHub
commit 4c877c47b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 128 additions and 167 deletions

View File

@ -1,32 +1,23 @@
<script>
import { SCHEMA, API_GROUP } from '@/config/types';
import { SCHEMA } from '@/config/types';
import { AGE, NAME, STATE } from '@/config/table-headers';
import SortableTable from '@/components/SortableTable';
import { DESCRIPTION } from '@/config/labels-annotations';
const CONSTRAINTS_REGEX = new RegExp(/^(.*\.)?constraints.gatekeeper.sh.*$/);
const CONSTRAINT_TEMPLATES_REGEX = new RegExp(/^(.*\.)?templates.gatekeeper.sh.*$/);
function getAllSchemas(store) {
const schemas = store.getters['cluster/all'](SCHEMA);
return schemas.filter((schema) => {
const attrs = schema.attributes || {};
const groupName = attrs.group || 'core';
const api = store.getters['cluster/byId'](API_GROUP, groupName);
return attrs.kind &&
(!api?.preferredVersion?.version || (api.preferredVersion.version === attrs.version));
});
}
function findTemplateType(schemas) {
return schemas.find(schema => CONSTRAINT_TEMPLATES_REGEX.test(schema.id))?.id;
// @TODO this will just be a regular single type now that the server filters to preferred version
// so you can just add templates.gatekeeper.sh.constrainttemplate as a constant in types.js
const template = schemas.find((schema) => {
return schema?.attributes?.group === 'templates.gatekeeper.sh' &&
schema?.attributes?.kind === 'ConstraintTemplate';
});
return template?.id;
}
function findConstraintTypes(schemas) {
return schemas
.filter(schema => CONSTRAINTS_REGEX.test(schema.id))
.filter(schema => schema?.attributes?.group === 'constraints.gatekeeper.sh')
.map(schema => schema.id);
}
@ -64,7 +55,8 @@ export default {
},
async created() {
const schemas = await getAllSchemas(this.$store);
const schemas = this.$store.getters['cluster/all'](SCHEMA);
const templateType = findTemplateType(schemas);
const constraintTypes = findConstraintTypes(schemas);

View File

@ -22,9 +22,9 @@ export default {
}
if ( this.toRemove.length > 1 ) {
return this.$store.getters['nav-tree/pluralLabelFor'](schema);
return this.$store.getters['type-map/pluralLabelFor'](schema);
} else {
return this.$store.getters['nav-tree/singularLabelFor'](schema);
return this.$store.getters['type-map/singularLabelFor'](schema);
}
},

View File

@ -14,8 +14,8 @@ export async function asyncData(ctx) {
const { store, params, route } = ctx;
const { resource, namespace, id } = params;
const hasCustomDetail = store.getters['nav-tree/hasCustomDetail'](resource);
const hasCustomEdit = store.getters['nav-tree/hasCustomEdit'](resource);
const hasCustomDetail = store.getters['type-map/hasCustomDetail'](resource);
const hasCustomEdit = store.getters['type-map/hasCustomEdit'](resource);
// There are 5 "real" modes: view, create, edit, stage, clone
// which later map to 3 logical/page modes: view, create, edit (stage and clone are "create")
@ -164,16 +164,16 @@ export default {
showComponent() {
if ( this.isView && this.hasCustomDetail ) {
return this.$store.getters['nav-tree/importDetail'](this.resource);
return this.$store.getters['type-map/importDetail'](this.resource);
} else if ( !this.isView && this.hasCustomEdit ) {
return this.$store.getters['nav-tree/importEdit'](this.resource);
return this.$store.getters['type-map/importEdit'](this.resource);
}
return null;
},
typeDisplay() {
return this.$store.getters['nav-tree/singularLabelFor'](this.schema);
return this.$store.getters['type-map/singularLabelFor'](this.schema);
},
namespaceSuffixOnCreate() {

View File

@ -64,7 +64,7 @@ export default {
if ( this.headers ) {
headers = this.headers.slice();
} else {
headers = this.$store.getters['nav-tree/headersFor'](this.schema);
headers = this.$store.getters['type-map/headersFor'](this.schema);
}
// If only one namespace is selected, replace the namespace_name

View File

@ -15,7 +15,7 @@ import {
BUILT_IN, CLUSTER_CREATOR_DEFAULT, INGRESS_TARGET
} from '@/config/table-headers';
import { DSL } from '@/store/nav-tree';
import { DSL } from '@/store/type-map';
export default function(store) {
const {
@ -44,8 +44,8 @@ export default function(store) {
PVC,
]);
ignoreType('events.k8s.io.v1beta1.event'); // Events type moved into core
ignoreType('extensions.v1beta1.ingress'); // Moved into networking
ignoreType('events.k8s.io.event'); // Events type moved into core
ignoreType('extensions.ingress'); // Moved into networking
mapType('core.v1.endpoints', 'Endpoint'); // Bad plural
@ -219,7 +219,7 @@ export default function(store) {
name: 'gatekeeper-constraints',
group: 'Cluster::OPA Gatekeeper',
route: { name: 'c-cluster-gatekeeper-constraints' },
ifHaveType: 'templates.gatekeeper.sh.v1beta1.constrainttemplate'
ifHaveType: 'templates.gatekeeper.sh.constrainttemplate'
});
virtualType({
@ -228,6 +228,6 @@ export default function(store) {
name: 'gatekeeper-templates',
group: 'Cluster::OPA Gatekeeper',
route: { name: 'c-cluster-gatekeeper-templates' },
ifHaveType: 'templates.gatekeeper.sh.v1beta1.constrainttemplate'
ifHaveType: 'templates.gatekeeper.sh.constrainttemplate'
});
}

View File

@ -1,19 +1,19 @@
// Steve
export const API_GROUP = 'apiGroups';
export const CONFIG_MAP = 'core.v1.configmap';
export const CONFIG_MAP = 'configmap';
export const COUNT = 'count';
export const EVENT = 'core.v1.event';
export const NAMESPACE = 'core.v1.namespace';
export const NODE = 'core.v1.node';
export const POD = 'core.v1.pod';
export const RESOURCE_QUOTA = 'core.v1.resourcequota';
export const EVENT = 'event';
export const NAMESPACE = 'namespace';
export const NODE = 'node';
export const POD = 'pod';
export const RESOURCE_QUOTA = 'resourcequota';
export const SCHEMA = 'schema';
export const SECRET = 'core.v1.secret';
export const SERVICE_ACCOUNT = 'core.v1.serviceaccount';
export const SERVICE = 'core.v1.service';
export const INGRESS = 'networking.k8s.io.v1beta1.ingress';
export const PV = 'core.v1.persistentvolume';
export const PVC = 'core.v1.persistentvolumeclaim';
export const SECRET = 'secret';
export const SERVICE_ACCOUNT = 'serviceaccount';
export const SERVICE = 'service';
export const INGRESS = 'networking.k8s.io.ingress';
export const PV = 'persistentvolume';
export const PVC = 'persistentvolumeclaim';
export const TLS_CERT = 'kubernetes.io/tls';
// Old Rancher API via Norman, /v3
@ -25,15 +25,15 @@ export const NORMAN = {
// Rancher Management API via Steve, /v1
export const MANAGEMENT = {
PROJECTS: 'management.cattle.io.v3.project',
CATALOGS: 'management.cattle.io.v3.catalog',
CATALOG_TEMPLATE: 'management.cattle.io.v3.catalogtemplate',
CLUSTER: 'management.cattle.io.v3.cluster',
USER: 'management.cattle.io.v3.user'
PROJECTS: 'management.cattle.io.project',
CATALOGS: 'management.cattle.io.catalog',
CATALOG_TEMPLATE: 'management.cattle.io.catalogtemplate',
CLUSTER: 'management.cattle.io.cluster',
USER: 'management.cattle.io.user'
};
// Rancher cluster-scoped things that actually live in management plane
// /v1/management.cattle.io.v3.clusters/<id>/
// /v1/management.cattle.io.clusters/<id>/
export const EXTERNAL = {
PROJECT: 'project',
APP: 'app',
@ -42,33 +42,33 @@ export const EXTERNAL = {
// Other types via Steve, /k8s/clusters/<id>/v1/
export const RBAC = {
ROLE: 'rbac.authorization.k8s.io.v1.role',
CLUSTER_ROLE: 'rbac.authorization.k8s.io.v1.clusterrole',
ROLE_BINDING: 'rbac.authorization.k8s.io.v1.rolebinding',
CLUSTER_ROLE_BINDING: 'rbac.authorization.k8s.io.v1.clusterrolebinding',
ROLE: 'rbac.authorization.k8s.io.role',
CLUSTER_ROLE: 'rbac.authorization.k8s.io.clusterrole',
ROLE_BINDING: 'rbac.authorization.k8s.io.rolebinding',
CLUSTER_ROLE_BINDING: 'rbac.authorization.k8s.io.clusterrolebinding',
};
export const RIO = {
CLUSTER_DOMAIN: 'admin.rio.cattle.io.v1.clusterdomain',
FEATURE: 'admin.rio.cattle.io.v1.feature',
INFO: 'admin.rio.cattle.io.v1.rioinfo',
PUBLIC_DOMAIN: 'admin.rio.cattle.io.v1.publicdomain',
CLUSTER_DOMAIN: 'admin.rio.cattle.io.clusterdomain',
FEATURE: 'admin.rio.cattle.io.feature',
INFO: 'admin.rio.cattle.io.rioinfo',
PUBLIC_DOMAIN: 'admin.rio.cattle.io.publicdomain',
APP: 'rio.cattle.io.v1.app',
EXTERNAL_SERVICE: 'rio.cattle.io.v1.externalservice',
STACK: 'rio.cattle.io.v1.stack',
ROUTER: 'rio.cattle.io.v1.router',
SERVICE: 'rio.cattle.io.v1.service',
APP: 'rio.cattle.io.app',
EXTERNAL_SERVICE: 'rio.cattle.io.externalservice',
STACK: 'rio.cattle.io.stack',
ROUTER: 'rio.cattle.io.router',
SERVICE: 'rio.cattle.io.service',
SYSTEM_NAMESPACE: 'rio-system',
};
export const WORKLOAD = {
DEPLOYMENT: 'apps.v1.deployment',
DAEMON_SET: 'apps.v1.daemonset',
STATEFUL_SET: 'apps.v1.statefulset',
CRON_JOB: 'batch.v1beta1.cronjob',
JOB: 'batch.v1.job',
REPLICA_SET: 'apps.v1.replicaset',
REPLICATION_CONTROLLER: 'core.v1.replicationcontroller'
DEPLOYMENT: 'apps.deployment',
DAEMON_SET: 'apps.daemonset',
STATEFUL_SET: 'apps.statefulset',
CRON_JOB: 'batch.cronjob',
JOB: 'batch.job',
REPLICA_SET: 'apps.replicaset',
REPLICATION_CONTROLLER: 'replicationcontroller'
};

View File

@ -2,7 +2,7 @@
import { get } from '@/utils/object';
import createEditView from '@/mixins/create-edit-view';
import ResourceQuota from '@/edit/core.v1.namespace/ResourceQuota';
import ResourceQuota from '@/edit/namespace/ResourceQuota';
import LabelsAndAnnotationsTabs from '@/components/LabelsAndAnnotations/Tabs';
import { DESCRIPTION } from '@/config/labels-annotations';

View File

@ -46,8 +46,8 @@ export default {
return {
schema,
id: key,
label: this.$store.getters['nav-tree/pluralLabelFor'](schema),
headers: this.$store.getters['nav-tree/headersFor'](schema),
label: this.$store.getters['type-map/pluralLabelFor'](schema),
headers: this.$store.getters['type-map/headersFor'](schema),
rows: map[key],
};
});

View File

@ -1,7 +1,7 @@
<script>
import { get } from '@/utils/object';
import { CERTMANAGER, DESCRIPTION } from '@/config/labels-annotations';
import { DOCKER_JSON } from '@/models/core.v1.secret';
import { DOCKER_JSON } from '@/models/secret';
import DetailTop from '@/components/DetailTop';
import SortableTable from '@/components/SortableTable';
import { KEY, VALUE } from '@/config/table-headers';

View File

@ -1,5 +1,5 @@
<script>
import { TLS } from '@/models/core.v1.secret';
import { TLS } from '@/models/secret';
import LoadDeps from '@/mixins/load-deps';
import Loading from '@/components/Loading';
import CreateEditView from '@/mixins/create-edit-view';

View File

@ -4,7 +4,7 @@ import { get } from '@/utils/object';
import createEditView from '@/mixins/create-edit-view';
import LabeledInput from '@/components/form/LabeledInput';
import ResourceQuota from '@/edit/core.v1.namespace/ResourceQuota';
import ResourceQuota from '@/edit/namespace/ResourceQuota';
import Footer from '@/components/form/Footer';
import LabelsAndAnnotationsEditor from '@/components/LabelsAndAnnotations/Editor';
import { DESCRIPTION } from '@/config/labels-annotations';

View File

@ -2,7 +2,7 @@
import { random32 } from '../../utils/string';
import RadioGroup from '@/components/form/RadioGroup';
import RulePath from '@/edit/networking.k8s.io.v1beta1.ingress/RulePath';
import RulePath from '@/edit/networking.k8s.io.ingress/RulePath';
import LabeledInput from '@/components/form/LabeledInput';
export default {

View File

@ -1,15 +1,16 @@
<script>
import { clone } from '../../utils/object';
import { allHash } from '../../utils/promise';
import Certificate from './Certificate';
import Rule from './Rule';
import { clone } from '@/utils/object';
import { allHash } from '@/utils/promise';
import { WORKLOAD, SECRET, TLS_CERT } from '@/config/types';
import NameNsDescription from '@/components/form/NameNsDescription';
import Rule from '@/edit/networking.k8s.io.v1beta1.ingress/Rule';
import CreateEditView from '@/mixins/create-edit-view';
import LoadDeps from '@/mixins/load-deps';
import Tabbed from '@/components/Tabbed';
import Tab from '@/components/Tabbed/Tab';
import Labels from '@/components/form/Labels';
import Certificate from '@/edit/networking.k8s.io.v1beta1.ingress/Certificate';
import Footer from '@/components/form/Footer';
export default {

View File

@ -6,7 +6,7 @@ import findIndex from 'lodash/findIndex';
import createEditView from '../../mixins/create-edit-view';
import { typeOf } from '@/utils/sort';
import KeyValue from '@/components/form/KeyValue';
import StringMatch from '@/edit/rio.cattle.io.v1.router/StringMatch';
import StringMatch from '@/edit/rio.cattle.io.router/StringMatch';
import LabeledInput from '@/components/form/LabeledInput';
export default {
components: {

View File

@ -4,11 +4,11 @@ import { isEmpty } from 'lodash';
import createEditView from '../../mixins/create-edit-view';
import { cleanUp } from '@/utils/object';
import { randomStr } from '@/utils/string';
import Match from '@/edit/rio.cattle.io.v1.router/Match';
import Destination from '@/edit/rio.cattle.io.v1.router/Destination';
import Redirect from '@/edit/rio.cattle.io.v1.router/Redirect';
import Headers from '@/edit/rio.cattle.io.v1.router/Headers';
import Fault from '@/edit/rio.cattle.io.v1.router/Fault';
import Match from '@/edit/rio.cattle.io.router/Match';
import Destination from '@/edit/rio.cattle.io.router/Destination';
import Redirect from '@/edit/rio.cattle.io.router/Redirect';
import Headers from '@/edit/rio.cattle.io.router/Headers';
import Fault from '@/edit/rio.cattle.io.router/Fault';
import Checkbox from '@/components/form/Checkbox';
export default {

View File

@ -5,7 +5,7 @@ import { get, cleanUp } from '@/utils/object';
import { randomStr } from '@/utils/string';
import CreateEditView from '@/mixins/create-edit-view';
import NameNsDescription from '@/components/form/NameNsDescription';
import Rule from '@/edit/rio.cattle.io.v1.router/Rule';
import Rule from '@/edit/rio.cattle.io.router/Rule';
import Footer from '@/components/form/Footer';
export default {

View File

@ -4,8 +4,8 @@ import Security from './Security';
import Upgrading from './Upgrading';
import Volumes from './Volumes';
import Labels from '@/components/form/Labels';
import Networking from '@/edit/rio.cattle.io.v1.service//Networking';
import Command from '@/edit/rio.cattle.io.v1.service/Command';
import Networking from '@/edit/rio.cattle.io.service//Networking';
import Command from '@/edit/rio.cattle.io.service/Command';
import HealthCheck from '@/components/form/HealthCheck';
import { get } from '@/utils/object';
import { CONFIG_MAP, SECRET, RIO } from '@/config/types';

View File

@ -1,5 +1,5 @@
<script>
import { DOCKER_JSON, OPAQUE, TLS } from '@/models/core.v1.secret';
import { DOCKER_JSON, OPAQUE, TLS } from '@/models/secret';
import { base64Encode, base64Decode } from '@/utils/crypto';
import { get } from '@/utils/object';
import { NAMESPACE } from '@/config/types';

View File

@ -126,7 +126,7 @@ export default {
const namespaces = this.$store.getters['namespaces'] || [];
const currentType = this.$route.params.resource || '';
const out = this.$store.getters['nav-tree/getTree'](mode, clusterId, namespaces, currentType);
const out = this.$store.getters['type-map/getTree'](mode, clusterId, namespaces, currentType);
this.groups = out;
},

View File

@ -57,9 +57,10 @@ export default async function({
const clusterId = get(route, 'params.cluster');
try {
// Not in parallel, cluster needs isRancher from management
await store.dispatch('loadManagement');
await store.dispatch('loadCluster', clusterId);
await Promise.all([
await store.dispatch('loadManagement'),
await store.dispatch('loadCluster', clusterId),
]);
} catch (e) {
if ( e instanceof ClusterNotFoundError ) {
redirect(302, '/clusters');

View File

@ -13,15 +13,15 @@ export default {
},
hasComponent() {
return this.$store.getters['nav-tree/hasCustomEdit'](this.resource);
return this.$store.getters['type-map/hasCustomEdit'](this.resource);
},
showComponent() {
return this.$store.getters['nav-tree/importEdit'](this.resource);
return this.$store.getters['type-map/importEdit'](this.resource);
},
typeDisplay() {
return this.$store.getters['nav-tree/singularLabelFor'](this.schema);
return this.$store.getters['type-map/singularLabelFor'](this.schema);
},
parentLink() {

View File

@ -9,19 +9,19 @@ export default {
},
headers() {
return this.$store.getters['nav-tree/headersFor'](this.schema);
return this.$store.getters['type-map/headersFor'](this.schema);
},
hasComponent() {
return this.$store.getters['nav-tree/hasCustomList'](this.resource);
return this.$store.getters['type-map/hasCustomList'](this.resource);
},
showComponent() {
return this.$store.getters['nav-tree/importList'](this.resource);
return this.$store.getters['type-map/importList'](this.resource);
},
typeDisplay() {
return this.$store.getters['nav-tree/pluralLabelFor'](this.schema);
return this.$store.getters['type-map/pluralLabelFor'](this.schema);
},
},
asyncData(ctx) {

View File

@ -15,6 +15,30 @@ export function normalizeType(type) {
return type;
}
/*
export function parseType(type) {
const match = type.match(/^(.*)\.(v\d[^.]*)\.([^.]+)$/);
if ( match ) {
return {
group: match[1],
version: match[2],
type: match[3]
};
}
}
export function stripVersion(type) {
const match = parseType(type);
if ( !match ) {
return type;
}
return `${ match.group }.${ match.type }`;
}
*/
export function cleanForNew(obj) {
delete obj.id;
delete obj.actions;

View File

@ -111,7 +111,7 @@ export default {
},
typeDisplay() {
return this.$store.getters['nav-tree/singularLabelFor'](this.schema);
return this.$store.getters['type-map/singularLabelFor'](this.schema);
},
namespacedName() {
@ -345,7 +345,7 @@ export default {
const all = [];
const links = this.links || {};
const hasView = !!links.rioview || !!links.view;
const customEdit = this.$rootGetters['nav-tree/hasCustomEdit'](this.type);
const customEdit = this.$rootGetters['type-map/hasCustomEdit'](this.type);
if ( customEdit ) {
all.push({
@ -713,7 +713,7 @@ export default {
const [group, version] = this.apiVersion.split('/');
const pluralName = this.$rootGetters['nav-tree/pluralLabelFor'](schema).split('.').pop().toLowerCase();
const pluralName = this.$rootGetters['type-map/pluralLabelFor'](schema).split('.').pop().toLowerCase();
url = `${ url.slice(0, url.indexOf('/v1')) }/apis/${ group }/${ version }/namespaces/${ namespace }/${ pluralName }`;

View File

@ -1,4 +1,3 @@
import { normalizeType } from './normalize';
import { get } from '@/utils/object';
import Socket, {
EVENT_CONNECTED,
@ -71,7 +70,7 @@ export const actions = {
},
watchType({ dispatch, getters }, { type, revision }) {
type = normalizeType(type);
type = getters.normalizeType(type);
if ( NO_WATCHING.includes(type) ) {
return;

View File

@ -1,6 +1,6 @@
import Steve from '@/plugins/steve';
import {
API_GROUP, COUNT, NAMESPACE, NORMAN, EXTERNAL, MANAGEMENT
COUNT, NAMESPACE, NORMAN, EXTERNAL, MANAGEMENT
} from '@/config/types';
import { CLUSTER as CLUSTER_PREF, NAMESPACES } from '@/store/prefs';
import SYSTEM_NAMESPACES from '@/config/system-namespaces';
@ -204,7 +204,6 @@ export const actions = {
}
const res = await allHash({
apiGroups: dispatch('cluster/findAll', { type: API_GROUP, opt: { url: 'apiGroups', watch: false } }),
counts: dispatch('cluster/findAll', { type: COUNT, opt: { url: 'counts' } }),
namespaces: dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'core.v1.namespaces' } })
});

View File

@ -75,10 +75,10 @@ import { sortBy } from '@/utils/sort';
import { get, clone } from '@/utils/object';
import { isArray, findBy, addObject, removeObject } from '@/utils/array';
import { escapeRegex, ucFirst } from '@/utils/string';
import { SCHEMA, COUNT, API_GROUP } from '@/config/types';
import { SCHEMA, COUNT } from '@/config/types';
import { STATE, NAMESPACE_NAME, NAME, AGE } from '@/config/table-headers';
export function DSL(store, module = 'nav-tree') {
export function DSL(store, module = 'type-map') {
return {
basicType(types) {
store.commit(`${ module }/basicType`, types);
@ -155,7 +155,6 @@ export const state = function() {
pluralLabels: {},
headers: {},
cache: {
isPreferred: {},
typeLabel: {},
typeMove: {},
groupLabel: {},
@ -360,11 +359,6 @@ export const getters = {
continue;
}
if ( !getters.isPreferred(schema) ) {
// Skip non-preferred versions of a type
continue;
}
out[schema.id] = {
schema,
group: groupName,
@ -566,55 +560,6 @@ export const getters = {
};
},
preferredVersions(_state, _getters, _rootState, rootGetters) {
return () => {
const versionMap = rootGetters['cluster/all'](API_GROUP).reduce((map, group) => {
if (group?.preferredVersion) {
map[group.name] = group?.preferredVersion?.version;
}
return map;
}, {});
return versionMap;
};
},
isPreferred(state, getters, rootState, rootGetters) {
return (schema) => {
let out = state.cache.isPreferred[schema.id];
if ( out === undefined ) {
out = true;
const attrs = schema.attributes || {};
const groupName = attrs.group || 'core';
const preferredVersion = getters.preferredVersions()[groupName];
if ( preferredVersion && attrs.version !== preferredVersion ) {
// This is not the preferred version, but see if there really is one for this type
// that is, because some resources only have a non-preferred version.
const allSchemas = rootGetters['cluster/all'](SCHEMA);
const matching = findBy(allSchemas, {
'attributes.group': groupName,
'attributes.version': preferredVersion,
'attributes.kind': attrs.kind,
});
if ( matching ) {
// There is a different schema for this type that is the preferred version
out = false;
}
}
state.cache.isPreferred[schema.id] = out;
}
return out;
};
},
isIgnored(state) {
return (schema) => {
if ( typeof state.cache.ignore[schema.id] === 'undefined' ) {