mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
fix(ui): kubernetes-consistent-styling EE-3820 (#7425)
This commit is contained in:
parent
b67f404d8d
commit
36c93c7f57
80 changed files with 713 additions and 548 deletions
|
@ -6,7 +6,6 @@
|
|||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'server'" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span>
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
|
@ -162,15 +161,19 @@
|
|||
<a
|
||||
ng-if="item.Status === 'Running' && $ctrl.useServerMetrics"
|
||||
ui-sref="kubernetes.applications.application.stats({ pod: item.PodName, container: item.Name })"
|
||||
style="margin-right: 10px"
|
||||
class="vertical-center mr-1"
|
||||
>
|
||||
<pr-icon icon="'pie-chart'" class="mr-1" feather="true"></pr-icon>Stats
|
||||
<pr-icon icon="'bar-chart'" feather="true"></pr-icon>Stats
|
||||
</a>
|
||||
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })">
|
||||
<pr-icon icon="'file-text'" class="mr-1" feather="true"></pr-icon>Logs
|
||||
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })" class="vertical-center mr-1">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon>Logs
|
||||
</a>
|
||||
<a ng-if="item.Status === 'Running'" ui-sref="kubernetes.applications.application.console({ pod: item.PodName, container: item.Name })" style="margin-left: 10px">
|
||||
<pr-icon icon="'terminal'" class="mr-1" feather="true"></pr-icon>Console
|
||||
<a
|
||||
ng-if="item.Status === 'Running'"
|
||||
ui-sref="kubernetes.applications.application.console({ pod: item.PodName, container: item.Name })"
|
||||
class="vertical-center mr-1"
|
||||
>
|
||||
<pr-icon icon="'terminal'" feather="true"></pr-icon>Console
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<div class="published-url-container">
|
||||
<div class="text-muted"> Published URL </div>
|
||||
<a ng-href="{{ $ctrl.publishedUrl }}" target="_blank" class="publish-url-link"> <i class="fa fa-external-link-alt" aria-hidden="true"></i> {{ $ctrl.publishedUrl }} </a>
|
||||
<a ng-href="{{ $ctrl.publishedUrl }}" target="_blank" class="publish-url-link vertical-center">
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
{{ $ctrl.publishedUrl }}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
Applications
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
@ -105,10 +105,10 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem" authorization="K8sAccessSystemNamespaces">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<span> System resources are hidden, this can be changed in the table settings. </span>
|
||||
<div class="flex flex-row w-full" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<!-- title -->
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'repeat'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-dataflow'" class-name="'[&>*]:mr-0.5'"></pr-icon>
|
||||
</div>
|
||||
Port mappings
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[300px]">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'icon !h-3'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
@ -77,8 +77,8 @@
|
|||
</div>
|
||||
<!-- info text -->
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon'"></pr-icon>
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
|
@ -162,7 +162,7 @@
|
|||
</span>
|
||||
</span>
|
||||
<!-- Internal -->
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.CLUSTER_IP"> <i class="fa fa-list-alt mr-0.5" aria-hidden="true"></i> ClusterIP </span>
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.CLUSTER_IP"> <pr-icon icon="'list'" feather="true"></pr-icon> ClusterIP </span>
|
||||
<!-- Cluster -->
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.NODE_PORT"> <pr-icon icon="'list'" feather="true" class-name="'icon'"></pr-icon> NodePort </span>
|
||||
</td>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon mt-2" aria-hidden="true"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -88,9 +88,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- info text -->
|
||||
<div class="flex flex-row">
|
||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -90,7 +90,7 @@
|
|||
</div>
|
||||
<div ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem" class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'!mb-0.5'" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'rotate-ccw'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-clockrewind'" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<div class="datatable">
|
||||
<rd-widget>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBar !gap-3">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
</div>
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||
<pr-icon icon="'search'" feather="true" class="vertical-center"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-laptopcode'"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="searchBar min-w-[260px]">
|
||||
<pr-icon icon="'search'" class="vertical-center" class-name="'searchIcon'" feather="true"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="settings vertical-center">
|
||||
<div class="searchBar">
|
||||
<pr-icon icon="'search'" class="vertical-center" feather="true"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput ml-1"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">
|
||||
<span uib-dropdown-toggle><pr-icon icon="'more-vertical'" feather="true"></pr-icon></span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
|
|
|
@ -3,7 +3,6 @@ angular.module('portainer.kubernetes').component('kubernetesNodeApplicationsData
|
|||
controller: 'KubernetesNodeApplicationsDatatableController',
|
||||
bindings: {
|
||||
titleText: '@',
|
||||
titleIcon: '@',
|
||||
dataset: '<',
|
||||
tableKey: '@',
|
||||
orderBy: '@',
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" feather="true"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for a node..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="settings">
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="setting vertical-center"
|
||||
ng-class="{ 'setting-active': $ctrl.settings.open }"
|
||||
|
@ -132,7 +131,9 @@
|
|||
ng-click="$ctrl.changeOrderBy('IPAddress')"
|
||||
></table-column-header>
|
||||
</th>
|
||||
<th ng-if="$ctrl.useServerMetrics"> Actions </th>
|
||||
<th ng-if="$ctrl.useServerMetrics">
|
||||
<table-column-header col-title="'Actions'" can-sort="false"></table-column-header>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -154,7 +155,7 @@
|
|||
<td>{{ item.Version }}</td>
|
||||
<td>{{ item.IPAddress }}</td>
|
||||
<td ng-if="$ctrl.useServerMetrics">
|
||||
<a ui-sref="kubernetes.cluster.node.stats({ name: item.Name })" style="cursor: pointer"> <i class="fa fa-chart-area" aria-hidden="true"></i> Stats </a>
|
||||
<a ui-sref="kubernetes.cluster.node.stats({ name: item.Name })" class="vertical-center"> <pr-icon icon="'bar-chart'" feather="true"></pr-icon> Stats </a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="!$ctrl.dataset">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
|
@ -13,7 +13,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for a namespace"
|
||||
placeholder="Search for a namespace..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
data-cy="k8sNamespace-namespaceSearchInput"
|
||||
|
@ -68,7 +68,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,9 +82,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'!mb-0.5'" mode="'primary'"></pr-icon>
|
||||
<div class="flex flex-row w-full" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<rd-widget>
|
||||
<div class="toolBar px-5 pt-5">
|
||||
<div class="toolBarTitle">
|
||||
<div class="toolBarTitle vertical-center text-[16px] font-medium">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'svg-helm'"></pr-icon>
|
||||
</div>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<div class="form-group nomargin" ng-show="addUserHelmRepoForm.repo.$invalid">
|
||||
<div class="small">
|
||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
||||
<p class="vertical-center" ng-message="pattern"
|
||||
<p class="vertical-center text-muted" ng-message="pattern"
|
||||
><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> A valid URL beginning with http(s) is required.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@
|
|||
<div class="form-group nomargin" ng-show="$ctrl.doesRepoExist()">
|
||||
<div class="small">
|
||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
||||
<p class="vertical-center"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Helm repo already exists.</p>
|
||||
<p class="vertical-center text-muted"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Helm repository already exists.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
src="$ctrl.model.icon"
|
||||
fallback-icon="'svg-helm'"
|
||||
class-name="'blocklist-item-logo h-16 w-auto'"
|
||||
fallback-class-name="'icon-nested-blue !h-12 !w-12'"
|
||||
fallback-class-name="'icon-nested-blue !h-12 !w-12 [&>*]:!h-8 [&>*]:!w-auto'"
|
||||
fallback-mode="'primary'"
|
||||
size="'xl'"
|
||||
></fallback-image>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
placeholder="Search for a chart..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
|
|
|
@ -31,8 +31,7 @@ export default class HelmTemplatesController {
|
|||
};
|
||||
}
|
||||
|
||||
editorUpdate(content) {
|
||||
const contentvalues = content.getValue();
|
||||
editorUpdate(contentvalues) {
|
||||
if (this.state.originalvalues === contentvalues) {
|
||||
this.state.isEditorDirty = false;
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<p class="inline-flex flex-row items-center">
|
||||
<pr-icon icon="'info'" feather="true" class="mr-1 vertical-center" mode="'primary'"></pr-icon>
|
||||
This is a first version for Helm charts, for more information see this <a
|
||||
class="text-blue-8 hover:underline hover:text-blue-8"
|
||||
class="hyperlink"
|
||||
href="https://www.portainer.io/blog/portainer-now-with-helm-support"
|
||||
target="_blank"
|
||||
>blog post</a
|
||||
|
@ -132,11 +132,14 @@
|
|||
yml="true"
|
||||
placeholder="# Define or paste the content of your values yaml file here"
|
||||
>
|
||||
<editor-description>
|
||||
You can get more information about Helm values file format in the
|
||||
<a href="https://helm.sh/docs/chart_template_guide/values_files/" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline"
|
||||
>official documentation</a
|
||||
>.
|
||||
<editor-description class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<span>
|
||||
You can get more information about Helm values file format in the
|
||||
<a href="https://helm.sh/docs/chart_template_guide/values_files/" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline"
|
||||
>official documentation</a
|
||||
>.
|
||||
</span>
|
||||
</editor-description>
|
||||
</web-editor-form>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<ng-form name="serviceForm">
|
||||
<div ng-if="$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
||||
<a ui-sref="kubernetes.cluster.setup">here</a> to configure load balancer.
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
||||
<a class="hyperlink" ui-sref="kubernetes.cluster.setup">here</a> to configure load balancer.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, contract your administrator.
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> No Load balancer is available in this cluster, contact your administrator.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -18,16 +18,16 @@
|
|||
$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT
|
||||
"
|
||||
>
|
||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5">
|
||||
<label class="control-label text-left">Published ports</label>
|
||||
<span class="label label-default interactive ml-10 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5 vertical-center">
|
||||
<label class="control-label text-left !pt-0">Published ports</label>
|
||||
<span class="label label-default interactive ml-2.5 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> publish a new port
|
||||
</span>
|
||||
</div>
|
||||
<div ng-repeat="servicePort in $ctrl.servicePorts" class="mt-5 service-form row">
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">container port</span>
|
||||
<span class="input-group-addon required">Container port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -47,17 +47,21 @@
|
|||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.targetPort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This container port is already used.
|
||||
</div>
|
||||
<div class="small mt-1" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<div class="small mt-1 text-muted" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p
|
||||
>
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p
|
||||
>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">service port</span>
|
||||
<span class="input-group-addon required">Service port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -76,11 +80,15 @@
|
|||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.servicePort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This service port is already used.
|
||||
</div>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['service_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number must be inside the range 1-65535.</p
|
||||
>
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number must be inside the range 1-65535.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -88,7 +96,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">nodeport</span>
|
||||
<span class="input-group-addon required">Nodeport</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -97,20 +105,22 @@
|
|||
placeholder="30080"
|
||||
ng-min="30000"
|
||||
ng-max="32767"
|
||||
required
|
||||
ng-change="$ctrl.onChangeNodePort()"
|
||||
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
||||
<p ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
<p ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -120,7 +130,7 @@
|
|||
</div>
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">loadbalancer port</span>
|
||||
<span class="input-group-addon">Loadbalancer port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -138,7 +148,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">ingress</span>
|
||||
<span class="input-group-addon">Ingress</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="ingress_port_{{ $index }}"
|
||||
|
@ -152,9 +162,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-5">
|
||||
<div class="small mt-5 text-muted">
|
||||
<div ng-messages="serviceForm['ingress_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress selection is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress selection is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -162,7 +172,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">hostname</span>
|
||||
<span class="input-group-addon">Hostname</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="hostname_port_{{ $index }}"
|
||||
|
@ -176,9 +186,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['hostname_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Host is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Hostname is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -186,7 +196,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3 clear-both" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">route</span>
|
||||
<span class="input-group-addon">Route</span>
|
||||
<input
|
||||
class="form-control"
|
||||
name="ingress_route_{{ $index }}"
|
||||
|
@ -199,10 +209,10 @@
|
|||
/>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['ingress_route_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Route is required.</p>
|
||||
<p ng-message="pattern"
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Route is required.</p>
|
||||
<p class="vertical-center" ng-message="pattern"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphanumeric characters or the special characters: '-', '_'
|
||||
or '/'. It must start and end with an alphanumeric character (e.g. 'my-route', or 'route-123').</p
|
||||
>
|
||||
|
@ -236,7 +246,7 @@
|
|||
<button
|
||||
ng-disabled="$ctrl.servicePorts.length === 1"
|
||||
ng-show="!$ctrl.multiItemDisable"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-sm btn-dangerlight btn-only-icon"
|
||||
type="button"
|
||||
ng-click="$ctrl.removePort($index)"
|
||||
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
||||
|
|
|
@ -9,13 +9,7 @@
|
|||
ng-options="item.typeValue as item.typeName for item in $ctrl.state.serviceType"
|
||||
data-cy="k8sAppCreate-publishingModeDropdown"
|
||||
></select>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-default vertical-center"
|
||||
style="margin-left: 0"
|
||||
ng-click="$ctrl.addEntry( $ctrl.state.selected )"
|
||||
data-cy="k8sAppCreate-createServiceButton"
|
||||
>
|
||||
<button type="button" class="btn btn-md btn-default vertical-center !ml-0" ng-click="$ctrl.addEntry( $ctrl.state.selected )" data-cy="k8sAppCreate-createServiceButton">
|
||||
<pr-icon icon="'plus'" size="'sm'" feather="true"></pr-icon> Create service
|
||||
</button>
|
||||
</div>
|
||||
|
@ -25,8 +19,10 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 20px" ng-repeat="service in $ctrl.formValues.Services">
|
||||
<div ng-if="!$ctrl.formValues.Services[$index].Ingress">
|
||||
<div class="text-muted">
|
||||
<i class="{{ $ctrl.iconStyle(service.Type) }}" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<div class="text-muted vertical-center">
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'ClusterIP'" icon="'list'" feather="true"></pr-icon>
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'LoadBalancer'" icon="'svg-dataflow'"></pr-icon>
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'NodePort'" icon="'list'" feather="true"></pr-icon>
|
||||
{{ $ctrl.serviceType(service.Type) }}
|
||||
</div>
|
||||
<kube-services-item-view
|
||||
|
@ -50,17 +46,17 @@
|
|||
|
||||
<div ng-if="$ctrl.formValues.Services[$index].Ingress && $ctrl.formValues.OriginalIngresses.length === 0">
|
||||
<div class="text-muted">
|
||||
<i class="fa fa-route" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-route'" class-name="'mr-0.5'"></pr-icon>
|
||||
Ingress
|
||||
</div>
|
||||
<div ng-if="$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress is not configured in this namespace, select another namespace or click
|
||||
<a ui-sref="kubernetes.cluster.setup">here</a> to configure ingress.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress is not configured in this namespace, select another namespace or contact your
|
||||
administrator.
|
||||
</p>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="$ctrl.formValues.IsSimple">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true" class="vertical-center"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Switch to advanced mode to copy and paste multiple key/values
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true" class="vertical-center"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Generate a configuration entry per line, use YAML format
|
||||
</div>
|
||||
</div>
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
<div ng-repeat="(index, entry) in $ctrl.formValues.Data" ng-if="$ctrl.formValues.IsSimple">
|
||||
<div class="form-group">
|
||||
<label for="configuration_data_key_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Key</label>
|
||||
<label for="configuration_data_key_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Key</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -76,7 +76,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && !entry.IsBinary">
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Value</label>
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Value</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<textarea
|
||||
class="form-control"
|
||||
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && entry.IsBinary">
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Value</label>
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Value</label>
|
||||
<div class="col-sm-8 control-label small text-muted text-left"
|
||||
>Binary data <portainer-tooltip message="'This key holds binary data and cannot be displayed.'"></portainer-tooltip
|
||||
></div>
|
||||
|
@ -117,15 +117,23 @@
|
|||
<pr-icon class="vertical-center" icon="'trash-2'" feather="true"></pr-icon> Remove entry
|
||||
</button>
|
||||
<span class="small text-muted" ng-if="entry.Used">
|
||||
<pr-icon icon="'alert-circle'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
This key is currently used by one or more applications
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<div class="form-group !px-[15px]" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<input type="text" ng-model="$ctrl.formValues.DataYaml" required style="display: none" />
|
||||
<code-editor identifier="kubernetes-configuration-editor" value="$ctrl.formValues.DataYaml" read-only="false" yml="true" on-change="($ctrl.editorUpdate)"></code-editor>
|
||||
|
||||
<web-editor-form
|
||||
identifier="kubernetes-configuration-editor"
|
||||
value="$ctrl.formValues.DataYaml"
|
||||
on-change="($ctrl.editorUpdate)"
|
||||
yml="true"
|
||||
placeholder="# Define or paste key-value pairs, one pair per line"
|
||||
>
|
||||
</web-editor-form>
|
||||
</div>
|
||||
</ng-form>
|
||||
|
|
|
@ -43,15 +43,15 @@ class KubernetesConfigurationDataController {
|
|||
this.onChangeKey();
|
||||
}
|
||||
|
||||
async editorUpdateAsync(cm) {
|
||||
if (this.formValues.DataYaml !== cm.getValue()) {
|
||||
this.formValues.DataYaml = cm.getValue();
|
||||
async editorUpdateAsync(value) {
|
||||
if (this.formValues.DataYaml !== value) {
|
||||
this.formValues.DataYaml = value;
|
||||
this.isEditorDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
editorUpdate(cm) {
|
||||
return this.$async(this.editorUpdateAsync, cm);
|
||||
editorUpdate(value) {
|
||||
return this.$async(this.editorUpdateAsync, value);
|
||||
}
|
||||
|
||||
async onFileLoadAsync(event) {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-12 form-section-title"> Resource reservation </div>
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
<p>
|
||||
{{ $ctrl.description }}
|
||||
</p>
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
{{ $ctrl.description }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.memoryLimit !== 0">
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<div>
|
||||
<code-editor identifier="application-details-yaml" read-only="true" value="$ctrl.data"></code-editor>
|
||||
<div class="p-5">
|
||||
<web-editor-form
|
||||
identifier="application-details-yaml"
|
||||
value="$ctrl.data"
|
||||
yml="true"
|
||||
placeholder="# Define or paste the content of your manifest here"
|
||||
read-only="true"
|
||||
hide-title="true"
|
||||
>
|
||||
</web-editor-form>
|
||||
<div class="py-5">
|
||||
<span class="btn btn-light btn-sm" ng-click="$ctrl.copyYAML()">
|
||||
<pr-icon class="vertical-center" icon="'copy'" feather="true"></pr-icon>
|
||||
Copy to clipboard
|
||||
</span>
|
||||
<span class="btn btn-light btn-sm space-left" ng-click="$ctrl.toggleYAMLInspectorExpansion()">
|
||||
<span class="btn btn-light btn-sm space-left !ml-0" ng-click="$ctrl.toggleYAMLInspectorExpansion()">
|
||||
<pr-icon class="vertical-center" icon="'minus'" size="'sm'" ng-if="$ctrl.expanded" feather="true"></pr-icon>
|
||||
<pr-icon class="vertical-center" icon="'plus'" size="'sm'" ng-if="!$ctrl.expanded" feather="true"></pr-icon>
|
||||
{{ $ctrl.expanded ? 'Collapse' : 'Expand' }}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="$ctrl.actionInProgress || $ctrl.form.$invalid || !$ctrl.formValues.Title || !$ctrl.formValues.FileContent"
|
||||
ng-click="$ctrl.submitAction()"
|
||||
button-spinner="$ctrl.actionInProgress"
|
||||
|
|
|
@ -63,9 +63,9 @@ angular
|
|||
return function (value) {
|
||||
switch (value) {
|
||||
case KubernetesApplicationDataAccessPolicies.ISOLATED:
|
||||
return 'fa-cubes';
|
||||
return 'svg-cubes';
|
||||
case KubernetesApplicationDataAccessPolicies.SHARED:
|
||||
return 'fa-cube';
|
||||
return 'box';
|
||||
}
|
||||
};
|
||||
})
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Note: adding this registry will expose the registry credentials to all users of this namespace
|
||||
Adding this registry will expose the registry credentials to all users of this namespace.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</kubernetes-applications-datatable>
|
||||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center"> <pr-icon icon="'repeat'" feather="true"></pr-icon> Port mappings </uib-tab-heading>
|
||||
<uib-tab-heading class="vertical-center"> <pr-icon icon="'svg-dataflow'"></pr-icon> Port mappings </uib-tab-heading>
|
||||
<kubernetes-applications-ports-datatable dataset="ctrl.state.ports" table-key="kubernetes.applications.ports" order-by="Name" refresh-callback="ctrl.getApplications">
|
||||
</kubernetes-applications-ports-datatable>
|
||||
</uib-tab>
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
title="'Edit application'"
|
||||
breadcrumbs="[
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{
|
||||
{
|
||||
label:ctrl.application.ResourcePool,
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
linkParams:{ id: ctrl.application.ResourcePool }
|
||||
},
|
||||
{ label:'Applications', link:'kubernetes.applications' },
|
||||
{
|
||||
{
|
||||
label:ctrl.application.Name,
|
||||
link: 'kubernetes.applications.application',
|
||||
link: 'kubernetes.applications.application',
|
||||
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
||||
},
|
||||
'Edit',
|
||||
|
@ -97,10 +97,12 @@
|
|||
>
|
||||
<editor-description>
|
||||
<span class="text-muted small" ng-show="ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that not
|
||||
all the Compose format options are supported by Kompose at the moment.
|
||||
<span>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that
|
||||
not all the Compose format options are supported by Kompose at the moment.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
You can get more information about Compose file format in the
|
||||
|
@ -108,8 +110,8 @@
|
|||
</p>
|
||||
</span>
|
||||
<span class="text-muted small" ng-show="!ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -124,7 +126,7 @@
|
|||
<div class="col-sm-12 form-section-title"> Application </div>
|
||||
<!-- #region NAME FIELD -->
|
||||
<div class="form-group">
|
||||
<label for="application_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
||||
<label for="application_name" class="col-sm-3 col-lg-2 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -142,17 +144,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.application_name.$invalid || ctrl.state.alreadyExists">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p>
|
||||
<p ng-message="pattern">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<div class="small">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8" ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||
<p class="text-muted vertical-center" ng-message="required"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p
|
||||
>
|
||||
<p class="text-muted vertical-center" ng-message="pattern">
|
||||
<pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This field must consist of lower case alphanumeric characters or '-', contain at most 63 characters, start with an alphabetic character, and end with an
|
||||
alphanumeric character (e.g. 'my-name', or 'abc-123').
|
||||
</p>
|
||||
</div>
|
||||
<p ng-if="ctrl.state.alreadyExists">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<p class="text-muted vertical-center" ng-if="ctrl.state.alreadyExists">
|
||||
<pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
An application with the same name already exists inside the selected namespace.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -166,8 +171,8 @@
|
|||
model="ctrl.formValues.ImageModel"
|
||||
ng-if="ctrl.formValues.ResourcePool"
|
||||
auto-complete="false"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
label-class="col-sm-3 col-lg-2"
|
||||
input-class="col-sm-8"
|
||||
namespace="ctrl.formValues.ResourcePool.Namespace.Name"
|
||||
endpoint="ctrl.endpoint"
|
||||
is-admin="ctrl.isAdmin"
|
||||
|
@ -182,8 +187,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Stack </div>
|
||||
<!-- #region STACK -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer can automatically bundle multiple applications inside a stack. Enter a name of a new stack or select an existing stack in the list. Leave empty to
|
||||
use the application name.
|
||||
</div>
|
||||
|
@ -209,8 +214,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Environment </div>
|
||||
<!-- #region ENVIRONMENT VARIABLES -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Environment variables</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Environment variables</label>
|
||||
<span
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
class="label label-default interactive vertical-center"
|
||||
|
@ -227,7 +232,7 @@
|
|||
<div style="margin-top: 2px">
|
||||
<div class="col-sm-4 input-group input-group-sm">
|
||||
<div class="input-group col-sm-12 input-group-sm" ng-class="{ striked: envVar.NeedsDeletion }">
|
||||
<span class="input-group-addon">name</span>
|
||||
<span class="input-group-addon required">name</span>
|
||||
<input
|
||||
type="text"
|
||||
name="environment_variable_name_{{ $index }}"
|
||||
|
@ -257,7 +262,12 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-2 input-group input-group-sm" ng-if="ctrl.formValues.Containers.length <= 1">
|
||||
<button ng-if="!envVar.NeedsDeletion" class="btn btn-md btn-light btn-only-icon" type="button" ng-click="ctrl.removeEnvironmentVariable(envVar)">
|
||||
<button
|
||||
ng-if="!envVar.NeedsDeletion"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.removeEnvironmentVariable(envVar)"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
|
@ -277,7 +287,7 @@
|
|||
ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<div class="col-sm-4 input-group input-group-sm">
|
||||
<div class="col-sm-8 input-group input-group-sm">
|
||||
<div
|
||||
class="small"
|
||||
style="margin-top: 5px"
|
||||
|
@ -287,19 +297,19 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['environment_variable_name_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Environment variable name is required.</p>
|
||||
<p ng-message="pattern"
|
||||
<p ng-message="required" class="text-muted vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true" class-="vertical-center"></pr-icon> Environment variable name is required.</p
|
||||
>
|
||||
<p ng-message="pattern" class="text-muted vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphabetic characters, digits, '_', '-',
|
||||
or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1'.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined"
|
||||
<p class="text-muted vertical-center" ng-if="ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This environment variable is already defined.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 input-group input-group-sm"></div>
|
||||
<div class="col-sm-2 input-group input-group-sm"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -309,8 +319,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Configurations </div>
|
||||
<!-- #region CONFIGURATIONS -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Configurations</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Configurations</label>
|
||||
<span
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
|
@ -321,8 +331,8 @@
|
|||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add configuration
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will automatically expose all the keys of a configuration as environment variables. This behavior can be overridden to filesystem mounts for each
|
||||
key via the override button.
|
||||
</div>
|
||||
|
@ -341,9 +351,9 @@
|
|||
data-cy="k8sAppCreate-addConfigSelect_{{ $index }}"
|
||||
></select>
|
||||
</div>
|
||||
<div class="col-sm-3" style="margin-top: 2px">
|
||||
<div class="col-sm-3">
|
||||
<button
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
class="btn btn-md btn-light vertical-center !ml-0"
|
||||
type="button"
|
||||
ng-if="!config.Overriden"
|
||||
ng-click="ctrl.overrideConfiguration(index)"
|
||||
|
@ -353,7 +363,7 @@
|
|||
<pr-icon icon="'list'" size="'md'" feather="true"></pr-icon> Override
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
class="btn btn-md btn-light vertical-center !ml-0"
|
||||
type="button"
|
||||
ng-if="config.Overriden"
|
||||
ng-click="ctrl.resetConfiguration(index)"
|
||||
|
@ -363,13 +373,13 @@
|
|||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon> Auto
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-dangerlight vertical-center"
|
||||
class="btn btn-md btn-dangerlight vertical-center btn-only-icon h-[34px]"
|
||||
type="button"
|
||||
ng-click="ctrl.removeConfiguration(index)"
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
data-cy="k8sAppCreate-configRemoveButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- no-override -->
|
||||
|
@ -390,16 +400,16 @@
|
|||
<div ng-repeat="(keyIndex, overridenKey) in config.OverridenKeys" style="margin-top: 2px">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-lg-2 form-group !m-0"><span> </span></div>
|
||||
<div class="col-sm-3 form-group" style="margin-left: -11px">
|
||||
<div class="col-sm-3 form-group !mr-1" style="margin-left: -11px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">configuration key</span>
|
||||
<input type="text" class="form-control" ng-value="overridenKey.Key" disabled />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 form-group" ng-if="overridenKey.Type === ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.FILESYSTEM">
|
||||
<div class="col-sm-3 form-group !mr-1" ng-if="overridenKey.Type === ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.FILESYSTEM">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">path on disk</span>
|
||||
<span class="input-group-addon required">path on disk</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -428,9 +438,11 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['overriden_key_path_' + index + '_' + keyIndex].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
<p class="vertical-center" ng-message="required"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.configurationPaths.refs[index + '_' + keyIndex] !== undefined"
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.configurationPaths.refs[index + '_' + keyIndex] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already used.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -459,17 +471,17 @@
|
|||
<div class="col-sm-12 form-section-title"> Persisting data </div>
|
||||
<!-- #region PERSISTED FOLDERS -->
|
||||
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
No storage option is available to persist data, contact your administrator to enable a storage option.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<label class="control-label text-left">Persisted folders</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<label class="control-label text-left !pt-0">Persisted folders</label>
|
||||
<span
|
||||
class="label label-default interactive"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
ng-click="ctrl.addPersistedFolder()"
|
||||
ng-if="ctrl.isAddPersistentFolderButtonShowed()"
|
||||
|
@ -480,7 +492,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<span class="small text-muted">
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its storage capacity. Contact your administrator to expand the capacity of the namespace.
|
||||
</span>
|
||||
|
@ -489,7 +501,7 @@
|
|||
<div class="col-sm-12 form-inline" style="margin-top: 10px" ng-repeat="persistedFolder in ctrl.formValues.PersistedFolders">
|
||||
<div style="margin-top: 2px">
|
||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }">
|
||||
<span class="input-group-addon">path in container</span>
|
||||
<span class="input-group-addon required">path in container</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -514,7 +526,7 @@
|
|||
"
|
||||
>
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
class="btn btn-light"
|
||||
ng-model="persistedFolder.UseNewVolume"
|
||||
uib-btn-radio="true"
|
||||
ng-change="ctrl.useNewVolume($index)"
|
||||
|
@ -522,7 +534,7 @@
|
|||
>New volume</label
|
||||
>
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
class="btn btn-light"
|
||||
ng-model="persistedFolder.UseNewVolume"
|
||||
uib-btn-radio="false"
|
||||
ng-change="ctrl.useExistingVolume($index)"
|
||||
|
@ -533,22 +545,23 @@
|
|||
</div>
|
||||
|
||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }" ng-if="persistedFolder.UseNewVolume">
|
||||
<span class="input-group-addon">requested size</span>
|
||||
<span class="input-group-addon required">requested size</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
class="form-control !rounded-none"
|
||||
name="persisted_folder_size_{{ $index }}"
|
||||
ng-model="persistedFolder.Size"
|
||||
placeholder="20"
|
||||
ng-min="0"
|
||||
min="0"
|
||||
required
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
/>
|
||||
<span class="input-group-addon" style="padding: 0">
|
||||
<span class="input-group-addon !p-0 !rounded-r-[5px]">
|
||||
<select
|
||||
class="form-control w-12 !h-[28px] !border-none !rounded-r-[5px] text-xs"
|
||||
ng-model="persistedFolder.SizeUnit"
|
||||
ng-style="{ width: '100%', height: '100%', cursor: ctrl.isEditAndExistingPersistedFolder($index) ? 'not-allowed' : 'auto' }"
|
||||
ng-style="{ height: '100%', cursor: ctrl.isEditAndExistingPersistedFolder($index) ? 'not-allowed' : 'auto' }"
|
||||
ng-options="unit for unit in ctrl.state.availableSizeUnits"
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
|
@ -595,12 +608,12 @@
|
|||
<div ng-if="!ctrl.isEditAndStatefulSet() && !ctrl.state.useExistingVolume[$index] && ctrl.formValues.Containers.length <= 1">
|
||||
<button
|
||||
ng-if="!persistedFolder.NeedsDeletion"
|
||||
class="btn btn-sm btn-danger"
|
||||
class="btn btn-sm btn-dangerlight !ml-0 h-[30px]"
|
||||
type="button"
|
||||
ng-click="ctrl.removePersistedFolder($index)"
|
||||
data-cy="k8sAppCreate-rmPersistentFolderButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
ng-if="persistedFolder.NeedsDeletion"
|
||||
|
@ -616,6 +629,7 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row gap-x-1"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid ||
|
||||
ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined ||
|
||||
|
@ -627,36 +641,36 @@
|
|||
>
|
||||
<div class="input-group col-sm-3 input-group-sm">
|
||||
<div
|
||||
class="small text-warning"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid || ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined"
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already defined.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-2 input-group-sm"></div>
|
||||
|
||||
<div class="input-group col-sm-5 input-group-sm">
|
||||
<div class="input-group col-sm-offset-2 col-sm-3 input-group-sm">
|
||||
<div
|
||||
class="small text-warning"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid || ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Size is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Size is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
You can only request up to
|
||||
{{ ctrl.state.storages.availabilities[persistedFolder.StorageClass.Name] | kubernetesAppStorageRequestSizeHumanReadable }} for
|
||||
|
@ -696,7 +710,7 @@
|
|||
|
||||
<!-- access policy options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div
|
||||
ng-if="
|
||||
(!ctrl.state.isEdit && !ctrl.state.persistedFoldersUseExistingVolumes) ||
|
||||
|
@ -712,7 +726,7 @@
|
|||
/>
|
||||
<label for="data_access_isolated">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Isolated
|
||||
</div>
|
||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
||||
|
@ -734,7 +748,7 @@
|
|||
style="cursor: pointer; border-color: #767676"
|
||||
>
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Isolated
|
||||
</div>
|
||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
||||
|
@ -750,7 +764,7 @@
|
|||
/>
|
||||
<label for="data_access_shared">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'sliders'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
Shared
|
||||
</div>
|
||||
<p>Application will be deployed as a Deployment with a shared storage access</p>
|
||||
|
@ -782,22 +796,22 @@
|
|||
<div class="col-sm-12 form-section-title"> Resource reservations </div>
|
||||
<!-- #region RESOURCE RESERVATIONS -->
|
||||
<div class="form-group" ng-if="!ctrl.state.resourcePoolHasQuota">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Resource reservations are applied per instance of the application.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
A resource quota is set on this namespace, you must specify resource reservations. Resource reservations are applied per instance of the application. Maximums
|
||||
are inherited from the namespace quota.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its resource capacity and you will not be able to deploy the application. Contact your administrator to expand the capacity of
|
||||
the namespace.
|
||||
|
@ -806,22 +820,22 @@
|
|||
|
||||
<!-- memory-limit-input -->
|
||||
<div
|
||||
class="form-group"
|
||||
class="form-group flex"
|
||||
ng-if="
|
||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
||||
"
|
||||
>
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px">
|
||||
Memory
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||
Memory limit (MB)
|
||||
<portainer-tooltip
|
||||
message="'An instance of this application will reserve this amount of memory. If the instance memory usage exceeds the reservation, it might be subject to OOM.'"
|
||||
>
|
||||
</portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-3">
|
||||
<div class="col-sm-6">
|
||||
<slider model="ctrl.formValues.MemoryLimit" floor="ctrl.state.sliders.memory.min" ceil="ctrl.state.sliders.memory.max" step="128"></slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
ng-model="ctrl.formValues.MemoryLimit"
|
||||
|
@ -834,14 +848,12 @@
|
|||
data-cy="k8sAppCreate-memoryLimit"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted" style="margin-top: 7px"> Maximum memory usage (<b>MB</b>) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.memory_limit.$error">
|
||||
<p
|
||||
<p class="vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Value must be between {{ ctrl.state.sliders.memory.min }} and
|
||||
{{ ctrl.state.sliders.memory.max }}
|
||||
</p>
|
||||
|
@ -851,28 +863,26 @@
|
|||
<!-- !memory-limit-input -->
|
||||
<!-- cpu-limit-input -->
|
||||
<div
|
||||
class="form-group"
|
||||
class="form-group flex"
|
||||
ng-if="
|
||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
||||
"
|
||||
>
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px">
|
||||
CPU
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||
CPU limit
|
||||
<portainer-tooltip
|
||||
message="'An instance of this application will reserve this amount of CPU. If the instance CPU usage exceeds the reservation, it might be subject to CPU throttling.'"
|
||||
>
|
||||
</portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-5">
|
||||
<div class="col-sm-8">
|
||||
<slider model="ctrl.formValues.CpuLimit" floor="ctrl.state.sliders.cpu.min" ceil="ctrl.state.sliders.cpu.max" step="0.10" precision="2"></slider>
|
||||
</div>
|
||||
<div class="col-sm-4" style="margin-top: 20px">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.nodeLimitsOverflow()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
These reservations would exceed the resources currently available in the cluster.
|
||||
</div>
|
||||
|
@ -888,7 +898,7 @@
|
|||
|
||||
<!-- deployment options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
|
@ -905,7 +915,7 @@
|
|||
<p>Run one or multiple instances of this container</p>
|
||||
</label>
|
||||
</div>
|
||||
<div style="color: #767676" ng-if="!ctrl.supportGlobalDeployment()">
|
||||
<div ng-if="!ctrl.supportGlobalDeployment()">
|
||||
<input type="radio" id="deployment_global" disabled />
|
||||
<label
|
||||
for="deployment_global"
|
||||
|
@ -913,10 +923,9 @@
|
|||
tooltip-placement="bottom"
|
||||
tooltip-class="portainer-tooltip"
|
||||
uib-tooltip="The storage or access policy used for persisted folders cannot be used with this option"
|
||||
style="cursor: pointer; border-color: #767676"
|
||||
>
|
||||
<div class="boxselector_header">
|
||||
<i class="fa fa-cubes" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Global
|
||||
</div>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the cluster</p>
|
||||
|
@ -933,10 +942,10 @@
|
|||
/>
|
||||
<label for="deployment_global">
|
||||
<div class="boxselector_header">
|
||||
<i class="fa fa-cubes" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Global
|
||||
</div>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the cluster</p>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the sdfh</p>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -945,8 +954,8 @@
|
|||
|
||||
<!-- replica count -->
|
||||
<div class="form-group form-inline" ng-if="ctrl.formValues.DeploymentType === ctrl.ApplicationDeploymentTypes.REPLICATED">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left"> Instance count </label>
|
||||
<div class="col-sm-12 vertical-center">
|
||||
<label class="control-label text-left !pt-0"> Instance count </label>
|
||||
<input
|
||||
type="number"
|
||||
name="replica_count"
|
||||
|
@ -964,10 +973,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="kubernetesApplicationCreationForm['replica_count'].$invalid">
|
||||
<div class="col-sm-12 small">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['replica_count'].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p
|
||||
>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -977,33 +988,37 @@
|
|||
class="form-group"
|
||||
ng-if="!ctrl.resourceReservationsOverflow() && ctrl.formValues.ReplicaCount > 1 && (ctrl.formValues.CpuLimit !== 0 || ctrl.formValues.MemoryLimit !== 0)"
|
||||
>
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
This application will reserve the following resources:
|
||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div>
|
||||
This application will reserve the following resources:
|
||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.resourceReservationsOverflow()">
|
||||
<div class="col-sm-12 small">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This application would exceed available resources. Please review resource reservations or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.storages.quotaExceeded">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This application would exceed available storage. Please review the persisted folders or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="!ctrl.supportScalableReplicaDeployment()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
The following storage option(s) do not support concurrent access from multiples instances: <code>{{ ctrl.getNonScalableStorage() }}</code
|
||||
>. You will not be able to scale that application.
|
||||
<div>
|
||||
The following storage option(s) do not support concurrent access from multiples instances: <code>{{ ctrl.getNonScalableStorage() }}</code
|
||||
>. You will not be able to scale that application.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- #endregion -->
|
||||
|
@ -1013,8 +1028,10 @@
|
|||
|
||||
<div class="form-group" ng-if="ctrl.formValues.DeploymentType !== ctrl.ApplicationDeploymentTypes.GLOBAL && ctrl.state.useServerMetrics">
|
||||
<div class="col-sm-12">
|
||||
<label for="enable_auto_scaling" class="control-label text-left"> Enable auto scaling for this application </label>
|
||||
<label class="switch" style="margin-left: 20px">
|
||||
<div class="col-sm-3 col-lg-2 pl-0 pt-0">
|
||||
<label for="enable_auto_scaling" class="control-label text-left"> Enable auto scaling for this application </label>
|
||||
</div>
|
||||
<label class="switch ml-4 mt-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-control"
|
||||
|
@ -1022,7 +1039,7 @@
|
|||
ng-model="ctrl.formValues.AutoScaler.IsUsed"
|
||||
data-cy="k8sAppCreate-autoScaleCheckbox"
|
||||
/>
|
||||
<i></i>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1137,23 +1154,23 @@
|
|||
|
||||
<!-- #region PLACEMENTS -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Placement rules</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Placement rules</label>
|
||||
<span class="label label-default interactive vertical-center" style="margin-left: 10px" ng-click="ctrl.addPlacement()">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add rule
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 small text-muted" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels.
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div> Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels. </div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 10px">
|
||||
<div ng-repeat-start="placement in ctrl.formValues.Placements" style="margin-top: 2px">
|
||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||
<select
|
||||
class="form-control"
|
||||
class="form-control !rounded"
|
||||
ng-model="placement.Label"
|
||||
ng-options="label as (label.Key | kubernetesNodeLabelHumanReadbleText) for label in ctrl.nodesLabels"
|
||||
ng-change="ctrl.onChangePlacementLabel($index)"
|
||||
|
@ -1164,7 +1181,7 @@
|
|||
</div>
|
||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||
<select
|
||||
class="form-control"
|
||||
class="form-control !rounded"
|
||||
ng-model="placement.Value"
|
||||
ng-options="value for value in placement.Label.Values"
|
||||
ng-disabled="ctrl.isEditAndNotNewPlacement($index)"
|
||||
|
@ -1176,7 +1193,7 @@
|
|||
<div class="col-sm-1 input-group">
|
||||
<button
|
||||
ng-if="!placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.removePlacement($index)"
|
||||
data-cy="k8sAppCreate-deletePlacementButton"
|
||||
|
@ -1185,7 +1202,7 @@
|
|||
</button>
|
||||
<button
|
||||
ng-if="placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-sm btn-light btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.restorePlacement($index)"
|
||||
data-cy="k8sAppCreate-restorePlacementButton"
|
||||
|
@ -1196,8 +1213,8 @@
|
|||
</div>
|
||||
<div ng-repeat-end ng-show="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<div class="col-sm-5 input-group">
|
||||
<div class="small text-warning" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<div class="small text-muted" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This label is already defined.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1218,7 +1235,7 @@
|
|||
|
||||
<!-- placement policy options -->
|
||||
<div class="form-group" style="margin-bottom: 0" ng-if="ctrl.formValues.Placements.length">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
|
@ -1316,7 +1333,7 @@
|
|||
<button
|
||||
ng-if="ctrl.state.appType === ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="!kubernetesApplicationCreationForm.$valid || ctrl.isDeployUpdateButtonDisabled() || !ctrl.imageValidityIsValid()"
|
||||
ng-click="ctrl.deployApplication()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
title="'Application details'"
|
||||
breadcrumbs="[
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{
|
||||
{
|
||||
label:ctrl.application.ResourcePool,
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
linkParams:{ id: ctrl.application.ResourcePool }
|
||||
},
|
||||
{ label:'Applications', link:'kubernetes.applications' },
|
||||
|
@ -24,7 +24,7 @@
|
|||
<rd-widget-body classes="no-padding">
|
||||
<uib-tabset active="ctrl.state.activeTab" justified="true" type="pills">
|
||||
<uib-tab index="0" classes="btn-sm" select="ctrl.selectTab(0)">
|
||||
<uib-tab-heading> <pr-icon icon="'fa-laptop-code'" class-name="'mr-1'"></pr-icon> Application </uib-tab-heading>
|
||||
<uib-tab-heading> <pr-icon icon="'svg-laptopcode'" class-name="'mr-1'"></pr-icon> Application </uib-tab-heading>
|
||||
<div style="padding: 20px">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
|
@ -156,19 +156,19 @@
|
|||
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading>
|
||||
<pr-icon icon="'fa-compress-arrows-alt'"></pr-icon> Placement
|
||||
<pr-icon icon="'svg-compress'"></pr-icon> Placement
|
||||
<div ng-if="ctrl.state.placementWarning" class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
warning
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
<div class="small text-muted vertical-center" style="padding: 20px">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
The placement component helps you understand whether or not this application can be deployed on a specific node.
|
||||
</div>
|
||||
<kubernetes-application-placements-datatable
|
||||
title-text="Placement constraints/preferences"
|
||||
title-icon="fa-compress-arrows-alt"
|
||||
title-icon="svg-compress"
|
||||
dataset="ctrl.placements"
|
||||
table-key="kubernetes.application.placements"
|
||||
order-by="Name"
|
||||
|
@ -180,7 +180,7 @@
|
|||
|
||||
<uib-tab index="2" classes="btn-sm" select="ctrl.selectTab(2)">
|
||||
<uib-tab-heading>
|
||||
<pr-icon icon="'fa-history'"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()" class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
@ -188,7 +188,7 @@
|
|||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="svg-clockrewind"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.application.events"
|
||||
order-by="Date"
|
||||
|
@ -200,7 +200,7 @@
|
|||
|
||||
<uib-tab index="3" ng-if="ctrl.application.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
||||
<uib-tab-heading> <pr-icon icon="'code'" feather="true"></pr-icon> YAML </uib-tab-heading>
|
||||
<div style="padding-right: 25px" ng-if="ctrl.state.showEditorTab">
|
||||
<div class="px-5" ng-if="ctrl.state.showEditorTab">
|
||||
<kubernetes-yaml-inspector key="application-yaml" data="ctrl.application.Yaml"></kubernetes-yaml-inspector>
|
||||
</div>
|
||||
</uib-tab>
|
||||
|
@ -270,14 +270,14 @@
|
|||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'external-link'" class="mr-1" feather="true"></pr-icon>Accessing the application </div>
|
||||
|
||||
<div class="small text-muted" ng-if="ctrl.application.PublishedPorts.length === 0" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is not exposing any port.
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is not exposing any port.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.application.Services.length !== 0">
|
||||
<!-- Services notice -->
|
||||
<div>
|
||||
<div class="small text-muted">
|
||||
<p> <pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is exposed through service(s) as below: </p>
|
||||
<p> <pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is exposed through service(s) as below: </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -298,7 +298,7 @@
|
|||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'move'" class="mr-1" feather="true"></pr-icon>Auto-scaling </div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.AutoScaler" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application does not have an autoscaling policy defined.
|
||||
</div>
|
||||
|
||||
|
@ -333,7 +333,7 @@
|
|||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.Env.length > 0 && !ctrl.hasVolumeConfiguration()" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application is not using any environment variable or configuration.
|
||||
</div>
|
||||
|
||||
|
@ -434,13 +434,14 @@
|
|||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.hasPersistedFolders()">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application has no persisted folders.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.hasPersistedFolders()">
|
||||
<div class="small text-muted" style="margin-bottom: 15px">
|
||||
Data access policy: <i class="fa {{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon }}" aria-hidden="true"></i>
|
||||
<div class="small text-muted vertical-center" style="margin-bottom: 15px">
|
||||
Data access policy:
|
||||
<pr-icon icon="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon" feather="true"></pr-icon>
|
||||
{{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyText }}
|
||||
<portainer-tooltip position="'right'" message="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyTooltip"> </portainer-tooltip>
|
||||
</div>
|
||||
|
@ -456,7 +457,10 @@
|
|||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<a ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName, namespace: ctrl.application.ResourcePool })" data-cy="k8sAppDetail-volClaimName"
|
||||
<a
|
||||
class="hyperlink"
|
||||
ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName, namespace: ctrl.application.ResourcePool })"
|
||||
data-cy="k8sAppDetail-volClaimName"
|
||||
><pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName }}</a
|
||||
>
|
||||
</td>
|
||||
|
@ -491,7 +495,10 @@
|
|||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<a ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName + '-' + container.PodName, namespace: ctrl.application.ResourcePool })">
|
||||
<a
|
||||
class="hyperlink"
|
||||
ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName + '-' + container.PodName, namespace: ctrl.application.ResourcePool })"
|
||||
>
|
||||
<pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName + '-' + container.PodName }}</a
|
||||
>
|
||||
</td>
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
|
@ -56,7 +55,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive border-none">
|
||||
<table class="table table-hover nowrap-cells">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<td>{{ service.spec.clusterIP }}</td>
|
||||
<td ng-show="service.spec.type === 'LoadBalancer'">
|
||||
<div ng-show="service.status.loadBalancer.ingress">
|
||||
<a target="_blank" ng-href="http://{{ service.status.loadBalancer.ingress[0].ip }}:{{ service.spec.ports[0].port }}">
|
||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i>
|
||||
<a class="vertical-center hyperlink" target="_blank" ng-href="http://{{ service.status.loadBalancer.ingress[0].ip }}:{{ service.spec.ports[0].port }}">
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
<span data-cy="k8sAppDetail-containerPort"> Access </span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -32,8 +32,14 @@
|
|||
</td>
|
||||
<td ng-if="!ctrl.portHasIngressRules(port)">
|
||||
<div ng-repeat="port in service.spec.ports">
|
||||
<a ng-if="$ctrl.publicUrl && port.nodePort" ng-href="http://{{ $ctrl.publicUrl }}:{{ port.nodePort }}" target="_blank" style="margin-left: 5px">
|
||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i>
|
||||
<a
|
||||
class="vertical-center hyperlink"
|
||||
ng-if="$ctrl.publicUrl && port.nodePort"
|
||||
ng-href="http://{{ $ctrl.publicUrl }}:{{ port.nodePort }}"
|
||||
target="_blank"
|
||||
style="margin-left: 5px"
|
||||
>
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
<span data-cy="k8sAppDetail-containerPort">
|
||||
{{ port.port }}
|
||||
</span>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="toolBarTitle text-muted small vertical-center px-5 !gap-0">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'!mr-1'" class="vertical-center"></pr-icon>
|
||||
This is a first version for Helm charts, for more information see this
|
||||
<a href="https://www.portainer.io/blog/portainer-now-with-helm-support" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline">blog post</a>.
|
||||
<a href="https://www.portainer.io/blog/portainer-now-with-helm-support" target="_blank" class="hyperlink">blog post</a>.
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<table class="table">
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
title="'Application logs'"
|
||||
breadcrumbs="[
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{
|
||||
{
|
||||
label:ctrl.application.ResourcePool,
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
linkParams:{ id: ctrl.application.ResourcePool }
|
||||
},
|
||||
{ label:'Applications', link:'kubernetes.applications' },
|
||||
{
|
||||
{
|
||||
label:ctrl.application.Name,
|
||||
link: 'kubernetes.applications.application',
|
||||
link: 'kubernetes.applications.application',
|
||||
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
||||
},
|
||||
'Pods',
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||
|
||||
<div ng-if="ctrl.state.viewReady" style="height: 100%">
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
|
@ -75,8 +75,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="height: 54%">
|
||||
<div class="col-sm-12" style="height: 100%">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||
<pre
|
||||
class="log_viewer widget"
|
||||
><div ng-repeat="line in ctrl.state.filteredLogs = (ctrl.applicationLogs | filter:ctrl.state.search) track by $index" class="line" ng-if="line"><p class="inner_line">{{ line }}</p></div><div ng-if="ctrl.applicationLogs.length && !ctrl.state.filteredLogs.length" class="line"><p class="inner_line">No log line matching the '{{ ctrl.state.search }}' filter</p></div><div ng-if="ctrl.applicationLogs.length === 0" class="line"><p class="inner_line">No logs available</p></div></pre>
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
title="'Application stats'"
|
||||
breadcrumbs="[
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{
|
||||
{
|
||||
label:ctrl.state.transition.namespace,
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
link: 'kubernetes.resourcePools.resourcePool',
|
||||
linkParams:{ id: ctrl.state.transition.namespace }
|
||||
},
|
||||
{ label:'Applications', link:'kubernetes.applications' },
|
||||
{
|
||||
{
|
||||
label:ctrl.state.transition.applicationName,
|
||||
link: 'kubernetes.applications.application',
|
||||
link: 'kubernetes.applications.application',
|
||||
linkParams:{ name: ctrl.state.transition.applicationName, namespace: ctrl.state.transition.namespace }
|
||||
},
|
||||
'Pods',
|
||||
|
@ -28,8 +28,8 @@
|
|||
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
||||
<span class="small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Portainer was unable to retrieve any metrics associated to that container. Please contact your administrator to ensure that the Kubernetes metrics feature is properly
|
||||
configured.
|
||||
</span>
|
||||
|
@ -37,7 +37,12 @@
|
|||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-md-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-info-circle" title-text="About statistics"> </rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> About statistics </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
|
@ -57,12 +62,15 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group" ng-if="ctrl.state.networkStatsUnavailable">
|
||||
<div class="col-sm-12">
|
||||
<span class="small text-muted"> <i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true"></i> Network stats are unavailable for this container. </span>
|
||||
<span class="small text-muted">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Network stats are unavailable for this container.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -74,7 +82,12 @@
|
|||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="Memory usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'svg-memory'" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> Memory usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-container" style="position: relative">
|
||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||
|
@ -84,7 +97,12 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12" ng-if="!ctrl.state.networkStatsUnavailable">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="CPU usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'cpu'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> CPU usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-container" style="position: relative">
|
||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<div class="col-sm-12">
|
||||
<kubernetes-nodes-datatable
|
||||
title-text="Nodes"
|
||||
title-icon="fa-hdd"
|
||||
title-icon="hard-drive"
|
||||
dataset="ctrl.nodes"
|
||||
table-key="kubernetes.nodes"
|
||||
order-by="Name"
|
||||
|
|
|
@ -51,19 +51,21 @@
|
|||
<tr>
|
||||
<td class="col-xs-3"> Availability </td>
|
||||
<td class="col-xs-9">
|
||||
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
||||
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
||||
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
||||
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
||||
</select>
|
||||
<span class="small vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot use this action while another node is currently being drained.
|
||||
</span>
|
||||
<span class="small vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot drain a node where this Portainer instance is running.
|
||||
</span>
|
||||
<div class="flex flex-col">
|
||||
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
||||
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
||||
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
||||
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
||||
</select>
|
||||
<div class="small text-muted vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot use this action while another node is currently being drained.
|
||||
</div>
|
||||
<div class="small text-muted vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot drain a node where this Portainer instance is running.
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -126,14 +128,14 @@
|
|||
>
|
||||
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||
</button>
|
||||
<button ng-if="!ctrl.isSystemLabel($index) && label.NeedsDeletion" class="btn btn-sm btn-primary" type="button" ng-click="ctrl.restoreLabel($index)">
|
||||
<button ng-if="!ctrl.isSystemLabel($index) && label.NeedsDeletion" class="btn btn-sm btn-secondary" type="button" ng-click="ctrl.restoreLabel($index)">
|
||||
Restore
|
||||
</button>
|
||||
<span class="label label-warning label-sm image-tag" ng-if="label.IsUsed && !ctrl.isSystemLabel($index)" style="margin-left: 5px">used</span>
|
||||
<span class="label label-info image-tag" ng-if="ctrl.isSystemLabel($index)" style="margin-left: 5px">system</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small mt-2" ng-show="kubernetesNodeUpdateForm['label_key_' + $index].$invalid || ctrl.state.duplicateLabelKeys[$index] !== undefined">
|
||||
<div class="small mt-2 text-muted" ng-show="kubernetesNodeUpdateForm['label_key_' + $index].$invalid || ctrl.state.duplicateLabelKeys[$index] !== undefined">
|
||||
<ng-messages for="kubernetesNodeUpdateForm['label_key_' + $index].$error">
|
||||
<p ng-message="required" class="vertical-center"> <pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Label key is required. </p>
|
||||
</ng-messages>
|
||||
|
@ -179,11 +181,11 @@
|
|||
<button ng-if="!taint.NeedsDeletion" class="btn btn-sm btn-dangerlight btn-only-icon" type="button" ng-click="ctrl.removeTaint($index)">
|
||||
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||
</button>
|
||||
<button ng-if="taint.NeedsDeletion" class="btn btn-sm btn-primary" type="button" ng-click="ctrl.restoreTaint($index)"> Restore </button>
|
||||
<button ng-if="taint.NeedsDeletion" class="btn btn-sm btn-secondary" type="button" ng-click="ctrl.restoreTaint($index)"> Restore </button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="small"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="kubernetesNodeUpdateForm['taint_key_' + $index].$invalid || ctrl.state.duplicateTaintKeys[$index] !== undefined"
|
||||
>
|
||||
|
@ -223,7 +225,7 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading>
|
||||
<div class="flex-center gap-1"> <pr-icon icon="'rotate-ccw'" size="'sm'" feather="true"></pr-icon> Events </div>
|
||||
<div class="flex-center gap-1"> <pr-icon icon="'svg-clockrewind'" size="'sm'" feather="true"></pr-icon> Events </div>
|
||||
<div class="flex-center gap-1" ng-if="ctrl.hasEventWarnings()">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning-alt'" size="'sm'" feather="true"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
@ -231,7 +233,7 @@
|
|||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="icon-nested-blue"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.node.events"
|
||||
order-by="Date"
|
||||
|
@ -264,7 +266,6 @@
|
|||
refresh-callback="ctrl.getApplications"
|
||||
loading="ctrl.state.applicationsLoading"
|
||||
title-text="Applications running on this node"
|
||||
title-icon="box"
|
||||
>
|
||||
</kubernetes-node-applications-datatable>
|
||||
</div>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
title="'Node stats'"
|
||||
breadcrumbs="[
|
||||
{ label:'Cluster', link:'kubernetes.cluster' },
|
||||
{
|
||||
{
|
||||
label:ctrl.state.transition.nodeName,
|
||||
link: 'kubernetes.cluster.node',
|
||||
link: 'kubernetes.cluster.node',
|
||||
linkParams:{name: ctrl.state.transition.nodeName}
|
||||
},
|
||||
ctrl.state.transition.nodeName,
|
||||
|
@ -17,15 +17,20 @@
|
|||
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
||||
<span class="small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'primary'"></pr-icon>
|
||||
Portainer was unable to retrieve any metrics associated to that node. Please contact your administrator to ensure that the Kubernetes metrics feature is properly configured.
|
||||
</span>
|
||||
</information-panel>
|
||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-md-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-info-circle" title-text="About statistics"> </rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> About statistics </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
|
@ -45,7 +50,7 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -57,7 +62,12 @@
|
|||
<div class="row" ng-show="ctrl.state.getMetrics">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="Memory usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'svg-memory'" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> Memory usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-node" style="position: relative">
|
||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||
|
@ -67,7 +77,12 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="CPU usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'cpu'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> CPU usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-node" style="position: relative">
|
||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
<form class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off">
|
||||
<!-- name -->
|
||||
<div class="form-group">
|
||||
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -32,7 +32,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesConfigurationCreationForm.configuration_name.$invalid || ctrl.state.alreadyExist">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 col-lg-9 small text-muted">
|
||||
<div ng-messages="kubernetesConfigurationCreationForm.configuration_name.$error">
|
||||
<p ng-message="required" class="vertical-center"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> This field is required.</p>
|
||||
<p ng-message="pattern" class="vertical-center"
|
||||
|
@ -52,7 +53,7 @@
|
|||
<!-- resource-pool -->
|
||||
<div class="form-group" ng-if="ctrl.formValues.ResourcePool">
|
||||
<label for="resource-pool-selector" class="col-sm-3 col-lg-2 control-label text-left">Namespace</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<select
|
||||
class="form-control"
|
||||
id="resource-pool-selector"
|
||||
|
@ -86,13 +87,13 @@
|
|||
</div>
|
||||
|
||||
<!-- type options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="form-group px-[15px]" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div>
|
||||
<input type="radio" id="type_basic" ng-value="ctrl.KubernetesConfigurationTypes.CONFIGMAP" ng-model="ctrl.formValues.Type" />
|
||||
<label for="type_basic" data-cy="k8sConfigCreate-nonSensitiveButton">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'code'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-filecode'"></pr-icon>
|
||||
ConfigMap
|
||||
</div>
|
||||
<p>This configuration holds non-sensitive information</p>
|
||||
|
@ -102,7 +103,7 @@
|
|||
<input type="radio" id="type_secret" ng-value="ctrl.KubernetesConfigurationTypes.SECRET" ng-model="ctrl.formValues.Type" />
|
||||
<label for="type_secret" data-cy="k8sConfigCreate-sensitiveButton">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'shield'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'lock'" feather="true"></pr-icon>
|
||||
Secret
|
||||
</div>
|
||||
<p>This configuration holds sensitive information</p>
|
||||
|
|
|
@ -60,13 +60,13 @@
|
|||
<pr-icon icon="'svg-clockrewind'"></pr-icon>
|
||||
Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="svg-clockrewind"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.configuration.events"
|
||||
order-by="Date"
|
||||
|
@ -143,9 +143,11 @@
|
|||
<td>
|
||||
<div style="white-space: pre-wrap">{{ item.Value }}</div>
|
||||
<div style="margin-top: 2px">
|
||||
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyConfigurationValue($index)"> <i class="fa fa-copy space-right" aria-hidden="true"></i>Copy </span>
|
||||
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyConfigurationValue($index)">
|
||||
<pr-icon icon="'copy'" feather="true" class-name="'mr-0.5'"></pr-icon>Copy
|
||||
</span>
|
||||
<span id="copyValueNotification_{{ $index }}" style="display: none; color: #23ae89; margin-left: 5px" class="small">
|
||||
<i class="fa fa-check" aria-hidden="true"></i> copied
|
||||
<pr-icon icon="'check'" feather="true"></pr-icon> copied
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
title="'Kubernetes features configuration'"
|
||||
breadcrumbs="[
|
||||
{ label:'Environments', link:'portainer.endpoints' },
|
||||
{
|
||||
{
|
||||
label:ctrl.endpoint.Name,
|
||||
link: 'portainer.endpoints.endpoint',
|
||||
link: 'portainer.endpoints.endpoint',
|
||||
linkParams:{id: ctrl.endpoint.Id}
|
||||
},
|
||||
'Kubernetes configuration'
|
||||
|
@ -34,7 +34,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Allow users to use external load balancer </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Allow users to use external load balancer </label>
|
||||
<label class="switch mb-0 col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.UseLoadBalancer" /><span class="slider round" data-cy="kubeSetup-loadBalancerToggle"></span>
|
||||
</label>
|
||||
|
@ -42,7 +42,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 text-muted small">
|
||||
<div class="col-sm-12 text-muted small mt-4">
|
||||
<p> Configuring ingress controllers will allow users to expose application they deploy over a HTTP route. </p>
|
||||
<p class="mt-1 vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
|
@ -165,7 +165,7 @@
|
|||
feature-id="ctrl.limitedFeatureAutoWindow"
|
||||
tooltip="'Specify a timeframe during which automatic updates can occur in this environment.'"
|
||||
on-change="(ctrl.onToggleAutoUpdate)"
|
||||
label-class="'col-sm-3 col-lg-2 px-0 !m-0'"
|
||||
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
||||
switch-class="'col-sm-8'"
|
||||
>
|
||||
</por-switch-field>
|
||||
|
@ -185,7 +185,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Restrict access to the default namespace </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Restrict access to the default namespace </label>
|
||||
<label class="switch col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.RestrictDefaultNamespace" /><span class="slider round" data-cy="kubeSetup-restrictDefaultNsToggle"></span>
|
||||
</label>
|
||||
|
@ -216,7 +216,7 @@
|
|||
feature-id="ctrl.limitedFeature"
|
||||
checked="ctrl.formValues.EnableResourceOverCommit"
|
||||
on-change="(ctrl.onChangeEnableResourceOverCommit)"
|
||||
label-class="'col-sm-3 col-lg-2 px-0 !m-0'"
|
||||
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
||||
switch-class="'col-sm-8'"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
|
@ -234,14 +234,14 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Enable features using the metrics API </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Enable features using the metrics API </label>
|
||||
<label class="switch col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
|
||||
<span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div ng-if="ctrl.state.metrics.pending && ctrl.state.metrics.userClick" class="col-sm-12 small text-muted" style="margin-top: 5px">
|
||||
Checking metrics API... <i class="fa fa-spinner fa-spin" style="margin-left: 2px"></i>
|
||||
Checking metrics API... <pr-icon icon="'loader'" feather="true" class-name="'ml-0.5'"></pr-icon>
|
||||
</div>
|
||||
<div
|
||||
ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
||||
|
@ -291,7 +291,7 @@
|
|||
</tr>
|
||||
<tr ng-repeat="class in ctrl.StorageClasses">
|
||||
<td>
|
||||
<div class="flex-center justify-start">
|
||||
<div class="flex-row vertical-center">
|
||||
<label class="switch mr-2 mb-0">
|
||||
<input type="checkbox" ng-model="class.selected" /><span class="slider round" data-cy="kubeSetup-storageToggle{{ class.Name }}"></span>
|
||||
</label>
|
||||
|
@ -341,7 +341,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-click="ctrl.configure()"
|
||||
ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
<div ng-if="ctrl.configurations" data-cy="k8sDashboard-configurations">
|
||||
<a ui-sref="kubernetes.configurations">
|
||||
<dashboard-item feather-icon="true" icon="'lock'" type="'Configuration'" value="ctrl.configurations.length"></dashboard-item>
|
||||
<dashboard-item feather-icon="true" icon="'lock'" type="'ConfigMaps & Secret'" value="ctrl.configurations.length"></dashboard-item>
|
||||
</a>
|
||||
</div>
|
||||
<div ng-if="ctrl.volumes" data-cy="k8sDashboard-volumes">
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-lg-2 col-sm-3 control-label text-left">Name</label>
|
||||
<label for="stack_name" class="col-lg-2 col-sm-3 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" ng-model="ctrl.formValues.StackName" id="stack_name" placeholder="my-app" auto-focus />
|
||||
</div>
|
||||
|
@ -117,10 +117,12 @@
|
|||
>
|
||||
<editor-description>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.COMPOSE">
|
||||
<p>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that
|
||||
not all the Compose format options are supported by Kompose at the moment.
|
||||
<span>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary
|
||||
that not all the Compose format options are supported by Kompose at the moment.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
You can get more information about Compose file format in the
|
||||
|
@ -128,8 +130,8 @@
|
|||
</p>
|
||||
</span>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES">
|
||||
<p>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -149,7 +151,7 @@
|
|||
<span class="col-sm-12 text-muted small"> Indicate the URL to the manifest. </span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="manifest_url" class="col-sm-3 col-lg-2 control-label text-left">URL</label>
|
||||
<label for="manifest_url" class="col-sm-3 col-lg-2 control-label text-left required">URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -170,7 +172,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="!deploymentForm.$valid ||ctrl.disableDeploy()"
|
||||
ng-click="ctrl.deploy()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -43,6 +43,14 @@
|
|||
<rd-widget-header icon="svg-userlock" title-text="Create access"></rd-widget-header>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Adding user access will require the affected user(s) to logout and login for the changes to be taken into account.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select user(s) and/or team(s) </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
|
@ -92,7 +100,7 @@
|
|||
<div class="col-sm-12">
|
||||
<access-datatable
|
||||
ng-if="ctrl.authorizedUsersAndTeams"
|
||||
title-text="Access"
|
||||
title-text="Namespace access"
|
||||
title-icon="svg-userlock"
|
||||
table-key="kubernetes_resourcepool_access"
|
||||
order-by="Name"
|
||||
|
|
|
@ -76,19 +76,20 @@
|
|||
<div ng-if="$ctrl.formValues.HasQuota">
|
||||
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
||||
<div>
|
||||
<div class="form-group" ng-if="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
||||
<span class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center"
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 small text-muted" ng-switch on="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
||||
<p class="vertical-center mb-0" ng-switch-when="true"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> At least a single limit must be set for the quota to be
|
||||
valid.
|
||||
</p>
|
||||
<p class="vertical-center mb-0" ng-switch-default></p>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- memory-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory </label>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group flex flex-row !mb-0">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory limit (MB) </label>
|
||||
<div class="col-xs-6">
|
||||
<slider
|
||||
model="$ctrl.formValues.MemoryLimit"
|
||||
floor="$ctrl.defaults.MemoryLimit"
|
||||
|
@ -99,7 +100,7 @@
|
|||
>
|
||||
</slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
type="number"
|
||||
|
@ -111,29 +112,29 @@
|
|||
data-cy="k8sNamespaceCreate-memoryLimitInput"
|
||||
required
|
||||
/>
|
||||
<span class="help-block">
|
||||
<div class="form-group" ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
||||
<p class="vertical-center"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between
|
||||
{{ $ctrl.defaults.MemoryLimit }} and
|
||||
{{ $ctrl.state.sliderMaxMemory }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="col-sm-3 col-lg-2"></span>
|
||||
<span class="help-block col-sm-9 col-lg-10">
|
||||
<div ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
||||
<div class="small text-muted">
|
||||
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
||||
<p class="vertical-center"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between
|
||||
{{ $ctrl.defaults.MemoryLimit }} and
|
||||
{{ $ctrl.state.sliderMaxMemory }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted"> Maximum memory usage (MB) </p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<!-- !memory-limit-input -->
|
||||
<!-- cpu-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU </label>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-group flex flex-row">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU limit </label>
|
||||
<div class="col-xs-8">
|
||||
<slider
|
||||
model="$ctrl.formValues.CpuLimit"
|
||||
floor="$ctrl.defaults.CpuLimit"
|
||||
|
@ -145,9 +146,6 @@
|
|||
>
|
||||
</slider>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !cpu-limit-input -->
|
||||
</div>
|
||||
|
@ -159,7 +157,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
You can set a quota on the amount of external load balancers that can be created inside this namespace. Set this quota to 0 to effectively disable the use of load
|
||||
balancers in this namespace.
|
||||
</span>
|
||||
|
@ -184,7 +182,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Quotas can be set on each storage option to prevent users from exceeding a specific threshold when deploying applications. You can set a quota to 0 to effectively
|
||||
prevent the usage of a specific storage option inside this namespace.
|
||||
</span>
|
||||
|
@ -211,7 +209,7 @@
|
|||
<div class="form-group" ng-if="$ctrl.formValues.IngressClasses.length > 0">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Enable and configure ingresses available to users when deploying applications.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -268,8 +266,8 @@
|
|||
data-cy="namespaceCreate-hostnameInput{{ ic.IngressClass.Name }}_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-1 input-group input-group-sm" ng-if="$index > 0">
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon !h-[30px]" type="button" ng-click="$ctrl.removeHostname(ic, $index)">
|
||||
<div class="col-sm-1 input-group input-group-sm !pt-2" ng-if="$index > 0">
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon" type="button" ng-click="$ctrl.removeHostname(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -282,13 +280,13 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="resourcePoolCreationForm['hostname_' + ic.IngressClass.Name + '_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Hostname is required.</p>
|
||||
<p ng-message="pattern">
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Hostname is required.</p>
|
||||
<p class="vertical-center" ng-message="pattern">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
This field must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com').
|
||||
</p>
|
||||
</ng-messages>
|
||||
<p ng-if="$ctrl.state.duplicates.ingressHosts.refs[ic.IngressClass.Name][$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="$ctrl.state.duplicates.ingressHosts.refs[ic.IngressClass.Name][$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> This hostname is already used.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -299,7 +297,7 @@
|
|||
<div ng-repeat-end class="form-group" ng-if="ic.Selected">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can specify a list of annotations that will be associated to the ingress.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -376,7 +374,7 @@
|
|||
</div>
|
||||
<div class="input-group input-group-sm col-sm-1">
|
||||
<button
|
||||
class="btn btn-sm btn-dangerlight btn-only-icon !h-[30px]"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeAnnotation(ic, $index)"
|
||||
data-cy="namespaceCreate-deleteAnnotationButton{{ ic.IngressClass.Name }}"
|
||||
|
@ -395,17 +393,17 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Define which registries can be used by users who have access to this namespace.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select registries </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && $ctrl.state.isAdmin">
|
||||
No registries available. Head over <a ui-sref="portainer.registries">registry view</a> to define container registry.
|
||||
No registries available. Head over to the <a ui-sref="portainer.registries">registry view</a> to define a container registry.
|
||||
</span>
|
||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && !$ctrl.state.isAdmin">
|
||||
No registries available. Contact your administrator to create a container registry.
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
||||
</a>
|
||||
<span ng-if="path.ApplicationName !== '-'">
|
||||
<i class="fas fa-long-arrow-alt-right" style="margin: 2px"></i>
|
||||
<pr-icon icon="'svg-arrowright'" class-name="'m-0.5'"></pr-icon>
|
||||
<a ui-sref="kubernetes.applications.application({ name: path.ApplicationName, namespace: item.Namespace })">{{ path.ApplicationName }}</a>
|
||||
</span>
|
||||
<span class="label label-warning image-tag label-margins" ng-if="path.ApplicationName === '-'">unused</span>
|
||||
|
|
|
@ -77,9 +77,9 @@
|
|||
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
||||
<div>
|
||||
<!-- memory-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> Memory limit </label>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group flex">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left vertical-center"> Memory limit (MB) </label>
|
||||
<div class="col-sm-6">
|
||||
<slider
|
||||
model="ctrl.formValues.MemoryLimit"
|
||||
floor="ctrl.ResourceQuotaDefaults.MemoryLimit"
|
||||
|
@ -88,7 +88,7 @@
|
|||
ng-if="ctrl.state.sliderMaxMemory"
|
||||
></slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
type="number"
|
||||
|
@ -100,12 +100,10 @@
|
|||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted" style="margin-top: 7px"> Memory limit (<b>MB</b>) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="resourcePoolEditForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<div ng-messages="resourcePoolEditForm.pool_name.$error">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between {{ ctrl.ResourceQuotaDefaults.MemoryLimit }} and
|
||||
|
@ -118,7 +116,7 @@
|
|||
<!-- cpu-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> CPU limit </label>
|
||||
<div class="col-sm-5">
|
||||
<div class="col-sm-8">
|
||||
<slider
|
||||
model="ctrl.formValues.CpuLimit"
|
||||
floor="ctrl.ResourceQuotaDefaults.CpuLimit"
|
||||
|
@ -128,9 +126,6 @@
|
|||
ng-if="ctrl.state.sliderMaxCpu"
|
||||
></slider>
|
||||
</div>
|
||||
<div class="col-sm-4" style="margin-top: 20px">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !cpu-limit-input -->
|
||||
</div>
|
||||
|
@ -141,7 +136,7 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can set a quota on the amount of external load balancers that can be created inside this namespace. Set this quota to 0 to effectively disable the use of
|
||||
load balancers in this namespace.
|
||||
</p>
|
||||
|
@ -174,7 +169,7 @@
|
|||
<div class="form-group" ng-if="ctrl.formValues.IngressClasses.length > 0">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Enable and configure ingresses available to users when deploying applications.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -220,7 +215,7 @@
|
|||
<div ng-repeat="item in ic.Hosts track by $index" style="margin-top: 2px">
|
||||
<div class="form-inline">
|
||||
<div class="col-sm-10 input-group input-group-sm" ng-class="{ striked: item.NeedsDeletion }">
|
||||
<span class="input-group-addon">Hostname</span>
|
||||
<span class="input-group-addon required">Hostname</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -257,7 +252,7 @@
|
|||
'example.com').
|
||||
</p>
|
||||
</ng-messages>
|
||||
<p ng-if="item.Duplicate">
|
||||
<p class="vertical-center" ng-if="item.Duplicate">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
This hostname is already used.
|
||||
</p>
|
||||
|
@ -269,7 +264,7 @@
|
|||
<div ng-repeat-end class="form-group" ng-if="ic.Selected" style="margin-bottom: 20px">
|
||||
<div class="col-sm-12 small text-muted" style="margin-top: 5px">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can specify a list of annotations that will be associated to the ingress.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -338,8 +333,8 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="col-sm-1 input-group input-group-sm">
|
||||
<button class="btn btn-sm btn-dangerlight" type="button" ng-click="ctrl.removeAnnotation(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon" type="button" ng-click="ctrl.removeAnnotation(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -363,18 +358,18 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Define which registries can be used by users who have access to this namespace.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left" style="padding-top: 0"> Select registries </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && ctrl.state.isAdmin">
|
||||
No registries available. Head over <a ui-sref="portainer.registries">registry view</a> to define container registry.
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && ctrl.isAdmin">
|
||||
No registries available. Head over to the <a ui-sref="portainer.registries">registry view</a> to define a container registry.
|
||||
</span>
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && !ctrl.state.isAdmin">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && !ctrl.isAdmin">
|
||||
No registries available. Contact your administrator to create a container registry.
|
||||
</span>
|
||||
<span
|
||||
|
@ -402,7 +397,7 @@
|
|||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="primary"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Quotas can be set on each storage option to prevent users from exceeding a specific threshold when deploying applications. You can set a quota to 0 to
|
||||
effectively prevent the usage of a specific storage option inside this namespace.
|
||||
</p>
|
||||
|
@ -433,7 +428,7 @@
|
|||
<button
|
||||
type="button"
|
||||
ng-if="!ctrl.isSystem"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0 !mr-1"
|
||||
ng-disabled="!resourcePoolEditForm.$valid || ctrl.isUpdateButtonDisabled()"
|
||||
ng-click="ctrl.updateResourcePool()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
@ -444,7 +439,7 @@
|
|||
<button
|
||||
ng-if="!ctrl.isDefaultNamespace"
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-light btn-sm !ml-0"
|
||||
ng-click="ctrl.markUnmarkAsSystem()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
data-cy="k8sNamespaceEdit-markSystem"
|
||||
|
@ -459,9 +454,9 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'" class-name="'mr-0.5'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
|
@ -478,7 +473,7 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="2" ng-if="ctrl.pool.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
||||
<uib-tab-heading class="vertical-center"><pr-icon icon="'code'" feather="true"></pr-icon> YAML </uib-tab-heading>
|
||||
<div style="padding-right: 25px" ng-if="ctrl.state.showEditorTab">
|
||||
<div class="px-5" ng-if="ctrl.state.showEditorTab">
|
||||
<kubernetes-yaml-inspector key="resource-pool-yaml" data="ctrl.pool.Yaml"></kubernetes-yaml-inspector>
|
||||
</div>
|
||||
</uib-tab>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
endpoint="ctrl.endpoint"
|
||||
dataset="ctrl.resourcePools"
|
||||
table-key="kubernetes.resourcePools"
|
||||
order-by="Namespace.Name"
|
||||
order-by="Name"
|
||||
remove-action="ctrl.removeAction"
|
||||
refresh-callback="ctrl.getResourcePools"
|
||||
endpoint="ctrl.endpoint"
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
ng-if="ctrl.state.viewReady"
|
||||
title="'Stacks logs'"
|
||||
breadcrumbs="[
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{ label:ctrl.state.transition.namespace, link:'kubernetes.resourcePools.resourcePool', linkParams:{ id: ctrl.state.transition.namespace } },
|
||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||
{ label:ctrl.state.transition.namespace, link:'kubernetes.resourcePools.resourcePool', linkParams:{ id: ctrl.state.transition.namespace } },
|
||||
{ label:'Applications', link:'kubernetes.applications' },
|
||||
'Stacks',
|
||||
ctrl.state.transition.name,
|
||||
|
@ -14,7 +14,7 @@ ctrl.state.transition.name,
|
|||
|
||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||
|
||||
<div ng-if="ctrl.state.viewReady" style="height: 100%">
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
|
@ -23,19 +23,22 @@ ctrl.state.transition.name,
|
|||
<div class="col-sm-12 form-section-title"> Actions </div>
|
||||
<!-- auto-refresh -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">
|
||||
Auto-refresh
|
||||
<portainer-tooltip message="'Automatically refresh logs every 30 seconds'"></portainer-tooltip>
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 vertical-center !py-2">
|
||||
Auto-refresh
|
||||
<portainer-tooltip message="'Automatically refresh logs every 30 seconds'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-8 col-sm-9 vertical-center">
|
||||
<label class="switch col-sm-8 col-sm-9 vertical-center !mb-0">
|
||||
<input type="checkbox" ng-model="ctrl.state.autoRefresh" ng-change="ctrl.updateAutoRefresh()" />
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px"> <input type="checkbox" ng-model="ctrl.state.autoRefresh" ng-change="ctrl.updateAutoRefresh()" /><i></i> </label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !auto-refresh -->
|
||||
<!-- search -->
|
||||
<div class="form-group">
|
||||
<label for="logs_search" class="col-sm-1 control-label text-left"> Search </label>
|
||||
<div class="col-sm-11">
|
||||
<label for="logs_search" class="col-sm-3 col-lg-2 control-label text-left"> Search </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
|
@ -51,7 +54,10 @@ ctrl.state.transition.name,
|
|||
<!-- actions -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button class="btn btn-primary btn-sm" type="button" ng-click="ctrl.downloadLogs()" style="margin-left: 0"><i class="fa fa-download"></i> Download logs</button>
|
||||
<button class="btn btn-primary btn-sm !ml-0 vertical-center" type="button" ng-click="ctrl.downloadLogs()">
|
||||
<pr-icon icon="'download'" feather="true"></pr-icon>
|
||||
Download logs
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
|
@ -61,8 +67,8 @@ ctrl.state.transition.name,
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="height: 54%">
|
||||
<div class="col-sm-12" style="height: 100%">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||
<pre
|
||||
class="log_viewer"
|
||||
><div ng-repeat="line in ctrl.state.filteredLogs = (ctrl.stackLogs | filter:ctrl.state.search) track by $index" class="line" ng-if="line"><p class="inner_line"><span ng-style="{'color': line.Color, 'font-weight': 'bold'};">{{ line.AppName }}</span> {{ line.Line }}</p></div><div ng-if="ctrl.stackLogs.length && !ctrl.state.filteredLogs.length" class="line"><p class="inner_line">No log line matching the '{{ ctrl.state.search }}' filter</p></div><div ng-if="ctrl.stackLogs.length === 0" class="line"><p class="inner_line">No logs available</p></div></pre>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class="flex justify-start form-section-title interactive" ng-click="$ctrl.toggleSummary()" ng-if="$ctrl.state.resources.length > 0">
|
||||
<pr-icon icon="$ctrl.state.expandedTemplate ? 'chevron-down' : 'chevron-right'" feather="true" class="!mr-1 vertical-center pb-1"></pr-icon>
|
||||
<div class="flex justify-start items-center form-section-title interactive" ng-click="$ctrl.toggleSummary()" ng-if="$ctrl.state.resources.length > 0">
|
||||
<pr-icon icon="$ctrl.state.expandedTemplate ? 'chevron-down' : 'chevron-right'" feather="true" class="!mr-1 vertical-center"></pr-icon>
|
||||
Summary
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.state.expandedTemplate">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will execute the following Kubernetes actions.
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap !p-0 w-full">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'database'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'hard-drive'" feather="true"></pr-icon>
|
||||
</div>
|
||||
Storage
|
||||
</div>
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center" data-cy="k8sVolDetail-volEventsTab">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'" feather="true"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue