<page-header
  ng-if="ctrl.state.viewReady"
  title="'Kubernetes features configuration'"
  breadcrumbs="[
    { label:'Environments', link:'portainer.endpoints' },
    {
      label:ctrl.endpoint.Name,
      link: 'portainer.endpoints.endpoint',
      linkParams:{id: ctrl.endpoint.Id}
    },
     'Kubernetes configuration'
     ]"
  reload="true"
>
</page-header>

<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>

<div ng-if="ctrl.state.viewReady">
  <div class="row">
    <div class="col-sm-12">
      <rd-widget>
        <rd-widget-body>
          <form class="form-horizontal" name="kubernetesClusterSetupForm">
            <div class="col-sm-12 form-section-title"> Networking </div>

            <div class="form-group">
              <div class="col-sm-12 text-muted small">
                <p> Enabling the load balancer feature will allow users to expose application they deploy over an external IP address assigned by cloud provider. </p>
                <div class="!inline-flex gap-1 !align-top">
                  <div class="icon icon-sm"><pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon></div>
                  <div>Ensure that your cloud provider allows you to create load balancers if you want to use this feature. Might incur costs.</div>
                </div>
              </div>

              <div class="col-sm-12 mt-4">
                <label class="control-label col-sm-5 col-lg-4 px-0 text-left"> Allow users to use external load balancer </label>
                <label class="switch col-sm-8 mb-0">
                  <input type="checkbox" ng-model="ctrl.formValues.UseLoadBalancer" /><span class="slider round" data-cy="kubeSetup-loadBalancerToggle"></span>
                </label>
              </div>
            </div>

            <ingress-class-datatable
              on-change-controllers="(ctrl.onChangeControllers)"
              allow-none-ingress-class="ctrl.formValues.AllowNoneIngressClass"
              ingress-controllers="ctrl.originalIngressControllers"
              is-loading="ctrl.isIngressControllersLoading"
              description="'Enabling ingress controllers in your cluster allows them to be available in the Portainer UI for users to publish applications over HTTP/HTTPS. A controller must have a class name for it to be included here.'"
              no-ingress-controller-label="'No supported ingress controllers found.'"
              view="'cluster'"
            ></ingress-class-datatable>

            <label htmlFor="foldingButtonIngControllerSettings" class="col-sm-12 form-section-title flex cursor-pointer items-center">
              <button
                id="foldingButtonIngControllerSettings"
                type="button"
                class="mx-2 !ml-0 inline-flex w-2 items-center justify-center border-0 bg-transparent"
                ng-click="ctrl.toggleAdvancedIngSettings($event)"
              >
                <pr-icon ng-if="!ctrl.state.isIngToggleSectionExpanded" icon="'chevron-right'"></pr-icon>
                <pr-icon ng-if="ctrl.state.isIngToggleSectionExpanded" icon="'chevron-down'"></pr-icon>
              </button>
              More settings
            </label>
            <div ng-if="ctrl.state.isIngToggleSectionExpanded" class="ml-4">
              <div class="form-group">
                <div class="col-sm-12">
                  <por-switch-field
                    checked="ctrl.formValues.AllowNoneIngressClass"
                    name="'allowNoIngressClass'"
                    label="'Allow ingress class to be set to &quot;none&quot;'"
                    tooltip="'This allows users setting up ingresses to select &quot;none&quot; as the ingress class.'"
                    on-change="(ctrl.onToggleAllowNoneIngressClass)"
                    label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                    switch-class="'col-sm-8'"
                  >
                  </por-switch-field>
                </div>
              </div>
              <div class="form-group">
                <div class="col-sm-12">
                  <por-switch-field
                    checked="ctrl.formValues.IngressAvailabilityPerNamespace"
                    name="'ingressAvailabilityPerNamespace'"
                    label="'Configure ingress controller availability per namespace'"
                    tooltip="'This allows an administrator to configure, in each namespace, which ingress controllers will be available for users to select when setting up ingresses for applications.'"
                    on-change="(ctrl.onToggleIngressAvailabilityPerNamespace)"
                    label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                    switch-class="'col-sm-8'"
                  >
                  </por-switch-field>
                </div>
              </div>
            </div>

            <!-- auto update window -->
            <div class="col-sm-12 form-section-title"> Change Window Settings </div>

            <div class="form-group">
              <div class="col-sm-12">
                <por-switch-field
                  checked="ctrl.state.autoUpdateSettings.Enabled"
                  name="'disableSysctlSettingForRegularUsers'"
                  label="'Enable Change Window'"
                  feature-id="ctrl.limitedFeatureAutoWindow"
                  tooltip="'GitOps updates to stacks or applications outside the defined change window will not occur.'"
                  on-change="(ctrl.onToggleAutoUpdate)"
                  label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                  switch-class="'col-sm-8 text-muted'"
                >
                </por-switch-field>
              </div>
            </div>

            <time-window-picker ng-show="ctrl.state.autoUpdateSettings.Enabled" time-window="ctrl.state.autoUpdateSettings" time-zone="ctrl.state.timeZone"></time-window-picker>

            <!-- #region SECURITY -->
            <div class="col-sm-12 form-section-title"> Security </div>

            <div
              ng-if="!ctrl.isRBACEnabled"
              class="small mt-1 mb-6 flex w-full gap-1 rounded-lg border border-solid border-warning-5 bg-warning-2 p-4 text-warning-8 th-highcontrast:bg-yellow-11 th-highcontrast:text-white th-dark:bg-yellow-11 th-dark:text-white"
            >
              <div class="mt-0.5">
                <pr-icon icon="'alert-triangle'" feather="true" class-name="'text-warning-7 th-dark:text-white th-highcontrast:text-white'"></pr-icon>
              </div>
              <div>
                <p> Your cluster does not have Kubernetes role-based access control (RBAC) enabled. </p>
                <p> This means you can't use Portainer RBAC functionality to regulate access to environment resources based on user roles. </p>
                <p class="mb-0">
                  To enable RBAC, start the&nbsp;<a
                    class="th-highcontrast:text-blue-4 th-dark:text-blue-7"
                    href="https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver"
                    target="_blank"
                    >API server</a
                  >&nbsp;with the&nbsp;<code class="bg-gray-4 box-decoration-clone th-highcontrast:bg-black th-dark:bg-black">--authorization-mode</code>&nbsp;flag set to a
                  comma-separated list that includes&nbsp;<code class="bg-gray-4 th-highcontrast:bg-black th-dark:bg-black">RBAC</code>, for example:&nbsp;
                  <code class="bg-gray-4 box-decoration-clone th-highcontrast:bg-black th-dark:bg-black">kube-apiserver --authorization-mode=Example1,RBAC,Example2</code>.
                </p>
              </div>
            </div>

            <div class="form-group">
              <span class="col-sm-12 text-muted small">
                By default, all the users have access to the default namespace. Enable this option to set accesses on the default namespace.
              </span>
            </div>

            <div class="form-group">
              <div class="col-sm-12">
                <por-switch-field
                  checked="ctrl.formValues.RestrictDefaultNamespace"
                  name="'restrictDefaultNs'"
                  label="'Restrict access to the default namespace'"
                  on-change="(ctrl.onToggleRestrictNs)"
                  label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                  switch-class="'col-sm-8 text-muted'"
                  data-cy="kubeSetup-restrictDefaultNsToggle"
                  disabled="!ctrl.isRBACEnabled"
                >
                </por-switch-field>
              </div>

              <div class="col-sm-12 mt-5">
                <por-switch-field
                  name="'restrictStandardUserIngressW'"
                  label="'Only allow admins to deploy ingresses'"
                  tooltip="'Enforces only allowing admins to deploy ingresses (and disallows standard users from doing so).'"
                  label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                  switch-class="'col-sm-8 text-muted'"
                  data-cy="kubeSetup-restrictStandardUserIngressWToggle"
                  feature-id="ctrl.limitedFeatureIngressDeploy"
                  disabled="!ctrl.isRBACEnabled"
                ></por-switch-field>
              </div>
            </div>
            <!-- #endregion -->

            <div class="col-sm-12 form-section-title"> Resources and Metrics </div>

            <div class="form-group">
              <div class="col-sm-12 text-muted small">
                <p>
                  By ENABLING resource over-commit, you are able to assign more resources to namespaces than is physically available in the cluster. This may lead to unexpected
                  deployment failures if there is insufficient resource to service demand.
                </p>
                <div class="mt-1 inline-flex gap-1 !align-top">
                  <div class="icon icon-sm"><pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon></div>
                  <div
                    >By DISABLING resource over-commit (highly recommended), you are only able to assign resources to namespaces that are less (in aggregate) than the cluster total
                    minus any system resource reservation.</div
                  >
                </div>
              </div>

              <div class="col-sm-12 mt-2">
                <por-switch-field
                  data-cy="'kubeSetup-resourceOverCommitToggle'"
                  label="'Allow resource over-commit'"
                  name="'resource-over-commit-switch'"
                  feature-id="ctrl.limitedFeature"
                  checked="ctrl.formValues.EnableResourceOverCommit"
                  on-change="(ctrl.onChangeEnableResourceOverCommit)"
                  label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
                  switch-class="'col-sm-8'"
                ></por-switch-field>
              </div>
            </div>

            <div class="form-group">
              <div class="col-sm-12 text-muted small">
                <p> Enabling this feature will allow users to use specific features like autoscaling and to see container and node resource usage. </p>
                <div class="mt-1 !inline-flex gap-1 !align-top">
                  <div class="icon icon-small"><pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon></div>
                  <div
                    >Ensure that
                    <a href="https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#metrics-server" target="_blank">metrics server</a> or
                    <a href="https://github.com/kubernetes-sigs/prometheus-adapter" target="_blank">prometheus</a> is running inside your cluster.</div
                  >
                </div>
              </div>
            </div>
            <div class="form-group">
              <div class="col-sm-12">
                <label class="control-label col-sm-5 col-lg-4 px-0 text-left"> Enable features using the metrics API </label>
                <label class="switch col-sm-8">
                  <input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
                  <span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
                </label>
              </div>
              <div ng-if="ctrl.state.metrics.pending && ctrl.state.metrics.userClick" class="col-sm-12 small text-muted" style="margin-top: 5px">
                Checking metrics API... <pr-icon icon="'loader'" class-name="'ml-0.5'"></pr-icon>
              </div>
              <div
                ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
                class="col-sm-12 small text-muted vertical-center"
                style="margin-top: 5px"
              >
                <pr-icon icon="'check'" mode="'success'"></pr-icon> Successfully reached metrics API
              </div>
              <div
                ng-if="!ctrl.state.metrics.pending && !ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
                class="col-sm-12 small text-muted vertical-center mt-2"
              >
                <pr-icon icon="'x'" mode="'danger'"></pr-icon> Unable to reach metrics API, make sure metrics server is properly deployed inside that cluster.
              </div>
            </div>

            <div class="col-sm-12 form-section-title"> Available storage options </div>

            <div class="form-group" ng-if="!ctrl.storageClassAvailable()">
              <div class="col-sm-12 small text-muted vertical-center">
                <pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
                Unable to detect any storage class available to persist data. Users won't be able to persist application data inside this cluster.
              </div>
            </div>

            <div class="form-group" ng-if="ctrl.storageClassAvailable()">
              <span class="col-sm-12 text-muted small">
                <p>
                  Select which storage options will be available for use when deploying applications. Have a look at your storage driver documentation to figure out which access
                  policy to configure and if the volume expansion capability is supported.
                </p>
                <p>
                  You can find more information about access modes
                  <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes" target="_blank">in the official Kubernetes documentation</a>.
                </p>
              </span>
            </div>

            <div class="form-group" ng-if="ctrl.storageClassAvailable()">
              <div style="margin-top: 10px" class="col-sm-12">
                <table class="table" style="table-layout: fixed">
                  <tbody>
                    <tr class="text-muted">
                      <td>Storage</td>
                      <td>Shared access policy</td>
                      <td>Volume expansion</td>
                    </tr>
                    <tr ng-repeat="class in ctrl.StorageClasses">
                      <td>
                        <div class="flex h-full flex-row items-center">
                          <label class="switch mr-2 mb-0">
                            <input type="checkbox" ng-model="class.selected" /><span class="slider round" data-cy="kubeSetup-storageToggle{{ class.Name }}"></span>
                          </label>
                          <span>{{ class.Name }}</span>
                        </div>
                      </td>
                      <td>
                        <storage-access-mode-selector
                          options="ctrl.availableAccessModes"
                          value="class.AccessModes"
                          on-change="(ctrl.onChangeStorageClassAccessMode)"
                          storage-class-name="class.Name"
                        ></storage-access-mode-selector>
                      </td>
                      <td>
                        <div class="flex h-full flex-row items-center">
                          <label class="switch mr-2 mb-0"
                            ><input type="checkbox" ng-model="class.AllowVolumeExpansion" /><span
                              class="slider round"
                              data-cy="kubeSetup-storageExpansionToggle{{ class.Name }}"
                            ></span>
                          </label>
                        </div>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div class="col-sm-12">
                <span ng-if="!ctrl.hasValidStorageConfiguration()" class="text-muted small vertical-center mt-2">
                  <pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
                  Shared access policy configuration required
                </span>
              </div>
            </div>

            <div class="col-sm-12 form-section-title"> Actions </div>
            <!-- actions -->
            <div class="form-group">
              <div class="col-sm-12">
                <button
                  type="submit"
                  class="btn btn-primary btn-sm !ml-0"
                  ng-click="ctrl.configure()"
                  ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
                  button-spinner="ctrl.state.actionInProgress"
                  analytics-on
                  analytics-if="ctrl.restrictDefaultToggledOn()"
                  analytics-category="kubernetes"
                  analytics-event="kubernetes-configure"
                  analytics-properties="{ metadata: { restrictAccessToDefaultNamespace: ctrl.formValues.RestrictDefaultNamespace } }"
                  data-cy="kubeSetup-saveConfigurationButton"
                >
                  <span ng-hide="ctrl.state.actionInProgress">Save configuration</span>
                  <span ng-show="ctrl.state.actionInProgress">Saving configuration...</span>
                </button>
              </div>
            </div>
          </form>
        </rd-widget-body>
      </rd-widget>
    </div>
  </div>
</div>
