Migrate secrets to class

This commit is contained in:
Vincent Fiduccia 2021-09-14 03:38:34 -07:00
parent 81b1b913a4
commit 0b22aecc7e
No known key found for this signature in database
GPG Key ID: 2B29AD6BB2BB2582
9 changed files with 69 additions and 116 deletions

View File

@ -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);

View File

@ -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]]__';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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: {

View File

@ -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';

View File

@ -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)) }&hellip;`;
} else if ( publicMode === 'suffix' ) {
return `&hellip;${ 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';
} }
}, }
}; }