signing ui improvements
This commit is contained in:
+25
-18
@@ -8,13 +8,11 @@ const ClusterAccess = {
|
||||
PubKey: "",
|
||||
Principal: "root",
|
||||
},
|
||||
sshUserCert: null,
|
||||
kubeSignReq: {
|
||||
CSR: "",
|
||||
User: "",
|
||||
Group: "system:masters",
|
||||
},
|
||||
kubeUserCert: null,
|
||||
downloadSet: null,
|
||||
selectedAssets: {},
|
||||
loading: false,
|
||||
@@ -30,8 +28,8 @@ const ClusterAccess = {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}).then(r => {
|
||||
if (r.ok) r.json().then(d => {
|
||||
if (d.user) this.kubeSignReq.User = d.user;
|
||||
if (d.group) this.kubeSignReq.Group = d.group;
|
||||
this.kubeSignReq.User = d.user || "anonymous";
|
||||
this.kubeSignReq.Group = d.group;
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
@@ -73,7 +71,15 @@ const ClusterAccess = {
|
||||
headers: { 'Authorization': 'Bearer ' + this.token, 'Content-Type': 'application/json' },
|
||||
}).then((resp) => {
|
||||
if (resp.ok) {
|
||||
resp.blob().then((cert) => { this.sshUserCert = URL.createObjectURL(cert); this.loading = false })
|
||||
resp.blob().then((cert) => {
|
||||
const url = URL.createObjectURL(cert);
|
||||
const a = document.createElement('a');
|
||||
const parts = this.sshSignReq.PubKey.trim().split(/\s+/);
|
||||
const user = parts.length > 2 ? parts[parts.length - 1] : this.sshSignReq.Principal;
|
||||
a.href = url; a.download = user + '-cert.pub';
|
||||
a.click(); URL.revokeObjectURL(url);
|
||||
this.loading = false;
|
||||
})
|
||||
} else {
|
||||
resp.json().then((resp) => { this.msg = 'failed to sign: '+resp.message; this.loading = false })
|
||||
}
|
||||
@@ -89,7 +95,13 @@ const ClusterAccess = {
|
||||
headers: { 'Authorization': 'Bearer ' + this.token, 'Content-Type': 'application/json' },
|
||||
}).then((resp) => {
|
||||
if (resp.ok) {
|
||||
resp.blob().then((cert) => { this.kubeUserCert = URL.createObjectURL(cert); this.loading = false })
|
||||
resp.blob().then((cert) => {
|
||||
const url = URL.createObjectURL(cert);
|
||||
const a = document.createElement('a');
|
||||
a.href = url; a.download = (this.kubeSignReq.User || this.kubeSignReq.Group) + '.crt';
|
||||
a.click(); URL.revokeObjectURL(url);
|
||||
this.loading = false;
|
||||
})
|
||||
} else {
|
||||
resp.json().then((resp) => { this.msg = 'failed to sign: '+resp.message; this.loading = false })
|
||||
}
|
||||
@@ -152,7 +164,8 @@ const ClusterAccess = {
|
||||
<label class="radio"><input type="radio" v-model="accessType" value="download-set" /> Download set</label>
|
||||
</p>
|
||||
|
||||
<p>Validity: <input type="text" v-model="signReqValidity"/> <small>time range, ie: -5m:1w, 5m, 1M, 1y, 1d-1s, etc.</small></p>
|
||||
<p>Validity: <input type="text" v-model="signReqValidity"/>
|
||||
← <template v-for="(v,i) in ['5m','1d','1w','1M','1y']">{{ i ? ', ' : ' ' }}<a href="#" @click.prevent="signReqValidity=v">{{ v }}</a></template></p>
|
||||
|
||||
<p class="error" v-if="msg">{{ msg }} <button class="btn-close" @click="msg=null">×</button></p>
|
||||
|
||||
@@ -163,26 +176,20 @@ const ClusterAccess = {
|
||||
<span class="text-and-file"><textarea v-model="sshSignReq.PubKey" style="height:3lh"></textarea>
|
||||
<input type="file" accept=".pub" @change="loadPubKey" /></span>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="sshCASign">{{ loading ? 'signing...' : 'Sign SSH access' }}</button>
|
||||
<template v-if="sshUserCert">
|
||||
=> <a :href="sshUserCert" download="ssh-cert.pub">Get certificate</a>
|
||||
</template>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="sshCASign">{{ loading ? 'signing...' : 'Sign SSH access' }}</button></p>
|
||||
</div>
|
||||
|
||||
<div v-if="accessType == 'kube'">
|
||||
<h4>Grant Kubernetes API access</h4>
|
||||
<p>User: <input type="text" v-model="kubeSignReq.User"/> (by default, from the CSR)</p>
|
||||
<p>Group: <input type="text" v-model="kubeSignReq.Group"/></p>
|
||||
<p>Certificate signing request (PEM format):<br/>
|
||||
<span class="text-and-file"><textarea v-model="kubeSignReq.CSR" style="height:7lh;"></textarea>
|
||||
<input type="file" accept=".csr" @change="loadCSR" /></span>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="kubeCASign">{{ loading ? 'signing...' : 'Sign Kubernetes API access' }}</button>
|
||||
<template v-if="kubeUserCert">
|
||||
=> <a :href="kubeUserCert" download="tls.crt">Get certificate</a>
|
||||
</template>
|
||||
<p>User: <input type="text" v-model="kubeSignReq.User"/></p>
|
||||
<p>Group: <input type="text" v-model="kubeSignReq.Group"/>
|
||||
← <a href="#" @click.prevent="kubeSignReq.Group=''">clear</a>, <a href="#" @click.prevent="kubeSignReq.Group='system:masters'">system:masters</a>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="kubeCASign">{{ loading ? 'signing...' : 'Sign Kubernetes API access' }}</button></p>
|
||||
</div>
|
||||
|
||||
<div v-if="accessType == 'download-set'">
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
<script src="/ui/app-4f0c6935250753e9.js" defer integrity="sha384-SrAfGs5pnGcgL5E78t2MszNYmdkGME9yPgtPsDg61Rljw+dfiP+rabjPnrMkWDUH" type="module"></script>
|
||||
<script src="/ui/Downloads-3c8cba0572aebfae.js" integrity="sha384-Pof/sPwhdqKGp7NUmYkDc0pSSyACabwLjkRRylZKHxRmiHBV3SGomPUMAWG9y7Ix"></script>
|
||||
<script src="/ui/GetCopy-2e04b7b63750e25a.js" integrity="sha384-sNvTYXhjog3BkYL20RzrUWIG9VGyHNO8oEiP5oxL5f2WKmLj/03fdR79FgHfzlj+"></script>
|
||||
<script src="/ui/ClusterAccess-1090c2ac32649bb9.js" integrity="sha384-xs5yHZycLFkyMIIULJMMeDk04sly74uUtO7qaagZcLLKos9YIOv0sEIJkXRveno3"></script>
|
||||
<script src="/ui/ClusterAccess-f38a8132c1c029e.js" integrity="sha384-jDiukS9Hz3HCNpLEoV9jdljj5UmvzS95TCY6U+cjSl07JzhgKRvwYwBi8jNoxFBH"></script>
|
||||
<script src="/ui/ClusterCAs-4f0a381bfb0c1b88.js" integrity="sha384-QcSHKzEHNSCqyjFELXfYFAdfmIZZwJHDzPqI2prH47jHrkeomJD60rcEMLkVAO3o"></script>
|
||||
<script src="/ui/Cluster-34a012ee0910827c.js" integrity="sha384-Q0sXP0WFJu4gHOI/8NMOGwpJvvFDNBR3T/vDCYxCWL2szAu4+sQuwHm81Jcad/ve"></script>
|
||||
<script src="/ui/Host-61916516a854adff.js" integrity="sha384-/wh3KrC0sb4MT7ekO2U84rswxI42WSH/0jB4dbDaaGaGhX60xTEZHFsdQAf7UgTG"></script>
|
||||
|
||||
+25
-18
@@ -8,13 +8,11 @@ const ClusterAccess = {
|
||||
PubKey: "",
|
||||
Principal: "root",
|
||||
},
|
||||
sshUserCert: null,
|
||||
kubeSignReq: {
|
||||
CSR: "",
|
||||
User: "",
|
||||
Group: "system:masters",
|
||||
},
|
||||
kubeUserCert: null,
|
||||
downloadSet: null,
|
||||
selectedAssets: {},
|
||||
loading: false,
|
||||
@@ -30,8 +28,8 @@ const ClusterAccess = {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}).then(r => {
|
||||
if (r.ok) r.json().then(d => {
|
||||
if (d.user) this.kubeSignReq.User = d.user;
|
||||
if (d.group) this.kubeSignReq.Group = d.group;
|
||||
this.kubeSignReq.User = d.user || "anonymous";
|
||||
this.kubeSignReq.Group = d.group;
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
@@ -73,7 +71,15 @@ const ClusterAccess = {
|
||||
headers: { 'Authorization': 'Bearer ' + this.token, 'Content-Type': 'application/json' },
|
||||
}).then((resp) => {
|
||||
if (resp.ok) {
|
||||
resp.blob().then((cert) => { this.sshUserCert = URL.createObjectURL(cert); this.loading = false })
|
||||
resp.blob().then((cert) => {
|
||||
const url = URL.createObjectURL(cert);
|
||||
const a = document.createElement('a');
|
||||
const parts = this.sshSignReq.PubKey.trim().split(/\s+/);
|
||||
const user = parts.length > 2 ? parts[parts.length - 1] : this.sshSignReq.Principal;
|
||||
a.href = url; a.download = user + '-cert.pub';
|
||||
a.click(); URL.revokeObjectURL(url);
|
||||
this.loading = false;
|
||||
})
|
||||
} else {
|
||||
resp.json().then((resp) => { this.msg = 'failed to sign: '+resp.message; this.loading = false })
|
||||
}
|
||||
@@ -89,7 +95,13 @@ const ClusterAccess = {
|
||||
headers: { 'Authorization': 'Bearer ' + this.token, 'Content-Type': 'application/json' },
|
||||
}).then((resp) => {
|
||||
if (resp.ok) {
|
||||
resp.blob().then((cert) => { this.kubeUserCert = URL.createObjectURL(cert); this.loading = false })
|
||||
resp.blob().then((cert) => {
|
||||
const url = URL.createObjectURL(cert);
|
||||
const a = document.createElement('a');
|
||||
a.href = url; a.download = (this.kubeSignReq.User || this.kubeSignReq.Group) + '.crt';
|
||||
a.click(); URL.revokeObjectURL(url);
|
||||
this.loading = false;
|
||||
})
|
||||
} else {
|
||||
resp.json().then((resp) => { this.msg = 'failed to sign: '+resp.message; this.loading = false })
|
||||
}
|
||||
@@ -152,7 +164,8 @@ const ClusterAccess = {
|
||||
<label class="radio"><input type="radio" v-model="accessType" value="download-set" /> Download set</label>
|
||||
</p>
|
||||
|
||||
<p>Validity: <input type="text" v-model="signReqValidity"/> <small>time range, ie: -5m:1w, 5m, 1M, 1y, 1d-1s, etc.</small></p>
|
||||
<p>Validity: <input type="text" v-model="signReqValidity"/>
|
||||
← <template v-for="(v,i) in ['5m','1d','1w','1M','1y']">{{ i ? ', ' : ' ' }}<a href="#" @click.prevent="signReqValidity=v">{{ v }}</a></template></p>
|
||||
|
||||
<p class="error" v-if="msg">{{ msg }} <button class="btn-close" @click="msg=null">×</button></p>
|
||||
|
||||
@@ -163,26 +176,20 @@ const ClusterAccess = {
|
||||
<span class="text-and-file"><textarea v-model="sshSignReq.PubKey" style="height:3lh"></textarea>
|
||||
<input type="file" accept=".pub" @change="loadPubKey" /></span>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="sshCASign">{{ loading ? 'signing...' : 'Sign SSH access' }}</button>
|
||||
<template v-if="sshUserCert">
|
||||
=> <a :href="sshUserCert" download="ssh-cert.pub">Get certificate</a>
|
||||
</template>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="sshCASign">{{ loading ? 'signing...' : 'Sign SSH access' }}</button></p>
|
||||
</div>
|
||||
|
||||
<div v-if="accessType == 'kube'">
|
||||
<h4>Grant Kubernetes API access</h4>
|
||||
<p>User: <input type="text" v-model="kubeSignReq.User"/> (by default, from the CSR)</p>
|
||||
<p>Group: <input type="text" v-model="kubeSignReq.Group"/></p>
|
||||
<p>Certificate signing request (PEM format):<br/>
|
||||
<span class="text-and-file"><textarea v-model="kubeSignReq.CSR" style="height:7lh;"></textarea>
|
||||
<input type="file" accept=".csr" @change="loadCSR" /></span>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="kubeCASign">{{ loading ? 'signing...' : 'Sign Kubernetes API access' }}</button>
|
||||
<template v-if="kubeUserCert">
|
||||
=> <a :href="kubeUserCert" download="tls.crt">Get certificate</a>
|
||||
</template>
|
||||
<p>User: <input type="text" v-model="kubeSignReq.User"/></p>
|
||||
<p>Group: <input type="text" v-model="kubeSignReq.Group"/>
|
||||
← <a href="#" @click.prevent="kubeSignReq.Group=''">clear</a>, <a href="#" @click.prevent="kubeSignReq.Group='system:masters'">system:masters</a>
|
||||
</p>
|
||||
<p><button :disabled="loading" @click="kubeCASign">{{ loading ? 'signing...' : 'Sign Kubernetes API access' }}</button></p>
|
||||
</div>
|
||||
|
||||
<div v-if="accessType == 'download-set'">
|
||||
|
||||
Reference in New Issue
Block a user