diff --git a/cost-optimization/.chainsaw-test/01-business-hours/test.yaml b/cost-optimization/.chainsaw-test/01-business-hours/test.yaml new file mode 100644 index 000000000..523457bde --- /dev/null +++ b/cost-optimization/.chainsaw-test/01-business-hours/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: business-hours +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-20T14:00:00Z" # Wednesday 2 PM + + - name: test-quota-business-hours + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota + namespace: default + spec: + hard: + cpu: "20" + memory: "40Gi" diff --git a/cost-optimization/.chainsaw-test/02-non-business-hours/test.yaml b/cost-optimization/.chainsaw-test/02-non-business-hours/test.yaml new file mode 100644 index 000000000..812acce6c --- /dev/null +++ b/cost-optimization/.chainsaw-test/02-non-business-hours/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: non-business-hours +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-20T23:00:00Z" # Wednesday 11 PM + + - name: test-quota-non-business-hours + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-night + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-night + namespace: default + spec: + hard: + cpu: "10" + memory: "20Gi" diff --git a/cost-optimization/.chainsaw-test/03-weekend/test.yaml b/cost-optimization/.chainsaw-test/03-weekend/test.yaml new file mode 100644 index 000000000..92d710fc9 --- /dev/null +++ b/cost-optimization/.chainsaw-test/03-weekend/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: weekend +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-23T14:00:00Z" # Saturday 2 PM + + - name: test-quota-weekend + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-weekend + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-weekend + namespace: default + spec: + hard: + cpu: "10" + memory: "20Gi" diff --git a/cost-optimization/schedule-based-quotas/.chainsaw-test/01-business-hours/test.yaml b/cost-optimization/schedule-based-quotas/.chainsaw-test/01-business-hours/test.yaml new file mode 100644 index 000000000..523457bde --- /dev/null +++ b/cost-optimization/schedule-based-quotas/.chainsaw-test/01-business-hours/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: business-hours +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-20T14:00:00Z" # Wednesday 2 PM + + - name: test-quota-business-hours + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota + namespace: default + spec: + hard: + cpu: "20" + memory: "40Gi" diff --git a/cost-optimization/schedule-based-quotas/.chainsaw-test/02-non-business-hours/test.yaml b/cost-optimization/schedule-based-quotas/.chainsaw-test/02-non-business-hours/test.yaml new file mode 100644 index 000000000..812acce6c --- /dev/null +++ b/cost-optimization/schedule-based-quotas/.chainsaw-test/02-non-business-hours/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: non-business-hours +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-20T23:00:00Z" # Wednesday 11 PM + + - name: test-quota-non-business-hours + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-night + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-night + namespace: default + spec: + hard: + cpu: "10" + memory: "20Gi" diff --git a/cost-optimization/schedule-based-quotas/.chainsaw-test/03-weekend/test.yaml b/cost-optimization/schedule-based-quotas/.chainsaw-test/03-weekend/test.yaml new file mode 100644 index 000000000..92d710fc9 --- /dev/null +++ b/cost-optimization/schedule-based-quotas/.chainsaw-test/03-weekend/test.yaml @@ -0,0 +1,40 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: weekend +spec: + steps: + - name: setup + try: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + file: ../../schedule-based-quotas.yaml + - apiVersion: v1 + kind: ConfigMap + metadata: + name: time-mock + namespace: default + data: + time: "2024-03-23T14:00:00Z" # Saturday 2 PM + + - name: test-quota-weekend + try: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-weekend + namespace: default + spec: + hard: + cpu: "15" + memory: "30Gi" + assert: + - apiVersion: v1 + kind: ResourceQuota + metadata: + name: test-quota-weekend + namespace: default + spec: + hard: + cpu: "10" + memory: "20Gi" diff --git a/cost-optimization/schedule-based-quotas/artifacthub-pkg.yaml b/cost-optimization/schedule-based-quotas/artifacthub-pkg.yaml new file mode 100644 index 000000000..bae5dac3e --- /dev/null +++ b/cost-optimization/schedule-based-quotas/artifacthub-pkg.yaml @@ -0,0 +1,39 @@ +--- +name: schedule-based-quotas +version: 1.0.0 +displayName: Schedule-based Resource Quotas +createdAt: "2024-03-20T00:00:00.000Z" +description: >- + Automatically adjusts resource quotas based on time schedules to optimize cloud costs. + During non-business hours, the policy reduces resource quotas to prevent overprovisioning + while ensuring essential services remain operational. +install: |- + ```sh + kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/cost-optimization/schedule-based-quotas/schedule-based-quotas.yaml + ``` +keywords: + - resource management + - cost optimization + - quota + - scheduling +readme: | + # Schedule-based Resource Quotas + + This policy automatically adjusts resource quotas based on time schedules to optimize cloud costs. + During non-business hours, the policy reduces resource quotas to prevent overprovisioning + while ensuring essential services remain operational. + + ## Business Hours + - Monday to Friday + - 9 AM to 5 PM (Pacific Time) + - Higher resource limits (CPU: 20, Memory: 40Gi) + + ## Non-Business Hours + - Weekdays outside 9 AM - 5 PM + - All weekend hours + - Lower resource limits (CPU: 10, Memory: 20Gi) +annotations: + kyverno/category: Resource Management + kyverno/severity: medium + kyverno/subject: ResourceQuota, Namespace + kyverno/kubernetesVersion: "1.23-1.28" diff --git a/cost-optimization/schedule-based-quotas/schedule-based-quotas.yaml b/cost-optimization/schedule-based-quotas/schedule-based-quotas.yaml new file mode 100644 index 000000000..ea7d2acec --- /dev/null +++ b/cost-optimization/schedule-based-quotas/schedule-based-quotas.yaml @@ -0,0 +1,42 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: schedule-based-quotas + annotations: + policies.kyverno.io/title: Schedule-based Resource Quotas + policies.kyverno.io/category: Resource Management + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: ResourceQuota, Namespace + policies.kyverno.io/description: >- + Automatically adjusts resource quotas based on time schedules to optimize cloud costs. + During non-business hours, the policy reduces resource quotas to prevent overprovisioning + while ensuring essential services remain operational. + kyverno.io/kyverno-version: 1.11.0 + policies.kyverno.io/minversion: 1.11.0 + kyverno.io/kubernetes-version: "1.23-1.28" +spec: + background: true + rules: + - name: update-quotas-by-schedule + match: + any: + - resources: + kinds: + - ResourceQuota + context: + - name: mockTime + configMap: + name: time-mock + namespace: default + key: time + - name: currentTime + variable: >- + {{ mockTime || time.Now() | time.ParseInLocation('America/Los_Angeles') }} + - name: isBusinessHours + variable: currentTime.Hour() >= 9 && currentTime.Hour() < 17 && (currentTime.Weekday() >= 1 && currentTime.Weekday() <= 5) + mutate: + patchStrategicMerge: + spec: + hard: + cpu: "{{ isBusinessHours ? '20' : '10' }}" + memory: "{{ isBusinessHours ? '40Gi' : '20Gi' }}"