mirror of https://github.com/rancher/dashboard.git
Migrate secrets to class
This commit is contained in:
parent
81b1b913a4
commit
0b22aecc7e
|
|
@ -220,6 +220,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
sortGenerationFn() {
|
sortGenerationFn() {
|
||||||
|
if ( !this.schema ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const resource = this.schema.id;
|
const resource = this.schema.id;
|
||||||
const inStore = this.$store.getters['currentStore'](resource);
|
const inStore = this.$store.getters['currentStore'](resource);
|
||||||
const generation = this.$store.getters[`${ inStore }/currentGeneration`](resource);
|
const generation = this.$store.getters[`${ inStore }/currentGeneration`](resource);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
import LabeledSelect from '@/components/form/LabeledSelect';
|
||||||
import { SECRET } from '@/config/types';
|
import { SECRET } from '@/config/types';
|
||||||
import { _EDIT, _VIEW } from '@/config/query-params';
|
import { _EDIT, _VIEW } from '@/config/query-params';
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
import sortBy from 'lodash/sortBy';
|
import sortBy from 'lodash/sortBy';
|
||||||
|
|
||||||
const NONE = '__[[NONE]]__';
|
const NONE = '__[[NONE]]__';
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import Loading from '@/components/Loading';
|
||||||
import LabeledInput from '@/components/form/LabeledInput';
|
import LabeledInput from '@/components/form/LabeledInput';
|
||||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
import LabeledSelect from '@/components/form/LabeledSelect';
|
||||||
import { NORMAN, SECRET } from '@/config/types';
|
import { NORMAN, SECRET } from '@/config/types';
|
||||||
import { TYPES as SECRET_TYPES } from '@/models/secret';
|
import { TYPES as SECRET_TYPES } from '@/models/secret.class';
|
||||||
import { base64Encode } from '@/utils/crypto';
|
import { base64Encode } from '@/utils/crypto';
|
||||||
import { addObjects, insertAt } from '@/utils/array';
|
import { addObjects, insertAt } from '@/utils/array';
|
||||||
import { sortBy } from '@/utils/sort';
|
import { sortBy } from '@/utils/sort';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
import { base64Decode } from '@/utils/crypto';
|
import { base64Decode } from '@/utils/crypto';
|
||||||
import CreateEditView from '@/mixins/create-edit-view';
|
import CreateEditView from '@/mixins/create-edit-view';
|
||||||
import ResourceTabs from '@/components/form/ResourceTabs';
|
import ResourceTabs from '@/components/form/ResourceTabs';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
import { MANAGEMENT, NORMAN, SCHEMA } from '@/config/types';
|
import { MANAGEMENT, NORMAN, SCHEMA } from '@/config/types';
|
||||||
import CreateEditView from '@/mixins/create-edit-view';
|
import CreateEditView from '@/mixins/create-edit-view';
|
||||||
import NameNsDescription from '@/components/form/NameNsDescription';
|
import NameNsDescription from '@/components/form/NameNsDescription';
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import CruResource from '@/components/CruResource';
|
||||||
import Labels from '@/components/form/Labels';
|
import Labels from '@/components/form/Labels';
|
||||||
import Tabbed from '@/components/Tabbed';
|
import Tabbed from '@/components/Tabbed';
|
||||||
import { get, set } from '@/utils/object';
|
import { get, set } from '@/utils/object';
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
import DefaultBackend from './DefaultBackend';
|
import DefaultBackend from './DefaultBackend';
|
||||||
import Certificates from './Certificates';
|
import Certificates from './Certificates';
|
||||||
import Rules from './Rules';
|
import Rules from './Rules';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import Checkbox from '@/components/form/Checkbox';
|
||||||
import SelectOrCreateAuthSecret from '@/components/form/SelectOrCreateAuthSecret';
|
import SelectOrCreateAuthSecret from '@/components/form/SelectOrCreateAuthSecret';
|
||||||
import CreateEditView from '@/mixins/create-edit-view';
|
import CreateEditView from '@/mixins/create-edit-view';
|
||||||
import SecretSelector from '@/components/form/SecretSelector';
|
import SecretSelector from '@/components/form/SecretSelector';
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { TYPES } from '@/models/secret';
|
import { TYPES } from '@/models/secret.class';
|
||||||
import { MANAGEMENT, NAMESPACE } from '@/config/types';
|
import { MANAGEMENT, NAMESPACE } from '@/config/types';
|
||||||
import CreateEditView from '@/mixins/create-edit-view';
|
import CreateEditView from '@/mixins/create-edit-view';
|
||||||
import NameNsDescription from '@/components/form/NameNsDescription';
|
import NameNsDescription from '@/components/form/NameNsDescription';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { removeObjects } from '@/utils/array';
|
||||||
import { SERVICE_ACCOUNT } from '@/config/types';
|
import { SERVICE_ACCOUNT } from '@/config/types';
|
||||||
import { set } from '@/utils/object';
|
import { set } from '@/utils/object';
|
||||||
import { NAME as MANAGER } from '@/config/product/manager';
|
import { NAME as MANAGER } from '@/config/product/manager';
|
||||||
|
import SteveModel from '@/plugins/steve/steve-class';
|
||||||
|
|
||||||
export const TYPES = {
|
export const TYPES = {
|
||||||
OPAQUE: 'Opaque',
|
OPAQUE: 'Opaque',
|
||||||
|
|
@ -22,26 +23,24 @@ export const TYPES = {
|
||||||
RKE_AUTH_CONFIG: 'rke.cattle.io/auth-config'
|
RKE_AUTH_CONFIG: 'rke.cattle.io/auth-config'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default class Secret extends SteveModel {
|
||||||
hasSensitiveData: () => true,
|
get hasSensitiveData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
isCertificate() {
|
get isCertificate() {
|
||||||
return this._type === TYPES.TLS;
|
return this._type === TYPES.TLS;
|
||||||
},
|
}
|
||||||
|
|
||||||
isRegistry() {
|
get isRegistry() {
|
||||||
return this._type === TYPES.DOCKER_JSON;
|
return this._type === TYPES.DOCKER_JSON;
|
||||||
},
|
}
|
||||||
|
|
||||||
isCloudCredential() {
|
get isCloudCredential() {
|
||||||
return this._type === TYPES.CLOUD_CREDENTIAL || (this.metadata.namespace === 'cattle-global-data' && this.metadata.generateName === 'cc-');
|
return this._type === TYPES.CLOUD_CREDENTIAL || (this.metadata.namespace === 'cattle-global-data' && this.metadata.generateName === 'cc-');
|
||||||
},
|
}
|
||||||
|
|
||||||
dockerJSON() {
|
get issuer() {
|
||||||
return TYPES.DOCKER_JSON;
|
|
||||||
},
|
|
||||||
|
|
||||||
issuer() {
|
|
||||||
const { metadata:{ annotations = {} } } = this;
|
const { metadata:{ annotations = {} } } = this;
|
||||||
|
|
||||||
if (annotations[CERTMANAGER.ISSUER]) {
|
if (annotations[CERTMANAGER.ISSUER]) {
|
||||||
|
|
@ -51,35 +50,35 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
notAfter() {
|
get notAfter() {
|
||||||
if (this.isCertificate) {
|
if (this.isCertificate) {
|
||||||
return this.certInfo?.notAfter;
|
return this.certInfo?.notAfter;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
cn() {
|
get cn() {
|
||||||
if (this.isCertificate) {
|
if (this.isCertificate) {
|
||||||
return this.certInfo?.cn;
|
return this.certInfo?.cn;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
}
|
||||||
|
|
||||||
// show plus n more for cert names
|
// show plus n more for cert names
|
||||||
plusMoreNames() {
|
get plusMoreNames() {
|
||||||
if (this.isCertificate) {
|
if (this.isCertificate) {
|
||||||
return this.unrepeatedSans.length;
|
return this.unrepeatedSans.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
}
|
||||||
|
|
||||||
// use text-warning' or 'text-error' if cert is expiring within 8 days or is expired
|
// use text-warning' or 'text-error' if cert is expiring within 8 days or is expired
|
||||||
dateClass() {
|
get dateClass() {
|
||||||
if (this.isCertificate) {
|
if (this.isCertificate) {
|
||||||
const eightDays = 691200000;
|
const eightDays = 691200000;
|
||||||
|
|
||||||
|
|
@ -93,9 +92,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
}
|
||||||
|
|
||||||
details() {
|
get details() {
|
||||||
const out = [
|
const out = [
|
||||||
{
|
{
|
||||||
label: this.t('secret.type'),
|
label: this.t('secret.type'),
|
||||||
|
|
@ -144,9 +143,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
},
|
}
|
||||||
|
|
||||||
canUpdate() {
|
get canUpdate() {
|
||||||
if ( !this.hasLink('update') ) {
|
if ( !this.hasLink('update') ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -156,9 +155,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.$rootGetters['type-map/optionsFor'](this.type).isEditable;
|
return this.$rootGetters['type-map/optionsFor'](this.type).isEditable;
|
||||||
},
|
}
|
||||||
|
|
||||||
keysDisplay() {
|
get keysDisplay() {
|
||||||
const keys = [
|
const keys = [
|
||||||
...Object.keys(this.data || []),
|
...Object.keys(this.data || []),
|
||||||
...Object.keys(this.binaryData || [])
|
...Object.keys(this.binaryData || [])
|
||||||
|
|
@ -173,10 +172,10 @@ export default {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return keys.join(', ');
|
return keys.join(', ');
|
||||||
},
|
}
|
||||||
|
|
||||||
// decode some secret data to show in list view
|
// decode some secret data to show in list view
|
||||||
dataPreview() {
|
get dataPreview() {
|
||||||
if (this._type === TYPES.DOCKER_JSON) {
|
if (this._type === TYPES.DOCKER_JSON) {
|
||||||
const encodedJSON = this.data['.dockerconfigjson'];
|
const encodedJSON = this.data['.dockerconfigjson'];
|
||||||
|
|
||||||
|
|
@ -204,20 +203,20 @@ export default {
|
||||||
return this.sshUser;
|
return this.sshUser;
|
||||||
} else if ( this._type === TYPES.SERVICE_ACCT ) {
|
} else if ( this._type === TYPES.SERVICE_ACCT ) {
|
||||||
return this.metadata?.annotations?.['kubernetes.io/service-account.name'];
|
return this.metadata?.annotations?.['kubernetes.io/service-account.name'];
|
||||||
} else {
|
}
|
||||||
|
|
||||||
return this.keysDisplay;
|
return this.keysDisplay;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
sshUser() {
|
get sshUser() {
|
||||||
if ( this._type !== TYPES.SSH ) {
|
if ( this._type !== TYPES.SSH ) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pub = base64Decode(this.data['ssh-publickey']);
|
const pub = base64Decode(this.data['ssh-publickey']);
|
||||||
|
|
||||||
if ( !pub ) {
|
if ( !pub ) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pub.startsWith('----') ) {
|
if ( pub.startsWith('----') ) {
|
||||||
|
|
@ -235,17 +234,19 @@ export default {
|
||||||
return parts[2];
|
return parts[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
subTypeDisplay() {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get subTypeDisplay() {
|
||||||
const type = this._type || '';
|
const type = this._type || '';
|
||||||
const fallback = type.replace(/^kubernetes.io\//, '');
|
const fallback = type.replace(/^kubernetes.io\//, '');
|
||||||
|
|
||||||
return this.$rootGetters['i18n/withFallback'](`secret.types."${ type }"`, null, fallback);
|
return this.$rootGetters['i18n/withFallback'](`secret.types."${ type }"`, null, fallback);
|
||||||
},
|
}
|
||||||
|
|
||||||
// parse TLS certs and return issuer, notAfter, cn, sans
|
// parse TLS certs and return issuer, notAfter, cn, sans
|
||||||
certInfo() {
|
get certInfo() {
|
||||||
const pem = base64Decode(this.data['tls.crt']);
|
const pem = base64Decode(this.data['tls.crt']);
|
||||||
let issuer, notAfter, cn, sans, x;
|
let issuer, notAfter, cn, sans, x;
|
||||||
|
|
||||||
|
|
@ -276,10 +277,12 @@ export default {
|
||||||
issuer, notAfter, cn, sans
|
issuer, notAfter, cn, sans
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// use for + n more name display
|
// use for + n more name display
|
||||||
unrepeatedSans() {
|
get unrepeatedSans() {
|
||||||
if (this._type === TYPES.TLS ) {
|
if (this._type === TYPES.TLS ) {
|
||||||
if (this.certInfo?.sans?.filter) {
|
if (this.certInfo?.sans?.filter) {
|
||||||
const commonBases = this.certInfo?.sans.filter(name => name.indexOf('*.') === 0 || name.indexOf('www.') === 0).map(name => name.substr(name.indexOf('.')));
|
const commonBases = this.certInfo?.sans.filter(name => name.indexOf('*.') === 0 || name.indexOf('www.') === 0).map(name => name.substr(name.indexOf('.')));
|
||||||
|
|
@ -290,9 +293,11 @@ export default {
|
||||||
|
|
||||||
return this.certInfo?.sans || [];
|
return this.certInfo?.sans || [];
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
timeTilExpiration() {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get timeTilExpiration() {
|
||||||
if (this._type === TYPES.TLS) {
|
if (this._type === TYPES.TLS) {
|
||||||
const expiration = this.certInfo.notAfter;
|
const expiration = this.certInfo.notAfter;
|
||||||
const timeThen = expiration.valueOf();
|
const timeThen = expiration.valueOf();
|
||||||
|
|
@ -300,9 +305,11 @@ export default {
|
||||||
|
|
||||||
return timeThen - timeNow;
|
return timeThen - timeNow;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
decodedData() {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get decodedData() {
|
||||||
const out = {};
|
const out = {};
|
||||||
|
|
||||||
for ( const k in this.data || {} ) {
|
for ( const k in this.data || {} ) {
|
||||||
|
|
@ -310,9 +317,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
},
|
}
|
||||||
|
|
||||||
setData() {
|
get setData() {
|
||||||
return (key, value) => { // or (mapOfNewData)
|
return (key, value) => { // or (mapOfNewData)
|
||||||
const isMap = key && typeof key === 'object';
|
const isMap = key && typeof key === 'object';
|
||||||
|
|
||||||
|
|
@ -333,71 +340,13 @@ export default {
|
||||||
set(this.data, `"${ k }"`, base64Encode(neu[k]));
|
set(this.data, `"${ k }"`, base64Encode(neu[k]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
cloudCredentialProvider() {
|
|
||||||
return this.metadata?.annotations?.[CAPI.CREDENTIAL_DRIVER];
|
|
||||||
},
|
|
||||||
|
|
||||||
cloudCredentialProviderDisplay() {
|
|
||||||
const provider = (this.cloudCredentialProvider || '').toLowerCase();
|
|
||||||
|
|
||||||
return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provider }"`, null, provider);
|
|
||||||
},
|
|
||||||
|
|
||||||
cloudCredentialPublicData() {
|
|
||||||
let { publicKey, publicMode } = this.$rootGetters['plugins/credentialOptions'](this.cloudCredentialProvider);
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
full: fullFields,
|
|
||||||
prefix: prefixFields,
|
|
||||||
suffix: suffixFields,
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( !publicKey ) {
|
|
||||||
for ( const k in this.decodedData || {} ) {
|
|
||||||
if ( publicKey ) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isEmpty(this.decodedData[k]) ) {
|
get doneRoute() {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( const mode in options ) {
|
|
||||||
if ( options[mode].includes( simplify(k) ) ) {
|
|
||||||
publicKey = k;
|
|
||||||
publicMode = mode;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !publicKey ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const val = this.decodedData[publicKey];
|
|
||||||
|
|
||||||
const maxLength = Math.min(8, Math.floor(val.length / 2));
|
|
||||||
|
|
||||||
if ( publicMode === 'prefix' ) {
|
|
||||||
return `${ escapeHtml(val.substr(0, maxLength)) }…`;
|
|
||||||
} else if ( publicMode === 'suffix' ) {
|
|
||||||
return `…${ escapeHtml(val.substr(-1 * maxLength)) }`;
|
|
||||||
} else {
|
|
||||||
return escapeHtml(val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
doneRoute() {
|
|
||||||
if ( this.$rootGetters['currentProduct'].name === MANAGER ) {
|
if ( this.$rootGetters['currentProduct'].name === MANAGER ) {
|
||||||
return 'c-cluster-manager-secret';
|
return 'c-cluster-manager-secret';
|
||||||
} else {
|
} else {
|
||||||
return 'c-cluster-product-resource';
|
return 'c-cluster-product-resource';
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
Loading…
Reference in New Issue