mirror of https://github.com/portainer/portainer
fix(ui): kubernetes-consistent-styling EE-3820 (#7425)
parent
b67f404d8d
commit
36c93c7f57
|
@ -881,3 +881,7 @@ input[style*='background-image: url("data:image/png'] + [data-cy='auth-passwordI
|
||||||
input[style*='background-image: url("data:image/png'] {
|
input[style*='background-image: url("data:image/png'] {
|
||||||
padding-right: 60px;
|
padding-right: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-editor .trancluded-item:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
|
@ -98,7 +98,8 @@ fieldset[disabled] .btn {
|
||||||
background-color: var(--ui-gray-3);
|
background-color: var(--ui-gray-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hyperlink {
|
.hyperlink,
|
||||||
|
.hyperlink:focus {
|
||||||
color: var(--ui-blue-8);
|
color: var(--ui-blue-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ code {
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
border: 1px solid var(--border-pre-color);
|
border: 1px solid var(--border-pre-color);
|
||||||
|
border-radius: 8px;
|
||||||
background-color: var(--bg-pre-color);
|
background-color: var(--bg-pre-color);
|
||||||
color: var(--text-pre-color);
|
color: var(--text-pre-color);
|
||||||
}
|
}
|
||||||
|
@ -394,6 +395,10 @@ input:-webkit-autofill {
|
||||||
|
|
||||||
/* Overide Vendor CSS */
|
/* Overide Vendor CSS */
|
||||||
|
|
||||||
|
.btn-link:hover {
|
||||||
|
color: var(--text-link-hover-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.multiSelect.inlineBlock button {
|
.multiSelect.inlineBlock button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
@ -425,3 +430,23 @@ input:-webkit-autofill {
|
||||||
background-color: var(--bg-nav-tabs-active-color);
|
background-color: var(--bg-nav-tabs-active-color);
|
||||||
border-top-right-radius: 8px;
|
border-top-right-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Code Script Style */
|
||||||
|
.code-script {
|
||||||
|
background-color: var(--bg-code-script-color);
|
||||||
|
border-bottom-left-radius: 8px;
|
||||||
|
border-bottom-right-radius: 8px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-container {
|
||||||
|
border: 1px solid var(--border-nav-container-color);
|
||||||
|
background-color: var(--bg-nav-container-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li {
|
||||||
|
background-color: var(--bg-nav-tabs-active-color);
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg><svg width="auto" height="auto" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M58.3333 9.45654V26.6671C58.3333 29.0007 58.3333 30.1675 58.7875 31.0588C59.1869 31.8428 59.8244 32.4802 60.6084 32.8797C61.4997 33.3338 62.6665 33.3338 65 33.3338H82.2106M58.3333 72.9168L68.75 62.5002L58.3333 52.0835M41.6667 52.0835L31.25 62.5002L41.6667 72.9168M83.3333 41.6178V71.6668C83.3333 78.6675 83.3333 82.1678 81.9709 84.8417C80.7725 87.1937 78.8602 89.106 76.5082 90.3044C73.8343 91.6668 70.334 91.6668 63.3333 91.6668H36.6667C29.666 91.6668 26.1657 91.6668 23.4918 90.3044C21.1398 89.106 19.2275 87.1937 18.0291 84.8417C16.6667 82.1678 16.6667 78.6675 16.6667 71.6668V28.3335C16.6667 21.3328 16.6667 17.8325 18.0291 15.1586C19.2275 12.8066 21.1398 10.8943 23.4918 9.69591C26.1657 8.3335 29.666 8.3335 36.6667 8.3335H50.0491C53.1064 8.3335 54.6351 8.3335 56.0737 8.67887C57.3492 8.98508 58.5685 9.49014 59.6869 10.1755C60.9484 10.9485 62.0293 12.0295 64.1912 14.1914L77.4755 27.4756C79.6374 29.6375 80.7183 30.7185 81.4913 31.9799C82.1767 33.0983 82.6818 34.3176 82.988 35.5931C83.3333 37.0317 83.3333 38.5604 83.3333 41.6178Z" stroke="currentColor" stroke-width="8.2" stroke-linecap="round" stroke-linejoin="round"/> </svg>
|
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 1.6 KiB |
|
@ -58,10 +58,11 @@
|
||||||
<!-- ! don't use registry -->
|
<!-- ! don't use registry -->
|
||||||
<!-- info message -->
|
<!-- info message -->
|
||||||
<div class="form-group" ng-show="$ctrl.form.image_name.$invalid">
|
<div class="form-group" ng-show="$ctrl.form.image_name.$invalid">
|
||||||
<div class="col-sm-12 small">
|
<div class="small">
|
||||||
<div ng-messages="$ctrl.form.image_name.$error">
|
<div class="col-sm-3 col-lg-2"></div>
|
||||||
<p ng-message="required">
|
<div class="col-sm-8" ng-messages="$ctrl.form.image_name.$error">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Image name is required.
|
<p class="text-muted vertical-center" ng-message="required">
|
||||||
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true" class="vertical-center"></pr-icon> Image name is required.
|
||||||
<span ng-if="$ctrl.canPull">Tag must be specified otherwise Portainer will pull all tags associated to the image.</span>
|
<span ng-if="$ctrl.canPull">Tag must be specified otherwise Portainer will pull all tags associated to the image.</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="'server'" feather="true"></pr-icon>
|
<pr-icon icon="'server'" feather="true"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -162,15 +161,19 @@
|
||||||
<a
|
<a
|
||||||
ng-if="item.Status === 'Running' && $ctrl.useServerMetrics"
|
ng-if="item.Status === 'Running' && $ctrl.useServerMetrics"
|
||||||
ui-sref="kubernetes.applications.application.stats({ pod: item.PodName, container: item.Name })"
|
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>
|
||||||
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })">
|
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })" class="vertical-center mr-1">
|
||||||
<pr-icon icon="'file-text'" class="mr-1" feather="true"></pr-icon>Logs
|
<pr-icon icon="'file-text'" feather="true"></pr-icon>Logs
|
||||||
</a>
|
</a>
|
||||||
<a ng-if="item.Status === 'Running'" ui-sref="kubernetes.applications.application.console({ pod: item.PodName, container: item.Name })" style="margin-left: 10px">
|
<a
|
||||||
<pr-icon icon="'terminal'" class="mr-1" feather="true"></pr-icon>Console
|
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>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<div class="published-url-container">
|
<div class="published-url-container">
|
||||||
<div class="text-muted"> Published URL </div>
|
<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>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</div>
|
</div>
|
||||||
Applications
|
Applications
|
||||||
</div>
|
</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>
|
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -105,10 +105,10 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row w-full">
|
<div class="flex flex-row w-full" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem" authorization="K8sAccessSystemNamespaces">
|
<span class="small text-muted mt-1 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>
|
||||||
<span> System resources are hidden, this can be changed in the table settings. </span>
|
System resources are hidden, this can be changed in the table settings.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
<!-- title -->
|
<!-- title -->
|
||||||
<div class="toolBarTitle vertical-center">
|
<div class="toolBarTitle vertical-center">
|
||||||
<div class="widget-icon space-right">
|
<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>
|
</div>
|
||||||
Port mappings
|
Port mappings
|
||||||
</div>
|
</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>
|
<pr-icon icon="'search'" feather="true" class-name="'icon !h-3'"></pr-icon>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -77,8 +77,8 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- info text -->
|
<!-- info text -->
|
||||||
<div class="flex flex-row w-full">
|
<div class="flex flex-row w-full">
|
||||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||||
<pr-icon icon="'info'" feather="true" class-name="'icon'"></pr-icon>
|
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||||
System resources are hidden, this can be changed in the table settings.
|
System resources are hidden, this can be changed in the table settings.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<!-- Internal -->
|
<!-- 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 -->
|
<!-- Cluster -->
|
||||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.NODE_PORT"> <pr-icon icon="'list'" feather="true" class-name="'icon'"></pr-icon> NodePort </span>
|
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.NODE_PORT"> <pr-icon icon="'list'" feather="true" class-name="'icon'"></pr-icon> NodePort </span>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
<option value="300">5min</option>
|
<option value="300">5min</option>
|
||||||
</select>
|
</select>
|
||||||
<span>
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,9 +88,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- info text -->
|
<!-- info text -->
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row w-full">
|
||||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||||
System resources are hidden, this can be changed in the table settings.
|
System resources are hidden, this can be changed in the table settings.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
<option value="300">5min</option>
|
<option value="300">5min</option>
|
||||||
</select>
|
</select>
|
||||||
<span>
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem" class="flex flex-row w-full">
|
<div ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem" class="flex flex-row w-full">
|
||||||
<span class="small text-muted mt-1 vertical-center">
|
<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>
|
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
<div class="toolBar">
|
<div class="toolBar">
|
||||||
<div class="toolBarTitle flex">
|
<div class="toolBarTitle flex">
|
||||||
<div class="widget-icon space-right">
|
<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>
|
</div>
|
||||||
|
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</div>
|
</div>
|
||||||
<div class="searchBar">
|
<div class="searchBar">
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<div class="datatable">
|
<div class="datatable">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<rd-widget-body classes="no-padding">
|
<rd-widget-body classes="no-padding">
|
||||||
<div class="toolBar">
|
<div class="toolBar !gap-3">
|
||||||
<div class="toolBarTitle vertical-center">
|
<div class="toolBarTitle vertical-center">
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</div>
|
</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>
|
<pr-icon icon="'search'" feather="true" class="vertical-center"></pr-icon>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -4,26 +4,25 @@
|
||||||
<div class="toolBar">
|
<div class="toolBar">
|
||||||
<div class="toolBarTitle flex">
|
<div class="toolBarTitle flex">
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
<pr-icon icon="'svg-laptopcode'"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="vertical-center">
|
<span class="vertical-center">
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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="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 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>
|
<span uib-dropdown-toggle><pr-icon icon="'more-vertical'" feather="true"></pr-icon></span>
|
||||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||||
|
|
|
@ -3,7 +3,6 @@ angular.module('portainer.kubernetes').component('kubernetesNodeApplicationsData
|
||||||
controller: 'KubernetesNodeApplicationsDatatableController',
|
controller: 'KubernetesNodeApplicationsDatatableController',
|
||||||
bindings: {
|
bindings: {
|
||||||
titleText: '@',
|
titleText: '@',
|
||||||
titleIcon: '@',
|
|
||||||
dataset: '<',
|
dataset: '<',
|
||||||
tableKey: '@',
|
tableKey: '@',
|
||||||
orderBy: '@',
|
orderBy: '@',
|
||||||
|
|
|
@ -4,26 +4,25 @@
|
||||||
<div class="toolBar">
|
<div class="toolBar">
|
||||||
<div class="toolBarTitle flex">
|
<div class="toolBarTitle flex">
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="vertical-center">
|
<span class="vertical-center">
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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="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
|
<span
|
||||||
class="setting vertical-center"
|
class="setting vertical-center"
|
||||||
ng-class="{ 'setting-active': $ctrl.settings.open }"
|
ng-class="{ 'setting-active': $ctrl.settings.open }"
|
||||||
|
@ -132,7 +131,9 @@
|
||||||
ng-click="$ctrl.changeOrderBy('IPAddress')"
|
ng-click="$ctrl.changeOrderBy('IPAddress')"
|
||||||
></table-column-header>
|
></table-column-header>
|
||||||
</th>
|
</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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -154,7 +155,7 @@
|
||||||
<td>{{ item.Version }}</td>
|
<td>{{ item.Version }}</td>
|
||||||
<td>{{ item.IPAddress }}</td>
|
<td>{{ item.IPAddress }}</td>
|
||||||
<td ng-if="$ctrl.useServerMetrics">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="!$ctrl.dataset">
|
<tr ng-if="!$ctrl.dataset">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<rd-widget-body classes="no-padding">
|
<rd-widget-body classes="no-padding">
|
||||||
<div class="toolBar">
|
<div class="toolBar">
|
||||||
<div class="toolBarTitle vertical-center">
|
<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 }}
|
{{ $ctrl.titleText }}
|
||||||
</div>
|
</div>
|
||||||
<div class="searchBar vertical-center">
|
<div class="searchBar vertical-center">
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
class="searchInput"
|
class="searchInput"
|
||||||
ng-model="$ctrl.state.textFilter"
|
ng-model="$ctrl.state.textFilter"
|
||||||
ng-change="$ctrl.onTextFilterChange()"
|
ng-change="$ctrl.onTextFilterChange()"
|
||||||
placeholder="Search for an application"
|
placeholder="Search for an application..."
|
||||||
auto-focus
|
auto-focus
|
||||||
ng-model-options="{ debounce: 300 }"
|
ng-model-options="{ debounce: 300 }"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
class="searchInput"
|
class="searchInput"
|
||||||
ng-model="$ctrl.state.textFilter"
|
ng-model="$ctrl.state.textFilter"
|
||||||
ng-change="$ctrl.onTextFilterChange()"
|
ng-change="$ctrl.onTextFilterChange()"
|
||||||
placeholder="Search for a namespace"
|
placeholder="Search for a namespace..."
|
||||||
auto-focus
|
auto-focus
|
||||||
ng-model-options="{ debounce: 300 }"
|
ng-model-options="{ debounce: 300 }"
|
||||||
data-cy="k8sNamespace-namespaceSearchInput"
|
data-cy="k8sNamespace-namespaceSearchInput"
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
<option value="300">5min</option>
|
<option value="300">5min</option>
|
||||||
</select>
|
</select>
|
||||||
<span>
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,9 +82,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-row w-full">
|
<div class="flex flex-row w-full" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
||||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
<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>
|
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<div class="toolBar px-5 pt-5">
|
<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">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="'svg-helm'"></pr-icon>
|
<pr-icon icon="'svg-helm'"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<div class="form-group nomargin" ng-show="addUserHelmRepoForm.repo.$invalid">
|
<div class="form-group nomargin" ng-show="addUserHelmRepoForm.repo.$invalid">
|
||||||
<div class="small">
|
<div class="small">
|
||||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
<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
|
><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> A valid URL beginning with http(s) is required.</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<div class="form-group nomargin" ng-show="$ctrl.doesRepoExist()">
|
<div class="form-group nomargin" ng-show="$ctrl.doesRepoExist()">
|
||||||
<div class="small">
|
<div class="small">
|
||||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
src="$ctrl.model.icon"
|
src="$ctrl.model.icon"
|
||||||
fallback-icon="'svg-helm'"
|
fallback-icon="'svg-helm'"
|
||||||
class-name="'blocklist-item-logo h-16 w-auto'"
|
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'"
|
fallback-mode="'primary'"
|
||||||
size="'xl'"
|
size="'xl'"
|
||||||
></fallback-image>
|
></fallback-image>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
class="searchInput"
|
class="searchInput"
|
||||||
ng-model="$ctrl.state.textFilter"
|
ng-model="$ctrl.state.textFilter"
|
||||||
ng-change="$ctrl.onTextFilterChange()"
|
ng-change="$ctrl.onTextFilterChange()"
|
||||||
placeholder="Search..."
|
placeholder="Search for a chart..."
|
||||||
auto-focus
|
auto-focus
|
||||||
ng-model-options="{ debounce: 300 }"
|
ng-model-options="{ debounce: 300 }"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -31,8 +31,7 @@ export default class HelmTemplatesController {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
editorUpdate(content) {
|
editorUpdate(contentvalues) {
|
||||||
const contentvalues = content.getValue();
|
|
||||||
if (this.state.originalvalues === contentvalues) {
|
if (this.state.originalvalues === contentvalues) {
|
||||||
this.state.isEditorDirty = false;
|
this.state.isEditorDirty = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<p class="inline-flex flex-row items-center">
|
<p class="inline-flex flex-row items-center">
|
||||||
<pr-icon icon="'info'" feather="true" class="mr-1 vertical-center" mode="'primary'"></pr-icon>
|
<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
|
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"
|
href="https://www.portainer.io/blog/portainer-now-with-helm-support"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>blog post</a
|
>blog post</a
|
||||||
|
@ -132,11 +132,14 @@
|
||||||
yml="true"
|
yml="true"
|
||||||
placeholder="# Define or paste the content of your values yaml file here"
|
placeholder="# Define or paste the content of your values yaml file here"
|
||||||
>
|
>
|
||||||
<editor-description>
|
<editor-description class="vertical-center">
|
||||||
You can get more information about Helm values file format in the
|
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||||
<a href="https://helm.sh/docs/chart_template_guide/values_files/" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline"
|
<span>
|
||||||
>official documentation</a
|
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>
|
</editor-description>
|
||||||
</web-editor-form>
|
</web-editor-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<ng-form name="serviceForm">
|
<ng-form name="serviceForm">
|
||||||
<div ng-if="$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
<div ng-if="$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||||
<p style="margin-top: 10px">
|
<p class="text-muted pt-2 vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
<pr-icon icon="'alert-triangle'" mode="'warning'" 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.
|
<a class="hyperlink" ui-sref="kubernetes.cluster.setup">here</a> to configure load balancer.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="!$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
<div ng-if="!$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||||
<p style="margin-top: 10px">
|
<p class="text-muted pt-2 vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, contract your administrator.
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> No Load balancer is available in this cluster, contact your administrator.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -18,16 +18,16 @@
|
||||||
$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT
|
$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5">
|
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5 vertical-center">
|
||||||
<label class="control-label text-left">Published ports</label>
|
<label class="control-label text-left !pt-0">Published ports</label>
|
||||||
<span class="label label-default interactive ml-10 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
<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
|
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> publish a new port
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div ng-repeat="servicePort in $ctrl.servicePorts" class="mt-5 service-form row">
|
<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="form-group !mx-0 !pl-0 col-sm-3">
|
||||||
<div class="input-group input-group-sm">
|
<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
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -47,17 +47,21 @@
|
||||||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.targetPort.refs[$index] !== undefined">
|
<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.
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This container port is already used.
|
||||||
</div>
|
</div>
|
||||||
<div class="small mt-1" ng-messages="serviceForm['container_port_'+$index].$error">
|
<div class="small mt-1 text-muted" 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 class="vertical-center" 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 class="vertical-center" ng-message="min"
|
||||||
<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>
|
><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>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||||
<div class="input-group input-group-sm">
|
<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
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -76,11 +80,15 @@
|
||||||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.servicePort.refs[$index] !== undefined">
|
<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.
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This service port is already used.
|
||||||
</div>
|
</div>
|
||||||
<div class="small mt-1">
|
<div class="small mt-1 text-muted">
|
||||||
<div ng-messages="serviceForm['service_port_'+$index].$error">
|
<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 class="vertical-center" 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 class="vertical-center" ng-message="min"
|
||||||
<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>
|
><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>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</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="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">nodeport</span>
|
<span class="input-group-addon required">Nodeport</span>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -97,20 +105,22 @@
|
||||||
placeholder="30080"
|
placeholder="30080"
|
||||||
ng-min="30000"
|
ng-min="30000"
|
||||||
ng-max="32767"
|
ng-max="32767"
|
||||||
|
required
|
||||||
ng-change="$ctrl.onChangeNodePort()"
|
ng-change="$ctrl.onChangeNodePort()"
|
||||||
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<span>
|
<span>
|
||||||
<div class="small mt-1">
|
<div class="small mt-1 text-muted">
|
||||||
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
||||||
<p ng-message="min"
|
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport is required.</p>
|
||||||
><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="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
|
allocated.</p
|
||||||
>
|
>
|
||||||
<p ng-message="max"
|
<p class="vertical-center" 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
|
><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
|
allocated.</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,7 +130,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER">
|
<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">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">loadbalancer port</span>
|
<span class="input-group-addon">Loadbalancer port</span>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control"
|
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="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">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">ingress</span>
|
<span class="input-group-addon">Ingress</span>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="ingress_port_{{ $index }}"
|
name="ingress_port_{{ $index }}"
|
||||||
|
@ -152,9 +162,9 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<div class="small mt-5">
|
<div class="small mt-5 text-muted">
|
||||||
<div ng-messages="serviceForm['ingress_port_'+$index].$error">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</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="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">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">hostname</span>
|
<span class="input-group-addon">Hostname</span>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="hostname_port_{{ $index }}"
|
name="hostname_port_{{ $index }}"
|
||||||
|
@ -176,9 +186,9 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<div class="small mt-1">
|
<div class="small mt-1 text-muted">
|
||||||
<div ng-messages="serviceForm['hostname_port_'+$index].$error">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</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="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">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">route</span>
|
<span class="input-group-addon">Route</span>
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="ingress_route_{{ $index }}"
|
name="ingress_route_{{ $index }}"
|
||||||
|
@ -199,10 +209,10 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<div class="small mt-1">
|
<div class="small mt-1 text-muted">
|
||||||
<div ng-messages="serviceForm['ingress_route_'+$index].$error">
|
<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 class="vertical-center" 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="pattern"
|
||||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphanumeric characters or the special characters: '-', '_'
|
><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
|
or '/'. It must start and end with an alphanumeric character (e.g. 'my-route', or 'route-123').</p
|
||||||
>
|
>
|
||||||
|
@ -236,7 +246,7 @@
|
||||||
<button
|
<button
|
||||||
ng-disabled="$ctrl.servicePorts.length === 1"
|
ng-disabled="$ctrl.servicePorts.length === 1"
|
||||||
ng-show="!$ctrl.multiItemDisable"
|
ng-show="!$ctrl.multiItemDisable"
|
||||||
class="btn btn-sm btn-light btn-only-icon"
|
class="btn btn-sm btn-dangerlight btn-only-icon"
|
||||||
type="button"
|
type="button"
|
||||||
ng-click="$ctrl.removePort($index)"
|
ng-click="$ctrl.removePort($index)"
|
||||||
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
||||||
|
|
|
@ -9,13 +9,7 @@
|
||||||
ng-options="item.typeValue as item.typeName for item in $ctrl.state.serviceType"
|
ng-options="item.typeValue as item.typeName for item in $ctrl.state.serviceType"
|
||||||
data-cy="k8sAppCreate-publishingModeDropdown"
|
data-cy="k8sAppCreate-publishingModeDropdown"
|
||||||
></select>
|
></select>
|
||||||
<button
|
<button type="button" class="btn btn-md btn-default vertical-center !ml-0" ng-click="$ctrl.addEntry( $ctrl.state.selected )" data-cy="k8sAppCreate-createServiceButton">
|
||||||
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"
|
|
||||||
>
|
|
||||||
<pr-icon icon="'plus'" size="'sm'" feather="true"></pr-icon> Create service
|
<pr-icon icon="'plus'" size="'sm'" feather="true"></pr-icon> Create service
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,8 +19,10 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 form-inline" style="margin-top: 20px" ng-repeat="service in $ctrl.formValues.Services">
|
<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 ng-if="!$ctrl.formValues.Services[$index].Ingress">
|
||||||
<div class="text-muted">
|
<div class="text-muted vertical-center">
|
||||||
<i class="{{ $ctrl.iconStyle(service.Type) }}" aria-hidden="true" style="margin-right: 2px"></i>
|
<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) }}
|
{{ $ctrl.serviceType(service.Type) }}
|
||||||
</div>
|
</div>
|
||||||
<kube-services-item-view
|
<kube-services-item-view
|
||||||
|
@ -50,17 +46,17 @@
|
||||||
|
|
||||||
<div ng-if="$ctrl.formValues.Services[$index].Ingress && $ctrl.formValues.OriginalIngresses.length === 0">
|
<div ng-if="$ctrl.formValues.Services[$index].Ingress && $ctrl.formValues.OriginalIngresses.length === 0">
|
||||||
<div class="text-muted">
|
<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
|
Ingress
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="$ctrl.isAdmin()" class="small">
|
<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
|
<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.
|
<a ui-sref="kubernetes.cluster.setup">here</a> to configure ingress.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="!$ctrl.isAdmin()" class="small">
|
<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
|
<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.
|
administrator.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="$ctrl.formValues.IsSimple">
|
<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
|
Switch to advanced mode to copy and paste multiple key/values
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="!$ctrl.formValues.IsSimple">
|
<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
|
Generate a configuration entry per line, use YAML format
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<div ng-repeat="(index, entry) in $ctrl.formValues.Data" ng-if="$ctrl.formValues.IsSimple">
|
<div ng-repeat="(index, entry) in $ctrl.formValues.Data" ng-if="$ctrl.formValues.IsSimple">
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && !entry.IsBinary">
|
<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">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<textarea
|
<textarea
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && entry.IsBinary">
|
<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"
|
<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
|
>Binary data <portainer-tooltip message="'This key holds binary data and cannot be displayed.'"></portainer-tooltip
|
||||||
></div>
|
></div>
|
||||||
|
@ -117,15 +117,23 @@
|
||||||
<pr-icon class="vertical-center" icon="'trash-2'" feather="true"></pr-icon> Remove entry
|
<pr-icon class="vertical-center" icon="'trash-2'" feather="true"></pr-icon> Remove entry
|
||||||
</button>
|
</button>
|
||||||
<span class="small text-muted" ng-if="entry.Used">
|
<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
|
This key is currently used by one or more applications
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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" />
|
<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>
|
</div>
|
||||||
</ng-form>
|
</ng-form>
|
||||||
|
|
|
@ -43,15 +43,15 @@ class KubernetesConfigurationDataController {
|
||||||
this.onChangeKey();
|
this.onChangeKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
async editorUpdateAsync(cm) {
|
async editorUpdateAsync(value) {
|
||||||
if (this.formValues.DataYaml !== cm.getValue()) {
|
if (this.formValues.DataYaml !== value) {
|
||||||
this.formValues.DataYaml = cm.getValue();
|
this.formValues.DataYaml = value;
|
||||||
this.isEditorDirty = true;
|
this.isEditorDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editorUpdate(cm) {
|
editorUpdate(value) {
|
||||||
return this.$async(this.editorUpdateAsync, cm);
|
return this.$async(this.editorUpdateAsync, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onFileLoadAsync(event) {
|
async onFileLoadAsync(event) {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 form-section-title"> Resource reservation </div>
|
<div class="col-sm-12 form-section-title"> Resource reservation </div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small">
|
<span class="col-sm-12 text-muted small vertical-center">
|
||||||
<p>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
{{ $ctrl.description }}
|
{{ $ctrl.description }}
|
||||||
</p>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-if="$ctrl.memoryLimit !== 0">
|
<div class="form-group" ng-if="$ctrl.memoryLimit !== 0">
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
<div>
|
<div>
|
||||||
<code-editor identifier="application-details-yaml" read-only="true" value="$ctrl.data"></code-editor>
|
<web-editor-form
|
||||||
<div class="p-5">
|
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()">
|
<span class="btn btn-light btn-sm" ng-click="$ctrl.copyYAML()">
|
||||||
<pr-icon class="vertical-center" icon="'copy'" feather="true"></pr-icon>
|
<pr-icon class="vertical-center" icon="'copy'" feather="true"></pr-icon>
|
||||||
Copy to clipboard
|
Copy to clipboard
|
||||||
</span>
|
</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="'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>
|
<pr-icon class="vertical-center" icon="'plus'" size="'sm'" ng-if="!$ctrl.expanded" feather="true"></pr-icon>
|
||||||
{{ $ctrl.expanded ? 'Collapse' : 'Expand' }}
|
{{ $ctrl.expanded ? 'Collapse' : 'Expand' }}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button
|
<button
|
||||||
type="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-disabled="$ctrl.actionInProgress || $ctrl.form.$invalid || !$ctrl.formValues.Title || !$ctrl.formValues.FileContent"
|
||||||
ng-click="$ctrl.submitAction()"
|
ng-click="$ctrl.submitAction()"
|
||||||
button-spinner="$ctrl.actionInProgress"
|
button-spinner="$ctrl.actionInProgress"
|
||||||
|
|
|
@ -63,9 +63,9 @@ angular
|
||||||
return function (value) {
|
return function (value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case KubernetesApplicationDataAccessPolicies.ISOLATED:
|
case KubernetesApplicationDataAccessPolicies.ISOLATED:
|
||||||
return 'fa-cubes';
|
return 'svg-cubes';
|
||||||
case KubernetesApplicationDataAccessPolicies.SHARED:
|
case KubernetesApplicationDataAccessPolicies.SHARED:
|
||||||
return 'fa-cube';
|
return 'box';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 small text-muted vertical-center">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</kubernetes-applications-datatable>
|
</kubernetes-applications-datatable>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
<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 dataset="ctrl.state.ports" table-key="kubernetes.applications.ports" order-by="Name" refresh-callback="ctrl.getApplications">
|
||||||
</kubernetes-applications-ports-datatable>
|
</kubernetes-applications-ports-datatable>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
title="'Edit application'"
|
title="'Edit application'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||||
{
|
{
|
||||||
label:ctrl.application.ResourcePool,
|
label:ctrl.application.ResourcePool,
|
||||||
link: 'kubernetes.resourcePools.resourcePool',
|
link: 'kubernetes.resourcePools.resourcePool',
|
||||||
linkParams:{ id: ctrl.application.ResourcePool }
|
linkParams:{ id: ctrl.application.ResourcePool }
|
||||||
},
|
},
|
||||||
{ label:'Applications', link:'kubernetes.applications' },
|
{ label:'Applications', link:'kubernetes.applications' },
|
||||||
{
|
{
|
||||||
label:ctrl.application.Name,
|
label:ctrl.application.Name,
|
||||||
link: 'kubernetes.applications.application',
|
link: 'kubernetes.applications.application',
|
||||||
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
||||||
},
|
},
|
||||||
'Edit',
|
'Edit',
|
||||||
|
@ -97,10 +97,12 @@
|
||||||
>
|
>
|
||||||
<editor-description>
|
<editor-description>
|
||||||
<span class="text-muted small" ng-show="ctrl.stack.IsComposeFormat">
|
<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>
|
<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
|
<span>
|
||||||
all the Compose format options are supported by Kompose at the moment.
|
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>
|
||||||
<p>
|
<p>
|
||||||
You can get more information about Compose file format in the
|
You can get more information about Compose file format in the
|
||||||
|
@ -108,8 +110,8 @@
|
||||||
</p>
|
</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted small" ng-show="!ctrl.stack.IsComposeFormat">
|
<span class="text-muted small" ng-show="!ctrl.stack.IsComposeFormat">
|
||||||
<p>
|
<p class="vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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...).
|
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -124,7 +126,7 @@
|
||||||
<div class="col-sm-12 form-section-title"> Application </div>
|
<div class="col-sm-12 form-section-title"> Application </div>
|
||||||
<!-- #region NAME FIELD -->
|
<!-- #region NAME FIELD -->
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -142,17 +144,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.application_name.$invalid || ctrl.state.alreadyExists">
|
<div class="form-group" ng-show="kubernetesApplicationCreationForm.application_name.$invalid || ctrl.state.alreadyExists">
|
||||||
<div class="col-sm-12 small">
|
<div class="small">
|
||||||
<div ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
<div class="col-sm-3 col-lg-2"></div>
|
||||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p>
|
<div class="col-sm-8" ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||||
<p ng-message="pattern">
|
<p class="text-muted vertical-center" ng-message="required"
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
><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
|
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').
|
alphanumeric character (e.g. 'my-name', or 'abc-123').
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p ng-if="ctrl.state.alreadyExists">
|
<p class="text-muted vertical-center" ng-if="ctrl.state.alreadyExists">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
<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.
|
An application with the same name already exists inside the selected namespace.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -166,8 +171,8 @@
|
||||||
model="ctrl.formValues.ImageModel"
|
model="ctrl.formValues.ImageModel"
|
||||||
ng-if="ctrl.formValues.ResourcePool"
|
ng-if="ctrl.formValues.ResourcePool"
|
||||||
auto-complete="false"
|
auto-complete="false"
|
||||||
label-class="col-sm-1"
|
label-class="col-sm-3 col-lg-2"
|
||||||
input-class="col-sm-11"
|
input-class="col-sm-8"
|
||||||
namespace="ctrl.formValues.ResourcePool.Namespace.Name"
|
namespace="ctrl.formValues.ResourcePool.Namespace.Name"
|
||||||
endpoint="ctrl.endpoint"
|
endpoint="ctrl.endpoint"
|
||||||
is-admin="ctrl.isAdmin"
|
is-admin="ctrl.isAdmin"
|
||||||
|
@ -182,8 +187,8 @@
|
||||||
<div class="col-sm-12 form-section-title"> Stack </div>
|
<div class="col-sm-12 form-section-title"> Stack </div>
|
||||||
<!-- #region STACK -->
|
<!-- #region STACK -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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
|
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.
|
use the application name.
|
||||||
</div>
|
</div>
|
||||||
|
@ -209,8 +214,8 @@
|
||||||
<div class="col-sm-12 form-section-title"> Environment </div>
|
<div class="col-sm-12 form-section-title"> Environment </div>
|
||||||
<!-- #region ENVIRONMENT VARIABLES -->
|
<!-- #region ENVIRONMENT VARIABLES -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12 vertical-center pt-2.5">
|
||||||
<label class="control-label text-left">Environment variables</label>
|
<label class="control-label text-left !pt-0">Environment variables</label>
|
||||||
<span
|
<span
|
||||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||||
class="label label-default interactive vertical-center"
|
class="label label-default interactive vertical-center"
|
||||||
|
@ -227,7 +232,7 @@
|
||||||
<div style="margin-top: 2px">
|
<div style="margin-top: 2px">
|
||||||
<div class="col-sm-4 input-group input-group-sm">
|
<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 }">
|
<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
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="environment_variable_name_{{ $index }}"
|
name="environment_variable_name_{{ $index }}"
|
||||||
|
@ -257,7 +262,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-2 input-group input-group-sm" ng-if="ctrl.formValues.Containers.length <= 1">
|
<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>
|
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
@ -277,7 +287,7 @@
|
||||||
ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined
|
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
|
<div
|
||||||
class="small"
|
class="small"
|
||||||
style="margin-top: 5px"
|
style="margin-top: 5px"
|
||||||
|
@ -287,19 +297,19 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ng-messages for="kubernetesApplicationCreationForm['environment_variable_name_' + $index].$error">
|
<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="required" class="text-muted vertical-center"
|
||||||
<p ng-message="pattern"
|
><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, '_', '-',
|
><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
|
or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1'.</p
|
||||||
>
|
>
|
||||||
</ng-messages>
|
</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
|
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This environment variable is already defined.</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -309,8 +319,8 @@
|
||||||
<div class="col-sm-12 form-section-title"> Configurations </div>
|
<div class="col-sm-12 form-section-title"> Configurations </div>
|
||||||
<!-- #region CONFIGURATIONS -->
|
<!-- #region CONFIGURATIONS -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12 vertical-center pt-2.5">
|
||||||
<label class="control-label text-left">Configurations</label>
|
<label class="control-label text-left !pt-0">Configurations</label>
|
||||||
<span
|
<span
|
||||||
class="label label-default interactive vertical-center"
|
class="label label-default interactive vertical-center"
|
||||||
style="margin-left: 10px"
|
style="margin-left: 10px"
|
||||||
|
@ -321,8 +331,8 @@
|
||||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add configuration
|
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add configuration
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 small text-muted" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
<div class="col-sm-12 small text-muted vertical-center" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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
|
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.
|
key via the override button.
|
||||||
</div>
|
</div>
|
||||||
|
@ -341,9 +351,9 @@
|
||||||
data-cy="k8sAppCreate-addConfigSelect_{{ $index }}"
|
data-cy="k8sAppCreate-addConfigSelect_{{ $index }}"
|
||||||
></select>
|
></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3" style="margin-top: 2px">
|
<div class="col-sm-3">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-light vertical-center"
|
class="btn btn-md btn-light vertical-center !ml-0"
|
||||||
type="button"
|
type="button"
|
||||||
ng-if="!config.Overriden"
|
ng-if="!config.Overriden"
|
||||||
ng-click="ctrl.overrideConfiguration(index)"
|
ng-click="ctrl.overrideConfiguration(index)"
|
||||||
|
@ -353,7 +363,7 @@
|
||||||
<pr-icon icon="'list'" size="'md'" feather="true"></pr-icon> Override
|
<pr-icon icon="'list'" size="'md'" feather="true"></pr-icon> Override
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-light vertical-center"
|
class="btn btn-md btn-light vertical-center !ml-0"
|
||||||
type="button"
|
type="button"
|
||||||
ng-if="config.Overriden"
|
ng-if="config.Overriden"
|
||||||
ng-click="ctrl.resetConfiguration(index)"
|
ng-click="ctrl.resetConfiguration(index)"
|
||||||
|
@ -363,13 +373,13 @@
|
||||||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon> Auto
|
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon> Auto
|
||||||
</button>
|
</button>
|
||||||
<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"
|
type="button"
|
||||||
ng-click="ctrl.removeConfiguration(index)"
|
ng-click="ctrl.removeConfiguration(index)"
|
||||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||||
data-cy="k8sAppCreate-configRemoveButton"
|
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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- no-override -->
|
<!-- no-override -->
|
||||||
|
@ -390,16 +400,16 @@
|
||||||
<div ng-repeat="(keyIndex, overridenKey) in config.OverridenKeys" style="margin-top: 2px">
|
<div ng-repeat="(keyIndex, overridenKey) in config.OverridenKeys" style="margin-top: 2px">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-lg-2 form-group !m-0"><span> </span></div>
|
<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">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-addon">configuration key</span>
|
<span class="input-group-addon">configuration key</span>
|
||||||
<input type="text" class="form-control" ng-value="overridenKey.Key" disabled />
|
<input type="text" class="form-control" ng-value="overridenKey.Key" disabled />
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -428,9 +438,11 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ng-messages for="kubernetesApplicationCreationForm['overriden_key_path_' + index + '_' + keyIndex].$error">
|
<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>
|
</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
|
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already used.</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -459,17 +471,17 @@
|
||||||
<div class="col-sm-12 form-section-title"> Persisting data </div>
|
<div class="col-sm-12 form-section-title"> Persisting data </div>
|
||||||
<!-- #region PERSISTED FOLDERS -->
|
<!-- #region PERSISTED FOLDERS -->
|
||||||
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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.
|
No storage option is available to persist data, contact your administrator to enable a storage option.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
||||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
<div class="col-sm-12 vertical-center pt-2.5" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||||
<label class="control-label text-left">Persisted folders</label>
|
<label class="control-label text-left !pt-0">Persisted folders</label>
|
||||||
<span
|
<span
|
||||||
class="label label-default interactive"
|
class="label label-default interactive vertical-center"
|
||||||
style="margin-left: 10px"
|
style="margin-left: 10px"
|
||||||
ng-click="ctrl.addPersistedFolder()"
|
ng-click="ctrl.addPersistedFolder()"
|
||||||
ng-if="ctrl.isAddPersistentFolderButtonShowed()"
|
ng-if="ctrl.isAddPersistentFolderButtonShowed()"
|
||||||
|
@ -480,7 +492,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
<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>
|
<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.
|
This namespace has exhausted its storage capacity. Contact your administrator to expand the capacity of the namespace.
|
||||||
</span>
|
</span>
|
||||||
|
@ -489,7 +501,7 @@
|
||||||
<div class="col-sm-12 form-inline" style="margin-top: 10px" ng-repeat="persistedFolder in ctrl.formValues.PersistedFolders">
|
<div class="col-sm-12 form-inline" style="margin-top: 10px" ng-repeat="persistedFolder in ctrl.formValues.PersistedFolders">
|
||||||
<div style="margin-top: 2px">
|
<div style="margin-top: 2px">
|
||||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }">
|
<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
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -514,7 +526,7 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="btn btn-primary"
|
class="btn btn-light"
|
||||||
ng-model="persistedFolder.UseNewVolume"
|
ng-model="persistedFolder.UseNewVolume"
|
||||||
uib-btn-radio="true"
|
uib-btn-radio="true"
|
||||||
ng-change="ctrl.useNewVolume($index)"
|
ng-change="ctrl.useNewVolume($index)"
|
||||||
|
@ -522,7 +534,7 @@
|
||||||
>New volume</label
|
>New volume</label
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="btn btn-primary"
|
class="btn btn-light"
|
||||||
ng-model="persistedFolder.UseNewVolume"
|
ng-model="persistedFolder.UseNewVolume"
|
||||||
uib-btn-radio="false"
|
uib-btn-radio="false"
|
||||||
ng-change="ctrl.useExistingVolume($index)"
|
ng-change="ctrl.useExistingVolume($index)"
|
||||||
|
@ -533,22 +545,23 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }" ng-if="persistedFolder.UseNewVolume">
|
<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
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control"
|
class="form-control !rounded-none"
|
||||||
name="persisted_folder_size_{{ $index }}"
|
name="persisted_folder_size_{{ $index }}"
|
||||||
ng-model="persistedFolder.Size"
|
ng-model="persistedFolder.Size"
|
||||||
placeholder="20"
|
placeholder="20"
|
||||||
ng-min="0"
|
min="0"
|
||||||
required
|
required
|
||||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||||
/>
|
/>
|
||||||
<span class="input-group-addon" style="padding: 0">
|
<span class="input-group-addon !p-0 !rounded-r-[5px]">
|
||||||
<select
|
<select
|
||||||
|
class="form-control w-12 !h-[28px] !border-none !rounded-r-[5px] text-xs"
|
||||||
ng-model="persistedFolder.SizeUnit"
|
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-options="unit for unit in ctrl.state.availableSizeUnits"
|
||||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||||
|
@ -595,12 +608,12 @@
|
||||||
<div ng-if="!ctrl.isEditAndStatefulSet() && !ctrl.state.useExistingVolume[$index] && ctrl.formValues.Containers.length <= 1">
|
<div ng-if="!ctrl.isEditAndStatefulSet() && !ctrl.state.useExistingVolume[$index] && ctrl.formValues.Containers.length <= 1">
|
||||||
<button
|
<button
|
||||||
ng-if="!persistedFolder.NeedsDeletion"
|
ng-if="!persistedFolder.NeedsDeletion"
|
||||||
class="btn btn-sm btn-danger"
|
class="btn btn-sm btn-dangerlight !ml-0 h-[30px]"
|
||||||
type="button"
|
type="button"
|
||||||
ng-click="ctrl.removePersistedFolder($index)"
|
ng-click="ctrl.removePersistedFolder($index)"
|
||||||
data-cy="k8sAppCreate-rmPersistentFolderButton"
|
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>
|
||||||
<button
|
<button
|
||||||
ng-if="persistedFolder.NeedsDeletion"
|
ng-if="persistedFolder.NeedsDeletion"
|
||||||
|
@ -616,6 +629,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
class="flex flex-row gap-x-1"
|
||||||
ng-show="
|
ng-show="
|
||||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid ||
|
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid ||
|
||||||
ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined ||
|
ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined ||
|
||||||
|
@ -627,36 +641,36 @@
|
||||||
>
|
>
|
||||||
<div class="input-group col-sm-3 input-group-sm">
|
<div class="input-group col-sm-3 input-group-sm">
|
||||||
<div
|
<div
|
||||||
class="small text-warning"
|
class="small text-muted"
|
||||||
style="margin-top: 5px"
|
style="margin-top: 5px"
|
||||||
ng-show="
|
ng-show="
|
||||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid || ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined
|
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid || ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$error">
|
<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>
|
</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
|
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already defined.</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group col-sm-2 input-group-sm"></div>
|
<div class="input-group col-sm-offset-2 col-sm-3 input-group-sm">
|
||||||
|
|
||||||
<div class="input-group col-sm-5 input-group-sm">
|
|
||||||
<div
|
<div
|
||||||
class="small text-warning"
|
class="small text-muted"
|
||||||
style="margin-top: 5px"
|
style="margin-top: 5px"
|
||||||
ng-show="
|
ng-show="
|
||||||
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid || ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined
|
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid || ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$error">
|
<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 class="vertical-center" 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="min"
|
||||||
|
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p
|
||||||
|
>
|
||||||
</ng-messages>
|
</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>
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
You can only request up to
|
You can only request up to
|
||||||
{{ ctrl.state.storages.availabilities[persistedFolder.StorageClass.Name] | kubernetesAppStorageRequestSizeHumanReadable }} for
|
{{ ctrl.state.storages.availabilities[persistedFolder.StorageClass.Name] | kubernetesAppStorageRequestSizeHumanReadable }} for
|
||||||
|
@ -696,7 +710,7 @@
|
||||||
|
|
||||||
<!-- access policy options -->
|
<!-- access policy options -->
|
||||||
<div class="form-group" style="margin-bottom: 0">
|
<div class="form-group" style="margin-bottom: 0">
|
||||||
<div class="boxselector_wrapper">
|
<div class="boxselector_wrapper !px-[15px]">
|
||||||
<div
|
<div
|
||||||
ng-if="
|
ng-if="
|
||||||
(!ctrl.state.isEdit && !ctrl.state.persistedFoldersUseExistingVolumes) ||
|
(!ctrl.state.isEdit && !ctrl.state.persistedFoldersUseExistingVolumes) ||
|
||||||
|
@ -712,7 +726,7 @@
|
||||||
/>
|
/>
|
||||||
<label for="data_access_isolated">
|
<label for="data_access_isolated">
|
||||||
<div class="boxselector_header">
|
<div class="boxselector_header">
|
||||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||||
Isolated
|
Isolated
|
||||||
</div>
|
</div>
|
||||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
<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"
|
style="cursor: pointer; border-color: #767676"
|
||||||
>
|
>
|
||||||
<div class="boxselector_header">
|
<div class="boxselector_header">
|
||||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||||
Isolated
|
Isolated
|
||||||
</div>
|
</div>
|
||||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
||||||
|
@ -750,7 +764,7 @@
|
||||||
/>
|
/>
|
||||||
<label for="data_access_shared">
|
<label for="data_access_shared">
|
||||||
<div class="boxselector_header">
|
<div class="boxselector_header">
|
||||||
<pr-icon icon="'sliders'" feather="true"></pr-icon>
|
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||||
Shared
|
Shared
|
||||||
</div>
|
</div>
|
||||||
<p>Application will be deployed as a Deployment with a shared storage access</p>
|
<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>
|
<div class="col-sm-12 form-section-title"> Resource reservations </div>
|
||||||
<!-- #region RESOURCE RESERVATIONS -->
|
<!-- #region RESOURCE RESERVATIONS -->
|
||||||
<div class="form-group" ng-if="!ctrl.state.resourcePoolHasQuota">
|
<div class="form-group" ng-if="!ctrl.state.resourcePoolHasQuota">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
Resource reservations are applied per instance of the application.
|
Resource reservations are applied per instance of the application.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded()">
|
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded()">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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
|
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.
|
are inherited from the namespace quota.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded()">
|
<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>
|
<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
|
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.
|
the namespace.
|
||||||
|
@ -806,22 +820,22 @@
|
||||||
|
|
||||||
<!-- memory-limit-input -->
|
<!-- memory-limit-input -->
|
||||||
<div
|
<div
|
||||||
class="form-group"
|
class="form-group flex"
|
||||||
ng-if="
|
ng-if="
|
||||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
(!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">
|
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||||
Memory
|
Memory limit (MB)
|
||||||
<portainer-tooltip
|
<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.'"
|
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>
|
</portainer-tooltip>
|
||||||
</label>
|
</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>
|
<slider model="ctrl.formValues.MemoryLimit" floor="ctrl.state.sliders.memory.min" ceil="ctrl.state.sliders.memory.max" step="128"></slider>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2 vertical-center">
|
||||||
<input
|
<input
|
||||||
name="memory_limit"
|
name="memory_limit"
|
||||||
ng-model="ctrl.formValues.MemoryLimit"
|
ng-model="ctrl.formValues.MemoryLimit"
|
||||||
|
@ -834,14 +848,12 @@
|
||||||
data-cy="k8sAppCreate-memoryLimit"
|
data-cy="k8sAppCreate-memoryLimit"
|
||||||
/>
|
/>
|
||||||
</div>
|
</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>
|
||||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.memory_limit.$invalid">
|
<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">
|
<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
|
><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 }}
|
{{ ctrl.state.sliders.memory.max }}
|
||||||
</p>
|
</p>
|
||||||
|
@ -851,28 +863,26 @@
|
||||||
<!-- !memory-limit-input -->
|
<!-- !memory-limit-input -->
|
||||||
<!-- cpu-limit-input -->
|
<!-- cpu-limit-input -->
|
||||||
<div
|
<div
|
||||||
class="form-group"
|
class="form-group flex"
|
||||||
ng-if="
|
ng-if="
|
||||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
(!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">
|
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||||
CPU
|
CPU limit
|
||||||
<portainer-tooltip
|
<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.'"
|
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>
|
</portainer-tooltip>
|
||||||
</label>
|
</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>
|
<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>
|
||||||
<div class="col-sm-4" style="margin-top: 20px">
|
|
||||||
<p class="small text-muted"> Maximum CPU usage </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.nodeLimitsOverflow()">
|
<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>
|
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||||
These reservations would exceed the resources currently available in the cluster.
|
These reservations would exceed the resources currently available in the cluster.
|
||||||
</div>
|
</div>
|
||||||
|
@ -888,7 +898,7 @@
|
||||||
|
|
||||||
<!-- deployment options -->
|
<!-- deployment options -->
|
||||||
<div class="form-group" style="margin-bottom: 0">
|
<div class="form-group" style="margin-bottom: 0">
|
||||||
<div class="boxselector_wrapper">
|
<div class="boxselector_wrapper !px-[15px]">
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
|
@ -905,7 +915,7 @@
|
||||||
<p>Run one or multiple instances of this container</p>
|
<p>Run one or multiple instances of this container</p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div style="color: #767676" ng-if="!ctrl.supportGlobalDeployment()">
|
<div ng-if="!ctrl.supportGlobalDeployment()">
|
||||||
<input type="radio" id="deployment_global" disabled />
|
<input type="radio" id="deployment_global" disabled />
|
||||||
<label
|
<label
|
||||||
for="deployment_global"
|
for="deployment_global"
|
||||||
|
@ -913,10 +923,9 @@
|
||||||
tooltip-placement="bottom"
|
tooltip-placement="bottom"
|
||||||
tooltip-class="portainer-tooltip"
|
tooltip-class="portainer-tooltip"
|
||||||
uib-tooltip="The storage or access policy used for persisted folders cannot be used with this option"
|
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">
|
<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
|
Global
|
||||||
</div>
|
</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 cluster</p>
|
||||||
|
@ -933,10 +942,10 @@
|
||||||
/>
|
/>
|
||||||
<label for="deployment_global">
|
<label for="deployment_global">
|
||||||
<div class="boxselector_header">
|
<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
|
Global
|
||||||
</div>
|
</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>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -945,8 +954,8 @@
|
||||||
|
|
||||||
<!-- replica count -->
|
<!-- replica count -->
|
||||||
<div class="form-group form-inline" ng-if="ctrl.formValues.DeploymentType === ctrl.ApplicationDeploymentTypes.REPLICATED">
|
<div class="form-group form-inline" ng-if="ctrl.formValues.DeploymentType === ctrl.ApplicationDeploymentTypes.REPLICATED">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12 vertical-center">
|
||||||
<label class="control-label text-left"> Instance count </label>
|
<label class="control-label text-left !pt-0"> Instance count </label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
name="replica_count"
|
name="replica_count"
|
||||||
|
@ -964,10 +973,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-if="kubernetesApplicationCreationForm['replica_count'].$invalid">
|
<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">
|
<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 class="vertical-center" 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="min"
|
||||||
|
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p
|
||||||
|
>
|
||||||
</ng-messages>
|
</ng-messages>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -977,33 +988,37 @@
|
||||||
class="form-group"
|
class="form-group"
|
||||||
ng-if="!ctrl.resourceReservationsOverflow() && ctrl.formValues.ReplicaCount > 1 && (ctrl.formValues.CpuLimit !== 0 || ctrl.formValues.MemoryLimit !== 0)"
|
ng-if="!ctrl.resourceReservationsOverflow() && ctrl.formValues.ReplicaCount > 1 && (ctrl.formValues.CpuLimit !== 0 || ctrl.formValues.MemoryLimit !== 0)"
|
||||||
>
|
>
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
This application will reserve the following resources:
|
<div>
|
||||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
This application will reserve the following resources:
|
||||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
<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>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.resourceReservationsOverflow()">
|
<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>
|
<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.
|
This application would exceed available resources. Please review resource reservations or the instance count.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.state.storages.quotaExceeded">
|
<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>
|
<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.
|
This application would exceed available storage. Please review the persisted folders or the instance count.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="!ctrl.supportScalableReplicaDeployment()">
|
<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>
|
<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
|
<div>
|
||||||
>. You will not be able to scale that application.
|
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>
|
||||||
</div>
|
</div>
|
||||||
<!-- #endregion -->
|
<!-- #endregion -->
|
||||||
|
@ -1013,8 +1028,10 @@
|
||||||
|
|
||||||
<div class="form-group" ng-if="ctrl.formValues.DeploymentType !== ctrl.ApplicationDeploymentTypes.GLOBAL && ctrl.state.useServerMetrics">
|
<div class="form-group" ng-if="ctrl.formValues.DeploymentType !== ctrl.ApplicationDeploymentTypes.GLOBAL && ctrl.state.useServerMetrics">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<label for="enable_auto_scaling" class="control-label text-left"> Enable auto scaling for this application </label>
|
<div class="col-sm-3 col-lg-2 pl-0 pt-0">
|
||||||
<label class="switch" style="margin-left: 20px">
|
<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
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -1022,7 +1039,7 @@
|
||||||
ng-model="ctrl.formValues.AutoScaler.IsUsed"
|
ng-model="ctrl.formValues.AutoScaler.IsUsed"
|
||||||
data-cy="k8sAppCreate-autoScaleCheckbox"
|
data-cy="k8sAppCreate-autoScaleCheckbox"
|
||||||
/>
|
/>
|
||||||
<i></i>
|
<span class="slider round"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1137,23 +1154,23 @@
|
||||||
|
|
||||||
<!-- #region PLACEMENTS -->
|
<!-- #region PLACEMENTS -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12 vertical-center pt-2.5">
|
||||||
<label class="control-label text-left">Placement rules</label>
|
<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()">
|
<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
|
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add rule
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12 small text-muted" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
<div class="col-sm-12 small text-muted vertical-center" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" 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> 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>
|
||||||
|
|
||||||
<div class="col-sm-12 form-inline" style="margin-top: 10px">
|
<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 ng-repeat-start="placement in ctrl.formValues.Placements" style="margin-top: 2px">
|
||||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control !rounded"
|
||||||
ng-model="placement.Label"
|
ng-model="placement.Label"
|
||||||
ng-options="label as (label.Key | kubernetesNodeLabelHumanReadbleText) for label in ctrl.nodesLabels"
|
ng-options="label as (label.Key | kubernetesNodeLabelHumanReadbleText) for label in ctrl.nodesLabels"
|
||||||
ng-change="ctrl.onChangePlacementLabel($index)"
|
ng-change="ctrl.onChangePlacementLabel($index)"
|
||||||
|
@ -1164,7 +1181,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control !rounded"
|
||||||
ng-model="placement.Value"
|
ng-model="placement.Value"
|
||||||
ng-options="value for value in placement.Label.Values"
|
ng-options="value for value in placement.Label.Values"
|
||||||
ng-disabled="ctrl.isEditAndNotNewPlacement($index)"
|
ng-disabled="ctrl.isEditAndNotNewPlacement($index)"
|
||||||
|
@ -1176,7 +1193,7 @@
|
||||||
<div class="col-sm-1 input-group">
|
<div class="col-sm-1 input-group">
|
||||||
<button
|
<button
|
||||||
ng-if="!placement.NeedsDeletion"
|
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"
|
type="button"
|
||||||
ng-click="ctrl.removePlacement($index)"
|
ng-click="ctrl.removePlacement($index)"
|
||||||
data-cy="k8sAppCreate-deletePlacementButton"
|
data-cy="k8sAppCreate-deletePlacementButton"
|
||||||
|
@ -1185,7 +1202,7 @@
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
ng-if="placement.NeedsDeletion"
|
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"
|
type="button"
|
||||||
ng-click="ctrl.restorePlacement($index)"
|
ng-click="ctrl.restorePlacement($index)"
|
||||||
data-cy="k8sAppCreate-restorePlacementButton"
|
data-cy="k8sAppCreate-restorePlacementButton"
|
||||||
|
@ -1196,8 +1213,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-repeat-end ng-show="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
<div ng-repeat-end ng-show="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||||
<div class="col-sm-5 input-group">
|
<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">
|
<div class="small text-muted" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||||
<p 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.
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This label is already defined.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1218,7 +1235,7 @@
|
||||||
|
|
||||||
<!-- placement policy options -->
|
<!-- placement policy options -->
|
||||||
<div class="form-group" style="margin-bottom: 0" ng-if="ctrl.formValues.Placements.length">
|
<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>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
|
@ -1316,7 +1333,7 @@
|
||||||
<button
|
<button
|
||||||
ng-if="ctrl.state.appType === ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"
|
ng-if="ctrl.state.appType === ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"
|
||||||
type="button"
|
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-disabled="!kubernetesApplicationCreationForm.$valid || ctrl.isDeployUpdateButtonDisabled() || !ctrl.imageValidityIsValid()"
|
||||||
ng-click="ctrl.deployApplication()"
|
ng-click="ctrl.deployApplication()"
|
||||||
button-spinner="ctrl.state.actionInProgress"
|
button-spinner="ctrl.state.actionInProgress"
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
title="'Application details'"
|
title="'Application details'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||||
{
|
{
|
||||||
label:ctrl.application.ResourcePool,
|
label:ctrl.application.ResourcePool,
|
||||||
link: 'kubernetes.resourcePools.resourcePool',
|
link: 'kubernetes.resourcePools.resourcePool',
|
||||||
linkParams:{ id: ctrl.application.ResourcePool }
|
linkParams:{ id: ctrl.application.ResourcePool }
|
||||||
},
|
},
|
||||||
{ label:'Applications', link:'kubernetes.applications' },
|
{ label:'Applications', link:'kubernetes.applications' },
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<rd-widget-body classes="no-padding">
|
<rd-widget-body classes="no-padding">
|
||||||
<uib-tabset active="ctrl.state.activeTab" justified="true" type="pills">
|
<uib-tabset active="ctrl.state.activeTab" justified="true" type="pills">
|
||||||
<uib-tab index="0" classes="btn-sm" select="ctrl.selectTab(0)">
|
<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">
|
<div style="padding: 20px">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -156,19 +156,19 @@
|
||||||
|
|
||||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||||
<uib-tab-heading>
|
<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">
|
<div ng-if="ctrl.state.placementWarning" class="vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
warning
|
warning
|
||||||
</div>
|
</div>
|
||||||
</uib-tab-heading>
|
</uib-tab-heading>
|
||||||
<div class="small text-muted vertical-center" style="padding: 20px">
|
<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.
|
The placement component helps you understand whether or not this application can be deployed on a specific node.
|
||||||
</div>
|
</div>
|
||||||
<kubernetes-application-placements-datatable
|
<kubernetes-application-placements-datatable
|
||||||
title-text="Placement constraints/preferences"
|
title-text="Placement constraints/preferences"
|
||||||
title-icon="fa-compress-arrows-alt"
|
title-icon="svg-compress"
|
||||||
dataset="ctrl.placements"
|
dataset="ctrl.placements"
|
||||||
table-key="kubernetes.application.placements"
|
table-key="kubernetes.application.placements"
|
||||||
order-by="Name"
|
order-by="Name"
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
|
|
||||||
<uib-tab index="2" classes="btn-sm" select="ctrl.selectTab(2)">
|
<uib-tab index="2" classes="btn-sm" select="ctrl.selectTab(2)">
|
||||||
<uib-tab-heading>
|
<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">
|
<div ng-if="ctrl.hasEventWarnings()" class="vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||||
|
@ -188,7 +188,7 @@
|
||||||
</uib-tab-heading>
|
</uib-tab-heading>
|
||||||
<kubernetes-events-datatable
|
<kubernetes-events-datatable
|
||||||
title-text="Events"
|
title-text="Events"
|
||||||
title-icon="fa-history"
|
title-icon="svg-clockrewind"
|
||||||
dataset="ctrl.events"
|
dataset="ctrl.events"
|
||||||
table-key="kubernetes.application.events"
|
table-key="kubernetes.application.events"
|
||||||
order-by="Date"
|
order-by="Date"
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
|
|
||||||
<uib-tab index="3" ng-if="ctrl.application.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
<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>
|
<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>
|
<kubernetes-yaml-inspector key="application-yaml" data="ctrl.application.Yaml"></kubernetes-yaml-inspector>
|
||||||
</div>
|
</div>
|
||||||
</uib-tab>
|
</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="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">
|
<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>
|
||||||
|
|
||||||
<div ng-if="ctrl.application.Services.length !== 0">
|
<div ng-if="ctrl.application.Services.length !== 0">
|
||||||
<!-- Services notice -->
|
<!-- Services notice -->
|
||||||
<div>
|
<div>
|
||||||
<div class="small text-muted">
|
<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>
|
||||||
</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="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">
|
<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.
|
This application does not have an autoscaling policy defined.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small text-muted" ng-if="!ctrl.application.Env.length > 0 && !ctrl.hasVolumeConfiguration()" style="margin-bottom: 15px">
|
<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.
|
This application is not using any environment variable or configuration.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -434,13 +434,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small text-muted" ng-if="!ctrl.hasPersistedFolders()">
|
<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.
|
This application has no persisted folders.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="ctrl.hasPersistedFolders()">
|
<div ng-if="ctrl.hasPersistedFolders()">
|
||||||
<div class="small text-muted" style="margin-bottom: 15px">
|
<div class="small text-muted vertical-center" style="margin-bottom: 15px">
|
||||||
Data access policy: <i class="fa {{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon }}" aria-hidden="true"></i>
|
Data access policy:
|
||||||
|
<pr-icon icon="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon" feather="true"></pr-icon>
|
||||||
{{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyText }}
|
{{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyText }}
|
||||||
<portainer-tooltip position="'right'" message="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyTooltip"> </portainer-tooltip>
|
<portainer-tooltip position="'right'" message="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyTooltip"> </portainer-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -456,7 +457,10 @@
|
||||||
{{ volume.MountPath }}
|
{{ volume.MountPath }}
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="volume.PersistentVolumeClaimName">
|
<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
|
><pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
|
@ -491,7 +495,10 @@
|
||||||
{{ volume.MountPath }}
|
{{ volume.MountPath }}
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="volume.PersistentVolumeClaimName">
|
<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
|
<pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName + '-' + container.PodName }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
<div class="toolBar">
|
<div class="toolBar">
|
||||||
<div class="toolBarTitle flex">
|
<div class="toolBarTitle flex">
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="vertical-center">
|
<span class="vertical-center">
|
||||||
{{ $ctrl.titleText }}
|
{{ $ctrl.titleText }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive border-none">
|
||||||
<table class="table table-hover nowrap-cells">
|
<table class="table table-hover nowrap-cells">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
<td>{{ service.spec.clusterIP }}</td>
|
<td>{{ service.spec.clusterIP }}</td>
|
||||||
<td ng-show="service.spec.type === 'LoadBalancer'">
|
<td ng-show="service.spec.type === 'LoadBalancer'">
|
||||||
<div ng-show="service.status.loadBalancer.ingress">
|
<div ng-show="service.status.loadBalancer.ingress">
|
||||||
<a target="_blank" ng-href="http://{{ service.status.loadBalancer.ingress[0].ip }}:{{ service.spec.ports[0].port }}">
|
<a class="vertical-center hyperlink" 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>
|
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||||
<span data-cy="k8sAppDetail-containerPort"> Access </span>
|
<span data-cy="k8sAppDetail-containerPort"> Access </span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,8 +32,14 @@
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="!ctrl.portHasIngressRules(port)">
|
<td ng-if="!ctrl.portHasIngressRules(port)">
|
||||||
<div ng-repeat="port in service.spec.ports">
|
<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">
|
<a
|
||||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i>
|
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">
|
<span data-cy="k8sAppDetail-containerPort">
|
||||||
{{ port.port }}
|
{{ port.port }}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<div class="toolBarTitle text-muted small vertical-center px-5 !gap-0">
|
<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>
|
<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
|
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>
|
</div>
|
||||||
<rd-widget-body>
|
<rd-widget-body>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
title="'Application logs'"
|
title="'Application logs'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||||
{
|
{
|
||||||
label:ctrl.application.ResourcePool,
|
label:ctrl.application.ResourcePool,
|
||||||
link: 'kubernetes.resourcePools.resourcePool',
|
link: 'kubernetes.resourcePools.resourcePool',
|
||||||
linkParams:{ id: ctrl.application.ResourcePool }
|
linkParams:{ id: ctrl.application.ResourcePool }
|
||||||
},
|
},
|
||||||
{ label:'Applications', link:'kubernetes.applications' },
|
{ label:'Applications', link:'kubernetes.applications' },
|
||||||
{
|
{
|
||||||
label:ctrl.application.Name,
|
label:ctrl.application.Name,
|
||||||
link: 'kubernetes.applications.application',
|
link: 'kubernetes.applications.application',
|
||||||
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
linkParams:{ name: ctrl.application.Name, namespace: ctrl.application.ResourcePool }
|
||||||
},
|
},
|
||||||
'Pods',
|
'Pods',
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
<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="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" style="height: 54%">
|
<div class="row">
|
||||||
<div class="col-sm-12" style="height: 100%">
|
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||||
<pre
|
<pre
|
||||||
class="log_viewer widget"
|
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>
|
><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'"
|
title="'Application stats'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||||
{
|
{
|
||||||
label:ctrl.state.transition.namespace,
|
label:ctrl.state.transition.namespace,
|
||||||
link: 'kubernetes.resourcePools.resourcePool',
|
link: 'kubernetes.resourcePools.resourcePool',
|
||||||
linkParams:{ id: ctrl.state.transition.namespace }
|
linkParams:{ id: ctrl.state.transition.namespace }
|
||||||
},
|
},
|
||||||
{ label:'Applications', link:'kubernetes.applications' },
|
{ label:'Applications', link:'kubernetes.applications' },
|
||||||
{
|
{
|
||||||
label:ctrl.state.transition.applicationName,
|
label:ctrl.state.transition.applicationName,
|
||||||
link: 'kubernetes.applications.application',
|
link: 'kubernetes.applications.application',
|
||||||
linkParams:{ name: ctrl.state.transition.applicationName, namespace: ctrl.state.transition.namespace }
|
linkParams:{ name: ctrl.state.transition.applicationName, namespace: ctrl.state.transition.namespace }
|
||||||
},
|
},
|
||||||
'Pods',
|
'Pods',
|
||||||
|
@ -28,8 +28,8 @@
|
||||||
|
|
||||||
<div ng-if="ctrl.state.viewReady">
|
<div ng-if="ctrl.state.viewReady">
|
||||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
||||||
<span class="small text-muted">
|
<span class="small text-muted vertical-center">
|
||||||
<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>
|
||||||
Portainer was unable to retrieve any metrics associated to that container. Please contact your administrator to ensure that the Kubernetes metrics feature is properly
|
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.
|
configured.
|
||||||
</span>
|
</span>
|
||||||
|
@ -37,7 +37,12 @@
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -57,12 +62,15 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-if="ctrl.state.networkStatsUnavailable">
|
<div class="form-group" ng-if="ctrl.state.networkStatsUnavailable">
|
||||||
<div class="col-sm-12">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -74,7 +82,12 @@
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<div class="chart-container" style="position: relative">
|
<div class="chart-container" style="position: relative">
|
||||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||||
|
@ -84,7 +97,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12" ng-if="!ctrl.state.networkStatsUnavailable">
|
<div class="col-lg-6 col-md-12 col-sm-12" ng-if="!ctrl.state.networkStatsUnavailable">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<div class="chart-container" style="position: relative">
|
<div class="chart-container" style="position: relative">
|
||||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<kubernetes-nodes-datatable
|
<kubernetes-nodes-datatable
|
||||||
title-text="Nodes"
|
title-text="Nodes"
|
||||||
title-icon="fa-hdd"
|
title-icon="hard-drive"
|
||||||
dataset="ctrl.nodes"
|
dataset="ctrl.nodes"
|
||||||
table-key="kubernetes.nodes"
|
table-key="kubernetes.nodes"
|
||||||
order-by="Name"
|
order-by="Name"
|
||||||
|
|
|
@ -51,19 +51,21 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-xs-3"> Availability </td>
|
<td class="col-xs-3"> Availability </td>
|
||||||
<td class="col-xs-9">
|
<td class="col-xs-9">
|
||||||
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
<div class="flex flex-col">
|
||||||
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
||||||
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
||||||
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
||||||
</select>
|
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
||||||
<span class="small vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
</select>
|
||||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
<div class="small text-muted vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||||
Cannot use this action while another node is currently being drained.
|
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||||
</span>
|
Cannot use this action while another node is currently being drained.
|
||||||
<span class="small vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
</div>
|
||||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
<div class="small text-muted vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||||
Cannot drain a node where this Portainer instance is running.
|
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||||
</span>
|
Cannot drain a node where this Portainer instance is running.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -126,14 +128,14 @@
|
||||||
>
|
>
|
||||||
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||||
</button>
|
</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
|
Restore
|
||||||
</button>
|
</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-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>
|
<span class="label label-info image-tag" ng-if="ctrl.isSystemLabel($index)" style="margin-left: 5px">system</span>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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>
|
<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>
|
</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)">
|
<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>
|
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||||
</button>
|
</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>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="small"
|
class="small text-muted"
|
||||||
style="margin-top: 5px"
|
style="margin-top: 5px"
|
||||||
ng-show="kubernetesNodeUpdateForm['taint_key_' + $index].$invalid || ctrl.state.duplicateTaintKeys[$index] !== undefined"
|
ng-show="kubernetesNodeUpdateForm['taint_key_' + $index].$invalid || ctrl.state.duplicateTaintKeys[$index] !== undefined"
|
||||||
>
|
>
|
||||||
|
@ -223,7 +225,7 @@
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||||
<uib-tab-heading>
|
<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()">
|
<div class="flex-center gap-1" ng-if="ctrl.hasEventWarnings()">
|
||||||
<pr-icon icon="'alert-circle'" mode="'warning-alt'" size="'sm'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-circle'" mode="'warning-alt'" size="'sm'" feather="true"></pr-icon>
|
||||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||||
|
@ -231,7 +233,7 @@
|
||||||
</uib-tab-heading>
|
</uib-tab-heading>
|
||||||
<kubernetes-events-datatable
|
<kubernetes-events-datatable
|
||||||
title-text="Events"
|
title-text="Events"
|
||||||
title-icon="fa-history"
|
title-icon="icon-nested-blue"
|
||||||
dataset="ctrl.events"
|
dataset="ctrl.events"
|
||||||
table-key="kubernetes.node.events"
|
table-key="kubernetes.node.events"
|
||||||
order-by="Date"
|
order-by="Date"
|
||||||
|
@ -264,7 +266,6 @@
|
||||||
refresh-callback="ctrl.getApplications"
|
refresh-callback="ctrl.getApplications"
|
||||||
loading="ctrl.state.applicationsLoading"
|
loading="ctrl.state.applicationsLoading"
|
||||||
title-text="Applications running on this node"
|
title-text="Applications running on this node"
|
||||||
title-icon="box"
|
|
||||||
>
|
>
|
||||||
</kubernetes-node-applications-datatable>
|
</kubernetes-node-applications-datatable>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
title="'Node stats'"
|
title="'Node stats'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Cluster', link:'kubernetes.cluster' },
|
{ label:'Cluster', link:'kubernetes.cluster' },
|
||||||
{
|
{
|
||||||
label:ctrl.state.transition.nodeName,
|
label:ctrl.state.transition.nodeName,
|
||||||
link: 'kubernetes.cluster.node',
|
link: 'kubernetes.cluster.node',
|
||||||
linkParams:{name: ctrl.state.transition.nodeName}
|
linkParams:{name: ctrl.state.transition.nodeName}
|
||||||
},
|
},
|
||||||
ctrl.state.transition.nodeName,
|
ctrl.state.transition.nodeName,
|
||||||
|
@ -17,15 +17,20 @@
|
||||||
|
|
||||||
<div ng-if="ctrl.state.viewReady">
|
<div ng-if="ctrl.state.viewReady">
|
||||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
||||||
<span class="small text-muted">
|
<span class="small text-muted vertical-center">
|
||||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
<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.
|
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>
|
</span>
|
||||||
</information-panel>
|
</information-panel>
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -45,7 +50,7 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -57,7 +62,12 @@
|
||||||
<div class="row" ng-show="ctrl.state.getMetrics">
|
<div class="row" ng-show="ctrl.state.getMetrics">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<div class="chart-node" style="position: relative">
|
<div class="chart-node" style="position: relative">
|
||||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||||
|
@ -67,7 +77,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<rd-widget>
|
<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>
|
<rd-widget-body>
|
||||||
<div class="chart-node" style="position: relative">
|
<div class="chart-node" style="position: relative">
|
||||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
<form class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off">
|
<form class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off">
|
||||||
<!-- name -->
|
<!-- name -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left required">Name</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -32,7 +32,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-show="kubernetesConfigurationCreationForm.configuration_name.$invalid || ctrl.state.alreadyExist">
|
<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">
|
<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="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"
|
<p ng-message="pattern" class="vertical-center"
|
||||||
|
@ -52,7 +53,7 @@
|
||||||
<!-- resource-pool -->
|
<!-- resource-pool -->
|
||||||
<div class="form-group" ng-if="ctrl.formValues.ResourcePool">
|
<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>
|
<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
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="resource-pool-selector"
|
id="resource-pool-selector"
|
||||||
|
@ -86,13 +87,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- type options -->
|
<!-- 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 class="boxselector_wrapper">
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="type_basic" ng-value="ctrl.KubernetesConfigurationTypes.CONFIGMAP" ng-model="ctrl.formValues.Type" />
|
<input type="radio" id="type_basic" ng-value="ctrl.KubernetesConfigurationTypes.CONFIGMAP" ng-model="ctrl.formValues.Type" />
|
||||||
<label for="type_basic" data-cy="k8sConfigCreate-nonSensitiveButton">
|
<label for="type_basic" data-cy="k8sConfigCreate-nonSensitiveButton">
|
||||||
<div class="boxselector_header">
|
<div class="boxselector_header">
|
||||||
<pr-icon icon="'code'" feather="true"></pr-icon>
|
<pr-icon icon="'svg-filecode'"></pr-icon>
|
||||||
ConfigMap
|
ConfigMap
|
||||||
</div>
|
</div>
|
||||||
<p>This configuration holds non-sensitive information</p>
|
<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" />
|
<input type="radio" id="type_secret" ng-value="ctrl.KubernetesConfigurationTypes.SECRET" ng-model="ctrl.formValues.Type" />
|
||||||
<label for="type_secret" data-cy="k8sConfigCreate-sensitiveButton">
|
<label for="type_secret" data-cy="k8sConfigCreate-sensitiveButton">
|
||||||
<div class="boxselector_header">
|
<div class="boxselector_header">
|
||||||
<pr-icon icon="'shield'" feather="true"></pr-icon>
|
<pr-icon icon="'lock'" feather="true"></pr-icon>
|
||||||
Secret
|
Secret
|
||||||
</div>
|
</div>
|
||||||
<p>This configuration holds sensitive information</p>
|
<p>This configuration holds sensitive information</p>
|
||||||
|
|
|
@ -60,13 +60,13 @@
|
||||||
<pr-icon icon="'svg-clockrewind'"></pr-icon>
|
<pr-icon icon="'svg-clockrewind'"></pr-icon>
|
||||||
Events
|
Events
|
||||||
<div ng-if="ctrl.hasEventWarnings()">
|
<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)
|
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||||
</div>
|
</div>
|
||||||
</uib-tab-heading>
|
</uib-tab-heading>
|
||||||
<kubernetes-events-datatable
|
<kubernetes-events-datatable
|
||||||
title-text="Events"
|
title-text="Events"
|
||||||
title-icon="fa-history"
|
title-icon="svg-clockrewind"
|
||||||
dataset="ctrl.events"
|
dataset="ctrl.events"
|
||||||
table-key="kubernetes.configuration.events"
|
table-key="kubernetes.configuration.events"
|
||||||
order-by="Date"
|
order-by="Date"
|
||||||
|
@ -143,9 +143,11 @@
|
||||||
<td>
|
<td>
|
||||||
<div style="white-space: pre-wrap">{{ item.Value }}</div>
|
<div style="white-space: pre-wrap">{{ item.Value }}</div>
|
||||||
<div style="margin-top: 2px">
|
<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">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
title="'Kubernetes features configuration'"
|
title="'Kubernetes features configuration'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Environments', link:'portainer.endpoints' },
|
{ label:'Environments', link:'portainer.endpoints' },
|
||||||
{
|
{
|
||||||
label:ctrl.endpoint.Name,
|
label:ctrl.endpoint.Name,
|
||||||
link: 'portainer.endpoints.endpoint',
|
link: 'portainer.endpoints.endpoint',
|
||||||
linkParams:{id: ctrl.endpoint.Id}
|
linkParams:{id: ctrl.endpoint.Id}
|
||||||
},
|
},
|
||||||
'Kubernetes configuration'
|
'Kubernetes configuration'
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12">
|
<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">
|
<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>
|
<input type="checkbox" ng-model="ctrl.formValues.UseLoadBalancer" /><span class="slider round" data-cy="kubeSetup-loadBalancerToggle"></span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<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> Configuring ingress controllers will allow users to expose application they deploy over a HTTP route. </p>
|
||||||
<p class="mt-1 vertical-center">
|
<p class="mt-1 vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
|
@ -165,7 +165,7 @@
|
||||||
feature-id="ctrl.limitedFeatureAutoWindow"
|
feature-id="ctrl.limitedFeatureAutoWindow"
|
||||||
tooltip="'Specify a timeframe during which automatic updates can occur in this environment.'"
|
tooltip="'Specify a timeframe during which automatic updates can occur in this environment.'"
|
||||||
on-change="(ctrl.onToggleAutoUpdate)"
|
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'"
|
switch-class="'col-sm-8'"
|
||||||
>
|
>
|
||||||
</por-switch-field>
|
</por-switch-field>
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<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">
|
<label class="switch col-sm-8">
|
||||||
<input type="checkbox" ng-model="ctrl.formValues.RestrictDefaultNamespace" /><span class="slider round" data-cy="kubeSetup-restrictDefaultNsToggle"></span>
|
<input type="checkbox" ng-model="ctrl.formValues.RestrictDefaultNamespace" /><span class="slider round" data-cy="kubeSetup-restrictDefaultNsToggle"></span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
feature-id="ctrl.limitedFeature"
|
feature-id="ctrl.limitedFeature"
|
||||||
checked="ctrl.formValues.EnableResourceOverCommit"
|
checked="ctrl.formValues.EnableResourceOverCommit"
|
||||||
on-change="(ctrl.onChangeEnableResourceOverCommit)"
|
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'"
|
switch-class="'col-sm-8'"
|
||||||
></por-switch-field>
|
></por-switch-field>
|
||||||
</div>
|
</div>
|
||||||
|
@ -234,14 +234,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<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">
|
<label class="switch col-sm-8">
|
||||||
<input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
|
<input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
|
||||||
<span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
|
<span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="ctrl.state.metrics.pending && ctrl.state.metrics.userClick" class="col-sm-12 small text-muted" style="margin-top: 5px">
|
<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>
|
||||||
<div
|
<div
|
||||||
ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
||||||
|
@ -291,7 +291,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-repeat="class in ctrl.StorageClasses">
|
<tr ng-repeat="class in ctrl.StorageClasses">
|
||||||
<td>
|
<td>
|
||||||
<div class="flex-center justify-start">
|
<div class="flex-row vertical-center">
|
||||||
<label class="switch mr-2 mb-0">
|
<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>
|
<input type="checkbox" ng-model="class.selected" /><span class="slider round" data-cy="kubeSetup-storageToggle{{ class.Name }}"></span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -341,7 +341,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-primary btn-sm !ml-0"
|
||||||
ng-click="ctrl.configure()"
|
ng-click="ctrl.configure()"
|
||||||
ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
|
ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
|
||||||
button-spinner="ctrl.state.actionInProgress"
|
button-spinner="ctrl.state.actionInProgress"
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="ctrl.configurations" data-cy="k8sDashboard-configurations">
|
<div ng-if="ctrl.configurations" data-cy="k8sDashboard-configurations">
|
||||||
<a ui-sref="kubernetes.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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="ctrl.volumes" data-cy="k8sDashboard-volumes">
|
<div ng-if="ctrl.volumes" data-cy="k8sDashboard-volumes">
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-sm-8">
|
||||||
<input type="text" class="form-control" ng-model="ctrl.formValues.StackName" id="stack_name" placeholder="my-app" auto-focus />
|
<input type="text" class="form-control" ng-model="ctrl.formValues.StackName" id="stack_name" placeholder="my-app" auto-focus />
|
||||||
</div>
|
</div>
|
||||||
|
@ -117,10 +117,12 @@
|
||||||
>
|
>
|
||||||
<editor-description>
|
<editor-description>
|
||||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.COMPOSE">
|
<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>
|
<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
|
<span>
|
||||||
not all the Compose format options are supported by Kompose at the moment.
|
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>
|
||||||
<p>
|
<p>
|
||||||
You can get more information about Compose file format in the
|
You can get more information about Compose file format in the
|
||||||
|
@ -128,8 +130,8 @@
|
||||||
</p>
|
</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES">
|
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES">
|
||||||
<p>
|
<p class="vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<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...).
|
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -149,7 +151,7 @@
|
||||||
<span class="col-sm-12 text-muted small"> Indicate the URL to the manifest. </span>
|
<span class="col-sm-12 text-muted small"> Indicate the URL to the manifest. </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -170,7 +172,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-primary btn-sm !ml-0"
|
||||||
ng-disabled="!deploymentForm.$valid ||ctrl.disableDeploy()"
|
ng-disabled="!deploymentForm.$valid ||ctrl.disableDeploy()"
|
||||||
ng-click="ctrl.deploy()"
|
ng-click="ctrl.deploy()"
|
||||||
button-spinner="ctrl.state.actionInProgress"
|
button-spinner="ctrl.state.actionInProgress"
|
||||||
|
|
|
@ -43,6 +43,14 @@
|
||||||
<rd-widget-header icon="svg-userlock" title-text="Create access"></rd-widget-header>
|
<rd-widget-header icon="svg-userlock" title-text="Create access"></rd-widget-header>
|
||||||
<rd-widget-body>
|
<rd-widget-body>
|
||||||
<form class="form-horizontal">
|
<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">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select user(s) and/or team(s) </label>
|
<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">
|
<div class="col-sm-9 col-lg-4">
|
||||||
|
@ -92,7 +100,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<access-datatable
|
<access-datatable
|
||||||
ng-if="ctrl.authorizedUsersAndTeams"
|
ng-if="ctrl.authorizedUsersAndTeams"
|
||||||
title-text="Access"
|
title-text="Namespace access"
|
||||||
title-icon="svg-userlock"
|
title-icon="svg-userlock"
|
||||||
table-key="kubernetes_resourcepool_access"
|
table-key="kubernetes_resourcepool_access"
|
||||||
order-by="Name"
|
order-by="Name"
|
||||||
|
|
|
@ -76,19 +76,20 @@
|
||||||
<div ng-if="$ctrl.formValues.HasQuota">
|
<div ng-if="$ctrl.formValues.HasQuota">
|
||||||
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
||||||
<div>
|
<div>
|
||||||
<div class="form-group" ng-if="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 small text-muted">
|
<span class="col-sm-12 small text-muted" ng-switch on="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
||||||
<p class="vertical-center"
|
<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
|
><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.
|
valid.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="vertical-center mb-0" ng-switch-default></p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- memory-limit-input -->
|
<!-- memory-limit-input -->
|
||||||
<div class="form-group">
|
<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 </label>
|
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory limit (MB) </label>
|
||||||
<div class="col-sm-3">
|
<div class="col-xs-6">
|
||||||
<slider
|
<slider
|
||||||
model="$ctrl.formValues.MemoryLimit"
|
model="$ctrl.formValues.MemoryLimit"
|
||||||
floor="$ctrl.defaults.MemoryLimit"
|
floor="$ctrl.defaults.MemoryLimit"
|
||||||
|
@ -99,7 +100,7 @@
|
||||||
>
|
>
|
||||||
</slider>
|
</slider>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2 vertical-center">
|
||||||
<input
|
<input
|
||||||
name="memory_limit"
|
name="memory_limit"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -111,29 +112,29 @@
|
||||||
data-cy="k8sNamespaceCreate-memoryLimitInput"
|
data-cy="k8sNamespaceCreate-memoryLimitInput"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<span class="help-block">
|
</div>
|
||||||
<div class="form-group" ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
</div>
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="flex flex-row w-full">
|
||||||
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
<span class="col-sm-3 col-lg-2"></span>
|
||||||
<p class="vertical-center"
|
<span class="help-block col-sm-9 col-lg-10">
|
||||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between
|
<div ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
||||||
{{ $ctrl.defaults.MemoryLimit }} and
|
<div class="small text-muted">
|
||||||
{{ $ctrl.state.sliderMaxMemory }}
|
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
||||||
</p>
|
<p class="vertical-center"
|
||||||
</div>
|
><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>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</span>
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="small text-muted"> Maximum memory usage (MB) </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- !memory-limit-input -->
|
<!-- !memory-limit-input -->
|
||||||
<!-- cpu-limit-input -->
|
<!-- cpu-limit-input -->
|
||||||
<div class="form-group">
|
<div class="form-group flex flex-row">
|
||||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU </label>
|
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU limit </label>
|
||||||
<div class="col-sm-5">
|
<div class="col-xs-8">
|
||||||
<slider
|
<slider
|
||||||
model="$ctrl.formValues.CpuLimit"
|
model="$ctrl.formValues.CpuLimit"
|
||||||
floor="$ctrl.defaults.CpuLimit"
|
floor="$ctrl.defaults.CpuLimit"
|
||||||
|
@ -145,9 +146,6 @@
|
||||||
>
|
>
|
||||||
</slider>
|
</slider>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="small text-muted"> Maximum CPU usage </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- !cpu-limit-input -->
|
<!-- !cpu-limit-input -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -159,7 +157,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small vertical-center">
|
<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
|
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.
|
balancers in this namespace.
|
||||||
</span>
|
</span>
|
||||||
|
@ -184,7 +182,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small vertical-center">
|
<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
|
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.
|
prevent the usage of a specific storage option inside this namespace.
|
||||||
</span>
|
</span>
|
||||||
|
@ -211,7 +209,7 @@
|
||||||
<div class="form-group" ng-if="$ctrl.formValues.IngressClasses.length > 0">
|
<div class="form-group" ng-if="$ctrl.formValues.IngressClasses.length > 0">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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.
|
Enable and configure ingresses available to users when deploying applications.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -268,8 +266,8 @@
|
||||||
data-cy="namespaceCreate-hostnameInput{{ ic.IngressClass.Name }}_{{ $index }}"
|
data-cy="namespaceCreate-hostnameInput{{ ic.IngressClass.Name }}_{{ $index }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-1 input-group input-group-sm" ng-if="$index > 0">
|
<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 !h-[30px]" type="button" ng-click="$ctrl.removeHostname(ic, $index)">
|
<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>
|
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -282,13 +280,13 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<ng-messages for="resourcePoolCreationForm['hostname_' + ic.IngressClass.Name + '_' + $index].$error">
|
<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 class="vertical-center" 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="pattern">
|
||||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
<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').
|
This field must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com').
|
||||||
</p>
|
</p>
|
||||||
</ng-messages>
|
</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.
|
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> This hostname is already used.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -299,7 +297,7 @@
|
||||||
<div ng-repeat-end class="form-group" ng-if="ic.Selected">
|
<div ng-repeat-end class="form-group" ng-if="ic.Selected">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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.
|
You can specify a list of annotations that will be associated to the ingress.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -376,7 +374,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group input-group-sm col-sm-1">
|
<div class="input-group input-group-sm col-sm-1">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-dangerlight btn-only-icon !h-[30px]"
|
class="btn btn-md btn-dangerlight btn-only-icon"
|
||||||
type="button"
|
type="button"
|
||||||
ng-click="$ctrl.removeAnnotation(ic, $index)"
|
ng-click="$ctrl.removeAnnotation(ic, $index)"
|
||||||
data-cy="namespaceCreate-deleteAnnotationButton{{ ic.IngressClass.Name }}"
|
data-cy="namespaceCreate-deleteAnnotationButton{{ ic.IngressClass.Name }}"
|
||||||
|
@ -395,17 +393,17 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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.
|
Define which registries can be used by users who have access to this namespace.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select registries </label>
|
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||||
<div class="col-sm-9 col-lg-4">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && $ctrl.state.isAdmin">
|
<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>
|
||||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && !$ctrl.state.isAdmin">
|
<span class="small text-muted" ng-if="!$ctrl.registries.length && !$ctrl.state.isAdmin">
|
||||||
No registries available. Contact your administrator to create a container registry.
|
No registries available. Contact your administrator to create a container registry.
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
||||||
</a>
|
</a>
|
||||||
<span ng-if="path.ApplicationName !== '-'">
|
<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>
|
<a ui-sref="kubernetes.applications.application({ name: path.ApplicationName, namespace: item.Namespace })">{{ path.ApplicationName }}</a>
|
||||||
</span>
|
</span>
|
||||||
<span class="label label-warning image-tag label-margins" ng-if="path.ApplicationName === '-'">unused</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 class="col-sm-12 form-section-title"> Resource limits </div>
|
||||||
<div>
|
<div>
|
||||||
<!-- memory-limit-input -->
|
<!-- memory-limit-input -->
|
||||||
<div class="form-group">
|
<div class="form-group flex">
|
||||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> Memory limit </label>
|
<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-3">
|
<div class="col-sm-6">
|
||||||
<slider
|
<slider
|
||||||
model="ctrl.formValues.MemoryLimit"
|
model="ctrl.formValues.MemoryLimit"
|
||||||
floor="ctrl.ResourceQuotaDefaults.MemoryLimit"
|
floor="ctrl.ResourceQuotaDefaults.MemoryLimit"
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
ng-if="ctrl.state.sliderMaxMemory"
|
ng-if="ctrl.state.sliderMaxMemory"
|
||||||
></slider>
|
></slider>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2 vertical-center">
|
||||||
<input
|
<input
|
||||||
name="memory_limit"
|
name="memory_limit"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -100,12 +100,10 @@
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
|
||||||
<p class="small text-muted" style="margin-top: 7px"> Memory limit (<b>MB</b>) </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-show="resourcePoolEditForm.memory_limit.$invalid">
|
<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">
|
<div ng-messages="resourcePoolEditForm.pool_name.$error">
|
||||||
<p class="vertical-center">
|
<p class="vertical-center">
|
||||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between {{ ctrl.ResourceQuotaDefaults.MemoryLimit }} and
|
<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 -->
|
<!-- cpu-limit-input -->
|
||||||
<div class="form-group">
|
<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>
|
<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
|
<slider
|
||||||
model="ctrl.formValues.CpuLimit"
|
model="ctrl.formValues.CpuLimit"
|
||||||
floor="ctrl.ResourceQuotaDefaults.CpuLimit"
|
floor="ctrl.ResourceQuotaDefaults.CpuLimit"
|
||||||
|
@ -128,9 +126,6 @@
|
||||||
ng-if="ctrl.state.sliderMaxCpu"
|
ng-if="ctrl.state.sliderMaxCpu"
|
||||||
></slider>
|
></slider>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4" style="margin-top: 20px">
|
|
||||||
<p class="small text-muted"> Maximum CPU usage </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- !cpu-limit-input -->
|
<!-- !cpu-limit-input -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -141,7 +136,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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
|
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.
|
load balancers in this namespace.
|
||||||
</p>
|
</p>
|
||||||
|
@ -174,7 +169,7 @@
|
||||||
<div class="form-group" ng-if="ctrl.formValues.IngressClasses.length > 0">
|
<div class="form-group" ng-if="ctrl.formValues.IngressClasses.length > 0">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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.
|
Enable and configure ingresses available to users when deploying applications.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -220,7 +215,7 @@
|
||||||
<div ng-repeat="item in ic.Hosts track by $index" style="margin-top: 2px">
|
<div ng-repeat="item in ic.Hosts track by $index" style="margin-top: 2px">
|
||||||
<div class="form-inline">
|
<div class="form-inline">
|
||||||
<div class="col-sm-10 input-group input-group-sm" ng-class="{ striked: item.NeedsDeletion }">
|
<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
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
@ -257,7 +252,7 @@
|
||||||
'example.com').
|
'example.com').
|
||||||
</p>
|
</p>
|
||||||
</ng-messages>
|
</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>
|
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||||
This hostname is already used.
|
This hostname is already used.
|
||||||
</p>
|
</p>
|
||||||
|
@ -269,7 +264,7 @@
|
||||||
<div ng-repeat-end class="form-group" ng-if="ic.Selected" style="margin-bottom: 20px">
|
<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">
|
<div class="col-sm-12 small text-muted" style="margin-top: 5px">
|
||||||
<p class="vertical-center">
|
<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.
|
You can specify a list of annotations that will be associated to the ingress.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -338,8 +333,8 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-1 input-group input-group-sm">
|
<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)">
|
<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"></pr-icon>
|
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -363,18 +358,18 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p class="vertical-center">
|
<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.
|
Define which registries can be used by users who have access to this namespace.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 col-lg-2 control-label text-left" style="padding-top: 0"> Select registries </label>
|
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||||
<div class="col-sm-9 col-lg-4">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<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. 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>
|
||||||
<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.
|
No registries available. Contact your administrator to create a container registry.
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
@ -402,7 +397,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small">
|
<span class="col-sm-12 text-muted small">
|
||||||
<p class="vertical-center">
|
<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
|
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.
|
effectively prevent the usage of a specific storage option inside this namespace.
|
||||||
</p>
|
</p>
|
||||||
|
@ -433,7 +428,7 @@
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
ng-if="!ctrl.isSystem"
|
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-disabled="!resourcePoolEditForm.$valid || ctrl.isUpdateButtonDisabled()"
|
||||||
ng-click="ctrl.updateResourcePool()"
|
ng-click="ctrl.updateResourcePool()"
|
||||||
button-spinner="ctrl.state.actionInProgress"
|
button-spinner="ctrl.state.actionInProgress"
|
||||||
|
@ -444,7 +439,7 @@
|
||||||
<button
|
<button
|
||||||
ng-if="!ctrl.isDefaultNamespace"
|
ng-if="!ctrl.isDefaultNamespace"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-light btn-sm !ml-0"
|
||||||
ng-click="ctrl.markUnmarkAsSystem()"
|
ng-click="ctrl.markUnmarkAsSystem()"
|
||||||
button-spinner="ctrl.state.actionInProgress"
|
button-spinner="ctrl.state.actionInProgress"
|
||||||
data-cy="k8sNamespaceEdit-markSystem"
|
data-cy="k8sNamespaceEdit-markSystem"
|
||||||
|
@ -459,9 +454,9 @@
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||||
<uib-tab-heading class="vertical-center">
|
<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()">
|
<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)
|
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||||
</div>
|
</div>
|
||||||
</uib-tab-heading>
|
</uib-tab-heading>
|
||||||
|
@ -478,7 +473,7 @@
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
<uib-tab index="2" ng-if="ctrl.pool.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
<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>
|
<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>
|
<kubernetes-yaml-inspector key="resource-pool-yaml" data="ctrl.pool.Yaml"></kubernetes-yaml-inspector>
|
||||||
</div>
|
</div>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
endpoint="ctrl.endpoint"
|
endpoint="ctrl.endpoint"
|
||||||
dataset="ctrl.resourcePools"
|
dataset="ctrl.resourcePools"
|
||||||
table-key="kubernetes.resourcePools"
|
table-key="kubernetes.resourcePools"
|
||||||
order-by="Namespace.Name"
|
order-by="Name"
|
||||||
remove-action="ctrl.removeAction"
|
remove-action="ctrl.removeAction"
|
||||||
refresh-callback="ctrl.getResourcePools"
|
refresh-callback="ctrl.getResourcePools"
|
||||||
endpoint="ctrl.endpoint"
|
endpoint="ctrl.endpoint"
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
ng-if="ctrl.state.viewReady"
|
ng-if="ctrl.state.viewReady"
|
||||||
title="'Stacks logs'"
|
title="'Stacks logs'"
|
||||||
breadcrumbs="[
|
breadcrumbs="[
|
||||||
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
{ label:'Namespaces', link:'kubernetes.resourcePools' },
|
||||||
{ label:ctrl.state.transition.namespace, link:'kubernetes.resourcePools.resourcePool', linkParams:{ id: ctrl.state.transition.namespace } },
|
{ label:ctrl.state.transition.namespace, link:'kubernetes.resourcePools.resourcePool', linkParams:{ id: ctrl.state.transition.namespace } },
|
||||||
{ label:'Applications', link:'kubernetes.applications' },
|
{ label:'Applications', link:'kubernetes.applications' },
|
||||||
'Stacks',
|
'Stacks',
|
||||||
ctrl.state.transition.name,
|
ctrl.state.transition.name,
|
||||||
|
@ -14,7 +14,7 @@ ctrl.state.transition.name,
|
||||||
|
|
||||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
<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="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
|
@ -23,19 +23,22 @@ ctrl.state.transition.name,
|
||||||
<div class="col-sm-12 form-section-title"> Actions </div>
|
<div class="col-sm-12 form-section-title"> Actions </div>
|
||||||
<!-- auto-refresh -->
|
<!-- auto-refresh -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<label class="control-label text-left col-sm-3 col-lg-2 vertical-center !py-2">
|
||||||
<label class="control-label text-left">
|
Auto-refresh
|
||||||
Auto-refresh
|
<portainer-tooltip message="'Automatically refresh logs every 30 seconds'"></portainer-tooltip>
|
||||||
<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>
|
||||||
<label class="switch" style="margin-left: 20px"> <input type="checkbox" ng-model="ctrl.state.autoRefresh" ng-change="ctrl.updateAutoRefresh()" /><i></i> </label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- !auto-refresh -->
|
<!-- !auto-refresh -->
|
||||||
<!-- search -->
|
<!-- search -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="logs_search" class="col-sm-1 control-label text-left"> Search </label>
|
<label for="logs_search" class="col-sm-3 col-lg-2 control-label text-left"> Search </label>
|
||||||
<div class="col-sm-11">
|
<div class="col-sm-8 col-lg-9">
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -51,7 +54,10 @@ ctrl.state.transition.name,
|
||||||
<!-- actions -->
|
<!-- actions -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<!-- !actions -->
|
<!-- !actions -->
|
||||||
|
@ -61,8 +67,8 @@ ctrl.state.transition.name,
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" style="height: 54%">
|
<div class="row">
|
||||||
<div class="col-sm-12" style="height: 100%">
|
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||||
<pre
|
<pre
|
||||||
class="log_viewer"
|
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>
|
><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">
|
<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 pb-1"></pr-icon>
|
<pr-icon icon="$ctrl.state.expandedTemplate ? 'chevron-down' : 'chevron-right'" feather="true" class="!mr-1 vertical-center"></pr-icon>
|
||||||
Summary
|
Summary
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="$ctrl.state.expandedTemplate">
|
<div class="form-group" ng-if="$ctrl.state.expandedTemplate">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
Portainer will execute the following Kubernetes actions.
|
Portainer will execute the following Kubernetes actions.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap !p-0 w-full">
|
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap !p-0 w-full">
|
||||||
<div class="toolBarTitle vertical-center">
|
<div class="toolBarTitle vertical-center">
|
||||||
<div class="widget-icon space-right">
|
<div class="widget-icon space-right">
|
||||||
<pr-icon icon="'database'" feather="true"></pr-icon>
|
<pr-icon icon="'hard-drive'" feather="true"></pr-icon>
|
||||||
</div>
|
</div>
|
||||||
Storage
|
Storage
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
|
|
||||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||||
<uib-tab-heading class="vertical-center" data-cy="k8sVolDetail-volEventsTab">
|
<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()">
|
<div ng-if="ctrl.hasEventWarnings()">
|
||||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<!-- !access-control-switch -->
|
<!-- !access-control-switch -->
|
||||||
<!-- restricted-access -->
|
<!-- restricted-access -->
|
||||||
<div class="form-group" ng-if="$ctrl.formData.AccessControlEnabled" style="margin-bottom: 0">
|
<div class="form-group" ng-if="$ctrl.formData.AccessControlEnabled" style="margin-bottom: 0">
|
||||||
<div class="boxselector_wrapper">
|
<div class="boxselector_wrapper px-[15px]">
|
||||||
<div ng-if="$ctrl.isAdmin">
|
<div ng-if="$ctrl.isAdmin">
|
||||||
<input type="radio" id="access_administrators" ng-model="$ctrl.formData.Ownership" value="administrators" />
|
<input type="radio" id="access_administrators" ng-model="$ctrl.formData.Ownership" value="administrators" />
|
||||||
<label for="access_administrators" data-cy="portainer-selectAdminAccess">
|
<label for="access_administrators" data-cy="portainer-selectAdminAccess">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<ng-form name="commonCustomTemplateForm">
|
<ng-form name="commonCustomTemplateForm">
|
||||||
<!-- title-input -->
|
<!-- title-input -->
|
||||||
<div class="form-group mb-0">
|
<div class="form-group mb-0">
|
||||||
<label for="template_title" class="col-sm-3 col-lg-2 control-label text-left"> Title </label>
|
<label for="template_title" class="col-sm-3 col-lg-2 control-label text-left required"> Title </label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
<!-- description-input -->
|
<!-- description-input -->
|
||||||
<div class="form-group mb-0">
|
<div class="form-group mb-0">
|
||||||
<label for="description" class="col-sm-3 col-lg-2 control-label text-left">Description</label>
|
<label for="description" class="col-sm-3 col-lg-2 control-label text-left required">Description</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="text" class="form-control" id="description" ng-model="$ctrl.formValues.Description" name="description" required />
|
<input type="text" class="form-control" id="description" ng-model="$ctrl.formValues.Description" name="description" required />
|
||||||
<span class="help-block">
|
<span class="help-block">
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
<option value="" label="Select a Custom template" disabled selected="selected"> </option>
|
<option value="" label="Select a Custom template" disabled selected="selected"> </option>
|
||||||
</select>
|
</select>
|
||||||
<span class="small text-muted pt-[7px]" ng-if="!$ctrl.templates.length">
|
<span class="small text-muted pt-[7px]" ng-if="!$ctrl.templates.length">
|
||||||
No custom templates are available. Head over to the <a class="text-blue-8 hover:underline hover:text-blue-8" ui-state="$ctrl.newTemplatePath">custom template view</a> to
|
No custom templates are available. Head over to the <a class="hyperlink" ui-state="$ctrl.newTemplatePath">custom template view</a> to create one.
|
||||||
create one.
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<rd-widget-body classes="no-padding">
|
<rd-widget-body classes="no-padding">
|
||||||
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap">
|
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap">
|
||||||
<rd-widget-header icon="{{ $ctrl.titleIcon }}" feather-icon="true" title-text="Custom Templates" class="!flex-auto !mr-0" parent-classes="!p-0"></rd-widget-header>
|
<div class="toolBarTitle vertical-center">
|
||||||
|
<pr-icon icon="$ctrl.titleIcon" feather="true" class-name="'icon-nested-blue'" mode="'primary'"></pr-icon>
|
||||||
|
Custom Templates
|
||||||
|
</div>
|
||||||
<div class="searchBar vertical-center !mr-0">
|
<div class="searchBar vertical-center !mr-0">
|
||||||
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
border-radius: 8px;
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -99,9 +99,11 @@
|
||||||
{{ item.URL }}
|
{{ item.URL }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a ng-if="$ctrl.canManageAccess(item)" ng-click="$ctrl.redirectToManageAccess(item)"> <pr-icon icon="'users'" feather="true"></pr-icon> Manage access </a>
|
<a class="vertical-center" ng-if="$ctrl.canManageAccess(item)" ng-click="$ctrl.redirectToManageAccess(item)">
|
||||||
|
<pr-icon icon="'users'" feather="true"></pr-icon> Manage access
|
||||||
|
</a>
|
||||||
<be-feature-indicator feature="$ctrl.limitedFeature" ng-if="$ctrl.canBrowse(item)">
|
<be-feature-indicator feature="$ctrl.limitedFeature" ng-if="$ctrl.canBrowse(item)">
|
||||||
<span class="text-muted space-left" style="padding-right: 5px"> <pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon> Browse </span>
|
<span class="text-muted space-left" style="padding-right: 5px"> <pr-icon icon="'search'" feather="true"></pr-icon> Browse </span>
|
||||||
</be-feature-indicator>
|
</be-feature-indicator>
|
||||||
|
|
||||||
<span ng-if="!$ctrl.canBrowse(item) && !$ctrl.canManageAccess(item)"> - </span>
|
<span ng-if="!$ctrl.canBrowse(item) && !$ctrl.canManageAccess(item)"> - </span>
|
||||||
|
|
|
@ -11,6 +11,7 @@ export const webEditorForm = {
|
||||||
value: '<',
|
value: '<',
|
||||||
readOnly: '<',
|
readOnly: '<',
|
||||||
onChange: '<',
|
onChange: '<',
|
||||||
|
hideTitle: '<',
|
||||||
},
|
},
|
||||||
|
|
||||||
transclude: {
|
transclude: {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<ng-form name="$ctrl.webEditorForm">
|
<ng-form name="$ctrl.webEditorForm">
|
||||||
<div class="web-editor">
|
<div class="web-editor overflow-auto">
|
||||||
<div class="col-sm-12 form-section-title"> Web editor </div>
|
<div ng-if="!$ctrl.hideTitle" class="col-sm-12 form-section-title">Web editor</div>
|
||||||
<div class="form-group col-sm-12 col-lg-12">
|
<div class="trancluded-item form-group col-sm-12 col-lg-12 text-muted small" ng-transclude="description"></div>
|
||||||
<div class="text-muted small" ng-transclude="description"> </div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 col-lg-12">
|
<div class="col-sm-12 col-lg-12">
|
||||||
<code-editor
|
<code-editor
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<div class="form-inline mt-3">
|
<div class="form-inline mt-3">
|
||||||
<div class="input-group col-sm-5 input-group-sm">
|
<div class="input-group col-sm-5 input-group-sm">
|
||||||
<span class="input-group-addon">path</span>
|
<span class="input-group-addon required">path</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="name"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-sm btn-light btn-only-icon" type="button" ng-click="$ctrl.removeValue()" title="Remove">
|
<button class="btn btn-sm btn-dangerlight btn-only-icon" type="button" ng-click="$ctrl.removeValue()" title="Remove">
|
||||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="$ctrl.model.RepositoryAuthentication" class="row">
|
<div ng-if="$ctrl.model.RepositoryAuthentication" class="row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="repository_username" class="col-lg-2 col-sm-3 control-label text-left"> Username </label>
|
<label for="repository_username" class="col-lg-2 col-sm-3 control-label text-left required"> Username </label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -30,9 +30,9 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group flex">
|
||||||
<label for="repository_password" class="col-lg-2 col-sm-3 control-label text-left">
|
<label for="repository_password" class="col-lg-2 col-sm-3 control-label text-left !pt-0">
|
||||||
Personal Access Token
|
<div class="required"> Personal Access Token </div>
|
||||||
<portainer-tooltip message="'Provide a personal access token or password'"></portainer-tooltip>
|
<portainer-tooltip message="'Provide a personal access token or password'"></portainer-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
></por-switch-field>
|
></por-switch-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="small" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
<div class="small vertical-center" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
<span class="text-muted">Any changes to this stack or application made locally in Portainer will be overridden, which may cause service interruption.</span>
|
<span class="text-muted">Any changes to this stack or application made locally in Portainer will be overridden, which may cause service interruption.</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
<label for="repository_mechanism" class="col-sm-3 col-lg-2 control-label text-left"> Webhook </label>
|
<label for="repository_mechanism" class="col-sm-3 col-lg-2 control-label text-left"> Webhook </label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<span class="text-muted"> {{ $ctrl.model.RepositoryWebhookURL | truncatelr }} </span>
|
<span class="text-muted"> {{ $ctrl.model.RepositoryWebhookURL | truncatelr }} </span>
|
||||||
<button type="button" class="btn btn-sm btn-light btn-sm space-left" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
<button type="button" class="btn btn-sm btn-light btn-sm space-left vertical-center" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
||||||
<span><pr-icon icon="'copy'" size="'sm'" feather="true"></pr-icon> Copy link</span>
|
<pr-icon icon="'copy'" size="'sm'" feather="true"></pr-icon> Copy link
|
||||||
</button>
|
</button>
|
||||||
<span>
|
<span>
|
||||||
<pr-icon icon="'check'" mode="'success'" feather="true" style="display: none"></pr-icon>
|
<pr-icon icon="'check'" mode="'success'" feather="true" style="display: none"></pr-icon>
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates && $ctrl.model.RepositoryMechanism === 'Interval'">
|
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates && $ctrl.model.RepositoryMechanism === 'Interval'">
|
||||||
<label for="repository_fetch_interval" class="col-sm-3 col-lg-2 control-label text-left"> Fetch interval </label>
|
<label for="repository_fetch_interval" class="col-sm-3 col-lg-2 control-label text-left required"> Fetch interval </label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -94,11 +94,11 @@
|
||||||
></por-switch-field>
|
></por-switch-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="small" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
<div class="small vertical-center" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
<span class="text-muted">When enabled, enforces automatic deployment at each interval or webhook invocation.</span>
|
<span class="text-muted">When enabled, enforces automatic deployment at each interval or webhook invocation.</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="small" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
<div class="small vertical-center" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
||||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
<span class="text-muted">When enabled, updates from the git repository will occur automatically at an interval or webhook.</span>
|
<span class="text-muted">When enabled, updates from the git repository will occur automatically at an interval or webhook.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<ng-form name="pathForm">
|
<ng-form name="pathForm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small"
|
<span class="col-sm-12 text-muted small vertical-center">
|
||||||
><pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon> Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from the root
|
||||||
the root of your repository (requires a yaml, yml, json, or hcl file extension)
|
of your repository (requires a yaml, yml, json, or hcl file extension)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="stack_repository_path" class="col-lg-2 col-sm-3 control-label text-left">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
<label for="stack_repository_path" class="col-lg-2 col-sm-3 control-label text-left required">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="col-sm-12 text-muted small">
|
<span class="col-sm-12 text-muted small vertical-center">
|
||||||
Specify a reference of the repository using the following syntax: branches with <code>refs/heads/branch_name</code> or tags with <code>refs/tags/tag_name</code>. If not
|
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||||
specified, will use the default <code>HEAD</code> reference normally the <code>master</code> branch.
|
<span>
|
||||||
|
Specify a reference of the repository using the following syntax: branches with <code>refs/heads/branch_name</code> or tags with <code>refs/tags/tag_name</code>. If not
|
||||||
|
specified, will use the default <code>HEAD</code> reference normally the <code>master</code> branch.
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<span class="col-sm-12 text-muted small"> You can use the URL of a git repository. </span>
|
<span class="col-sm-12 text-muted small"> You can use the URL of a git repository. </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="stack_repository_url" class="col-lg-2 col-sm-3 control-label text-left">Repository URL</label>
|
<label for="stack_repository_url" class="col-lg-2 col-sm-3 control-label text-left required">Repository URL</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="row" ng-if="$ctrl.registry">
|
<div class="row" ng-if="$ctrl.registry">
|
||||||
<div class="col-lg-12 col-md-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-xs-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<rd-widget-header icon="svg-plug" title-text="Registry"></rd-widget-header>
|
<rd-widget-header icon="radio" feather-icon="true" title-text="Registry"></rd-widget-header>
|
||||||
<rd-widget-body classes="no-padding">
|
<rd-widget-body classes="no-padding">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
<div ng-class="{ 'blocklist-item--selected': $ctrl.model.Selected }" class="blocklist-item template-item !mr-0 !my-0" ng-click="$ctrl.onSelect($ctrl.model)">
|
<div ng-class="{ 'blocklist-item--selected': $ctrl.model.Selected }" class="blocklist-item template-item !mr-0 !my-0" ng-click="$ctrl.onSelect($ctrl.model)">
|
||||||
<div class="blocklist-item-box">
|
<div class="blocklist-item-box">
|
||||||
<!-- template-image -->
|
<!-- template-image -->
|
||||||
<div ng-if="$ctrl.model.Logo" class="vertical-center justify-center">
|
<div class="vertical-center justify-center min-w-[56px]">
|
||||||
<img class="blocklist-item-logo" ng-src="{{ $ctrl.model.Logo }}" />
|
<fallback-image
|
||||||
</div>
|
src="$ctrl.model.Logo"
|
||||||
<div class="blocklist-item-logo vertical-center justify-center" ng-if="!$ctrl.model.Logo">
|
fallback-icon="'svg-rocket'"
|
||||||
<pr-icon icon="'svg-rocket'" class-name="'[&>*]:!h-10 [&>*]:!w-auto [&>*>path]:stroke-blue-8'" mode="'primary'"></pr-icon>
|
class-name="'blocklist-item-logo'"
|
||||||
|
fallback-class-name="'!h-14 !w-14 [&>*]:!h-8 [&>*]:!w-auto icon-nested-blue'"
|
||||||
|
fallback-mode="'primary'"
|
||||||
|
></fallback-image>
|
||||||
</div>
|
</div>
|
||||||
<!-- !template-image -->
|
<!-- !template-image -->
|
||||||
<!-- template-details -->
|
<!-- template-details -->
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-primary btn-sm !ml-0"
|
||||||
ng-disabled="$ctrl.actionInProgress || customTemplateForm.$invalid
|
ng-disabled="$ctrl.actionInProgress || customTemplateForm.$invalid
|
||||||
|| !$ctrl.formValues.Title
|
|| !$ctrl.formValues.Title
|
||||||
|| !$ctrl.formValues.FileContent
|
|| !$ctrl.formValues.FileContent
|
||||||
|
|
|
@ -17,6 +17,7 @@ import checked from '@/assets/ico/checked.svg?c';
|
||||||
import circlenotch from '@/assets/ico/circle-notch.svg?c';
|
import circlenotch from '@/assets/ico/circle-notch.svg?c';
|
||||||
import clockrewind from '@/assets/ico/clock-rewind.svg?c';
|
import clockrewind from '@/assets/ico/clock-rewind.svg?c';
|
||||||
import compress from '@/assets/ico/compress.svg?c';
|
import compress from '@/assets/ico/compress.svg?c';
|
||||||
|
import cubes from '@/assets/ico/cubes.svg?c';
|
||||||
import custom from '@/assets/ico/custom.svg?c';
|
import custom from '@/assets/ico/custom.svg?c';
|
||||||
import dataflow from '@/assets/ico/dataflow-1.svg?c';
|
import dataflow from '@/assets/ico/dataflow-1.svg?c';
|
||||||
import dataflow2 from '@/assets/ico/dataflow-2.svg?c';
|
import dataflow2 from '@/assets/ico/dataflow-2.svg?c';
|
||||||
|
@ -96,6 +97,7 @@ export const SvgIcons = {
|
||||||
circlenotch,
|
circlenotch,
|
||||||
clockrewind,
|
clockrewind,
|
||||||
compress,
|
compress,
|
||||||
|
cubes,
|
||||||
custom,
|
custom,
|
||||||
expand,
|
expand,
|
||||||
filecode,
|
filecode,
|
||||||
|
|
|
@ -6,3 +6,13 @@
|
||||||
.inner-datatable table thead {
|
.inner-datatable table thead {
|
||||||
border-top: none !important;
|
border-top: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner-datatable tr > th:first-child,
|
||||||
|
.inner-datatable tr > td:first-child {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-datatable tr > th:last-child,
|
||||||
|
.inner-datatable tr > td:last-child {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
height: 495px;
|
height: 495px;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root.minimized {
|
.root.minimized {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -21,11 +27,11 @@
|
||||||
background: rgb(245, 245, 245);
|
background: rgb(245, 245, 245);
|
||||||
border-top: 1px solid rgb(190, 190, 190);
|
border-top: 1px solid rgb(190, 190, 190);
|
||||||
|
|
||||||
padding: 0 30px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: bold;
|
font-weight: 500;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,5 +42,6 @@
|
||||||
|
|
||||||
.terminal-container .loading-message {
|
.terminal-container .loading-message {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
padding: 10px 16px 0px 16px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { EnvironmentId } from '@/portainer/environments/types';
|
||||||
import { error as notifyError } from '@/portainer/services/notifications';
|
import { error as notifyError } from '@/portainer/services/notifications';
|
||||||
import { useLocalStorage } from '@/portainer/hooks/useLocalStorage';
|
import { useLocalStorage } from '@/portainer/hooks/useLocalStorage';
|
||||||
|
|
||||||
|
import { Icon } from '@@/Icon';
|
||||||
import { Button } from '@@/buttons';
|
import { Button } from '@@/buttons';
|
||||||
|
|
||||||
import styles from './KubectlShell.module.css';
|
import styles from './KubectlShell.module.css';
|
||||||
|
@ -125,27 +126,26 @@ export function KubeCtlShell({ environmentId, onClose }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className={clsx(styles.root, { [styles.minimized]: shell.minimized })}>
|
<div className={clsx(styles.root, { [styles.minimized]: shell.minimized })}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.title}>
|
<div className={clsx(styles.title, 'vertical-center')}>
|
||||||
<i className="fas fa-terminal space-right" />
|
<Icon icon="terminal" feather />
|
||||||
kubectl shell
|
kubectl shell
|
||||||
</div>
|
</div>
|
||||||
<div className={clsx(styles.actions, 'space-x-8')}>
|
<div className={clsx(styles.actions, 'space-x-8')}>
|
||||||
<Button color="link" onClick={clearScreen}>
|
<Button color="link" onClick={clearScreen}>
|
||||||
<i className="fas fa-redo-alt" data-cy="k8sShell-refreshButton" />
|
<Icon icon="rotate-cw" feather size="md" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button color="link" onClick={toggleMinimize}>
|
<Button color="link" onClick={toggleMinimize}>
|
||||||
<i
|
<Icon
|
||||||
className={clsx(
|
icon={shell.minimized ? 'maximize-2' : 'minimize-2'}
|
||||||
'fas',
|
feather
|
||||||
shell.minimized ? 'fa-window-restore' : 'fa-window-minimize'
|
size="md"
|
||||||
)}
|
|
||||||
data-cy={
|
data-cy={
|
||||||
shell.minimized ? 'k8sShell-restore' : 'k8sShell-minimise'
|
shell.minimized ? 'k8sShell-restore' : 'k8sShell-minimise'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button color="link" onClick={handleClose}>
|
<Button color="link" onClick={handleClose}>
|
||||||
<i className="fas fa-times" data-cy="k8sShell-closeButton" />
|
<Icon icon="x" feather size="md" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.root {
|
.root {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: -5px auto -8px auto;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
|
|
||||||
|
@ -5,6 +6,7 @@ import { EnvironmentId } from '@/portainer/environments/types';
|
||||||
import { useAnalytics } from '@/angulartics.matomo/analytics-services';
|
import { useAnalytics } from '@/angulartics.matomo/analytics-services';
|
||||||
|
|
||||||
import { Button } from '@@/buttons';
|
import { Button } from '@@/buttons';
|
||||||
|
import { Icon } from '@@/Icon';
|
||||||
|
|
||||||
import { KubeCtlShell } from './KubectlShell';
|
import { KubeCtlShell } from './KubectlShell';
|
||||||
import styles from './KubectlShellButton.module.css';
|
import styles from './KubectlShellButton.module.css';
|
||||||
|
@ -19,13 +21,14 @@ export function KubectlShellButton({ environmentId }: Props) {
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
size="xsmall"
|
size="small"
|
||||||
disabled={open}
|
disabled={open}
|
||||||
data-cy="k8sSidebar-shellButton"
|
data-cy="k8sSidebar-shellButton"
|
||||||
onClick={() => handleOpen()}
|
onClick={() => handleOpen()}
|
||||||
className={styles.root}
|
className={clsx(styles.root, '!flex')}
|
||||||
>
|
>
|
||||||
<i className="fa fa-terminal space-right" /> kubectl shell
|
<Icon icon="terminal" feather className="vertical-center" size="md" />{' '}
|
||||||
|
kubectl shell
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{open &&
|
{open &&
|
||||||
|
|
Loading…
Reference in New Issue