mirror of https://github.com/rancher/ui.git
commit
b6069d80bd
|
|
@ -0,0 +1,206 @@
|
||||||
|
import Controller from '@ember/controller';
|
||||||
|
import { get, computed } from '@ember/object';
|
||||||
|
import {
|
||||||
|
searchFields as containerSearchFields
|
||||||
|
} from 'shared/components/pod-dots/component';
|
||||||
|
|
||||||
|
const podsHeaders = [
|
||||||
|
{
|
||||||
|
name: 'expand',
|
||||||
|
sort: false,
|
||||||
|
searchField: null,
|
||||||
|
width: 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
sort: ['sortState', 'displayName'],
|
||||||
|
searchField: 'displayState',
|
||||||
|
translationKey: 'generic.state',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
sort: ['sortName', 'id'],
|
||||||
|
searchField: 'displayName',
|
||||||
|
translationKey: 'generic.name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
sort: ['image', 'displayName'],
|
||||||
|
searchField: 'image',
|
||||||
|
translationKey: 'generic.image',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scale',
|
||||||
|
sort: ['scale:desc', 'isGlobalScale:desc', 'displayName'],
|
||||||
|
searchField: null,
|
||||||
|
translationKey: 'stacksPage.table.scale',
|
||||||
|
classNames: 'text-center',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const ingressHeaders = [
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
sort: ['sortState','displayName'],
|
||||||
|
searchField: 'displayState',
|
||||||
|
translationKey: 'generic.state',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
sort: ['sortName','id'],
|
||||||
|
searchField: 'displayName',
|
||||||
|
translationKey: 'generic.name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'created',
|
||||||
|
sort: ['created','id'],
|
||||||
|
classNames: 'text-right pr-20',
|
||||||
|
searchField: 'created',
|
||||||
|
translationKey: 'generic.created',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const servicesHeaders = [
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
sort: ['stack.isDefault:desc','stack.displayName','sortState','displayName'],
|
||||||
|
searchField: 'displayState',
|
||||||
|
translationKey: 'generic.state',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
sort: ['stack.isDefault:desc','stack.displayName','displayName','id'],
|
||||||
|
searchField: 'displayName',
|
||||||
|
translationKey: 'generic.name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'displayType',
|
||||||
|
sort: ['displayType','displayName','id'],
|
||||||
|
searchField: 'displayType',
|
||||||
|
translationKey: 'generic.type',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'target',
|
||||||
|
sort: false,
|
||||||
|
searchField: 'displayTargets',
|
||||||
|
translationKey: 'dnsPage.table.target',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const volumesHeaders = [
|
||||||
|
// {
|
||||||
|
// name: 'expand',
|
||||||
|
// sort: false,
|
||||||
|
// searchField: null,
|
||||||
|
// width: 30
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
sort: ['sortState','displayName'],
|
||||||
|
searchField: 'displayState',
|
||||||
|
translationKey: 'generic.state',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
sort: ['displayName','id'],
|
||||||
|
searchField: 'displayName',
|
||||||
|
translationKey: 'volumesPage.claimName.label',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'size',
|
||||||
|
sort: ['sizeBytes'],
|
||||||
|
search: ['sizeBytes','displaySize'],
|
||||||
|
translationKey: 'generic.size',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'volume',
|
||||||
|
sort: ['volume.displayName','displayName','id'],
|
||||||
|
translationKey: 'volumesPage.volume.label',
|
||||||
|
searchField: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'storageClass',
|
||||||
|
sort: ['storageClass.displayName','displayName','id'],
|
||||||
|
translationKey: 'volumesPage.storageClass.label',
|
||||||
|
searchField: null,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const secretsHeaders = [
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
sort: ['sortState','name','id'],
|
||||||
|
type: 'string',
|
||||||
|
searchField: 'displayState',
|
||||||
|
translationKey: 'generic.state',
|
||||||
|
width: 125,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
sort: ['name','id'],
|
||||||
|
translationKey: 'generic.name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'namespace',
|
||||||
|
translationKey: 'generic.namespace',
|
||||||
|
searchField: 'namespace.displayName',
|
||||||
|
sort: ['namespace.displayName','name','id'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'keys',
|
||||||
|
translationKey: 'secretsPage.table.keys',
|
||||||
|
searchField: 'keys',
|
||||||
|
sort: ['firstKey','name','id'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'created',
|
||||||
|
translationKey: 'generic.created',
|
||||||
|
sort: ['created:desc','name','id'],
|
||||||
|
searchField: false,
|
||||||
|
type: 'string',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default Controller.extend({
|
||||||
|
// TODO =- expand logic?
|
||||||
|
expandedInstances: [],
|
||||||
|
ingressHeaders: ingressHeaders,
|
||||||
|
servicesHeaders: servicesHeaders,
|
||||||
|
volumesHeaders: volumesHeaders,
|
||||||
|
secretsHeaders: secretsHeaders,
|
||||||
|
ingressSearchText: '',
|
||||||
|
secretsSearchText: '',
|
||||||
|
podsHeaders: podsHeaders,
|
||||||
|
podsSearchText: '',
|
||||||
|
servicesSearchText: '',
|
||||||
|
volumesSearchText: '',
|
||||||
|
sortBy: 'name',
|
||||||
|
extraSearchFields: ['id:prefix', 'displayIp:ip'],
|
||||||
|
extraSearchSubFields: containerSearchFields,
|
||||||
|
actions: {
|
||||||
|
toggleExpand() {
|
||||||
|
// ???
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stdOut: computed('model.app.stdOut', function() {
|
||||||
|
return get(this, 'model.app.status.stdOutput');
|
||||||
|
}),
|
||||||
|
stderr: computed('model.app.stdErr', function() {
|
||||||
|
return get(this, 'model.app.status.stdError');
|
||||||
|
}),
|
||||||
|
|
||||||
|
workloadsAndPods: computed('model.app.workloads', 'model.app.pods', function() {
|
||||||
|
let out = [];
|
||||||
|
out = this.get('model.app.pods').filter(obj => !obj.get('workloadId'));
|
||||||
|
out.pushObjects(this.get('model.app.workloads').slice());
|
||||||
|
return out;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { get } from '@ember/object';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import Route from '@ember/routing/route';
|
||||||
|
import { hash } from 'rsvp';
|
||||||
|
|
||||||
|
export default Route.extend({
|
||||||
|
catalog: service(),
|
||||||
|
store: service(),
|
||||||
|
|
||||||
|
model(params) {
|
||||||
|
const store = get(this, 'store');
|
||||||
|
return hash({
|
||||||
|
app: store.find('app', get(params, 'app_id')),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,243 @@
|
||||||
|
<section class="header clearfix">
|
||||||
|
<div class="pull-left">
|
||||||
|
<h1 class="vertical-middle">
|
||||||
|
{{t 'appDetailPage.header' appName=model.app.displayName}}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="vertical-middle"></div>
|
||||||
|
<div class="right-buttons">
|
||||||
|
{{badge-state model=model.app}}
|
||||||
|
{{action-menu model=model.app showPrimary=false classNames="ml-10 pull-right" size="sm"}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
{{#accordion-list as |al expandFn|}}
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.output.title')
|
||||||
|
detail=(t 'appDetailPage.output.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
<pre class="log-body" style="margin:0; font-size: 80%; color: whitesmoke;">{{stdOut}}</pre>
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.workloads.title')
|
||||||
|
detail=(t 'appDetailPage.workloads.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
{{#sortable-table
|
||||||
|
tableClassNames="double-rows"
|
||||||
|
classNames="grid sortable-table"
|
||||||
|
body=workloadsAndPods
|
||||||
|
searchText=podsSearchText
|
||||||
|
sortBy=sortBy
|
||||||
|
bulkActions=true
|
||||||
|
subRows=true
|
||||||
|
pagingLabel="pagination.workload"
|
||||||
|
subSearchField="pods"
|
||||||
|
extraSearchFields=extraSearchFields
|
||||||
|
extraSearchSubFields=extraSearchSubFields
|
||||||
|
headers=podsHeaders as |sortable kind inst dt|}}
|
||||||
|
{{#if (eq kind "row")}}
|
||||||
|
{{#if (eq inst.type "pod")}}
|
||||||
|
{{pod-row
|
||||||
|
model=inst
|
||||||
|
dt=dt
|
||||||
|
showNode=true
|
||||||
|
expandPlaceholder=true
|
||||||
|
scalePlaceholder=true
|
||||||
|
fullColspan=sortable.fullColspan
|
||||||
|
toggle=(action "toggleExpand" inst.id)
|
||||||
|
expanded=(array-includes expandedInstances inst.id)
|
||||||
|
}}
|
||||||
|
{{else}}
|
||||||
|
{{workload-row
|
||||||
|
model=inst
|
||||||
|
toggle=(action "toggleExpand" inst.id)
|
||||||
|
expanded=(array-includes expandedInstances inst.id)
|
||||||
|
searchText=searchText
|
||||||
|
subMatches=sortable.subMatches
|
||||||
|
fullColspan=sortable.fullColspan
|
||||||
|
dt=dt
|
||||||
|
}}
|
||||||
|
{{/if}}
|
||||||
|
{{else if (eq kind "nomatch")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'containersPage.table.noMatch'}}</td></tr>
|
||||||
|
{{else if (eq kind "norows")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'appDetailPage.workloads.nodata'}}</td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/sortable-table}}
|
||||||
|
{{!--
|
||||||
|
--}}
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.ingress.title')
|
||||||
|
detail=(t 'appDetailPage.ingress.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
<section class="pl-0 pr-0">
|
||||||
|
{{#sortable-table
|
||||||
|
classNames="grid sortable-table"
|
||||||
|
body=model.app.ingress
|
||||||
|
searchText=ingressSearchText
|
||||||
|
sortBy=sortBy
|
||||||
|
bulkActions=true
|
||||||
|
pagingLabel="pagination.ingress"
|
||||||
|
subSearchField="instances"
|
||||||
|
headers=ingressHeaders as |sortable kind inst dt|
|
||||||
|
}}
|
||||||
|
{{#if (eq kind "row")}}
|
||||||
|
<tr class="main-row">
|
||||||
|
<td class="row-check" valign="middle" style="padding-top: 2px;">
|
||||||
|
{{check-box nodeId=inst.id}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.state}}" class="state">
|
||||||
|
{{badge-state model=inst}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.name}}" class="clip">
|
||||||
|
<a href="{{href-to "ingress" inst.id}}">{{inst.displayName}}</a>
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.created}}" class="text-right pr-20">
|
||||||
|
{{date-calendar inst.created}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.actions}}" class="actions">
|
||||||
|
{{action-menu model=inst}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{else if (eq kind "nomatch")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'ingressPage.table.noMatch'}}</td></tr>
|
||||||
|
{{else if (eq kind "norows")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'appDetailPage.ingress.nodata'}}</td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/sortable-table}}
|
||||||
|
</section>
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.services.title')
|
||||||
|
detail=(t 'appDetailPage.services.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
{{#sortable-table
|
||||||
|
classNames="grid sortable-table"
|
||||||
|
body=model.app.services
|
||||||
|
searchText=servicesSearchText
|
||||||
|
sortBy=sortBy
|
||||||
|
bulkActions=true
|
||||||
|
pagingLabel="pagination.dnsRecord"
|
||||||
|
headers=servicesHeaders as |sortable kind inst dt|
|
||||||
|
}}
|
||||||
|
{{#if (eq kind "row")}}
|
||||||
|
{{dns-row
|
||||||
|
model=inst
|
||||||
|
searchText=searchText
|
||||||
|
fullColspan=sortable.fullColspan
|
||||||
|
dt=dt
|
||||||
|
}}
|
||||||
|
{{else if (eq kind "nomatch")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted pt-20 pb-20">{{t 'dnsPage.noMatch'}}</td></tr>
|
||||||
|
{{else if (eq kind "norows")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'appDetailPage.services.nodata'}}</td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/sortable-table}}
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.volumes.title')
|
||||||
|
detail=(t 'appDetailPage.volumes.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
<section class="pl-0 pr-0">
|
||||||
|
{{#sortable-table
|
||||||
|
classNames="grid sortable-table"
|
||||||
|
body=model.app.volumes
|
||||||
|
searchText=volumesSearchText
|
||||||
|
sortBy=sortBy
|
||||||
|
bulkActions=true
|
||||||
|
pagingLabel="pagination.volume"
|
||||||
|
headers=volumesHeaders as |sortable kind obj dt|
|
||||||
|
}}
|
||||||
|
{{#if (eq kind "row")}}
|
||||||
|
<tr class="main-row">
|
||||||
|
<td class="row-check" valign="middle" style="padding-top: 2px;">
|
||||||
|
{{check-box nodeId=obj.id}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.state}}">
|
||||||
|
{{badge-state model=obj}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.name}}">
|
||||||
|
<a href="{{href-to "volumes.detail" obj.id}}">{{obj.displayName}}</a>
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.size}}">
|
||||||
|
{{obj.displaySize}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.volume}}">
|
||||||
|
{{#if obj.persistentVolume}}
|
||||||
|
<a href="{{href-to "authenticated.cluster.storage.persistent-volumes.detail" scope.currentCluster.id obj.persistentVolume.id}}">
|
||||||
|
{{obj.persistentVolume.displayName}}
|
||||||
|
</a>
|
||||||
|
{{else}}
|
||||||
|
<span class="text-muted">–</span>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.storageClass}}">
|
||||||
|
{{#if obj.storageClass}}
|
||||||
|
<a href="{{href-to "authenticated.cluster.storage.classes.detail" scope.currentCluster.id obj.storageClass.id}}">
|
||||||
|
{{obj.storageClass.displayName}}
|
||||||
|
</a>
|
||||||
|
{{else}}
|
||||||
|
<span class="text-muted">–</span>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td data-title="{{dt.actions}}" class="actions">
|
||||||
|
{{action-menu model=obj}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{else if (eq kind "nomatch")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'volumesPage.noMatch'}}</td></tr>
|
||||||
|
{{else if (eq kind "norows")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'appDetailPage.volumes.nodata'}}</td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/sortable-table}}
|
||||||
|
</section>
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{#accordion-list-item
|
||||||
|
title=(t 'appDetailPage.secrets.title')
|
||||||
|
detail=(t 'appDetailPage.secrets.detail')
|
||||||
|
expandAll=al.expandAll
|
||||||
|
expand=(action expandFn)
|
||||||
|
expandOnInit=true
|
||||||
|
}}
|
||||||
|
{{#sortable-table
|
||||||
|
classNames="grid sortable-table"
|
||||||
|
body=model.app.secrets
|
||||||
|
sortBy=sortBy
|
||||||
|
bulkActions=true
|
||||||
|
searchText=secretsSearchText
|
||||||
|
headers=secretsHeaders as |sortable kind row dt|
|
||||||
|
}}
|
||||||
|
{{#if (eq kind "row")}}
|
||||||
|
{{secret-row model=row dt=dt}}
|
||||||
|
{{else if (eq kind "nomatch")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted pt-20 pb-20">{{t 'secretsPage.index.noMatch'}}</td></tr>
|
||||||
|
{{else if (eq kind "norows")}}
|
||||||
|
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'appDetailPage.secrets.nodata'}}</td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/sortable-table}}
|
||||||
|
{{/accordion-list-item}}
|
||||||
|
|
||||||
|
{{/accordion-list}}
|
||||||
|
</section>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import Resource from 'ember-api-store/models/resource';
|
import Resource from 'ember-api-store/models/resource';
|
||||||
import { hasMany } from 'ember-api-store/utils/denormalize';
|
import { hasMany, reference } from 'ember-api-store/utils/denormalize';
|
||||||
import { computed, get } from '@ember/object';
|
import { computed, get } from '@ember/object';
|
||||||
import { parseHelmExternalId } from 'ui/utils/parse-externalid';
|
import { parseHelmExternalId } from 'ui/utils/parse-externalid';
|
||||||
import StateCounts from 'ui/mixins/state-counts';
|
import StateCounts from 'ui/mixins/state-counts';
|
||||||
|
|
@ -8,7 +8,20 @@ import { inject as service } from '@ember/service';
|
||||||
const App = Resource.extend(StateCounts, {
|
const App = Resource.extend(StateCounts, {
|
||||||
catalog: service(),
|
catalog: service(),
|
||||||
router: service(),
|
router: service(),
|
||||||
|
// pods: hasMany('id', 'pod', 'appId'),
|
||||||
|
// services: hasMany('id', 'service', 'appId'),
|
||||||
|
// workloads: hasMany('id', 'workload', 'appId'),
|
||||||
|
// secrets: hasMany('id', 'secret', 'appId'),
|
||||||
|
// ingress: hasMany('id', 'ingress', 'appId'),
|
||||||
|
// volumes: hasMany('id', 'persistentVolumeClaim', 'appId'),
|
||||||
pods: hasMany('installNamespace', 'pod', 'namespaceId'),
|
pods: hasMany('installNamespace', 'pod', 'namespaceId'),
|
||||||
|
services: hasMany('installNamespace', 'service', 'namespaceId'),
|
||||||
|
workloads: hasMany('installNamespace', 'workload', 'namespaceId'),
|
||||||
|
secrets: hasMany('installNamespace', 'secret', 'namespaceId'),
|
||||||
|
ingress: hasMany('installNamespace', 'ingress', 'namespaceId'),
|
||||||
|
volumes: hasMany('installNamespace', 'persistentVolumeClaim', 'namespaceId'),
|
||||||
|
namespace: reference('namespaceId', 'namespace', 'clusterStore'),
|
||||||
|
//workloads on pod
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
|
||||||
|
|
@ -150,11 +150,13 @@ Router.map(function() {
|
||||||
// Catalog
|
// Catalog
|
||||||
this.route('apps-tab', {path: '/apps', resetNamespace: true}, function() {
|
this.route('apps-tab', {path: '/apps', resetNamespace: true}, function() {
|
||||||
this.route('index', {path: '/'});
|
this.route('index', {path: '/'});
|
||||||
|
this.route('detail', {path: '/:app_id'});
|
||||||
|
|
||||||
this.route('catalog-tab', {path: '/catalog', resetNamespace: true}, function() {
|
this.route('catalog-tab', {path: '/catalog', resetNamespace: true}, function() {
|
||||||
this.route('index', {path: '/'});
|
this.route('index', {path: '/'});
|
||||||
this.route('launch', {path: '/:template'});
|
this.route('launch', {path: '/:template'});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import Controller from '@ember/controller';
|
||||||
import Errors from 'ui/utils/errors';
|
import Errors from 'ui/utils/errors';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
import { computed, observer } from '@ember/object';
|
import { get, set, computed, observer } from '@ember/object';
|
||||||
|
|
||||||
var PLAIN_PORT = 389;
|
var PLAIN_PORT = 389;
|
||||||
var TLS_PORT = 636;
|
var TLS_PORT = 636;
|
||||||
|
|
@ -31,44 +31,44 @@ export default Controller.extend({
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (this.get('adConfig')){
|
if (get(this, 'adConfig')){
|
||||||
this.tlsChanged();
|
this.tlsChanged();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createDisabled: computed('username.length','password.length', function() {
|
createDisabled: computed('username.length','password.length', function() {
|
||||||
return !this.get('username.length') || !this.get('password.length');
|
return !get(this, 'username.length') || !get(this, 'password.length');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
numUsers: computed('adConfig.allowedIdentities.@each.externalIdType','userType','groupType', function() {
|
numUsers: computed('adConfig.allowedIdentities.@each.externalIdType','userType','groupType', function() {
|
||||||
return (this.get('adConfig.allowedIdentities')||[]).filterBy('externalIdType', this.get('userType')).get('length');
|
return ( get(this, 'adConfig.allowedPrincipalIds') || [] ).filter(principal => principal.includes(C.PROJECT.TYPE_ACTIVE_DIRECTORY_USER)).get('length');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
numGroups: computed('adConfig.allowedIdentities.@each.externalIdType','userType','groupType', function() {
|
numGroups: computed('adConfig.allowedIdentities.@each.externalIdType','userType','groupType', function() {
|
||||||
return (this.get('adConfig.allowedIdentities')||[]).filterBy('externalIdType', this.get('groupType')).get('length');
|
return ( get(this, 'adConfig.allowedPrincipalIds') || [] ).filter(principal => principal.includes(C.PROJECT.TYPE_ACTIVE_DIRECTORY_GROUP)).get('length');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
configServers: computed('adConfig.servers', {
|
configServers: computed('adConfig.servers', {
|
||||||
get() {
|
get() {
|
||||||
return (this.get('adConfig.servers')||[]).join(',');
|
return (get(this, 'adConfig.servers')||[]).join(',');
|
||||||
},
|
},
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
this.set('adConfig.servers', value.split(','));
|
set(this, 'adConfig.servers', value.split(','));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
tlsChanged: observer('adConfig.tls', function() {
|
tlsChanged: observer('adConfig.tls', function() {
|
||||||
var on = (this.get('adConfig.tls')||false);
|
var on = (get(this, 'adConfig.tls')||false);
|
||||||
var port = parseInt(this.get('adConfig.port'),10);
|
var port = parseInt(get(this, 'adConfig.port'),10);
|
||||||
|
|
||||||
if ( on && port === PLAIN_PORT )
|
if ( on && port === PLAIN_PORT )
|
||||||
{
|
{
|
||||||
this.set('adConfig.port', TLS_PORT);
|
set(this, 'adConfig.port', TLS_PORT);
|
||||||
}
|
}
|
||||||
else if ( !on /* && port === TLS_PORT */ ) // TODO 2.0
|
else if ( !on /* && port === TLS_PORT */ ) // TODO 2.0
|
||||||
{
|
{
|
||||||
this.set('adConfig.port', PLAIN_PORT);
|
set(this, 'adConfig.port', PLAIN_PORT);
|
||||||
this.set('adConfig.tls', false);
|
set(this, 'adConfig.tls', false);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ export default Controller.extend({
|
||||||
test: function() {
|
test: function() {
|
||||||
this.send('clearError');
|
this.send('clearError');
|
||||||
|
|
||||||
var model = this.get('adConfig');
|
var model = get(this, 'adConfig');
|
||||||
model.setProperties({
|
model.setProperties({
|
||||||
accessMode: 'unrestricted',
|
accessMode: 'unrestricted',
|
||||||
});
|
});
|
||||||
|
|
@ -84,16 +84,16 @@ export default Controller.extend({
|
||||||
var errors = model.validationErrors();
|
var errors = model.validationErrors();
|
||||||
if ( errors.get('length') )
|
if ( errors.get('length') )
|
||||||
{
|
{
|
||||||
this.set('errors', errors);
|
set(this, 'errors', errors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.set('testing', true);
|
set(this, 'testing', true);
|
||||||
model.doAction('testAndApply', {
|
model.doAction('testAndApply', {
|
||||||
activeDirectoryConfig: model,
|
activeDirectoryConfig: model,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
username: this.get('username'),
|
username: get(this, 'username'),
|
||||||
password: this.get('password'),
|
password: get(this, 'password'),
|
||||||
}).then( () => {
|
}).then( () => {
|
||||||
this.send('waitAndRefresh');
|
this.send('waitAndRefresh');
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
@ -111,25 +111,25 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
promptDisable: function() {
|
promptDisable: function() {
|
||||||
this.set('confirmDisable', true);
|
set(this, 'confirmDisable', true);
|
||||||
later(this, function() {
|
later(this, function() {
|
||||||
this.set('confirmDisable', false);
|
set(this, 'confirmDisable', false);
|
||||||
}, 10000);
|
}, 10000);
|
||||||
},
|
},
|
||||||
|
|
||||||
gotError: function(err) {
|
gotError: function(err) {
|
||||||
this.set('errors', [Errors.stringify(err)]);
|
set(this, 'errors', [Errors.stringify(err)]);
|
||||||
this.set('testing', false);
|
set(this, 'testing', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
clearError: function() {
|
clearError: function() {
|
||||||
this.set('errors', null);
|
set(this, 'errors', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
disable: function() {
|
disable: function() {
|
||||||
this.send('clearError');
|
this.send('clearError');
|
||||||
|
|
||||||
var model = this.get('adConfig');
|
var model = get(this, 'adConfig');
|
||||||
model.setProperties({
|
model.setProperties({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
});
|
});
|
||||||
|
|
@ -140,7 +140,7 @@ export default Controller.extend({
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.send('gotError', err);
|
this.send('gotError', err);
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.set('confirmDisable', false);
|
set(this, 'confirmDisable', false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { once, later } from '@ember/runloop';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
|
import C from 'ui/utils/constants';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
github: service(),
|
github: service(),
|
||||||
|
|
@ -52,13 +53,12 @@ export default Controller.extend({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
numUsers: computed('githubConfig.allowedPrincipals.@each.externalIdType','wasRestricted', function() {
|
numUsers: computed('githubConfig.allowedPrincipals.@each.externalIdType','wasRestricted', function() {
|
||||||
return 3; //TODO
|
return ( get(this, 'githubConfig.allowedPrincipalIds') || []).filter(principal => principal.includes(C.PROJECT.TYPE_GITHUB_USER)).get('length');
|
||||||
// return get(this, 'githubConfig.principals').filterBy('externalIdType',C.PROJECT.TYPE_GITHUB_USER).get('length');
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
numOrgs: computed('githubConfig.allowedPrincipals.@each.externalIdType','wasRestricted',function() {
|
numOrgs: computed('githubConfig.allowedPrincipals.@each.externalIdType','wasRestricted',function() {
|
||||||
return 4; //TODO
|
|
||||||
// return get(this, 'githubConfig.principals').filterBy('externalIdType',C.PROJECT.TYPE_GITHUB_ORG).get('length');
|
return ( get(this, 'githubConfig.allowedPrincipalIds') || []).filter(principal => principal.includes(C.PROJECT.TYPE_GITHUB_ORG)).get('length');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
destinationUrl: computed(function() {
|
destinationUrl: computed(function() {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col span-4">
|
<div class="col span-4">
|
||||||
<h3>{{t 'ldap.accessEnabled.general.header'}}</h3>
|
<h3>{{t 'ldap.accessEnabled.general.header'}}</h3>
|
||||||
<div><b>{{t 'ldap.accessEnabled.general.server'}} </b> <span class="text-muted">{{adConfig.server}}:{{adConfig.port}}</span></div>
|
<div><b>{{t 'ldap.accessEnabled.general.server'}} </b> <span class="text-muted">{{adConfig.servers.firstObject}}:{{adConfig.port}}</span></div>
|
||||||
<div><b>{{t 'ldap.accessEnabled.general.tls'}} </b> <span class="text-muted">{{if adConfig.tls "Yes" "No"}}</span></div>
|
<div><b>{{t 'ldap.accessEnabled.general.tls'}} </b> <span class="text-muted">{{if adConfig.tls "Yes" "No"}}</span></div>
|
||||||
<div><b>{{t 'ldap.accessEnabled.general.serviceAccount'}} </b> <span class="text-muted">{{adConfig.serviceAccountUsername}}</span></div>
|
<div><b>{{t 'ldap.accessEnabled.general.serviceAccount'}} </b> <span class="text-muted">{{adConfig.serviceAccountUsername}}</span></div>
|
||||||
{{#unless isOpenLdap}}
|
{{#unless isOpenLdap}}
|
||||||
|
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
import { get, set, computed } from '@ember/object';
|
|
||||||
import { next } from '@ember/runloop';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Component from '@ember/component';
|
|
||||||
import C from 'ui/utils/constants';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
access: service(),
|
|
||||||
cookies: service(),
|
|
||||||
isCaas: computed('app.mode', function() {
|
|
||||||
return this.get('app.mode') === 'caas' ? true : false;
|
|
||||||
}),
|
|
||||||
waiting: null,
|
|
||||||
|
|
||||||
username: null,
|
|
||||||
rememberUsername: false,
|
|
||||||
password: null,
|
|
||||||
shown: false,
|
|
||||||
provider: null,
|
|
||||||
readableProvider: null,
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
showLocal() {
|
|
||||||
this.toggleProperty('shown');
|
|
||||||
next(this, 'focusSomething');
|
|
||||||
},
|
|
||||||
authenticate: function() {
|
|
||||||
const username = get(this, 'username');
|
|
||||||
let password = get(this, 'password');
|
|
||||||
const remember = get(this, 'rememberUsername');
|
|
||||||
|
|
||||||
if (password && get(this, 'provider') === 'local') {
|
|
||||||
password = password.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
const code = {
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( remember ) {
|
|
||||||
if (get(this, 'provider') === 'local') {
|
|
||||||
get(this, 'cookies').setWithOptions(C.COOKIE.USERNAME, username, {expire: 365, secure: 'auto'});
|
|
||||||
} else {
|
|
||||||
get(this, 'cookies').setWithOptions(`${get(this, 'provider').toUpperCase()}-USERNAME`, username, {expire: 365, secure: 'auto'});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
get(this, 'cookies').remove(C.COOKIE.USERNAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(this, 'password', '');
|
|
||||||
if ( get(this,'access.providers') ) {
|
|
||||||
this.sendAction('action', get(this, 'provider'), code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this._super(...arguments);
|
|
||||||
|
|
||||||
var username = null;
|
|
||||||
if (get(this, 'provider') === 'local') {
|
|
||||||
username = get(this, `cookies.${C.COOKIE.USERNAME}`);
|
|
||||||
} else {
|
|
||||||
username = get(this, `cookies.${get(this, 'provider').toUpperCase()}-USERNAME`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( username ) {
|
|
||||||
set(this, 'username', username);
|
|
||||||
set(this, 'rememberUsername', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get(this, 'provider')) {
|
|
||||||
let pv = null;
|
|
||||||
switch(get(this, 'provider')) {
|
|
||||||
case 'activedirectory':
|
|
||||||
pv = 'Active Directory';
|
|
||||||
break;
|
|
||||||
case 'local':
|
|
||||||
default:
|
|
||||||
pv = 'Local Auth';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
set(this, 'readableProvider', pv);
|
|
||||||
|
|
||||||
// console.log(this.get('provider'));
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
focusSomething() {
|
|
||||||
if ( this.isDestroyed || this.isDestroying ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let elem = this.$('#login-username-ad');
|
|
||||||
if ( get(this, 'username') ) {
|
|
||||||
elem = this.$('#login-password-ad');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( elem && elem[0] ) {
|
|
||||||
elem[0].focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
|
||||||
next(this, 'focusSomething');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
{{#if shown}}
|
|
||||||
<form {{action "authenticate" on="submit"}} class="text-left mt-10">
|
|
||||||
<div class="mt-20">
|
|
||||||
<div>
|
|
||||||
{{#if isCaas}}
|
|
||||||
<label class="acc-label">{{t 'loginUserPass.caasLabel'}}</label>
|
|
||||||
{{else}}
|
|
||||||
<label class="acc-label">{{t 'loginUserPass.userLabel'}}</label>
|
|
||||||
{{/if}}
|
|
||||||
<div class="pull-right">
|
|
||||||
<label class="acc-label">{{t 'loginUserPass.remember'}} {{input type="checkbox" checked=rememberUsername}}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{input type="text" id="login-username-ad" autocomplete="username" class="form-control login-user" value=username placeholder=(t 'loginUserPass.userPlaceholder')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pt-15 pb-15">
|
|
||||||
<label class="acc-label">{{t 'loginUserPass.passwordLabel'}}</label>
|
|
||||||
<div>
|
|
||||||
{{input id="login-password-ad" autocomplete="password" type="password" class="form-control login-pass" value=password}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-center">
|
|
||||||
<button disabled={{waiting}} class="btn bg-primary" {{action "authenticate"}}>
|
|
||||||
{{#if waiting}}
|
|
||||||
<i class="icon icon-spinner icon-spin"></i> {{t 'loginUserPass.loggingInLabel'}}
|
|
||||||
{{else}}
|
|
||||||
{{t 'loginUserPass.loginLabel' provider=readableProvider}}
|
|
||||||
{{/if}}
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
{{else}}
|
|
||||||
{{#if (eq provider 'local')}}
|
|
||||||
<a class="link-text text-small mt-10 hand" {{action 'showLocal'}}>{{t 'loginUserPass.local'}}</a>
|
|
||||||
{{else}}
|
|
||||||
<a class="btn bg-primary" {{action 'showLocal'}}> <i class="icon icon-key"></i> {{t 'loginUserPass.provider' kind=readableProvider}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
@ -108,4 +108,9 @@ export default Component.extend({
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
next(this, 'focusSomething');
|
next(this, 'focusSomething');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
set(this, 'shown', false);
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{input type="text" id="login-username" autocomplete="username" class="form-control login-user" value=username placeholder=(t 'loginUserPass.userPlaceholder')}}
|
{{input type="text" id=(concat "login-username-" provider) autocomplete="username" class="form-control login-user" value=username placeholder=(t 'loginUserPass.userPlaceholder')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-15 pb-15">
|
<div class="pt-15 pb-15">
|
||||||
<label class="acc-label">{{t 'loginUserPass.passwordLabel'}}</label>
|
<label class="acc-label">{{t 'loginUserPass.passwordLabel'}}</label>
|
||||||
<div>
|
<div>
|
||||||
{{input id="login-password" autocomplete="password" type="password" class="form-control login-pass" value=password}}
|
{{input id=(concat "login-password-" provider) autocomplete="password" type="password" class="form-control login-pass" value=password}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ export default Controller.extend({
|
||||||
isForbidden: equal('errorCode', '403'),
|
isForbidden: equal('errorCode', '403'),
|
||||||
|
|
||||||
waiting: false,
|
waiting: false,
|
||||||
|
adWaiting: false,
|
||||||
|
localWaiting: false,
|
||||||
|
shibbolethWaiting: false,
|
||||||
errorMsg: null,
|
errorMsg: null,
|
||||||
errorCode: null,
|
errorCode: null,
|
||||||
resetPassword: false,
|
resetPassword: false,
|
||||||
|
|
@ -76,7 +79,6 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
started() {
|
started() {
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
'waiting': true,
|
'waiting': true,
|
||||||
|
|
@ -84,6 +86,27 @@ export default Controller.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
waiting(provider) {
|
||||||
|
// setProperties(this, {
|
||||||
|
// 'waiting': true,
|
||||||
|
// 'errorMsg': null,
|
||||||
|
// });
|
||||||
|
set(this, 'errorMsg', null);
|
||||||
|
switch (provider) {
|
||||||
|
case 'local':
|
||||||
|
this.toggleProperty('localWaiting');
|
||||||
|
break;
|
||||||
|
case 'activedirectory':
|
||||||
|
this.toggleProperty('adWaiting');
|
||||||
|
break;
|
||||||
|
case 'shibboleth':
|
||||||
|
this.toggleProperty('shibbolethWaiting');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
complete(success) {
|
complete(success) {
|
||||||
if (success) {
|
if (success) {
|
||||||
this.shouldSetServerUrl().then((proceed) => {
|
this.shouldSetServerUrl().then((proceed) => {
|
||||||
|
|
@ -102,7 +125,7 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
authenticate(provider, code) {
|
authenticate(provider, code) {
|
||||||
this.send('started');
|
this.send('waiting', provider);
|
||||||
|
|
||||||
later(() => {
|
later(() => {
|
||||||
get(this, 'access').login(provider, code).then((user) => {
|
get(this, 'access').login(provider, code).then((user) => {
|
||||||
|
|
@ -118,9 +141,10 @@ export default Controller.extend({
|
||||||
get(this, 'access').set('userCode', null);
|
get(this, 'access').set('userCode', null);
|
||||||
get(this, 'access').set('firstLogin', false);
|
get(this, 'access').set('firstLogin', false);
|
||||||
this.send('complete', true);
|
this.send('complete', true);
|
||||||
|
this.send('waiting', provider);
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
set(this, 'waiting', false);
|
this.send('waiting', provider);
|
||||||
|
|
||||||
if ( err && err.status === 401 ) {
|
if ( err && err.status === 401 ) {
|
||||||
let key = 'loginPage.error.authFailed'
|
let key = 'loginPage.error.authFailed'
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,13 @@ export default Route.extend({
|
||||||
|
|
||||||
resetController(controller, isExisting /*, transition*/ ) {
|
resetController(controller, isExisting /*, transition*/ ) {
|
||||||
if (isExisting) {
|
if (isExisting) {
|
||||||
controller.set('changePassword', false);
|
controller.setProperties({
|
||||||
controller.set('waiting',false);
|
changePassword: false,
|
||||||
|
waiting: false,
|
||||||
|
adWaiting: false,
|
||||||
|
shibbolethWaiting: false,
|
||||||
|
localWaiting: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
{{login-shibboleth
|
{{login-shibboleth
|
||||||
action="started"
|
action="started"
|
||||||
waiting=waiting
|
waiting=shibbolethWaiting
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
@ -25,23 +25,23 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isActiveDirectory}}
|
{{#if isActiveDirectory}}
|
||||||
{{login-ad
|
{{login-user-pass
|
||||||
classNames="row"
|
|
||||||
action="authenticate"
|
action="authenticate"
|
||||||
waiting=waiting
|
classNames="row"
|
||||||
shown=true
|
|
||||||
provider="activedirectory"
|
provider="activedirectory"
|
||||||
|
shown=true
|
||||||
|
waiting=adWaiting
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isLocal}}
|
{{#if isLocal}}
|
||||||
{{login-user-pass
|
{{login-user-pass
|
||||||
classNames="row"
|
|
||||||
action="authenticate"
|
action="authenticate"
|
||||||
waiting=waiting
|
classNames="row"
|
||||||
shown=onlyLocal
|
|
||||||
onlyLocal=onlyLocal
|
onlyLocal=onlyLocal
|
||||||
provider="local"
|
provider="local"
|
||||||
|
shown=onlyLocal
|
||||||
|
waiting=localWaiting
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import C from 'shared/utils/constants';
|
||||||
import EmberObject from '@ember/object'
|
import EmberObject from '@ember/object'
|
||||||
import { get } from '@ember/object';
|
import { get } from '@ember/object';
|
||||||
import { /* parseExternalId, */ parseHelmExternalId } from 'ui/utils/parse-externalid';
|
import { /* parseExternalId, */ parseHelmExternalId } from 'ui/utils/parse-externalid';
|
||||||
import { all } from 'rsvp';
|
import { all, allSettled } from 'rsvp';
|
||||||
|
|
||||||
const RANCHER_VERSION = 'rancherVersion';
|
const RANCHER_VERSION = 'rancherVersion';
|
||||||
const DEFAULT_BASE = 'kubernetes';
|
const DEFAULT_BASE = 'kubernetes';
|
||||||
|
|
@ -47,7 +47,7 @@ export default Service.extend({
|
||||||
deps.push(this.fetchTemplate(extInfo.templateId, false));
|
deps.push(this.fetchTemplate(extInfo.templateId, false));
|
||||||
});
|
});
|
||||||
|
|
||||||
return all(deps);
|
return allSettled(deps);
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchCatalogs(opts) {
|
fetchCatalogs(opts) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ export default Component.extend({
|
||||||
questions: alias('selectedTemplate.questions'),
|
questions: alias('selectedTemplate.questions'),
|
||||||
pasteOrUpload: false,
|
pasteOrUpload: false,
|
||||||
accept : '.yml, .yaml',
|
accept : '.yml, .yaml',
|
||||||
|
showHeader: true,
|
||||||
_boundChange : null,
|
_boundChange : null,
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this.set('_boundChange', (event) => { this.change(event); });
|
this.set('_boundChange', (event) => { this.change(event); });
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,13 @@
|
||||||
<button class="btn btn-sm bg-primary" {{action 'showPaste'}}>{{t 'generic.paste'}} <span class="icon icon-copy"></span></button>
|
<button class="btn btn-sm bg-primary" {{action 'showPaste'}}>{{t 'generic.paste'}} <span class="icon icon-copy"></span></button>
|
||||||
<button class="btn btn-sm bg-primary" {{action 'upload'}}>{{t 'generic.upload'}} <span class="icon icon-upload"></span></button>
|
<button class="btn btn-sm bg-primary" {{action 'upload'}}>{{t 'generic.upload'}} <span class="icon icon-upload"></span></button>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
{{#if showHeader}}
|
||||||
<h4 class="mb-0">{{t 'inputAnswers.config'}}</h4>
|
<h4 class="mb-0">{{t 'inputAnswers.config'}}</h4>
|
||||||
<span class="protip">{{t 'inputAnswers.protip'}}</span>
|
<span class="protip">{{t 'inputAnswers.protip'}}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
<div class="mt-20">
|
<div class="mt-20">
|
||||||
{{#if pasteOrUpload}}
|
{{#if pasteOrUpload}}
|
||||||
{{textarea-autogrow
|
{{textarea-autogrow
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,19 @@
|
||||||
<div class="stack-info-row box">
|
<div class="stack-info-row box">
|
||||||
<div class="stack-info-top row">
|
<div class="stack-info-top row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
{{#link-to "apps-tab.detail" model.id}}
|
||||||
{{model.displayName}}
|
{{model.displayName}}
|
||||||
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-right pull-right">
|
<div class="col text-right pull-right">
|
||||||
|
{{#upgrade-btn model=model classNames="btn-xs " as |btn|}}
|
||||||
|
{{#if btn.model.externalIdInfo.version}}
|
||||||
|
{{t (concat 'upgradeBtn.status.' btn.upgradeStatus)}}
|
||||||
|
<span class="text-small">({{btn.latestVersion}})</span>
|
||||||
|
{{else}}
|
||||||
|
{{t (concat 'upgradeBtn.status.' btn.upgradeStatus)}}
|
||||||
|
{{/if}}
|
||||||
|
{{/upgrade-btn}}
|
||||||
{{badge-state model=model classNames="btn-xs"}}
|
{{badge-state model=model classNames="btn-xs"}}
|
||||||
{{action-menu model=model classNames="inline-block"}}
|
{{action-menu model=model classNames="inline-block"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -25,17 +35,15 @@
|
||||||
{{model.pods.length}}
|
{{model.pods.length}}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
{{#upgrade-btn model=model classNames="btn-sm" as |btn|}}
|
<div class="col">
|
||||||
{{model.externalIdInfo.version}}
|
{{#if model.workloads}}
|
||||||
{{#if btn.model.externalIdInfo.version}}
|
<div class="clip text-small">
|
||||||
{{t (concat 'upgradeBtn.status.' btn.upgradeStatus)}}
|
{{#each model.workloads as |workload|}}
|
||||||
<span class="text-small">({{btn.latestVersion}})</span>
|
{{workload.displayEndpoints}}
|
||||||
{{else}}
|
{{/each}}
|
||||||
{{t (concat 'upgradeBtn.status.' btn.upgradeStatus)}}
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/upgrade-btn}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#if expanded}}
|
</div>
|
||||||
{{/if}}
|
|
||||||
|
|
@ -121,7 +121,7 @@ export default Component.extend(NewOrEdit, {
|
||||||
value: file.name
|
value: file.name
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
files.addObject({label: 'answers', value: 'answers'});
|
files.addObject({label: 'answers.yaml', value: 'answers'});
|
||||||
return files.sortBy('label');
|
return files.sortBy('label');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,42 +8,20 @@
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<section class="{{sectionClass}} row">
|
<div class="accordion"> {{!-- container-section --}}
|
||||||
<div class="col span-3">
|
<div class="accordion-header"> {{!-- header-section --}}
|
||||||
|
<div class="title">
|
||||||
|
<span class="m-0 ">{{t 'newCatalog.appInfo'}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-content row"> {{!-- content-section --}}
|
||||||
|
<div class="col span-12 text-center">
|
||||||
{{#if templateResource.links.icon}}
|
{{#if templateResource.links.icon}}
|
||||||
<img src={{templateResource.links.icon}} alt={{templateResource.name}} class="mr-20" style="height:75px;max-width: 100%;">
|
<img src={{templateResource.links.icon}} alt={{templateResource.name}} class="mr-20" style="height:75px;max-width: 100%;">
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div>
|
|
||||||
<small><strong>{{t 'newCatalog.catalog'}}</strong> <span class="text-capitalize">{{templateResource.catalogId}}</span></small>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<small><strong>{{t 'newCatalog.kind'}}</strong> <span class="text-capitalize">{{templateKind}}</span></small>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<small><strong>{{t 'newCatalog.category'}}</strong> {{join-array templateResource.categoryArray}}</small>
|
|
||||||
</div>
|
|
||||||
{{#if (eq templateResource.certifiedType 'rancher')}}
|
|
||||||
<small><strong>{{t 'newCatalog.support'}} </strong>{{t 'newCatalog.official'}}</small>
|
|
||||||
{{else}}
|
|
||||||
<small><strong>{{t 'newCatalog.support'}} </strong>{{t 'newCatalog.maintainedBy'}}</small>
|
|
||||||
{{/if}}
|
|
||||||
{{#if templateResource.maintainer}}
|
|
||||||
<div>
|
|
||||||
<small><strong>{{t 'newCatalog.maintainer'}}</strong> {{templateResource.maintainer}}</small>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{#if templateResource.license}}
|
|
||||||
<div>
|
|
||||||
<small><strong>{{t 'newCatalog.license'}}</strong> {{templateResource.license}}</small>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{#if templateResource.links.project}}
|
|
||||||
<small class="force-wrap"><strong>{{t 'newCatalog.url'}}</strong> <a href="{{templateResource.cleanProjectUrl}}" target="_blank">{{templateResource.cleanProjectUrl}}</a></small>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
{{#if readmeContent}}
|
{{#if readmeContent}}
|
||||||
<div class="col span-9" style="overflow-y: auto; max-height: 500px;">
|
<div class="col span-12" style="overflow-y: auto; max-height: 500px;">
|
||||||
{{marked-down markdown=readmeContent}}
|
{{marked-down markdown=readmeContent}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
@ -52,34 +30,30 @@
|
||||||
</h2>
|
</h2>
|
||||||
<p>{{templateResource.description}}</p>
|
<p>{{templateResource.description}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</div>
|
||||||
<section class="{{sectionClass}}">
|
</div>
|
||||||
<h4>{{t 'newCatalog.newApp'}}</h4>
|
|
||||||
|
|
||||||
|
<div class="accordion">
|
||||||
|
<div class="accordion-header">
|
||||||
|
<div class="title">
|
||||||
|
<span class="m-0 ">{{t 'newCatalog.newApp'}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-content row">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col span-6">
|
||||||
{{form-name-description
|
{{form-name-description
|
||||||
model=catalogApp
|
model=catalogApp
|
||||||
nameRequired=true
|
nameRequired=true
|
||||||
descriptionShow=false
|
descriptionShow=false
|
||||||
nameDisabled=showName
|
nameDisabled=showName
|
||||||
|
bothColClass="col span-12"
|
||||||
|
colClass="col span-12"
|
||||||
}}
|
}}
|
||||||
|
</div>
|
||||||
{{#if showName}}
|
<div class="col span-6" style="padding-top: 6px;"> {{!-- matches styles of form-name-description --}}
|
||||||
{{#advanced-section}}
|
<label for="" class="acc-label">{{t 'newCatalog.templateVersion'}}</label>
|
||||||
<hr class="mt-20 mb-20"/>
|
|
||||||
|
|
||||||
{{form-namespace
|
|
||||||
namespace=primaryResource
|
|
||||||
mode='reuse'
|
|
||||||
errors=namespaceErrors
|
|
||||||
}}
|
|
||||||
{{/advanced-section}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="{{sectionClass}}">
|
|
||||||
<h4>{{t 'newCatalog.templateVersion'}}</h4>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col span-6">
|
|
||||||
{{new-select
|
{{new-select
|
||||||
classNames="form-control"
|
classNames="form-control"
|
||||||
content=sortedVersions
|
content=sortedVersions
|
||||||
|
|
@ -93,26 +67,54 @@
|
||||||
<p class="text-info">{{t (if editing selectVersionUpgrade selectVersionAdd)}}</p>
|
<p class="text-info">{{t (if editing selectVersionUpgrade selectVersionAdd)}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<div class="col span-12">
|
||||||
|
{{#if showName}}
|
||||||
|
{{#advanced-section}}
|
||||||
|
<hr class="mt-20 mb-20"/>
|
||||||
|
|
||||||
|
{{form-namespace
|
||||||
|
namespace=primaryResource
|
||||||
|
mode='reuse'
|
||||||
|
errors=namespaceErrors
|
||||||
|
}}
|
||||||
|
{{/advanced-section}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section class="{{sectionClass}}">
|
|
||||||
{{#if getTemplate.isRunning}}
|
{{#if getTemplate.isRunning}}
|
||||||
|
<section class="row">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<i class="icon icon-spinner icon-spin" style="font-size:36px;"></i>
|
<i class="icon icon-spinner icon-spin" style="font-size:36px;"></i>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
{{else}}
|
||||||
|
<div class="accordion">
|
||||||
|
<div class="accordion-header">
|
||||||
|
<div class="title">
|
||||||
|
{{#if (or (eq templateKind 'native') selectedTemplateModel.questions)}}
|
||||||
|
<span class="m-0 block">{{t 'inputAnswers.config'}}</span>
|
||||||
|
<span class="help-block">{{t 'inputAnswers.protip'}}</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="m-0 block">{{t 'newCatalog.helm.label'}}</span>
|
||||||
|
<span class="help-block">{{t 'newCatalog.helm.protip'}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-content row">
|
||||||
{{#if selectedTemplateModel}}
|
{{#if selectedTemplateModel}}
|
||||||
{{#if (eq templateKind 'native')}}
|
{{#if (eq templateKind 'native')}}
|
||||||
{{input-answers
|
{{input-answers
|
||||||
selectedTemplate=selectedTemplateModel
|
selectedTemplate=selectedTemplateModel
|
||||||
|
showHeader=false
|
||||||
}}
|
}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<h4>{{t 'newCatalog.helm.label'}}</h4>
|
|
||||||
<div class="span-12">
|
<div class="span-12">
|
||||||
{{#if selectedTemplateModel.questions}}
|
{{#if selectedTemplateModel.questions}}
|
||||||
{{input-answers
|
{{input-answers
|
||||||
selectedTemplate=selectedTemplateModel
|
selectedTemplate=selectedTemplateModel
|
||||||
|
showHeader=false
|
||||||
}}
|
}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{form-key-value
|
{{form-key-value
|
||||||
|
|
@ -130,9 +132,10 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if (and selectedTemplateModel (not getTemplate.isRunning))}}
|
{{#if (and selectedTemplateModel (not getTemplate.isRunning))}}
|
||||||
{{#if showPreview}}
|
{{#if showPreview}}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export default Mixin.create({
|
||||||
color: computed('upgradeStatus', function() {
|
color: computed('upgradeStatus', function() {
|
||||||
switch ( get(this, 'upgradeStatus') ) {
|
switch ( get(this, 'upgradeStatus') ) {
|
||||||
case NONE:
|
case NONE:
|
||||||
return 'hide';
|
return 'none';
|
||||||
case CURRENT:
|
case CURRENT:
|
||||||
case LOADING:
|
case LOADING:
|
||||||
return 'bg-default';
|
return 'bg-default';
|
||||||
|
|
@ -102,6 +102,7 @@ export default Mixin.create({
|
||||||
let info = get(this, 'model.externalIdInfo');
|
let info = get(this, 'model.externalIdInfo');
|
||||||
let catalogTemplate = get(this, 'model.catalogTemplate');
|
let catalogTemplate = get(this, 'model.catalogTemplate');
|
||||||
let upgradeVersions = {};
|
let upgradeVersions = {};
|
||||||
|
let allVersions = {};
|
||||||
|
|
||||||
if ( state === 'upgraded' ) {
|
if ( state === 'upgraded' ) {
|
||||||
set(this, 'upgradeStatus', UPGRADED);
|
set(this, 'upgradeStatus', UPGRADED);
|
||||||
|
|
@ -119,7 +120,14 @@ export default Mixin.create({
|
||||||
set(this, 'upgradeStatus', NONE);
|
set(this, 'upgradeStatus', NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeVersions = parseUpgradeVersions(catalogTemplate.get('versionLinks'), info.version, get(this, 'model'));
|
if ( catalogTemplate ) {
|
||||||
|
upgradeVersions = parseUpgradeVersions(
|
||||||
|
get(catalogTemplate, 'versionLinks'),
|
||||||
|
get(info, 'version'),
|
||||||
|
get(this, 'model')
|
||||||
|
);
|
||||||
|
get(catalogTemplate, 'versionLinks');
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(upgradeVersions).length >= 1) {
|
if (Object.keys(upgradeVersions).length >= 1) {
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
|
|
@ -127,7 +135,10 @@ export default Mixin.create({
|
||||||
latestVersion: Object.keys(upgradeVersions)[Object.keys(upgradeVersions).length-1],
|
latestVersion: Object.keys(upgradeVersions)[Object.keys(upgradeVersions).length-1],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
set(this, 'upgradeStatus', NONE);
|
setProperties(this, {
|
||||||
|
upgradeStatus: CURRENT,
|
||||||
|
latestVersion: get(info, 'version'),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('upgradeVersions', upgradeVersions);
|
// console.log('upgradeVersions', upgradeVersions);
|
||||||
|
|
@ -149,7 +160,7 @@ export default Mixin.create({
|
||||||
}
|
}
|
||||||
|
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
allVersions: catalogTemplate.get('versionLinks'),
|
allVersions: allVersions,
|
||||||
upgradeVersions: upgradeVersions
|
upgradeVersions: upgradeVersions
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,8 @@ var C = {
|
||||||
|
|
||||||
PROJECT: {
|
PROJECT: {
|
||||||
TYPE_RANCHER: 'local',
|
TYPE_RANCHER: 'local',
|
||||||
|
TYPE_ACTIVE_DIRECTORY_USER: 'activedirectory_user',
|
||||||
|
TYPE_ACTIVE_DIRECTORY_GROUP: 'activedirectory_group',
|
||||||
TYPE_AZURE_USER: 'azuread_user',
|
TYPE_AZURE_USER: 'azuread_user',
|
||||||
TYPE_AZURE_GROUP: 'azuread_group',
|
TYPE_AZURE_GROUP: 'azuread_group',
|
||||||
TYPE_GITHUB_USER: 'github_user',
|
TYPE_GITHUB_USER: 'github_user',
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,32 @@ accountsPage:
|
||||||
modal:
|
modal:
|
||||||
password: Change Password
|
password: Change Password
|
||||||
|
|
||||||
|
appDetailPage:
|
||||||
|
header: "App: {appName}"
|
||||||
|
output:
|
||||||
|
title: Launch Output
|
||||||
|
detail: TBD
|
||||||
|
workloads:
|
||||||
|
title: Workloads
|
||||||
|
detail: Workloads created for this application.
|
||||||
|
nodata: No workloads were created for this application.
|
||||||
|
ingress:
|
||||||
|
title: Ingress Rules
|
||||||
|
detail: Ingress rules created for this application.
|
||||||
|
nodata: No ingress rules were created for this application.
|
||||||
|
services:
|
||||||
|
title: Services
|
||||||
|
detail: Services created with this application
|
||||||
|
nodata: No services were created for this application.
|
||||||
|
volumes:
|
||||||
|
title: Volumes
|
||||||
|
detail: Persistant Volume claims created with this application
|
||||||
|
nodata: No volume claims were made for this application.
|
||||||
|
secrets:
|
||||||
|
title: Secrets
|
||||||
|
detail: Secrets associated with this application
|
||||||
|
nodata: This application has no secrets
|
||||||
|
|
||||||
podSecurityPoliciesPage:
|
podSecurityPoliciesPage:
|
||||||
index:
|
index:
|
||||||
header: Pod Security Policies
|
header: Pod Security Policies
|
||||||
|
|
@ -311,8 +337,6 @@ authPage:
|
||||||
buttonText:
|
buttonText:
|
||||||
pre: Authenticate with IDP
|
pre: Authenticate with IDP
|
||||||
post: Waiting to hear back from IDP
|
post: Waiting to hear back from IDP
|
||||||
|
|
||||||
|
|
||||||
providerName:
|
providerName:
|
||||||
shibboleth: Shibboleth
|
shibboleth: Shibboleth
|
||||||
root:
|
root:
|
||||||
|
|
@ -323,33 +347,32 @@ authPage:
|
||||||
header:
|
header:
|
||||||
enabled:
|
enabled:
|
||||||
label: "{github} is enabled"
|
label: "{github} is enabled"
|
||||||
required: "{appName} is configured to allow access to authorized users and organizations."
|
# required: "{appName} is configured to allow access to authorized users and organizations."
|
||||||
restricted: "{appName} is configured to allow access to project members, authorized users and organizations."
|
# restricted: "{appName} is configured to allow access to project members, authorized users and organizations."
|
||||||
# required: |
|
required: |
|
||||||
# {appName} is configured to allow access to {orgs, plural,
|
{appName} is configured to allow access to {orgs, plural,
|
||||||
# =0 {no organizations}
|
=0 {no organizations}
|
||||||
# =1 {# organization}
|
=1 {# organization}
|
||||||
# other {# organizations}
|
other {# organizations}
|
||||||
# } and {users, plural,
|
} and {users, plural,
|
||||||
# =0 {no users}
|
=0 {no users}
|
||||||
# =1 {# user}
|
=1 {# user}
|
||||||
# other {# users}
|
other {# users}
|
||||||
# }.
|
}.
|
||||||
# restricted: |
|
restricted: |
|
||||||
# {appName} is configured to allow access to project members, {orgs, plural,
|
{appName} is configured to allow access to project members, {orgs, plural,
|
||||||
# =0 {no organizations}
|
=0 {no organizations}
|
||||||
# =1 {# organization}
|
=1 {# organization}
|
||||||
# other {# organizations}
|
other {# organizations}
|
||||||
# } and {users, plural,
|
} and {users, plural,
|
||||||
# =0 {no users}
|
=0 {no users}
|
||||||
# =1 {# user}
|
=1 {# user}
|
||||||
# other {# users}
|
other {# users}
|
||||||
# }.
|
}.
|
||||||
# unrestricted: "{appName} is configured to allow access to any {github} user."
|
# unrestricted: "{appName} is configured to allow access to any {github} user."
|
||||||
disabled:
|
disabled:
|
||||||
label: GitHub is not configured
|
label: GitHub is not configured
|
||||||
warning: "{appName} can be configured to restrict access to a set of GitHub users and organization members."
|
warning: "{appName} can be configured to restrict access to a set of GitHub users and organization members."
|
||||||
|
|
||||||
authenticated:
|
authenticated:
|
||||||
header:
|
header:
|
||||||
text: Authentication
|
text: Authentication
|
||||||
|
|
@ -398,7 +421,6 @@ authPage:
|
||||||
buttonText:
|
buttonText:
|
||||||
pre: Authenticate with GitHub
|
pre: Authenticate with GitHub
|
||||||
post: Waiting to hear back from GitHub
|
post: Waiting to hear back from GitHub
|
||||||
|
|
||||||
azuread:
|
azuread:
|
||||||
header:
|
header:
|
||||||
enabled: 'Azure AD Authentication is <b>enabled</b>'
|
enabled: 'Azure AD Authentication is <b>enabled</b>'
|
||||||
|
|
@ -439,8 +461,6 @@ authPage:
|
||||||
label: Login Password
|
label: Login Password
|
||||||
pre: Authenticate with Azure
|
pre: Authenticate with Azure
|
||||||
post: Waiting to hear back from Azure
|
post: Waiting to hear back from Azure
|
||||||
|
|
||||||
|
|
||||||
localAuth:
|
localAuth:
|
||||||
header:
|
header:
|
||||||
enabled: 'Local Authentication is enabled'
|
enabled: 'Local Authentication is enabled'
|
||||||
|
|
@ -652,6 +672,7 @@ ingressPage:
|
||||||
header: 'Ingress: {name}'
|
header: 'Ingress: {name}'
|
||||||
table:
|
table:
|
||||||
noMatch: No ingresses match the current search.
|
noMatch: No ingresses match the current search.
|
||||||
|
noData: You do not have any ingress rules yet.
|
||||||
containerPage:
|
containerPage:
|
||||||
header: 'Container: {name}'
|
header: 'Container: {name}'
|
||||||
portsTab:
|
portsTab:
|
||||||
|
|
@ -4162,6 +4183,7 @@ newCatalog:
|
||||||
maintainer: "Maintainer:"
|
maintainer: "Maintainer:"
|
||||||
newNamespace: New Namespace
|
newNamespace: New Namespace
|
||||||
newApp: New Application
|
newApp: New Application
|
||||||
|
appInfo: Application Read Me
|
||||||
noConfig: This template has no configuration options
|
noConfig: This template has no configuration options
|
||||||
official: Officially Certified
|
official: Officially Certified
|
||||||
preview: Preview
|
preview: Preview
|
||||||
|
|
@ -4945,7 +4967,7 @@ upgradeBtn:
|
||||||
version:
|
version:
|
||||||
current: 'Current'
|
current: 'Current'
|
||||||
status:
|
status:
|
||||||
none: 'None'
|
none: 'Upgrade: None'
|
||||||
loading: 'Checking upgrades...'
|
loading: 'Checking upgrades...'
|
||||||
current: 'Up to date'
|
current: 'Up to date'
|
||||||
available: 'Upgrade available'
|
available: 'Upgrade available'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue