charts
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
new file mode 100644
index 0000000..fd762f9
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
@@ -0,0 +1,31 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+rules:
+  - apiGroups:
+      - admissionregistration.k8s.io
+    resources:
+      - validatingwebhookconfigurations
+    verbs:
+      - get
+      - update
+{{- if .Values.podSecurityPolicy.enabled }}
+  - apiGroups: ['extensions']
+    resources: ['podsecuritypolicies']
+    verbs:     ['use']
+    resourceNames:
+    {{- with .Values.controller.admissionWebhooks.existingPsp }}
+    - {{ . }}
+    {{- else }}
+    - {{ include "ingress-nginx.fullname" . }}-admission
+    {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
new file mode 100644
index 0000000..4990fb1
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
@@ -0,0 +1,20 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "ingress-nginx.fullname" . }}-admission
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
new file mode 100644
index 0000000..1f58bdc
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
@@ -0,0 +1,64 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission-create
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
+  # Alpha feature since k8s 1.12
+  ttlSecondsAfterFinished: 0
+{{- end }}
+  template:
+    metadata:
+      name: {{ include "ingress-nginx.fullname" . }}-admission-create
+    {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }}
+      annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
+        app.kubernetes.io/component: admission-webhook
+    spec:
+    {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
+      priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
+    {{- end }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+      containers:
+        - name: create
+          {{- with .Values.controller.admissionWebhooks.patch.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }}
+          args:
+            - create
+            - --host={{ include "ingress-nginx.controller.fullname" . }}-admission,{{ include "ingress-nginx.controller.fullname" . }}-admission.$(POD_NAMESPACE).svc
+            - --namespace=$(POD_NAMESPACE)
+            - --secret-name={{ include "ingress-nginx.fullname" . }}-admission
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.createSecretJob.resources }}
+          resources: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.resources | nindent 12 }}
+          {{- end }}
+      restartPolicy: OnFailure
+      serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission
+    {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
+      tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
+    {{- end }}
+      securityContext:
+        runAsNonRoot: true
+        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
new file mode 100644
index 0000000..6d01ad2
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
@@ -0,0 +1,66 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission-patch
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
+  # Alpha feature since k8s 1.12
+  ttlSecondsAfterFinished: 0
+{{- end }}
+  template:
+    metadata:
+      name: {{ include "ingress-nginx.fullname" . }}-admission-patch
+    {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }}
+      annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
+        app.kubernetes.io/component: admission-webhook
+    spec:
+    {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
+      priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
+    {{- end }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+      containers:
+        - name: patch
+          {{- with .Values.controller.admissionWebhooks.patch.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }}
+          args:
+            - patch
+            - --webhook-name={{ include "ingress-nginx.fullname" . }}-admission
+            - --namespace=$(POD_NAMESPACE)
+            - --patch-mutating=false
+            - --secret-name={{ include "ingress-nginx.fullname" . }}-admission
+            - --patch-failure-policy={{ .Values.controller.admissionWebhooks.failurePolicy }}
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.patchWebhookJob.resources }}
+          resources: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.resources | nindent 12 }}
+          {{- end }}
+      restartPolicy: OnFailure
+      serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission
+    {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
+      tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
+    {{- end }}
+      securityContext:
+        runAsNonRoot: true
+        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
new file mode 100644
index 0000000..d2c7de6
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
@@ -0,0 +1,36 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled .Values.podSecurityPolicy.enabled (empty .Values.controller.admissionWebhooks.existingPsp) -}}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+  allowPrivilegeEscalation: false
+  fsGroup:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  requiredDropCapabilities:
+  - ALL
+  runAsUser:
+    rule: MustRunAsNonRoot
+  seLinux:
+    rule: RunAsAny
+  supplementalGroups:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  volumes:
+  - configMap
+  - emptyDir
+  - projected
+  - secret
+  - downwardAPI
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
new file mode 100644
index 0000000..9b083ee
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
@@ -0,0 +1,21 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - secrets
+    verbs:
+      - get
+      - create
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
new file mode 100644
index 0000000..edda07f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
@@ -0,0 +1,21 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "ingress-nginx.fullname" . }}-admission
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
new file mode 100644
index 0000000..1ff0f7f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
new file mode 100644
index 0000000..712f74f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
@@ -0,0 +1,45 @@
+{{- if .Values.controller.admissionWebhooks.enabled -}}
+# before changing this value, check the required kubernetes version
+# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+  {{- if .Values.controller.admissionWebhooks.annotations }}
+  annotations: {{ toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }}
+  {{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+webhooks:
+  - name: validate.nginx.ingress.kubernetes.io
+    matchPolicy: Equivalent
+    rules:
+      - apiGroups:
+          - networking.k8s.io
+        apiVersions:
+          - v1
+        operations:
+          - CREATE
+          - UPDATE
+        resources:
+          - ingresses
+    failurePolicy: {{ .Values.controller.admissionWebhooks.failurePolicy | default "Fail" }}
+    sideEffects: None
+    admissionReviewVersions:
+      - v1
+    clientConfig:
+      service:
+        namespace: {{ .Release.Namespace | quote }}
+        name: {{ include "ingress-nginx.controller.fullname" . }}-admission
+        path: /networking/v1/ingresses
+    {{- if .Values.controller.admissionWebhooks.timeoutSeconds }}
+    timeoutSeconds: {{ .Values.controller.admissionWebhooks.timeoutSeconds }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.namespaceSelector }}
+    namespaceSelector: {{ toYaml .Values.controller.admissionWebhooks.namespaceSelector | nindent 6 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.objectSelector }}
+    objectSelector: {{ toYaml .Values.controller.admissionWebhooks.objectSelector | nindent 6 }}
+    {{- end }}
+{{- end }}