mirror of https://github.com/portainer/portainer
feat(kubernetes): UI improvements kube app create EE-3462 (#7149)
parent
de59ea030a
commit
82fb5f7ac1
|
@ -122,3 +122,11 @@ pr-icon {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-only-icon {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.btn-only-icon pr-icon {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="form-group" ng-if="$ctrl.pullRateLimits">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-if="$ctrl.pullRateLimits.remaining > 0" class="text-muted">
|
||||
<i class="fa fa-exclamation-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<div ng-if="$ctrl.pullRateLimits.remaining > 0" class="text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<span ng-if="$ctrl.isAuthenticated">
|
||||
You are currently using a free account to pull images from DockerHub and will be limited to 200 pulls every 6 hours. Remaining pulls:
|
||||
<span style="font-weight: bold">{{ $ctrl.pullRateLimits.remaining }}/{{ $ctrl.pullRateLimits.limit }}</span>
|
||||
|
@ -19,8 +19,8 @@
|
|||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div ng-if="$ctrl.pullRateLimits.remaining <= 0" class="text-warning">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
<div ng-if="$ctrl.pullRateLimits.remaining <= 0" class="text-warning vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<span ng-if="$ctrl.isAuthenticated">
|
||||
Your authorized pull count quota as a free user is now exceeded.
|
||||
<span ng-transclude="rateLimitExceeded">You will not be able to pull any image from the DockerHub registry.</span>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<!-- use registry -->
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="form-group" ng-if="$ctrl.model.UseRegistry">
|
||||
<label for="image_registry" class="control-label text-left" ng-class="$ctrl.labelClass"> Registry </label>
|
||||
<div ng-class="$ctrl.inputClass">
|
||||
<label for="image_registry" class="control-label text-left col-sm-3 col-lg-2" ng-class="$ctrl.labelClass"> Registry </label>
|
||||
<div ng-class="$ctrl.inputClass" class="col-sm-8">
|
||||
<select
|
||||
ng-options="registry as registry.Name for registry in $ctrl.registries track by registry.Id"
|
||||
ng-model="$ctrl.model.Registry"
|
||||
|
@ -11,8 +11,10 @@
|
|||
data-cy="component-registrySelect"
|
||||
></select>
|
||||
</div>
|
||||
<label for="image_name" ng-class="$ctrl.labelClass" class="margin-sm-top control-label text-left">Image</label>
|
||||
<div ng-class="$ctrl.inputClass" class="margin-sm-top">
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.model.UseRegistry">
|
||||
<label for="image_name" ng-class="$ctrl.labelClass" class="control-label text-left col-sm-3 col-lg-2">Image</label>
|
||||
<div ng-class="$ctrl.inputClass" class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="registry-name">{{ $ctrl.displayedRegistryURL() }}</span>
|
||||
<input
|
||||
|
@ -30,11 +32,11 @@
|
|||
<span ng-if="$ctrl.isDockerHubRegistry()" class="input-group-btn">
|
||||
<a
|
||||
href="https://hub.docker.com/search?type=image&q={{ $ctrl.model.Image | trimshasum | trimversiontag }}"
|
||||
class="btn btn-default"
|
||||
class="btn btn-default vertical-center"
|
||||
title="Search image on Docker Hub"
|
||||
target="_blank"
|
||||
>
|
||||
<i class="fab fa-docker"></i> Search
|
||||
<i class="fab fa-docker text-blue-6"></i> Search
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -45,13 +47,13 @@
|
|||
<div ng-if="!$ctrl.model.UseRegistry">
|
||||
<div class="form-group">
|
||||
<span class="small">
|
||||
<p class="text-muted" style="margin-left: 15px">
|
||||
<i class="fa fa-exclamation-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<p class="text-muted mb-5" style="margin-left: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
When using advanced mode, image and repository <b>must be</b> publicly available.
|
||||
</p>
|
||||
</span>
|
||||
<label for="image_name" ng-class="$ctrl.labelClass" class="control-label text-left">Image </label>
|
||||
<div ng-class="$ctrl.inputClass">
|
||||
<label for="image_name" ng-class="$ctrl.labelClass" class="control-label text-left col-sm-3 col-lg-2">Image </label>
|
||||
<div ng-class="$ctrl.inputClass" class="col-sm-8">
|
||||
<input type="text" class="form-control" ng-model="$ctrl.model.Image" name="image_name" placeholder="e.g. registry:port/my-image:my-tag" required />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,10 +61,10 @@
|
|||
<!-- ! don't use registry -->
|
||||
<!-- info message -->
|
||||
<div class="form-group" ng-show="$ctrl.form.image_name.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-messages="$ctrl.form.image_name.$error">
|
||||
<p ng-message="required">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Image name is required.
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></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>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import registriesModule from './registries';
|
||||
import customTemplateModule from './custom-templates';
|
||||
import { reactModule } from './react';
|
||||
import './views/kubernetes.css';
|
||||
|
||||
angular.module('portainer.kubernetes', ['portainer.app', registriesModule, customTemplateModule, reactModule]).config([
|
||||
'$stateRegistryProvider',
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<ng-form name="serviceForm">
|
||||
<div ng-if="$ctrl.isAdmin()" class="small text-warning" 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">
|
||||
<i class="fa fa-exclamation-circle" aria-hidden="true"></i> No Load balancer is available in this cluster, click
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
||||
<a ui-sref="portainer.k8sendpoint.kubernetesConfig({id: $ctrl.state.endpointId})">here</a> to configure load balancer.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small text-warning" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px"> <i class="fa fa-exclamation-circle" aria-hidden="true"></i> No Load balancer is available in this cluster, contract your administrator. </p>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, contract your administrator.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -16,223 +18,231 @@
|
|||
$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT
|
||||
"
|
||||
>
|
||||
<div ng-show="!$ctrl.multiItemDisable" style="margin-top: 5px; margin-bottom: 5px">
|
||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5">
|
||||
<label class="control-label text-left">Published ports</label>
|
||||
<span class="label label-default interactive" style="margin-left: 10px" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> publish a new port
|
||||
<span class="label label-default interactive ml-10 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> publish a new port
|
||||
</span>
|
||||
</div>
|
||||
<div ng-repeat="servicePort in $ctrl.servicePorts" style="margin-top: 10px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">container port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="container_port_{{ $index }}"
|
||||
ng-model="servicePort.targetPort"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
ng-change="$ctrl.servicePort($index)"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0 || ($ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled)"
|
||||
ng-change="$ctrl.onChangeContainerPort()"
|
||||
data-cy="k8sAppCreate-containerPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">service port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="service_port_{{ $index }}"
|
||||
ng-model="servicePort.port"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0 || ($ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled)"
|
||||
ng-change="$ctrl.onChangeServicePort()"
|
||||
data-cy="k8sAppCreate-servicePort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT" class="input-group input-group-sm">
|
||||
<span class="input-group-addon">nodeport</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="node_port_{{ $index }}"
|
||||
ng-model="servicePort.nodePort"
|
||||
placeholder="30080"
|
||||
ng-min="30000"
|
||||
ng-max="32767"
|
||||
ng-change="$ctrl.onChangeNodePort()"
|
||||
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER" class="input-group input-group-sm">
|
||||
<span class="input-group-addon">loadbalancer port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="loadbalancer_port_{{ $index }}"
|
||||
ng-model="servicePort.port"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
required
|
||||
ng-disabled="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled"
|
||||
data-cy="k8sAppCreate-loadbalancerPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType" class="input-group input-group-sm">
|
||||
<span class="input-group-addon">ingress</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="ingress_port_{{ $index }}"
|
||||
ng-model="servicePort.ingress.IngressName"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-options="ingress.Name as ingress.Name for ingress in $ctrl.originalIngresses"
|
||||
data-cy="k8sAppCreate-ingressPort_{{ $index }}"
|
||||
>
|
||||
<option selected disabled hidden value="">Select an ingress</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType" class="input-group input-group-sm">
|
||||
<span class="input-group-addon">hostname</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="hostname_port_{{ $index }}"
|
||||
ng-model="servicePort.ingress.Host"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-options="host as host for host in ($ctrl.originalIngresses | filter:{ Name: servicePort.ingress.IngressName })[0].Hosts"
|
||||
data-cy="k8sAppCreate-hostnamePort_{{ $index }}"
|
||||
>
|
||||
<option selected disabled hidden value="">Select a hostname</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType" class="input-group input-group-sm">
|
||||
<span class="input-group-addon">route</span>
|
||||
<input
|
||||
class="form-control"
|
||||
name="ingress_route_{{ $index }}"
|
||||
ng-model="servicePort.ingress.Path"
|
||||
placeholder="route"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-pattern="/^(\/?[a-zA-Z0-9]+([a-zA-Z0-9-/_]*[a-zA-Z0-9])?|[a-zA-Z0-9]+)|(\/){1}$/"
|
||||
data-cy="k8sAppCreate-route_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-2 input-group-sm">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
ng-model="servicePort.protocol"
|
||||
uib-btn-radio="'TCP'"
|
||||
ng-change="ctrl.onChangePortProtocol($index)"
|
||||
ng-disabled="ctrl.isProtocolOptionDisabled($index, 'TCP')"
|
||||
data-cy="k8sAppCreate-TCPButton_{{ $index }}"
|
||||
>TCP</label
|
||||
>
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
ng-model="servicePort.protocol"
|
||||
uib-btn-radio="'UDP'"
|
||||
ng-change="ctrl.onChangePortProtocol($index)"
|
||||
ng-disabled="ctrl.isProtocolOptionDisabled($index, 'UDP')"
|
||||
data-cy="k8sAppCreate-UDPButton_{{ $index }}"
|
||||
>UDP</label
|
||||
>
|
||||
<div ng-repeat="servicePort in $ctrl.servicePorts" class="mt-5 service-form row">
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">container port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="container_port_{{ $index }}"
|
||||
ng-model="servicePort.targetPort"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
ng-change="$ctrl.servicePort($index)"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0 || ($ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled)"
|
||||
ng-change="$ctrl.onChangeContainerPort()"
|
||||
data-cy="k8sAppCreate-containerPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
ng-disabled="$ctrl.servicePorts.length === 1"
|
||||
ng-show="!$ctrl.multiItemDisable"
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
ng-click="$ctrl.removePort($index)"
|
||||
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i>
|
||||
</button>
|
||||
<span>
|
||||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.targetPort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This container port is already used.
|
||||
</div>
|
||||
<div class="small mt-1" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 input-group input-group-sm">
|
||||
<div class="col-sm-2">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<p ng-if="$ctrl.state.duplicates.targetPort.refs[$index] !== undefined">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This container port is already used.
|
||||
</p>
|
||||
</div>
|
||||
<div class="small text-warning" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Container port number is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Container port number must be inside the range 1-65535.</p>
|
||||
</div>
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">service port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="service_port_{{ $index }}"
|
||||
ng-model="servicePort.port"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0 || ($ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled)"
|
||||
ng-change="$ctrl.onChangeServicePort()"
|
||||
data-cy="k8sAppCreate-servicePort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<p ng-if="$ctrl.state.duplicates.servicePort.refs[$index] !== undefined">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This service port is already used.
|
||||
</p>
|
||||
<span>
|
||||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.servicePort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This service port is already used.
|
||||
</div>
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<div class="small mt-1">
|
||||
<div ng-messages="serviceForm['service_port_'+$index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Service port number is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
||||
<p ng-message="min"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Node port number must be inside the range 30000-32767 or blank for system allocated.</p
|
||||
>
|
||||
<p ng-message="max"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Node port number must be inside the range 30000-32767 or blank for system allocated.</p
|
||||
>
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">nodeport</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="node_port_{{ $index }}"
|
||||
ng-model="servicePort.nodePort"
|
||||
placeholder="30080"
|
||||
ng-min="30000"
|
||||
ng-max="32767"
|
||||
ng-change="$ctrl.onChangeNodePort()"
|
||||
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
||||
<p ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
<p ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">loadbalancer port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
name="loadbalancer_port_{{ $index }}"
|
||||
ng-model="servicePort.port"
|
||||
placeholder="80"
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
required
|
||||
ng-disabled="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled"
|
||||
data-cy="k8sAppCreate-loadbalancerPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">ingress</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="ingress_port_{{ $index }}"
|
||||
ng-model="servicePort.ingress.IngressName"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-options="ingress.Name as ingress.Name for ingress in $ctrl.originalIngresses"
|
||||
data-cy="k8sAppCreate-ingressPort_{{ $index }}"
|
||||
>
|
||||
<option selected disabled hidden value="">Select an ingress</option>
|
||||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-5">
|
||||
<div ng-messages="serviceForm['ingress_port_'+$index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Ingress selection is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress selection is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">hostname</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="hostname_port_{{ $index }}"
|
||||
ng-model="servicePort.ingress.Host"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-options="host as host for host in ($ctrl.originalIngresses | filter:{ Name: servicePort.ingress.IngressName })[0].Hosts"
|
||||
data-cy="k8sAppCreate-hostnamePort_{{ $index }}"
|
||||
>
|
||||
<option selected disabled hidden value="">Select a hostname</option>
|
||||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div ng-messages="serviceForm['hostname_port_'+$index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Host is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Host is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3 clear-both" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">route</span>
|
||||
<input
|
||||
class="form-control"
|
||||
name="ingress_route_{{ $index }}"
|
||||
ng-model="servicePort.ingress.Path"
|
||||
placeholder="route"
|
||||
required
|
||||
ng-disabled="$ctrl.originalIngresses.length === 0"
|
||||
ng-pattern="/^(\/?[a-zA-Z0-9]+([a-zA-Z0-9-/_]*[a-zA-Z0-9])?|[a-zA-Z0-9]+)|(\/){1}$/"
|
||||
data-cy="k8sAppCreate-route_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-8" ng-show="">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div ng-messages="serviceForm['ingress_route_'+$index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Route is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Route is required.</p>
|
||||
<p ng-message="pattern"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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
|
||||
><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
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-2">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<label
|
||||
class="btn btn-light"
|
||||
ng-model="servicePort.protocol"
|
||||
uib-btn-radio="'TCP'"
|
||||
ng-change="ctrl.onChangePortProtocol($index)"
|
||||
ng-disabled="ctrl.isProtocolOptionDisabled($index, 'TCP')"
|
||||
data-cy="k8sAppCreate-TCPButton_{{ $index }}"
|
||||
>TCP</label
|
||||
>
|
||||
<label
|
||||
class="btn btn-light"
|
||||
ng-model="servicePort.protocol"
|
||||
uib-btn-radio="'UDP'"
|
||||
ng-change="ctrl.onChangePortProtocol($index)"
|
||||
ng-disabled="ctrl.isProtocolOptionDisabled($index, 'UDP')"
|
||||
data-cy="k8sAppCreate-UDPButton_{{ $index }}"
|
||||
>UDP</label
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
ng-disabled="$ctrl.servicePorts.length === 1"
|
||||
ng-show="!$ctrl.multiItemDisable"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
type="button"
|
||||
ng-click="$ctrl.removePort($index)"
|
||||
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,8 +9,14 @@
|
|||
ng-options="item.typeValue as item.typeName for item in $ctrl.state.serviceType"
|
||||
data-cy="k8sAppCreate-publishingModeDropdown"
|
||||
></select>
|
||||
<button type="button" class="btn btn-sm btn-default" style="margin-left: 0" ng-click="$ctrl.addEntry( $ctrl.state.selected )" data-cy="k8sAppCreate-createServiceButton">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> Create service
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-default vertical-center"
|
||||
style="margin-left: 0"
|
||||
ng-click="$ctrl.addEntry( $ctrl.state.selected )"
|
||||
data-cy="k8sAppCreate-createServiceButton"
|
||||
>
|
||||
<pr-icon icon="'plus'" size="'sm'" feather="true"></pr-icon> Create service
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -33,12 +39,12 @@
|
|||
></kube-services-item-view>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger space-right"
|
||||
class="btn btn-sm btn-dangerlight space-right vertical-center"
|
||||
style="margin-left: 0; margin-top: 10px"
|
||||
ng-click="$ctrl.deleteService( $index )"
|
||||
data-cy="k8sConfigCreate-removeButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -47,25 +53,26 @@
|
|||
<i class="fa fa-route" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
Ingress
|
||||
</div>
|
||||
<div ng-if="$ctrl.isAdmin()" class="small text-warning">
|
||||
<div ng-if="$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<i class="fa fa-exclamation-circle" aria-hidden="true"></i> 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="portainer.k8sendpoint.kubernetesConfig({id: $ctrl.state.endpointId})">here</a> to configure ingress.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small text-warning">
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<i class="fa fa-exclamation-circle" aria-hidden="true"></i> Ingress is not configured in this namespace, select another namespace or contact your administrator.
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress is not configured in this namespace, select another namespace or contact your
|
||||
administrator.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger space-right"
|
||||
class="btn btn-sm btn-dangerlight space-right vertical-center"
|
||||
style="margin-left: 0; margin-top: 10px"
|
||||
ng-click="$ctrl.deleteService( $index )"
|
||||
data-cy="k8sConfigCreate-removeButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -85,12 +92,12 @@
|
|||
></kube-services-item-view>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger space-right"
|
||||
class="btn btn-sm btn-dangerlight space-right vertical-center"
|
||||
style="margin-left: 0; margin-top: 10px"
|
||||
ng-click="$ctrl.deleteService( $index )"
|
||||
data-cy="k8sConfigCreate-removeButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<div class="row">
|
||||
<div class="row kubernetes-create">
|
||||
<div class="col-xs-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
|
@ -50,8 +50,8 @@
|
|||
<div class="col-sm-12 form-section-title" ng-if="ctrl.state.appType === ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"> Namespace </div>
|
||||
<!-- #region NAMESPACE -->
|
||||
<div class="form-group" ng-if="ctrl.formValues.ResourcePool">
|
||||
<label for="resource-pool-selector" class="col-sm-1 control-label text-left">Namespace</label>
|
||||
<div class="col-sm-11">
|
||||
<label for="resource-pool-selector" class="col-sm-3 col-lg-2 control-label text-left">Namespace</label>
|
||||
<div class="col-sm-8">
|
||||
<select
|
||||
class="form-control"
|
||||
id="resource-pool-selector"
|
||||
|
@ -65,14 +65,14 @@
|
|||
</div>
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded() && ctrl.formValues.ResourcePool">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its resource capacity and you will not be able to deploy the application. Contact your administrator to expand the capacity of the
|
||||
namespace.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="!ctrl.formValues.ResourcePool">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true"></pr-icon>
|
||||
You do not have access to any namespace. Contact your administrator to get access to a namespace.
|
||||
</div>
|
||||
</div>
|
||||
|
@ -98,7 +98,7 @@
|
|||
<editor-description>
|
||||
<span class="text-muted small" ng-show="ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that not
|
||||
all the Compose format options are supported by Kompose at the moment.
|
||||
</p>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</span>
|
||||
<span class="text-muted small" ng-show="!ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -124,8 +124,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Application </div>
|
||||
<!-- #region NAME FIELD -->
|
||||
<div class="form-group">
|
||||
<label for="application_name" class="col-sm-1 control-label text-left">Name</label>
|
||||
<div class="col-sm-11">
|
||||
<label for="application_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -142,17 +142,17 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.application_name.$invalid || ctrl.state.alreadyExists">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p>
|
||||
<p ng-message="pattern">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This field must consist of lower case alphanumeric characters or '-', contain at most 63 characters, start with an alphabetic character, and end with an
|
||||
alphanumeric character (e.g. 'my-name', or 'abc-123').
|
||||
</p>
|
||||
</div>
|
||||
<p ng-if="ctrl.state.alreadyExists">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
An application with the same name already exists inside the selected namespace.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -160,8 +160,7 @@
|
|||
<!-- #endregion -->
|
||||
|
||||
<!-- #region IMAGE FIELD -->
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-group mb-0">
|
||||
<div class="col-sm-12">
|
||||
<por-image-registry
|
||||
model="ctrl.formValues.ImageModel"
|
||||
|
@ -177,20 +176,22 @@
|
|||
></por-image-registry>
|
||||
</div>
|
||||
</div>
|
||||
<!-- #end region IMAGE FIELD -->
|
||||
|
||||
<div ng-if="ctrl.formValues.ResourcePool">
|
||||
<div class="col-sm-12 form-section-title"> Stack </div>
|
||||
<!-- #region STACK -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer can automatically bundle multiple applications inside a stack. Enter a name of a new stack or select an existing stack in the list. Leave empty to
|
||||
use the application name.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-sm-1 control-label text-left">Stack</label>
|
||||
<div class="col-sm-11">
|
||||
<label for="stack_name" class="col-sm-3 col-lg-2 control-label text-left">Stack</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -213,12 +214,12 @@
|
|||
<label class="control-label text-left">Environment variables</label>
|
||||
<span
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
class="label label-default interactive"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
ng-click="ctrl.addEnvironmentVariable()"
|
||||
data-cy="k8sAppCreate-addEnvVarButton"
|
||||
>
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add environment variable
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add environment variable
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -257,17 +258,17 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-2 input-group input-group-sm" ng-if="ctrl.formValues.Containers.length <= 1">
|
||||
<button ng-if="!envVar.NeedsDeletion" class="btn btn-sm btn-danger" type="button" ng-click="ctrl.removeEnvironmentVariable(envVar)">
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i>
|
||||
<button ng-if="!envVar.NeedsDeletion" class="btn btn-md btn-light btn-only-icon" type="button" ng-click="ctrl.removeEnvironmentVariable(envVar)">
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
ng-if="envVar.NeedsDeletion"
|
||||
class="btn btn-sm btn-primary"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
type="button"
|
||||
ng-click="ctrl.restoreEnvironmentVariable(envVar)"
|
||||
data-cy="k8sAppCreate-removeEnvVarButton_{{ $index }}"
|
||||
>
|
||||
<i class="fa fa-trash-restore" aria-hidden="true"></i>
|
||||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -279,7 +280,7 @@
|
|||
>
|
||||
<div class="col-sm-4 input-group input-group-sm">
|
||||
<div
|
||||
class="small text-warning"
|
||||
class="small"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['environment_variable_name_' + $index].$invalid ||
|
||||
|
@ -287,14 +288,14 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['environment_variable_name_' + $index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Environment variable name is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Environment variable name is required.</p>
|
||||
<p ng-message="pattern"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphabetic characters, digits, '_', '-',
|
||||
or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1'.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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>
|
||||
|
@ -312,17 +313,17 @@
|
|||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Configurations</label>
|
||||
<span
|
||||
class="label label-default interactive"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
ng-click="ctrl.addConfiguration()"
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
data-cy="k8sAppCreate-addConfigButton"
|
||||
>
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add configuration
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add configuration
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will automatically expose all the keys of a configuration as environment variables. This behavior can be overridden to filesystem mounts for each
|
||||
key via the override button.
|
||||
</div>
|
||||
|
@ -330,8 +331,8 @@
|
|||
|
||||
<!-- config-element -->
|
||||
<div class="form-group" ng-repeat="(index, config) in ctrl.formValues.Configurations">
|
||||
<label for="stack_name" class="col-md-1 col-sm-2 control-label text-left">Configuration</label>
|
||||
<div class="col-sm-5">
|
||||
<label for="stack_name" class="col-sm-3 col-lg-2 control-label text-left">Configuration</label>
|
||||
<div class="col-sm-6">
|
||||
<select
|
||||
class="form-control"
|
||||
ng-model="config.SelectedConfiguration"
|
||||
|
@ -341,41 +342,41 @@
|
|||
data-cy="k8sAppCreate-addConfigSelect_{{ $index }}"
|
||||
></select>
|
||||
</div>
|
||||
<div class="col-sm-6" style="margin-top: 2px">
|
||||
<div class="col-sm-3" style="margin-top: 2px">
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
type="button"
|
||||
ng-if="!config.Overriden"
|
||||
ng-click="ctrl.overrideConfiguration(index)"
|
||||
ng-disabled="!config.SelectedConfiguration || ctrl.formValues.Containers.length > 1"
|
||||
data-cy="k8sAppCreate-configOverrideButton_{{ $index }}"
|
||||
>
|
||||
<i class="fa fa-list" aria-hidden="true"></i> Override
|
||||
<pr-icon icon="'list'" size="'md'" feather="true"></pr-icon> Override
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
type="button"
|
||||
ng-if="config.Overriden"
|
||||
ng-click="ctrl.resetConfiguration(index)"
|
||||
ng-disabled="ctrl.formValues.Containers.length > 1"
|
||||
data-cy="k8sAppCreate-configAutoButton_{{ $index }}"
|
||||
>
|
||||
<i class="fa fa-undo" aria-hidden="true"></i> Auto
|
||||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon> Auto
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-danger"
|
||||
class="btn btn-sm btn-dangerlight vertical-center"
|
||||
type="button"
|
||||
ng-click="ctrl.removeConfiguration(index)"
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
data-cy="k8sAppCreate-configRemoveButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
</button>
|
||||
</div>
|
||||
<!-- no-override -->
|
||||
<div class="col-sm-12" style="margin-top: 10px" ng-if="config.SelectedConfiguration && !config.Overriden">
|
||||
<div class="col-md-1 col-sm-2"></div>
|
||||
<div class="col-md-11 col-sm-10 small text-muted" style="padding-left: 5px">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-6 small text-muted" style="padding-left: 5px">
|
||||
The following keys will be loaded from the <code>{{ config.SelectedConfiguration.Name }}</code> configuration as environment variables:
|
||||
<span ng-repeat="(key, _) in config.SelectedConfiguration.Data">
|
||||
<code>{{ key }}</code
|
||||
|
@ -414,10 +415,10 @@
|
|||
|
||||
<div class="input-group col-sm-4 btn-group btn-group-sm">
|
||||
<label class="btn btn-primary" ng-model="overridenKey.Type" uib-btn-radio="ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.ENVIRONMENT">
|
||||
<i class="fa fa-list" aria-hidden="true"></i> Environment
|
||||
<pr-icon icon="'list'" feather="true"></pr-icon> Environment
|
||||
</label>
|
||||
<label class="btn btn-primary" ng-model="overridenKey.Type" uib-btn-radio="ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.FILESYSTEM">
|
||||
<i class="fa fa-file" aria-hidden="true"></i> Filesystem
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon> Filesystem
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -440,10 +441,10 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['overriden_key_path_' + index + '_' + keyIndex].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Path is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.configurationPaths.refs[index + '_' + keyIndex] !== undefined"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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>
|
||||
|
@ -460,13 +461,13 @@
|
|||
<!-- #region PERSISTED FOLDERS -->
|
||||
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
No storage option is available to persist data, contact your administrator to enable a storage option.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12" style="margin-top: 5px">
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<label class="control-label text-left">Persisted folders</label>
|
||||
<span
|
||||
class="label label-default interactive"
|
||||
|
@ -475,7 +476,14 @@
|
|||
ng-if="ctrl.isAddPersistentFolderButtonShowed()"
|
||||
data-cy="k8sAppCreate-addPersistentFolderButton"
|
||||
>
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add persisted folder
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add persisted folder
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<span class="small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its storage capacity. Contact your administrator to expand the capacity of the namespace.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -536,6 +544,7 @@
|
|||
ng-min="0"
|
||||
required
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
/>
|
||||
<span class="input-group-addon" style="padding: 0">
|
||||
<select
|
||||
|
@ -543,6 +552,7 @@
|
|||
ng-style="{ width: '100%', height: '100%', cursor: ctrl.isEditAndExistingPersistedFolder($index) ? 'not-allowed' : 'auto' }"
|
||||
ng-options="unit for unit in ctrl.state.availableSizeUnits"
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
></select>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -591,7 +601,7 @@
|
|||
ng-click="ctrl.removePersistedFolder($index)"
|
||||
data-cy="k8sAppCreate-rmPersistentFolderButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i>
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
ng-if="persistedFolder.NeedsDeletion"
|
||||
|
@ -600,7 +610,7 @@
|
|||
ng-click="ctrl.restorePersistedFolder($index)"
|
||||
data-cy="k8sAppCreate-restorePersistentButton"
|
||||
>
|
||||
<i class="fa fa-trash-restore" aria-hidden="true"></i>
|
||||
<pr-icon icon="'rotate-cw'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -611,6 +621,7 @@
|
|||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid ||
|
||||
ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined ||
|
||||
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid ||
|
||||
ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined ||
|
||||
kubernetesApplicationCreationForm['existing_volumes_' + $index].$invalid ||
|
||||
ctrl.state.duplicates.existingVolumes.refs[$index] !== undefined
|
||||
"
|
||||
|
@ -624,10 +635,10 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Path is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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>
|
||||
|
@ -635,21 +646,33 @@
|
|||
<div class="input-group col-sm-2 input-group-sm"></div>
|
||||
|
||||
<div class="input-group col-sm-5 input-group-sm">
|
||||
<div class="small text-warning" style="margin-top: 5px" ng-show="kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid">
|
||||
<div
|
||||
class="small text-warning"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid || ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Size is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This value must be greater than zero.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Size is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
You can only request up to
|
||||
{{ ctrl.state.storages.availabilities[persistedFolder.StorageClass.Name] | kubernetesAppStorageRequestSizeHumanReadable }} for
|
||||
{{ persistedFolder.StorageClass.Name }}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="small text-warning"
|
||||
ng-show="kubernetesApplicationCreationForm['existing_volumes_' + $index].$invalid || ctrl.state.duplicates.existingVolumes.refs[$index] !== undefined"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['existing_volumes_' + $index].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Volume is required.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Volume is required.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.existingVolumes.refs[$index] !== undefined"
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This volume is already used.</p
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This volume is already used.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -761,14 +784,14 @@
|
|||
<!-- #region RESOURCE RESERVATIONS -->
|
||||
<div class="form-group" ng-if="!ctrl.state.resourcePoolHasQuota">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Resource reservations are applied per instance of the application.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
A resource quota is set on this namespace, you must specify resource reservations. Resource reservations are applied per instance of the application. Maximums
|
||||
are inherited from the namespace quota.
|
||||
</div>
|
||||
|
@ -776,7 +799,7 @@
|
|||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its resource capacity and you will not be able to deploy the application. Contact your administrator to expand the capacity of
|
||||
the namespace.
|
||||
</div>
|
||||
|
@ -820,7 +843,7 @@
|
|||
<div class="col-sm-12 small text-warning">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.memory_limit.$error">
|
||||
<p
|
||||
><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 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 }}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -851,7 +874,7 @@
|
|||
|
||||
<div class="form-group" ng-if="ctrl.nodeLimitsOverflow()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
These reservations would exceed the resources currently available in the cluster.
|
||||
</div>
|
||||
</div>
|
||||
|
@ -942,10 +965,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="kubernetesApplicationCreationForm['replica_count'].$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div class="col-sm-12 small">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['replica_count'].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Instance count is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Instance count must be greater than 0.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -956,7 +979,7 @@
|
|||
ng-if="!ctrl.resourceReservationsOverflow() && ctrl.formValues.ReplicaCount > 1 && (ctrl.formValues.CpuLimit !== 0 || ctrl.formValues.MemoryLimit !== 0)"
|
||||
>
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
This application will reserve the following resources:
|
||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
||||
|
@ -964,15 +987,22 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.resourceReservationsOverflow()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<div class="col-sm-12 small">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This application would exceed available resources. Please review resource reservations or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.storages.quotaExceeded">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This application would exceed available storage. Please review the persisted folders or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="!ctrl.supportScalableReplicaDeployment()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
The following storage option(s) do not support concurrent access from multiples instances: <code>{{ ctrl.getNonScalableStorage() }}</code
|
||||
>. You will not be able to scale that application.
|
||||
</div>
|
||||
|
@ -1037,9 +1067,11 @@
|
|||
<div class="input-group input-group-sm" ng-show="kubernetesApplicationCreationForm['auto_scaler_min'].$invalid">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['auto_scaler_min'].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Minimum instances is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Minimum instances must be greater than 0.</p>
|
||||
<p ng-message="max"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Minimum instances must be smaller than maximum instances.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Minimum instances is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Minimum instances must be greater than 0.</p>
|
||||
<p ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Minimum instances must be smaller than maximum instances.</p
|
||||
>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1057,8 +1089,10 @@
|
|||
<div class="input-group input-group-sm" ng-show="kubernetesApplicationCreationForm['auto_scaler_max'].$invalid || ctrl.autoScalerOverflow()">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['auto_scaler_max'].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Maximum instances is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Maximum instances must be greater than minimum instances.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Maximum instances is required.</p>
|
||||
<p ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Maximum instances must be greater than minimum instances.</p
|
||||
>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1079,9 +1113,9 @@
|
|||
<div class="input-group input-group-sm" ng-show="kubernetesApplicationCreationForm['auto_scaler_cpu'].$invalid">
|
||||
<div class="small text-warning" style="margin-top: 5px">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['auto_scaler_cpu'].$error">
|
||||
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Target CPU usage is required.</p>
|
||||
<p ng-message="min"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Target CPU usage must be greater than 0.</p>
|
||||
<p ng-message="max"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Target CPU usage must be smaller than 100.</p>
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Target CPU usage is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Target CPU usage must be greater than 0.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Target CPU usage must be smaller than 100.</p>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1092,7 +1126,7 @@
|
|||
|
||||
<div class="form-group" ng-if="ctrl.autoScalerOverflow()" style="margin-bottom: 10px">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This application would exceed available resources. Please review resource reservations or the maximum instance count of the auto-scaling policy.
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1106,13 +1140,13 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Placement rules</label>
|
||||
<span class="label label-default interactive" style="margin-left: 10px" ng-click="ctrl.addPlacement()">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add rule
|
||||
<span class="label label-default interactive vertical-center" style="margin-left: 10px" ng-click="ctrl.addPlacement()">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add rule
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 small text-muted" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels.
|
||||
</div>
|
||||
|
||||
|
@ -1143,21 +1177,21 @@
|
|||
<div class="col-sm-1 input-group">
|
||||
<button
|
||||
ng-if="!placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-danger"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
type="button"
|
||||
ng-click="ctrl.removePlacement($index)"
|
||||
data-cy="k8sAppCreate-deletePlacementButton"
|
||||
>
|
||||
<i class="fa fa-trash-alt" aria-hidden="true"></i>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
ng-if="placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-primary"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
type="button"
|
||||
ng-click="ctrl.restorePlacement($index)"
|
||||
data-cy="k8sAppCreate-restorePlacementButton"
|
||||
>
|
||||
<i class="fa fa-trash-restore" aria-hidden="true"></i>
|
||||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1165,7 +1199,7 @@
|
|||
<div class="col-sm-5 input-group">
|
||||
<div class="small text-warning" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This label is already defined.
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This label is already defined.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1257,14 +1291,14 @@
|
|||
</div>
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded() && ctrl.formValues.ResourcePool">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<i class="fa fa-exclamation-circle red-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its resource capacity and you will not be able to deploy the application. Contact your administrator to expand the capacity of the
|
||||
namespace.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="!ctrl.formValues.ResourcePool">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
You do not have access to any namespace. Contact your administrator to get access to a namespace.
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
<div ng-if="ctrl.state.viewReady">
|
||||
<kubernetes-feedback-panel></kubernetes-feedback-panel>
|
||||
|
||||
<div class="row">
|
||||
<div class="row kubernetes-deploy">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<uib-tabset active="ctrl.state.activeTab" justified="true" type="pills">
|
||||
<uib-tab index="0">
|
||||
<uib-tab-heading> <i class="fa fa-code space-right" aria-hidden="true"></i> Deploy </uib-tab-heading>
|
||||
<uib-tab-heading> <pr-icon icon="'code'" feather="true"></pr-icon> Deploy </uib-tab-heading>
|
||||
<div class="col-sm-12 form-section-title"> Namespace </div>
|
||||
<form class="form-horizontal" style="margin-top: 20px" name="deploymentForm">
|
||||
<div class="form-group" ng-if="ctrl.formValues.Namespace">
|
||||
<label for="target_node" class="col-lg-1 col-sm-2 control-label text-left">Namespace</label>
|
||||
<div class="col-lg-11 col-sm-10">
|
||||
<label for="target_node" class="col-lg-2 col-sm-3 control-label text-left">Namespace</label>
|
||||
<div class="col-sm-8">
|
||||
<select
|
||||
ng-disabled="ctrl.formValues.namespace_toggle"
|
||||
class="form-control"
|
||||
|
@ -26,11 +26,16 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="ctrl.formValues.Namespace">
|
||||
<div class="col-sm-12">
|
||||
<label for="toggle_logo" class="control-label text-left"> Use namespace(s) specified from manifest </label>
|
||||
<label for="toggle_logo" class="col-lg-2 col-sm-3 control-label text-left">
|
||||
Use namespace(s) specified from manifest
|
||||
<portainer-tooltip message="'If you have defined namespaces in your deployment file turning this on will enforce the use of those only in the deployment'">
|
||||
</portainer-tooltip>
|
||||
<label class="switch" style="margin-left: 20px"> <input type="checkbox" name="toggle_logo" ng-model="ctrl.formValues.namespace_toggle" /><i></i> </label>
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
<label class="switch">
|
||||
<input type="checkbox" name="toggle_logo" ng-model="ctrl.formValues.namespace_toggle" />
|
||||
<i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="!ctrl.formValues.Namespace">
|
||||
|
@ -41,8 +46,8 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-sm-1 control-label text-left">Name</label>
|
||||
<div class="col-lg-11 col-sm-10">
|
||||
<label for="stack_name" class="col-lg-2 col-sm-3 control-label text-left">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" ng-model="ctrl.formValues.StackName" id="stack_name" placeholder="my-app" auto-focus />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -110,7 +115,7 @@
|
|||
<editor-description>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.COMPOSE">
|
||||
<p>
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that
|
||||
not all the Compose format options are supported by Kompose at the moment.
|
||||
</p>
|
||||
|
@ -119,12 +124,9 @@
|
|||
<a href="https://docs.docker.com/compose/compose-file/" target="_blank">official documentation</a>.
|
||||
</p>
|
||||
</span>
|
||||
<span
|
||||
class="col-sm-12 text-muted small"
|
||||
ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES && ctrl.state.BuildMethod === ctrl.BuildMethods.WEB_EDITOR"
|
||||
>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES">
|
||||
<p>
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -144,8 +146,8 @@
|
|||
<span class="col-sm-12 text-muted small"> Indicate the URL to the manifest. </span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="manifest_url" class="col-sm-1 control-label text-left">URL</label>
|
||||
<div class="col-sm-11">
|
||||
<label for="manifest_url" class="col-sm-3 col-lg-2 control-label text-left">URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -166,7 +168,7 @@
|
|||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-disabled="!deploymentForm.$valid || ctrl.disableDeploy()"
|
||||
ng-disabled="!deploymentForm.$valid ||ctrl.disableDeploy()"
|
||||
ng-click="ctrl.deploy()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
data-cy="k8sAppDeploy-deployButton"
|
||||
|
@ -185,7 +187,7 @@
|
|||
</uib-tab>
|
||||
|
||||
<uib-tab index="1" disable="ctrl.state.tabLogsDisabled">
|
||||
<uib-tab-heading> <i class="fa fa-file space-right" aria-hidden="true"></i> Logs </uib-tab-heading>
|
||||
<uib-tab-heading> <pr-icon icon="'file-text'" feather="true"></pr-icon> Logs </uib-tab-heading>
|
||||
<form class="form-horizontal" style="margin-top: 20px">
|
||||
<div class="form-group" ng-if="ctrl.state.activeTab === 1">
|
||||
<div class="col-sm-12">
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
.service-form .form-group {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.service-form .form-group .input-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.service-form .clear-both {
|
||||
clear: both;
|
||||
}
|
|
@ -6,19 +6,19 @@
|
|||
>
|
||||
Summary
|
||||
<span class="small space-left">
|
||||
<a ng-if="!$ctrl.state.expandedTemplate"><i class="fa fa-angle-down" aria-hidden="true"></i> expand</a>
|
||||
<a ng-if="$ctrl.state.expandedTemplate"><i class="fa fa-angle-up" aria-hidden="true"></i> collapse</a>
|
||||
<a ng-if="!$ctrl.state.expandedTemplate"><pr-icon icon="'chevron-down'" feather="true"></pr-icon> expand</a>
|
||||
<a ng-if="$ctrl.state.expandedTemplate"><pr-icon icon="'chevron-up'" feather="true"></pr-icon> collapse</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.state.expandedTemplate">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will execute the following Kubernetes actions.
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 small text-muted" style="padding-top: 1em" ng-if="$ctrl.state.resources.length > 0">
|
||||
<ul>
|
||||
<ul class="ml-5">
|
||||
<li ng-repeat="summary in $ctrl.state.resources" ng-if="summary.action && summary.kind && summary.name">
|
||||
{{ summary.action }}
|
||||
{{ $ctrl.getArticle(summary.kind, summary.action) }}
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
required
|
||||
/>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.removeValue()">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
<button class="btn btn-sm btn-light btn-only-icon" type="button" ng-click="$ctrl.removeValue()" title="Remove">
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div ng-show="$ctrl[$ctrl.formName].name.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div ng-messages="$ctrl[$ctrl.formName].name.$error">
|
||||
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Path is required. </p>
|
||||
<p ng-message="pattern"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> File path must include yaml, yml, json, or hcl extension </p>
|
||||
<div class="small">
|
||||
<div ng-messages="$ctrl[$ctrl.formName].name.$error" class="mt-1">
|
||||
<p ng-message="required"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required. </p>
|
||||
<p ng-message="pattern"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> File path must include yaml, yml, json, or hcl extension </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12" style="margin-top: 5px">
|
||||
<label class="control-label text-left">Additional paths</label>
|
||||
<span class="label label-default interactive" style="margin-left: 10px" ng-click="$ctrl.add()"> <i class="fa fa-plus-circle" aria-hidden="true"></i> add file </span>
|
||||
<span class="label label-default interactive" style="margin-left: 10px" ng-click="$ctrl.add()">
|
||||
<pr-icon icon="'plus'" size="'sm'" mode="'alt'" feather="true"></pr-icon> add file
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 10px">
|
||||
<git-form-additional-file-item
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small text-warning" style="margin: 5px 0 15px 0" ng-if="$ctrl.model.RepositoryAuthentication && $ctrl.showAuthExplanation">
|
||||
<i class="fa fa-exclamation-circle" aria-hidden="true"></i>
|
||||
<div class="small" style="margin: 5px 0 15px 0" ng-if="$ctrl.model.RepositoryAuthentication && $ctrl.showAuthExplanation">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<span class="text-muted">Enabling authentication will store the credentials and it is advisable to use a git service account</span>
|
||||
</div>
|
||||
<div ng-if="$ctrl.model.RepositoryAuthentication">
|
||||
<div ng-if="$ctrl.model.RepositoryAuthentication" class="row">
|
||||
<div class="form-group">
|
||||
<label for="repository_username" class="control-label text-left inline-label"> Username </label>
|
||||
<div class="inline-input">
|
||||
<label for="repository_username" class="col-lg-2 col-sm-3 control-label text-left"> Username </label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -29,11 +29,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="repository_password" class="control-label text-left inline-label">
|
||||
<label for="repository_password" class="col-lg-2 col-sm-3 control-label text-left">
|
||||
Personal Access Token
|
||||
<portainer-tooltip message="'Provide a personal access token or password'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="inline-input">
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control"
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="small text-warning" style="margin: 5px 0 10px 0" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<i class="fa fa-exclamation-circle" aria-hidden="true"></i>
|
||||
<pr-icon icon="'alert-circle'" 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>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<label for="repository_mechanism" class="col-sm-1 control-label text-left"> Mechanism </label>
|
||||
<div class="col-sm-11">
|
||||
<label for="repository_mechanism" class="col-lg-2 col-sm-3 control-label text-left"> Mechanism </label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group col-sm-10 input-group-sm">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<label class="btn btn-primary" ng-click="$ctrl.onChangeMechanism($ctrl.model.RepositoryMechanism)" ng-model="$ctrl.model.RepositoryMechanism" uib-btn-radio="'Interval'"
|
||||
<label class="btn btn-light" ng-click="$ctrl.onChangeMechanism($ctrl.model.RepositoryMechanism)" ng-model="$ctrl.model.RepositoryMechanism" uib-btn-radio="'Interval'"
|
||||
>Polling</label
|
||||
>
|
||||
<label class="btn btn-primary" ng-click="$ctrl.onChangeMechanism($ctrl.model.RepositoryMechanism)" ng-model="$ctrl.model.RepositoryMechanism" uib-btn-radio="'Webhook'"
|
||||
<label class="btn btn-light" ng-click="$ctrl.onChangeMechanism($ctrl.model.RepositoryMechanism)" ng-model="$ctrl.model.RepositoryMechanism" uib-btn-radio="'Webhook'"
|
||||
>Webhook</label
|
||||
>
|
||||
</div>
|
||||
|
@ -25,20 +25,20 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates && $ctrl.model.RepositoryMechanism === 'Webhook'">
|
||||
<label for="repository_mechanism" class="col-sm-1 control-label text-left"> Webhook </label>
|
||||
<div class="col-sm-11">
|
||||
<label for="repository_mechanism" class="col-sm-3 col-lg-2 control-label text-left"> Webhook </label>
|
||||
<div class="col-sm-8">
|
||||
<span class="text-muted"> {{ $ctrl.model.RepositoryWebhookURL | truncatelr }} </span>
|
||||
<button type="button" class="btn btn-sm btn-primary btn-sm space-left" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
||||
<span><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy link</span>
|
||||
<button type="button" class="btn btn-sm btn-light btn-sm space-left" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
||||
<span><pr-icon icon="'copy'" size="'sm'" feather="true"></pr-icon> Copy link</span>
|
||||
</button>
|
||||
<span>
|
||||
<i id="copyNotification" class="fa fa-check green-icon" aria-hidden="true" style="margin-left: 7px; display: none"></i>
|
||||
<pr-icon icon="'check'" mode="'success'" feather="true" style="display: none"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates && $ctrl.model.RepositoryMechanism === 'Interval'">
|
||||
<label for="repository_fetch_interval" class="col-sm-1 control-label text-left"> Fetch interval </label>
|
||||
<div class="col-sm-11">
|
||||
<label for="repository_fetch_interval" class="col-sm-3 col-lg-2 control-label text-left"> Fetch interval </label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -51,11 +51,27 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.showForcePullImage && $ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field name="forcePullImage" feature-id="$ctrl.stackPullImageFeature" checked="$ctrl.model.ForcePullImage" label="'Pull latest image'"> </por-switch-field>
|
||||
<div class="form-group col-md-12" ng-show="autoUpdateForm.repository_fetch_interval.$touched && autoUpdateForm.repository_fetch_interval.$invalid">
|
||||
<div class="small">
|
||||
<div ng-messages="autoUpdateForm.repository_fetch_interval.$error">
|
||||
<p ng-message="required"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p>
|
||||
<p ng-message="invalidIntervalFormat"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Please enter a valid time interval.</p>
|
||||
<p ng-message="minimumInterval"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Minimum interval is 1m</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.showForcePullImage && $ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
name="'forcePullImage'"
|
||||
feature="$ctrl.limitedFeaturePullImage"
|
||||
checked="$ctrl.model.ForcePullImage"
|
||||
label="'Pull latest image'"
|
||||
on-change="($ctrl.onChangeForcePullImage)"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
|
@ -67,21 +83,12 @@
|
|||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small text-warning" style="margin: 5px 0 10px 0" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<i class="fa fa-exclamation-circle blue-icon" aria-hidden="true"></i>
|
||||
<div class="small" style="margin: 5px 0 10px 0" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<span class="text-muted">When enabled, enforces automatic deployment at each interval or webhook invocation.</span>
|
||||
</div>
|
||||
<div class="form-group col-md-12" ng-show="autoUpdateForm.repository_fetch_interval.$touched && autoUpdateForm.repository_fetch_interval.$invalid">
|
||||
<div class="small text-warning">
|
||||
<div ng-messages="autoUpdateForm.repository_fetch_interval.$error">
|
||||
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
|
||||
<p ng-message="invalidIntervalFormat"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Please enter a valid time interval.</p>
|
||||
<p ng-message="minimumInterval"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Minimum interval is 1m</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small text-warning" style="margin: 5px 0 10px 0" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<i class="fa fa-exclamation-circle blue-icon" aria-hidden="true"></i>
|
||||
<div class="small" style="margin: 5px 0 10px 0" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<span class="text-muted">When enabled, updates from the git repository will occur automatically at an interval or webhook.</span>
|
||||
</div>
|
||||
</ng-form>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<ng-form name="pathForm">
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small"
|
||||
><i class="fa fa-info-circle blue-icon space-right" aria-hidden="true"></i>Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from
|
||||
><pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from
|
||||
the root of your repository (requires a yaml, yml, json, or hcl file extension)
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stack_repository_path" class="col-sm-2 control-label text-left">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="stack_repository_path" class="col-lg-2 col-sm-3 control-label text-left">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -19,7 +19,7 @@
|
|||
ng-pattern="/.+\.(yml|yaml|json|hcl)$/i"
|
||||
required
|
||||
/>
|
||||
<p class="mt-10 text-warning" ng-show="pathForm.repoPathField.$error.pattern"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> Invalid file path </p>
|
||||
<p class="mt-2" ng-show="pathForm.repoPathField.$error.pattern"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Invalid file path </p>
|
||||
</div>
|
||||
</div>
|
||||
</ng-form>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stack_repository_reference_name" class="col-sm-2 control-label text-left">Repository reference</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="stack_repository_reference_name" class="col-lg-2 col-sm-3 control-label text-left">Repository reference</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<span class="col-sm-12 text-muted small"> You can use the URL of a git repository. </span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stack_repository_url" class="col-sm-2 control-label text-left">Repository URL</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="stack_repository_url" class="col-lg-2 col-sm-3 control-label text-left">Repository URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
name="repoUrlField"
|
||||
|
|
Loading…
Reference in New Issue