fix linkFor error on create retry

add/remove resources reactively
This commit is contained in:
Nancy Butler 2020-05-05 16:41:50 -07:00
parent 37a29d2d2a
commit 9e95b3b9ad
14 changed files with 119 additions and 70 deletions

View File

@ -65,11 +65,10 @@ export default {
} else {
headers = this.$store.getters['type-map/headersFor'](this.schema);
}
// If only one namespace is selected, replace the namespace_name
// column with the just name one.
if ( !showNamespace ) {
let idx = headers.indexOf(NAMESPACE_NAME);
let idx = headers.findIndex(header => header.value === NAMESPACE_NAME.value);
if ( idx >= 0 ) {
headers.splice(idx, 1, NAME);

View File

@ -9,7 +9,7 @@ export default {
props: {
value: {
type: String,
type: [String, Object],
default: null,
},
options: {
@ -40,6 +40,16 @@ export default {
type: Boolean,
default: false
},
reduce: {
type: Function,
default: (e) => {
if ( e && typeof e === 'object' && e.value !== undefined ) {
return e.value;
}
return e;
}
}
},
data() {
@ -67,16 +77,6 @@ export default {
},
methods: {
get,
reduce(e) {
if ( e && typeof e === 'object' && e.value !== undefined ) {
return e.value;
}
return e;
},
onFocus() {
this.selectedVisibility = 'hidden';
this.onFocusLabeled();
@ -145,6 +145,14 @@ export default {
*/
return () => popper.destroy();
},
open() {
const input = this.$refs.input;
if (input) {
input.open = true;
}
},
get
},
};
</script>
@ -169,9 +177,9 @@ export default {
<v-select
v-if="!isView"
ref="input"
:value="value ? value : ' '"
class="inline"
:disabled="disabled"
:value="value"
:disabled="isView || disabled"
:options="options"
:get-option-label="opt=>getOptionLabel(opt)"
:get-option-key="opt=>optionKey ? get(opt, optionKey) : getOptionLabel(opt)"
@ -180,9 +188,9 @@ export default {
v-bind="$attrs"
:append-to-body="!!placement"
:calculate-position="placement ? withPopper : undefined"
@input="x => $emit('input', reduce(x))"
@search:focus="onFocus"
@search:blur="onBlur"
@input="e=>$emit('input', e)"
>
<template v-slot:selected-option-container>
<span style="display: none"></span>

View File

@ -62,7 +62,6 @@ export default {
if ( this.namespaced && !metadata.namespace ) {
metadata.namespace = this.$store.getters['defaultNamespace'];
}
const description = metadata.annotations?.[DESCRIPTION];
return {
@ -159,7 +158,7 @@ export default {
select-label="Namespace"
:text-value="name"
:text-required="true"
select-value="default"
:select-value="namespace"
:mode="mode"
:disabled="nameDisabled"
@input="changeNameAndNamespace($event)"

View File

@ -101,7 +101,11 @@ export default function(store) {
width: 100,
formatter: 'SecretType'
},
KEYS,
{
name: 'data',
label: 'Data',
value: 'dataPreview'
},
AGE
]);
headers(INGRESS, [STATE, NAME, INGRESS_TARGET, AGE]);

View File

@ -62,6 +62,7 @@ export default {
}
if (this.value._type === TLS) {
// remove private key on edit page
key = this.mode === 'edit' ? '' : base64Decode((this.value.data || {})['tls.key']);
crt = base64Decode((this.value.data || {})['tls.crt']);
}
@ -81,9 +82,10 @@ export default {
registryFQDN,
toUpload: null,
key,
crt
crt,
};
},
computed: {
dockerconfigjson() {
let dockerServer = this.registryProvider === 'DockerHub' ? 'index.dockerhub.io/v1/' : 'quay.io';
@ -131,6 +133,8 @@ export default {
}
},
watch: { 'value.data': () => {} },
methods: {
saveSecret(buttonCb) {
if (this.isRegistry) {
@ -216,7 +220,7 @@ export default {
<LabeledInput v-model="username" label="Username" :mode="mode" />
</div>
<div class="col span-6">
<LabeledInput v-model="password" label="Password" :mode="mode" />
<LabeledInput v-model="password" label="Password" :mode="mode" :type="mode==='edit' ? 'password':'text'" />
</div>
</div>
</template>

View File

@ -1,5 +1,4 @@
<script>
import { get } from '../../utils/object';
import LabeledInput from '@/components/form/LabeledInput';
import ShellInput from '@/components/form/ShellInput';
import UnitInput from '@/components/form/UnitInput';
@ -92,15 +91,6 @@ export default {
addFromReference() {
this.referencedValues.push({ name: '', valueFrom: {} });
this.$nextTick(() => {
const newRow = this.$refs.referenced[this.referencedValues.length - 1];
const input = get(newRow, '$refs.typeSelect.$refs.input');
if (input) {
input.open = true;
}
});
},
},

View File

@ -42,12 +42,12 @@ export default {
{ value: 'fieldRef', label: 'Field' },
{ value: 'secretRef', label: 'Secret' }];
let type = Object.keys((this.row.valueFrom || {}))[0];
let type = this.row.secretRef ? 'secretRef' : Object.keys((this.row.valueFrom))[0];
let refName;
let name;
let fieldPath;
let referenced = {};
let referenced;
let key;
switch (type) {
@ -63,33 +63,19 @@ export default {
type = Object.keys(this.row.valueFrom)[0];
key = this.row.valueFrom[type].key || '';
refName = this.row.valueFrom[type].name;
if (!refName.includes('/')) {
refName = `${ this.namespace }/${ refName }`;
}
this.getReferenced(refName, CONFIG_MAP);
break;
case 'secretRef':
name = this.row.prefix;
type = 'secretRef';
refName = this.row[type].name;
if (!refName.includes('/')) {
refName = `${ this.namespace }/${ refName }`;
}
this.getReferenced(refName, SECRET);
break;
case 'secretKeyRef':
name = this.row.name;
type = Object.keys(this.row.valueFrom)[0];
key = this.row.valueFrom[type].key || '';
refName = this.row.valueFrom[type].name;
if (!refName.includes('/')) {
refName = `${ this.namespace }/${ refName }`;
}
this.getReferenced(refName, SECRET);
break;
case 'fieldRef':
referenced = {};
fieldPath = get(this.row.valueFrom, `${ type }.fieldPath`) || '';
name = this.row.name;
break;
@ -98,7 +84,7 @@ export default {
}
return {
typeOpts, type, refName, referenced, secrets: this.allSecrets, keys: [], key, fieldPath, name
typeOpts, type, refName, referenced: refName, secrets: this.allSecrets, keys: [], key, fieldPath, name
};
},
computed: {
@ -122,31 +108,34 @@ export default {
return [];
}
},
referencedID: {
get() {
return this.referenced.id;
},
set(neu) {
this.referenced = { id: neu };
}
}
},
watch: {
type() {
this.referenced = {};
this.referenced = null;
},
referenced(neu, old) {
if (Object.keys(old).length) {
if (old) {
this.key = '';
}
if (neu) {
if (neu.type === SECRET || neu.type === CONFIG_MAP) {
this.keys = Object.keys(neu.data);
}
this.refName = neu?.metadata?.name;
}
},
},
mounted() {
const typeSelect = this.$refs.typeSelect;
if (typeSelect && this.mode === 'create') {
typeSelect.open();
}
},
methods: {
async getReferenced(name, type) {
const resource = await this.$store.dispatch('cluster/find', { id: name, type });
@ -155,7 +144,7 @@ export default {
},
updateRow() {
const out = { name: this.name };
const out = { name: this.name || this.refName };
const old = { ...this.row };
switch (this.type) {
@ -163,7 +152,7 @@ export default {
case 'secretKeyRef':
out.valueFrom = {
[this.type]: {
key: this.key, name: this.referencedID, optional: false
key: this.key, name: this.refName, optional: false
}
};
break;
@ -180,10 +169,11 @@ export default {
default:
delete out.name;
out.prefix = this.name;
out[this.type] = { name: this.referencedID, optional: false };
out[this.type] = { name: this.refName, optional: false };
}
this.$emit('input', { value: out, old });
}
},
}
};
</script>
@ -210,6 +200,7 @@ export default {
:multiple="false"
label="Source"
option-label="metadata.name"
option-key
:mode="mode"
@input="updateRow"
/>

View File

@ -185,7 +185,7 @@ export default {
url = url || this.schema.linkFor('collection');
if ( this.value?.metadata?.namespace ) {
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: this.value.metadata.namespace }, { root: true });
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, val: this.value.metadata.namespace }, { root: true });
}
const res = await this.value.save({ url });

View File

@ -1,4 +1,5 @@
import { KUBERNETES } from '@/config/labels-annotations';
import { base64Decode } from '@/utils/crypto';
export const OPAQUE = 'Opaque';
export const SERVICE_ACCT = 'kubernetes.io/service-account-token';
@ -23,6 +24,24 @@ const DISPLAY_TYPES = {
};
export default {
// TODO find out if you should be able ot edit service account tokens
// // remove edit option for service acct tokens
// _availableActions() {
// let out = this._standardActions;
// if (this.secretType === SERVICE_ACCT) {
// const toFilter = ['goToEdit', 'goToEditYaml'];
// out = out.filter((action) => {
// if (!toFilter.includes(action.action)) {
// return action;
// }
// });
// }
// return out;
// },
keysDisplay() {
const keys = [
...Object.keys(this.data || []),
@ -40,6 +59,33 @@ export default {
return keys.join(', ');
},
// decode some secret data to show in list view
dataPreview() {
if (this._type === DOCKER_JSON) {
const encodedJSON = this.data['.dockerconfigjson'];
if (encodedJSON) {
const decodedJSON = base64Decode(encodedJSON);
try {
const auths = JSON.parse(decodedJSON).auths;
const out = [];
for (const domain in auths) {
out.push(domain);
}
return out.join(', ');
} catch (e) {
// if the dockerconfigjson somehow isn't valid json, give up :(
return decodedJSON;
}
}
} else {
return this.keysDisplay;
}
},
secretType() {
return this._type;
},

View File

@ -72,6 +72,10 @@ export default {
// use it instead of making a new proxy
entry = existing;
Object.assign(entry, data);
// if no entry for this id in cache, add it
if (!cache.map.get(id)) {
addObject(cache.list, entry);
}
cache.map.set(id, entry);
} else if ( entry ) {
// There's already an entry in the store, update it

View File

@ -55,6 +55,8 @@ export function cleanForNew(obj) {
delete m.resourceVersion;
delete m.selfLink;
delete m.creationTimestamp;
delete m.deletionTimestamp;
delete m.state;
dropKeys(m.annotations);
dropKeys(m.labels);
}

View File

@ -613,11 +613,11 @@ export default {
}
// @TODO remove this once the API maps steve _type <-> k8s type in both directions
if (this._type) {
this.type = this._type;
}
opt.data = { ...this };
opt.data = this;
if (opt?.data._type) {
opt.data.type = opt.data._type;
}
const res = await this.$dispatch('request', opt);
@ -803,5 +803,5 @@ export default {
url = `${ url.slice(0, url.indexOf('/v1')) }/apis/${ group }/namespaces/${ namespace }/${ resource }`;
return url;
}
},
};

View File

@ -171,7 +171,9 @@ export const getters = {
}
}
return all[0] || 'default';
console.log('7', all[0]); // eslint-disable-line no-console
return all[0];
}
};

View File

@ -2,7 +2,7 @@ import { xor } from 'lodash';
import { get } from '@/utils/object';
export function removeObject(ary, obj) {
const idx = ary.indexOf(obj);
const idx = ary.findIndex(resource => resource.id === obj.id);
if ( idx >= 0 ) {
ary.splice(idx, 1);