Repository: hashicorp/terraform-provider-kubernetes

Issue:
Error listing K8s resources using data_kubernetes_resources
### Terraform Version, Provider Version and Kubernetes Version
```
Terraform version: v1.5.5
Kubernetes provider version: 1.22.0
Kubernetes version: v1.24.15
```

### Affected Resource(s)

- pvc
- pv
- namespace

Issue appears to affect multiple resources, it may be an issue with Terraform's core.

### Terraform Configuration Files
```hcl
data "kubernetes_resources" "pvc" {
  api_version    = "v1"
  kind           = "PersistentVolumeClaim"
  namespace      = "mongodb"
  field_selector = "metadata.namespace=mongodb"
}
```

### Debug Output
https://gist.github.com/rafed/742a2f107c92f81f2b0a0ba37eeffc3a


### Steps to Reproduce

1. `terraform plan`

### Expected Behavior
Should list the pvcs in the mongodb namespace

### Actual Behavior
Throws error

### Important Factoids
Running in EKS

### References
https://github.com/hashicorp/terraform-provider-kubernetes/pull/2214

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment


Hints from issue comments:
@arybolovlev: Hi @rafed,

I am not able to reproduce this issue. Is there any other facts we need to know to reproduce the issue? Have you tried data source `kubernetes_persistent_volume_claim_v1` to gather the data you need?

Thank you.@rafed: Hey @arybolovlev. Thanks for looking into this!

I think I understand what's causing this on my end.

When I tried listing PVCs on all other namespaces in my cluster, I am getting them without any issue.

However, the issue occurs in my mongodb namespace. And it's probably because of one non ready PVC. The following is a screenshot of my mongodb PVCs.

![image](https://github.com/hashicorp/terraform-provider-kubernetes/assets/10649912/1b54fcea-82b8-4185-ab0a-f8615db0733c)

If I use `limit=2` in the parameter, the two running PVCs data are returned without any issue. However, by omitting `limit=2` an error is thrown and I see the following in my console.

`│Error: Failed to save resource state

   with data.kubernetes_resources.pvc,
   on main.tf line 71, in data "kubernetes_resources" "pvc":
   71: data "kubernetes_resources" "pvc" {

 AttributeName("metadata").AttributeName("managedFields"): AttributeName("metadata").AttributeName("managedFields")] incompatible tuple types`

Any thoughts on this? :/ @arybolovlev: Hi @rafed,

Thank you for this clarification. Now I am able to reproduce this issue and get the same error message.

A quick investigation brought me to the idea that it might be related to the `status` of the objects.

My example:

```console
$ kubectl -n this get pvc

NAME             STATUS    VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
task-pv-claim    Bound     task-pv-volume   10Gi       RWO            manual         28m
task-pv-claim2   Pending                                              manual         28m


$ kubectl -n this get pvc -o yaml
apiVersion: v1
items:
- apiVersion: v1
  kind: PersistentVolumeClaim
  ...
  status:
    accessModes:
    - ReadWriteOnce
    capacity:
      storage: 10Gi
    phase: Bound

- apiVersion: v1
  kind: PersistentVolumeClaim
  ...
  status:
    phase: Pending
```

As you can see, PVC with status `Bound` has 3 attributes under `status`: `accessModes`, `capacity`, and `phase`. PVC with status `Pending` has 1 attribute under `status`: `phase`. This status mismatch leads to [this condition](https://github.com/hashicorp/terraform-provider-kubernetes/blob/main/manifest/morph/scaffold.go#L66) where `attr` has length 3 and as the result it ends up with an error.

We definitely need more time to investigate and address this issue.@bradhandy: I get the same error when searching for Services in Kubernetes with `kubernetes_resources`.

```plain
data "kubernetes_resources" "services" {
  api_version = "v1"
  kind = "Service"
  namespace = "[namepsace]"
  label_selector = "customer-label=value"
}
```

EDIT: I'm using version 2.23.0 of the Kubernetes Provider. This issue says 1.22.0. I'm not sure if that's a mistype or if I should create another ticket.@jeremymcgee73: @bradhandy any luck with this? I'm running into it as well. I'm trying to get a podname. 

```
data "kubernetes_resources" "gitlab_toolbox" {
  api_version = "v1"
  kind        = "Pod"
  namespace   = var.namespace

  label_selector = "app=toolbox"
}
```

```
 AttributeName("metadata").AttributeName("managedFields"):
│ [AttributeName("metadata").AttributeName("managedFields")] incompatible
│ tuple types
```@bradhandy: What I ended up doing was creating a list of the services I expected to be in the namespace, then using `for_each` on a `kubernetes_service_v1` data source to get all of the information I needed. Then I ended up not needing the logic anyway so I ditched it.

I experimented with using an [external data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) to call a script. The script would run `kubectl` to output the results in JSON, then use `jq` to massage the results. The final output of the script would be a JSON object with a single key/value pair where the value was the massaged JSON encoded as a string. Then I could use the `jsondecode` method to access the data. Definitely not ideal, but it seemed to work locally. I haven't tried it in project code yet.@JBOClara: Same error with v2.24.0
```hcl
data "kubernetes_resources" "namespaces" {
  api_version    = "v1"
  kind           = "Namespace"
  field_selector = "metadata.name!=kube-system"
}
output "namespaces" {
  value = data.kubernetes_resources.namespaces.objects
}
```

```
│
│ AttributeName("metadata").AttributeName("managedFields"): [AttributeName("metadata").AttributeName("managedFields")] incompatible tuple types
╵
```
@cunningr: so, even the example in the docs doesn't work?@ldelgadop44: Same error with v2.25.2
```
data "kubernetes_resources" "example" {
  provider       = kubernetes.local
  api_version    = "apps/v1"
  kind           = "Deployment"
  namespace      = "linkerd"
}
output "deployments" {
  value = data.kubernetes_resources.namespaces.objects
}
```

**Error:** `AttributeName("metadata").AttributeName("managedFields"):
│ [AttributeName("metadata").AttributeName("managedFields")] incompatible tuple types`@macleanj: Still issues on 2.27.0@clone206: > Still issues on 2.27.0

Same

```
terraform {
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.27.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.97.1"
    }
  }
  required_version = ">= 1.1.0"
}
...
data "kubernetes_resources" "my_namespaces" {
  api_version = "v1"
  kind        = "Namespace"
}

output "my_objs" {
  value = data.kubernetes_resources.my_namespaces.objects
}
```

```
...
data.kubernetes_resources.my_namespaces: Reading...
╷
│ Error: Failed to save resource state
│
│   with data.kubernetes_resources.my_namespaces,
│   on main.tf line 67, in data "kubernetes_resources" "my_namespaces":
│   67: data "kubernetes_resources" "my_namespaces" {
│
│ AttributeName("metadata").AttributeName("managedFields"): [AttributeName("metadata").AttributeName("managedFields")] incompatible tuple types
```

Solution patch:
diff --git a/.changelog/2372.txt b/.changelog/2372.txt
new file mode 100644
index 00000000..0422ed3c
--- /dev/null
+++ b/.changelog/2372.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+`data_source/kubernetes_resources`: fix an issue where the provider exit with an error when the data source `kubernetes_resources` receives multiple Kubernetes objects containing tuples with different numbers of elements.
+```
diff --git a/.changelog/2384.txt b/.changelog/2384.txt
new file mode 100644
index 00000000..5e1f7fa4
--- /dev/null
+++ b/.changelog/2384.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+`kubernetes_manifest`: Implement response for GetMetadata protocol function
+```
diff --git a/.changelog/2387.txt b/.changelog/2387.txt
new file mode 100644
index 00000000..6fc3fa3c
--- /dev/null
+++ b/.changelog/2387.txt
@@ -0,0 +1,31 @@
+```release-note:bug
+`resource/kubernetes_stateful_set_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:bug
+`resource/kubernetes_stateful_set`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:bug
+`resource/kubernetes_daemon_set_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:bug
+`resource/kubernetes_daemonset`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:bug
+`resource/kubernetes_cron_job_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:bug
+`resource/kubernetes_cron_job`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema.
+```
+
+```release-note:note
+Resources `kubernetes_stateful_set_v1`, `kubernetes_stateful_set`, `kubernetes_daemon_set_v1`, and `kubernetes_daemonset` got a new attribute `spec.template.metadata.namespace`. It is a stub attribute that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+```
+
+```release-note:note
+Resources `kubernetes_cron_job_v1` and `kubernetes_cron_job` got a new attribute `spec.job_template.metadata.namespace`. It is a stub attribute that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+```
diff --git a/.changelog/2394.txt b/.changelog/2394.txt
new file mode 100644
index 00000000..ccc91901
--- /dev/null
+++ b/.changelog/2394.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+`resource/kubernetes_job_v1`: add new attribute `spec.pod_failure_policy` to job spec
+```
\ No newline at end of file
diff --git a/.changelog/2395.txt b/.changelog/2395.txt
new file mode 100644
index 00000000..0a26cf26
--- /dev/null
+++ b/.changelog/2395.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+`kubernetes/kubernetes_deployment_v1`: Add support for `HugePages` in `emptyDir.medium`
+```
\ No newline at end of file
diff --git a/.changelog/2404.txt b/.changelog/2404.txt
new file mode 100644
index 00000000..89913040
--- /dev/null
+++ b/.changelog/2404.txt
@@ -0,0 +1,3 @@
+```release-note:note
+Bump Kubernetes dependencies from x.27.8 to x.28.6.
+```
diff --git a/.changelog/2428.txt b/.changelog/2428.txt
new file mode 100644
index 00000000..be5ab0e9
--- /dev/null
+++ b/.changelog/2428.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+Add provider defined functions: `manifest_encode`, `manifest_decode`, `manifest_decode_multi`
+```
\ No newline at end of file
diff --git a/.changelog/2429.txt b/.changelog/2429.txt
new file mode 100644
index 00000000..f554f5b5
--- /dev/null
+++ b/.changelog/2429.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+`resource/kubernetes_pod_v1`: add missing `topology_spread_constraints`: `node_affinity_policy`, `node_taints_policy`, `match_label_keys`, `min_domains`
+```
diff --git a/.changelog/2461.txt b/.changelog/2461.txt
new file mode 100644
index 00000000..3baeab48
--- /dev/null
+++ b/.changelog/2461.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+`manifest_decode()`: fix handling of manifests containing null values
+```
diff --git a/.changelog/2464.txt b/.changelog/2464.txt
new file mode 100644
index 00000000..02b51ca2
--- /dev/null
+++ b/.changelog/2464.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+data-sources: revert a recently introduced deviation on datasources where querying a non-existent resource would cause an error (#2434).
+```
diff --git a/.github/workflows/acceptance_tests_aks.yaml b/.github/workflows/acceptance_tests_aks.yaml
index cf852d6c..0a0c4b3e 100644
--- a/.github/workflows/acceptance_tests_aks.yaml
+++ b/.github/workflows/acceptance_tests_aks.yaml
@@ -5,7 +5,7 @@ on:
     inputs:
       location:
         description: 'Location'
-        default: "West US 3"
+        default: "Canada East"
       nodeCount:
         description: 'Number of nodes to provision'
         default: 2
@@ -17,7 +17,7 @@ on:
         default: "1.27"
       terraformVersion:
         description: Terraform version
-        default: 1.5.6
+        default: 1.7.5
       runTests:
         description: The regex passed to the -run option of `go test`
         default: "^TestAcc"
@@ -41,18 +41,18 @@ jobs:
     runs-on: [custom, linux, medium]
     steps:
       - name: Checkout repository
-        uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2
       - name: Set up go
-        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
         with:
           go-version-file: 'go.mod'
       - name: Install Terraform
-        uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
+        uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
         with:
           terraform_version: ${{ env.TERRAFORM_VERSION }} 
           terraform_wrapper: false
       - name: Azure login 
-        uses: azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
+        uses: azure/login@8c334a195cbb38e46038007b304988d888bf676a # v2.0.0
         with:
           creds: ${{ secrets.AZURE_CREDENTIALS }}
       - name: Provision AKS
diff --git a/.github/workflows/acceptance_tests_eks.yaml b/.github/workflows/acceptance_tests_eks.yaml
index f1658c4a..003b040b 100644
--- a/.github/workflows/acceptance_tests_eks.yaml
+++ b/.github/workflows/acceptance_tests_eks.yaml
@@ -5,7 +5,7 @@ on:
     inputs:
       region:
         description: The AWS region
-        default: us-east-1
+        default: ca-central-1
       azSpan:
         description: The number of AZs to spread cluster nodes across
         default: 2
@@ -26,7 +26,7 @@ on:
         default: "^TestAcc"
       terraformVersion:
         description: Terraform version
-        default: 1.5.6
+        default: 1.7.5
   schedule:
     - cron: '0 20 * * *'
 
@@ -46,13 +46,13 @@ jobs:
     runs-on: [custom, linux, medium]
     steps:
       - name: Checkout repository
-        uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2
       - name: Set up Go
-        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
         with:
           go-version-file: 'go.mod'
       - name: Configure AWS Credentials
-        uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
+        uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
         with:
           aws-region: ${{ env.AWS_REGION }}
           aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -61,7 +61,7 @@ jobs:
           role-session-name: github-actions-tests-${{ github.run_number }}
           role-duration-seconds: 14400
       - name: Install Terraform
-        uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
+        uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
         with:
           terraform_version: ${{ env.TERRAFORM_VERSION }}
           terraform_wrapper: false
diff --git a/.github/workflows/acceptance_tests_gke.yaml b/.github/workflows/acceptance_tests_gke.yaml
index 41e79b40..bb50c3ad 100644
--- a/.github/workflows/acceptance_tests_gke.yaml
+++ b/.github/workflows/acceptance_tests_gke.yaml
@@ -5,10 +5,10 @@ on:
     inputs:
       region:
         description: The GKE region
-        default: us-west1
+        default: northamerica-northeast1
       zone:
         description: The GKE zone
-        default: us-west1-c
+        default: northamerica-northeast1-a
       clusterVersion:
         description: The GKE cluster version
         default: 1.27
@@ -26,7 +26,7 @@ on:
         default: "^TestAcc"
       terraformVersion:
         description: Terraform version
-        default: 1.5.6
+        default: 1.7.5
   schedule:
     - cron: '0 23 * * *'
 
@@ -47,18 +47,18 @@ jobs:
     runs-on: [custom, linux, medium]
     steps:
       - name: Checkout repository
-        uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2
       - name: Set up Go
-        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
         with:
           go-version-file: 'go.mod'
       - name: Authenticate to Google Cloud
-        uses: google-github-actions/auth@35b0e87d162680511bf346c299f71c9c5c379033 # v1.1.1
+        uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c # v2.1.2
         with:
           credentials_json: ${{ secrets.GOOGLE_CREDENTIALS }}
           access_token_lifetime: '14400s'
       - name: Set up gcloud SDK
-        uses: google-github-actions/setup-gcloud@e30db14379863a8c79331b04a9969f4c1e225e0b # v1.1.1
+        uses: google-github-actions/setup-gcloud@98ddc00a17442e89a24bbf282954a3b65ce6d200 # v2.1.0
         with:
           install_components: 'beta,gke-gcloud-auth-plugin'
       - name: Initialize gcloud SDK
@@ -66,7 +66,7 @@ jobs:
           gcloud init
           gcloud info
       - name: Install Terraform
-        uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
+        uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
         with:
           terraform_version: ${{ env.TERRAFORM_VERSION }}
           terraform_wrapper: false
diff --git a/.github/workflows/acceptance_tests_kind.yaml b/.github/workflows/acceptance_tests_kind.yaml
index 9ecf8a9f..d2f0605d 100644
--- a/.github/workflows/acceptance_tests_kind.yaml
+++ b/.github/workflows/acceptance_tests_kind.yaml
@@ -11,7 +11,7 @@ on:
         default: "^TestAcc"
       terraformVersion:
         description: Terraform version
-        default: 1.5.6
+        default: 1.7.5
       parallelRuns:
         description: The maximum number of tests to run simultaneously
         default: 8
@@ -35,18 +35,18 @@ jobs:
     runs-on: [custom, linux, medium]
     steps:
       - name: Checkout repository
-        uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2
       - name: Set up Go
-        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
         with:
           go-version-file: 'go.mod'
       - name: Install Terraform
-        uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
+        uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
         with:
           terraform_version: ${{ env.TERRAFORM_VERSION }}
           terraform_wrapper: false
       - name: Setup kind
-        uses: helm/kind-action@fa81e57adff234b2908110485695db0f181f3c67 # v1.7.0
+        uses: helm/kind-action@99576bfa6ddf9a8e612d83b513da5a75875caced # v1.9.0
         with:
           wait: 2m
           version: v${{ env.KIND_VERSION }}
diff --git a/.github/workflows/check_examples.yaml b/.github/workflows/check_examples.yaml
index 9746ce09..7d1e6396 100644
--- a/.github/workflows/check_examples.yaml
+++ b/.github/workflows/check_examples.yaml
@@ -24,21 +24,22 @@ jobs:
     strategy:
       matrix:
         terraform_version:
-          - "1.0.11"
-          - "1.1.9"
           - "1.2.9"
           - "1.3.9"
           - "1.4.0"
+          - "1.6.0"
+          - "1.7.0"
+          - "1.8.0"
     env:
       TF_X_KUBERNETES_MANIFEST_RESOURCE: 1
       TERM: linux
     steps:
-      - uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
+      - uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
         with:
           terraform_version: ${{ matrix.terraform_version }}
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2
       - name: Set up Go
-        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
         with:
           go-version-file: 'go.mod'
       - name: Go mod verify
@@ -46,7 +47,7 @@ jobs:
       - name: Go build
         run: go build
       - name: Setup kind
-        uses: helm/kind-action@fa81e57adff234b2908110485695db0f181f3c67 # v1.7.0
+        uses: helm/kind-action@99576bfa6ddf9a8e612d83b513da5a75875caced # v1.9.0
         with:
           wait: 2m
           version: "v0.17.0" # Kubernetes version: 1.25.X
diff --git a/.github/workflows/manifest_acc.yaml b/.github/workflows/manifest_acc.yaml
index 1a9530f4..d3fcd733 100644
--- a/.github/workflows/manifest_acc.yaml
+++ b/.github/workflows/manifest_acc.yaml
@@ -32,6 +32,7 @@ jobs:
           - v1.25.11@sha256:577c630ce8e509131eab1aea12c022190978dd2f745aac5eb1fe65c0807eb315
           - v1.23.15@sha256:ef453bb7c79f0e3caba88d2067d4196f427794086a7d0df8df4f019d5e336b61
         terraform_version:
+          - 1.8.0
           - 1.5.7
           - 1.4.7
           - 1.3.10
diff --git a/.github/workflows/provider_functions_unit.yaml b/.github/workflows/provider_functions_unit.yaml
new file mode 100644
index 00000000..af1b65b3
--- /dev/null
+++ b/.github/workflows/provider_functions_unit.yaml
@@ -0,0 +1,32 @@
+name: Provider Functions Unit Tests
+
+on:
+  push:
+    branches:
+      - main
+    paths:
+      - "internal/framework/provider/functions/**/*.go"
+  pull_request:
+    branches:
+      - main
+    paths:
+      - "internal/framework/provider/functions/**/*.go"
+  workflow_dispatch:
+
+jobs:
+  unit_tests:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+      - name: Set up Go
+        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
+        with:
+          go-version-file: 'go.mod'
+      - name: Go mod verify
+        run: go mod verify
+      - name: Run unit tests
+        env:
+          TF_ACC_TERRAFORM_VERSION: 1.8.0
+        run: |
+          make testfuncs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93b06379..682aa9bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,95 @@
+## 2.29.0 (April 11, 2024)
+
+BUG FIXES:
+
+* data-sources: revert a recently introduced deviation on datasources where querying a non-existent resource would cause an error (#2434). [[GH-2464](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2464)]
+
+## 2.28.1 (April 9, 2024)
+
+HOTFIX:
+
+* `manifest_decode()`: fix handling of manifests containing null values [[GH-2461](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2461)]
+
+## 2.28.0 (April 8, 2024)
+
+ENHANCEMENTS:
+
+**NOTE: Using [Provider Defined Functions](https://developer.hashicorp.com/terraform/plugin/framework/functions/concepts) requires Terraform version 1.8.0.**
+
+* Add provider defined functions: `manifest_encode`, `manifest_decode`, `manifest_decode_multi` [[GH-2428](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2428)]
+
+## 2.27.0 (Mar, 6 2024)
+
+ENHANCEMENTS:
+
+* `resource/kubernetes_pod_v1`: add missing `topology_spread_constraints`: `node_affinity_policy`, `node_taints_policy`, `match_label_keys`, `min_domains` [[GH-2429](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2429)]
+
+## 2.26.0 (Feb 15, 2024)
+
+ENHANCEMENTS:
+
+* `kubernetes/kubernetes_deployment_v1`: Add support for `HugePages` in `emptyDir.medium` [[GH-2395](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2395)]
+* `resource/kubernetes_job_v1`: add new attribute `spec.pod_failure_policy` to job spec [[GH-2394](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2394)]
+
+NOTES:
+
+* Bump Kubernetes dependencies from x.27.8 to x.28.6. [[GH-2404](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2404)]
+
+## 2.25.2 (Jan 8, 2024)
+
+BUG FIXES:
+
+* `resource/kubernetes_cron_job_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* `resource/kubernetes_cron_job`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* `resource/kubernetes_daemon_set_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* `resource/kubernetes_daemonset`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* `resource/kubernetes_stateful_set_v1`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* `resource/kubernetes_stateful_set`: fix an issue when the provider forces a resource recreation after upgrading to `2.25.0` and `2.25.1` due to changes in the resource schema. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+
+NOTES:
+
+* Resources `kubernetes_cron_job_v1` and `kubernetes_cron_job` got a new attribute `spec.job_template.metadata.namespace`. It is a stub attribute that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+* Resources `kubernetes_stateful_set_v1`, `kubernetes_stateful_set`, `kubernetes_daemon_set_v1`, and `kubernetes_daemonset` got a new attribute `spec.template.metadata.namespace`. It is a stub attribute that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation. [[GH-2387](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2387)]
+
+## 2.25.1 (Jan 4, 2024)
+
+HOTFIX:
+
+* `kubernetes_manifest`: Implement response for GetMetadata protocol function [[GH-2384](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2384)]
+
+## 2.25.0 (Jan 4, 2024)
+
+ENHANCEMENTS:
+
+* Add terraform-plugin-framework provider [[GH-2347](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2347)]
+* `data_source/kubernetes_persistent_volume_claim_v1`: add a new attribute `spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+* `data_source/kubernetes_persistent_volume_claim`: add a new attribute `spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+* `kubernetes/schema_stateful_set_spec.go`: Add `spec.persistentVolumeClaimRetentionPolicy` in `kubernetes_stateful_set` [[GH-2333](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2333)]
+* `resource/kubernetes_persistent_volume_claim_v1`: add a new attribute `spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+* `resource/kubernetes_persistent_volume_claim`: add a new attribute `spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+* `resource/kubernetes_stateful_set_v1`: add a new attribute `spec.volume_claim_template.spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+* `resource/kubernetes_stateful_set`: add a new attribute `spec.volume_claim_template.spec.volume_mode`. [[GH-2353](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2353)]
+
+BUG FIXES:
+
+* `resource/kubernetes_cron_job_v1`: Change the schema to include a namespace in `jobTemplate`
+`resource/kubernetes_stateful_set_v1`: Change the schema to include a namespace in `template` [[GH-2362](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2362)]
+* `resource/kubernetes_ingress_v1`: Fix an issue where the empty `tls` attribute in the configuration does not generate the corresponding Ingress object without any TLS configuration. [[GH-2344](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2344)]
+* `resource/kubernetes_ingress`: Fix an issue where the empty `tls` attribute in the configuration does not generate the corresponding Ingress object without any TLS configuration. [[GH-2344](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2344)]
+
+NOTES:
+
+* We have updated the logic of data sources and now the provider will return all annotations and labels attached to the object, regardless of the `ignore_annotations` and `ignore_labels` provider settings. In addition to that, a list of ignored labels when they are attached to `kubernetes_job(_v1)` and `kubernetes_cron_job(_v1)` resources were extended with labels `batch.kubernetes.io/controller-uid` and `batch.kubernetes.io/job-name` since they aim to replace `controller-uid` and `job-name` in the future Kubernetes releases. [[GH-2345](https://github.com/hashicorp/terraform-provider-kubernetes/issues/2345)]
+
+A special and warm welcome to the first contribution from our teammate @SarahFrench! 🚀
+
+## Community Contributors :raised_hands:
+
+- @tbobm made their contribution in https://github.com/hashicorp/terraform-provider-kubernetes/pull/2348
+- @andremarianiello made their contribution in https://github.com/hashicorp/terraform-provider-kubernetes/pull/2344
+- @adinhodovic made their contribution in https://github.com/hashicorp/terraform-provider-kubernetes/pull/2333
+- @wonko made their contribution in https://github.com/hashicorp/terraform-provider-kubernetes/pull/2362
+
 ## 2.24.0 (Nov 27, 2023)
 
 ENHANCEMENTS:
diff --git a/GNUmakefile b/GNUmakefile
index ad45824f..566cd3e1 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -8,6 +8,8 @@ PKG_NAME     := kubernetes
 OS_ARCH      := $(shell go env GOOS)_$(shell go env GOARCH)
 TF_PROV_DOCS := $(PWD)/kubernetes/test-infra/tfproviderdocs
 
+PROVIDER_FUNCTIONS_DIR := "$(PROVIDER_DIR)/internal/framework/provider/functions"
+
 ifneq ($(PWD),$(PROVIDER_DIR))
 $(error "Makefile must be run from the provider directory")
 endif
@@ -75,6 +77,9 @@ test: fmtcheck vet
 testacc: fmtcheck vet
 	TF_ACC=1 go test $(TEST) -v -vet=off $(TESTARGS) -parallel $(PARALLEL_RUNS) -timeout 3h
 
+testfuncs: fmtcheck 
+	go test $(PROVIDER_FUNCTIONS_DIR) -v -vet=off $(TESTARGS) -parallel $(PARALLEL_RUNS) 
+
 test-compile:
 	@if [ "$(TEST)" = "./..." ]; then \
 		echo "ERROR: Set TEST to a specific package. For example,"; \
@@ -99,8 +104,8 @@ tests-lint-fix: tools
 tools:
 	go install github.com/client9/misspell/cmd/misspell@v0.3.4
 	go install github.com/bflad/tfproviderlint/cmd/tfproviderlint@v0.28.1
-	go install github.com/bflad/tfproviderdocs@v0.9.1
-	go install github.com/katbyte/terrafmt@v0.5.2
+	go install github.com/bflad/tfproviderdocs@v0.12.0
+	go install github.com/katbyte/terrafmt@v0.5.3
 	go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2
 	go install github.com/hashicorp/go-changelog/cmd/changelog-build@latest
 	go install github.com/hashicorp/go-changelog/cmd/changelog-entry@latest
diff --git a/RELEASING.md b/RELEASING.md
new file mode 100644
index 00000000..8402681d
--- /dev/null
+++ b/RELEASING.md
@@ -0,0 +1,55 @@
+# Releasing
+
+The purpose of this document is to outline the release process for the Kubernetes Provider for Terraform.
+
+The Semantic Versioning agreement is being followed by this project. Further details can be found [here](https://semver.org/).
+
+## How To Release
+
+To create a new release, adhere to the following steps:
+
+- Decide on the version number that you intend to release. Throughout the following steps, it will be denoted as `<SEMVER>`.
+
+- Switch to the `main` branch and fetch the latest changes:
+
+  ```console
+  $ git switch main
+  $ git pull
+  ```
+
+- Create a new branch from the `main`. The branch name is required to adhere to the following template: `release/v<SEMVER>`.
+
+  ```console
+  $ git checkout -b release/v<SEMVER>
+  ```
+
+- Generate change log entries:
+
+  ```console
+  $ make changelog
+  ```
+
+- Update the [`CHANGELOG`](./CHANGELOG.md) file with the output produced in the previous step preceded by the release version and the planned release date expressed as `Mon DD, YYYY` format. The version number in this file must correspond with the `<SEMVER>` of the release branch name.
+
+- Create a pull request against the `main` branch and follow the regular code review and merge procedures.
+
+- After merging the release branch into the `main` one, a git tag with the new release version number needs to be attached to the release commit to start a release process. The version number in the tag must correspond with the `v<SEMVER>` of the merged release branch name. Below is an example of the commands that need to be run in this step:
+
+  ```console
+  $ git switch main
+  $ git pull
+  $ git log --pretty=oneline -n 1
+
+  ccd98a787308e6887c97291652430bd083106ccb (HEAD -> main, ...) v<SEMVER> (#XXXX)
+
+  $ git tag v<SEMVER> ccd98a787308e6887c97291652430bd083106ccb
+  $ git log --pretty=oneline -n 1
+
+  ccd98a787308e6887c97291652430bd083106ccb (..., tag: v<SEMVER>) v<SEMVER> (#XXXX)
+
+  $ git push origin v<SEMVER>
+  ```
+
+- Confirm this succeeded by viewing the repository [tags](https://github.com/hashicorp/terraform-provider-kubernetes/tags).
+
+- Monitor the [release](https://github.com/hashicorp/terraform-provider-kubernetes/actions/workflows/release.yaml) action on GitHub. Once it is completed, a new release should be available on the [registry](https://registry.terraform.io/providers/hashicorp/kubernetes/latest) portal within 15-30 minutes. If this does not happen or the action fails, please reach out to the release engineering team to troubleshoot the issue.
diff --git a/_examples/google-gke-nfs-filestore/main.tf b/_examples/google-gke-nfs-filestore/main.tf
index b59ccdc4..e160d8ff 100644
--- a/_examples/google-gke-nfs-filestore/main.tf
+++ b/_examples/google-gke-nfs-filestore/main.tf
@@ -92,10 +92,8 @@ resource "google_filestore_instance" "test" {
   }
 }
 
-data "template_file" "kubeconfig" {
-  template = file("${path.module}/kubeconfig-template.yaml")
-
-  vars = {
+resource "local_file" "kubeconfig" {
+  content  = templatefile("${path.module}/kubeconfig-template.yaml",{
     cluster_name    = google_container_cluster.primary.name
     user_name       = google_container_cluster.primary.master_auth[0].username
     user_password   = google_container_cluster.primary.master_auth[0].password
@@ -103,11 +101,7 @@ data "template_file" "kubeconfig" {
     cluster_ca      = google_container_cluster.primary.master_auth[0].cluster_ca_certificate
     client_cert     = google_container_cluster.primary.master_auth[0].client_certificate
     client_cert_key = google_container_cluster.primary.master_auth[0].client_key
-  }
-}
-
-resource "local_file" "kubeconfig" {
-  content  = data.template_file.kubeconfig.rendered
+  })
   filename = "${path.module}/kubeconfig"
 }
 
diff --git a/go.mod b/go.mod
index 800ea97b..692dec6d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,49 +1,53 @@
 module github.com/hashicorp/terraform-provider-kubernetes
 
+go 1.21
+
 require (
 	github.com/Masterminds/semver v1.5.0
 	github.com/getkin/kin-openapi v0.111.0
 	github.com/google/go-cmp v0.6.0
-	github.com/hashicorp/go-hclog v1.5.0
-	github.com/hashicorp/go-plugin v1.5.2
+	github.com/hashicorp/go-hclog v1.6.2
+	github.com/hashicorp/go-plugin v1.6.0
 	github.com/hashicorp/go-version v1.6.0
-	github.com/hashicorp/hc-install v0.6.0
-	github.com/hashicorp/hcl/v2 v2.18.0
-	github.com/hashicorp/terraform-exec v0.19.0
-	github.com/hashicorp/terraform-json v0.17.1
+	github.com/hashicorp/hc-install v0.6.3
+	github.com/hashicorp/hcl/v2 v2.20.0
+	github.com/hashicorp/terraform-exec v0.20.0
+	github.com/hashicorp/terraform-json v0.21.0
 	github.com/hashicorp/terraform-plugin-docs v0.16.0
-	github.com/hashicorp/terraform-plugin-framework v1.4.2
-	github.com/hashicorp/terraform-plugin-go v0.19.1
+	github.com/hashicorp/terraform-plugin-framework v1.7.0
+	github.com/hashicorp/terraform-plugin-go v0.22.1
 	github.com/hashicorp/terraform-plugin-log v0.9.0
-	github.com/hashicorp/terraform-plugin-mux v0.12.0
-	github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
+	github.com/hashicorp/terraform-plugin-mux v0.15.0
+	github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
+	github.com/hashicorp/terraform-plugin-testing v1.7.0
 	github.com/jinzhu/copier v0.3.5
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/mitchellh/hashstructure v1.1.0
 	github.com/robfig/cron v1.2.0
-	github.com/stretchr/testify v1.8.1
-	golang.org/x/mod v0.13.0
-	k8s.io/api v0.27.8
-	k8s.io/apiextensions-apiserver v0.27.8
-	k8s.io/apimachinery v0.27.8
-	k8s.io/client-go v0.27.8
-	k8s.io/kube-aggregator v0.27.8
-	k8s.io/kubectl v0.27.8
-	k8s.io/kubernetes v1.27.8
+	github.com/stretchr/testify v1.8.2
+	golang.org/x/mod v0.15.0
+	k8s.io/api v0.28.6
+	k8s.io/apiextensions-apiserver v0.28.6
+	k8s.io/apimachinery v0.28.6
+	k8s.io/client-go v0.28.6
+	k8s.io/kube-aggregator v0.28.6
+	k8s.io/kubectl v0.28.6
+	k8s.io/kubernetes v1.28.6
+	sigs.k8s.io/yaml v1.4.0
 )
 
 require (
 	github.com/Masterminds/goutils v1.1.1 // indirect
-	github.com/Masterminds/semver/v3 v3.1.1 // indirect
-	github.com/Masterminds/sprig/v3 v3.2.2 // indirect
-	github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
+	github.com/Masterminds/semver/v3 v3.2.0 // indirect
+	github.com/Masterminds/sprig/v3 v3.2.3 // indirect
+	github.com/ProtonMail/go-crypto v1.1.0-alpha.0 // indirect
 	github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
 	github.com/armon/go-radix v1.0.0 // indirect
 	github.com/bgentry/speakeasy v0.1.0 // indirect
-	github.com/cloudflare/circl v1.3.3 // indirect
+	github.com/cloudflare/circl v1.3.7 // indirect
 	github.com/emicklei/go-restful/v3 v3.10.1 // indirect
-	github.com/google/gnostic v0.6.9 // indirect
-	github.com/huandu/xstrings v1.3.2 // indirect
+	github.com/google/gnostic-models v0.6.8 // indirect
+	github.com/huandu/xstrings v1.3.3 // indirect
 	github.com/invopop/yaml v0.2.0 // indirect
 	github.com/mitchellh/cli v1.1.5 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
@@ -55,7 +59,9 @@ require (
 	github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 	golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
+	golang.org/x/sync v0.6.0 // indirect
+	golang.org/x/tools v0.16.1 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
 )
 
 require (
@@ -67,18 +73,18 @@ require (
 	github.com/evanphx/json-patch v5.6.0+incompatible // indirect
 	github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
 	github.com/fatih/camelcase v1.0.0 // indirect
-	github.com/fatih/color v1.13.0 // indirect
+	github.com/fatih/color v1.16.0 // indirect
 	github.com/go-errors/errors v1.4.2 // indirect
-	github.com/go-logr/logr v1.2.3 // indirect
+	github.com/go-logr/logr v1.2.4 // indirect
 	github.com/go-openapi/jsonpointer v0.19.6 // indirect
-	github.com/go-openapi/jsonreference v0.20.1 // indirect
+	github.com/go-openapi/jsonreference v0.20.2 // indirect
 	github.com/go-openapi/swag v0.22.3 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/google/btree v1.1.2 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
-	github.com/google/uuid v1.3.1 // indirect
+	github.com/google/uuid v1.6.0 // indirect
 	github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/hashicorp/go-checkpoint v0.5.0 // indirect
@@ -97,7 +103,7 @@ require (
 	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.16 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-testing-interface v1.14.1
 	github.com/mitchellh/go-wordwrap v1.0.1 // indirect
@@ -113,44 +119,32 @@ require (
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/russross/blackfriday v1.6.0 // indirect
-	github.com/spf13/cobra v1.6.1 // indirect
+	github.com/spf13/cobra v1.7.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
-	github.com/xlab/treeprint v1.1.0 // indirect
-	github.com/zclconf/go-cty v1.14.0
-	go.starlark.net v0.0.0-20221205180719-3fd0dac74452 // indirect
-	golang.org/x/crypto v0.17.0 // indirect
-	golang.org/x/net v0.17.0 // indirect
-	golang.org/x/oauth2 v0.11.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
-	golang.org/x/term v0.15.0 // indirect
+	github.com/xlab/treeprint v1.2.0 // indirect
+	github.com/zclconf/go-cty v1.14.3
+	go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
+	golang.org/x/crypto v0.21.0 // indirect
+	golang.org/x/net v0.21.0 // indirect
+	golang.org/x/oauth2 v0.16.0 // indirect
+	golang.org/x/sys v0.18.0 // indirect
+	golang.org/x/term v0.18.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
-	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/grpc v1.59.0
-	google.golang.org/protobuf v1.31.0 // indirect
+	google.golang.org/appengine v1.6.8 // indirect
+	google.golang.org/grpc v1.62.1
+	google.golang.org/protobuf v1.33.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/cli-runtime v0.27.8 // indirect
-	k8s.io/component-base v0.27.8 // indirect
-	k8s.io/klog/v2 v2.90.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
+	k8s.io/cli-runtime v0.28.6 // indirect
+	k8s.io/component-base v0.28.6 // indirect
+	k8s.io/klog/v2 v2.100.1 // indirect
+	k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
 	k8s.io/utils v0.0.0-20231127182322-b307cd553661
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
-	sigs.k8s.io/kustomize/api v0.13.2 // indirect
-	sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
+	sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
+	sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
-	sigs.k8s.io/yaml v1.3.0 // indirect
-)
-
-// kustomize needs to be kept in sync with the cli-runtime.
-// go-openapi needs to be locked at a version that is compatible with kustomize
-replace (
-	github.com/go-openapi/spec => github.com/go-openapi/spec v0.20.9
-	k8s.io/client-go => k8s.io/client-go v0.27.7
-// sigs.k8s.io/kustomize/pkg/transformers => ./vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer
-// sigs.k8s.io/kustomize/pkg/transformers/config => ./vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/config
 )
-
-go 1.21
diff --git a/go.sum b/go.sum
index 8aa2c137..8f849ae2 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,4 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
 dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
@@ -11,21 +10,18 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
 github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
 github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
-github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
-github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
-github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
-github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
-github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.0 h1:nHGfwXmFvJrSR9xu8qL7BkO4DqTHXE9N5vPhgY2I+j0=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.0/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
 github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
 github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
 github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
 github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
@@ -38,38 +34,29 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
 github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
-github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
-github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
 github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
-github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
 github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
+github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
 github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
 github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
 github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
 github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -78,35 +65,34 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSY
 github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
 github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
-github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
+github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
+github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
 github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
 github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
 github.com/getkin/kin-openapi v0.111.0 h1:zspOcFKBCQOY8d9Yockcbit8iVR2hco9qLaoQoj7kmw=
 github.com/getkin/kin-openapi v0.111.0/go.mod h1:QtwUNt0PAAgIIBEvFWYfB7dfngxtAaqCX1zYHMZDeK8=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
 github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
 github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
 github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
-github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
-github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
-github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
-github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
+github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
+github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
+github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
 github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
-github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
 github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
 github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
 github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -117,25 +103,21 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
 github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
-github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
+github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
+github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -143,6 +125,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -154,13 +137,12 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
-github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
 github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -171,40 +153,42 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
 github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
-github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
-github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I=
+github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
 github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
-github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y=
-github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4=
+github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
+github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
 github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
 github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4=
-github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA=
-github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8=
-github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
+github.com/hashicorp/hc-install v0.6.3 h1:yE/r1yJvWbtrJ0STwScgEnCanb0U9v7zp0Gbkmcoxqs=
+github.com/hashicorp/hc-install v0.6.3/go.mod h1:KamGdbodYzlufbWh4r9NRo8y6GLHWZP2GBtdnms1Ln0=
+github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4=
+github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk=
 github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM=
-github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg=
-github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA=
-github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o=
+github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo=
+github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw=
+github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U=
+github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
 github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI=
 github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA=
-github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI=
-github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY=
-github.com/hashicorp/terraform-plugin-go v0.19.1 h1:lf/jTGTeELcz5IIbn/94mJdmnTjRYm6S6ct/JqCSr50=
-github.com/hashicorp/terraform-plugin-go v0.19.1/go.mod h1:5NMIS+DXkfacX6o5HCpswda5yjkSYfKzn1Nfl9l+qRs=
+github.com/hashicorp/terraform-plugin-framework v1.7.0 h1:wOULbVmfONnJo9iq7/q+iBOBJul5vRovaYJIu2cY/Pw=
+github.com/hashicorp/terraform-plugin-framework v1.7.0/go.mod h1:jY9Id+3KbZ17OMpulgnWLSfwxNVYSoYBQFTgsx044CI=
+github.com/hashicorp/terraform-plugin-go v0.22.1 h1:iTS7WHNVrn7uhe3cojtvWWn83cm2Z6ryIUDTRO0EV7w=
+github.com/hashicorp/terraform-plugin-go v0.22.1/go.mod h1:qrjnqRghvQ6KnDbB12XeZ4FluclYwptntoWCr9QaXTI=
 github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
 github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
-github.com/hashicorp/terraform-plugin-mux v0.12.0 h1:TJlmeslQ11WlQtIFAfth0vXx+gSNgvMEng2Rn9z3WZY=
-github.com/hashicorp/terraform-plugin-mux v0.12.0/go.mod h1:8MR0AgmV+Q03DIjyrAKxXyYlq2EUnYBQP8gxAAA0zeM=
-github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14=
-github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8=
+github.com/hashicorp/terraform-plugin-mux v0.15.0 h1:+/+lDx0WUsIOpkAmdwBIoFU8UP9o2eZASoOnLsWbKME=
+github.com/hashicorp/terraform-plugin-mux v0.15.0/go.mod h1:9ezplb1Dyq394zQ+ldB0nvy/qbNAz3mMoHHseMTMaKo=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A=
+github.com/hashicorp/terraform-plugin-testing v1.7.0 h1:I6aeCyZ30z4NiI3tzyDoO6fS7YxP5xSL1ceOon3gTe8=
+github.com/hashicorp/terraform-plugin-testing v1.7.0/go.mod h1:sbAreCleJNOCz+y5vVHV8EJkIWZKi/t4ndKiUjM9vao=
 github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI=
 github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM=
 github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
@@ -212,12 +196,12 @@ github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv2
 github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
 github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
 github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
 github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
 github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
-github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
@@ -238,10 +222,9 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -262,8 +245,9 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng=
 github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4=
 github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
@@ -299,10 +283,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
 github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
-github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
-github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
-github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
-github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
+github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
+github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM=
+github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
+github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
 github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
@@ -317,9 +301,8 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
 github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
-github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
 github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
 github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -329,17 +312,15 @@ github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
 github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
 github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
-github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
-github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
+github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
 github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
-github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
-github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
@@ -353,8 +334,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
 github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
 github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
@@ -364,29 +346,24 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
 github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
 github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
 github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
-github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
+github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
+github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc=
-github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.starlark.net v0.0.0-20221205180719-3fd0dac74452 h1:JZtNuL6LPB+scU5yaQ6hqRlJFRiddZm2FwRt2AQqtHA=
-go.starlark.net v0.0.0-20221205180719-3fd0dac74452/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk=
+github.com/zclconf/go-cty v1.14.3 h1:1JXy1XroaGrzZuG6X9dt7HL6s9AwbY+l4UNL8o5B6ho=
+github.com/zclconf/go-cty v1.14.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
+go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
+go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U=
 golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
@@ -396,52 +373,39 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
-golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
-golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
+golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
+golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -452,28 +416,21 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
@@ -487,50 +444,40 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
+golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
-google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
+google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
+google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -538,49 +485,47 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.27.8 h1:Ja93gbyII5c3TJzWefEwGhlqC5SZksWhzRS+OYHIocU=
-k8s.io/api v0.27.8/go.mod h1:2HuWJC6gpx4UScY+ezziNzv6j6Jqd2q0rGgobYSSjcs=
-k8s.io/apiextensions-apiserver v0.27.8 h1:u9PON71euIhVbHdZ5YlznpY60GtRjPagf1mQXLo1siA=
-k8s.io/apiextensions-apiserver v0.27.8/go.mod h1:qBlRJTKCA0gnFVCsjzbz3YJZ49TCBNEwvEF2TPMRqOs=
-k8s.io/apimachinery v0.27.8 h1:Xg+ogjDm8s7KmV3vZGf7uOZ0jrC6FPy2Lk/h7BIRmvg=
-k8s.io/apimachinery v0.27.8/go.mod h1:EIXLxLt/b1muPITiF5zlrcm7I+YnXsIgM+0GdnPTQvA=
-k8s.io/cli-runtime v0.27.8 h1:ZaDL/cjiQL+Wy+Rli42YOIJUy0/RnFAN8MFgh+5MK7Y=
-k8s.io/cli-runtime v0.27.8/go.mod h1:QSiR1aJwFj33pxLkd6wVzORDfLq8OFog53qHRW7KkWg=
-k8s.io/client-go v0.27.7 h1:+Xgh9OOKv6A3qdD4Dnl/0VOI5EvAv+0s/OseDxVVTwQ=
-k8s.io/client-go v0.27.7/go.mod h1:dZ2kqcalYp5YZ2EV12XIMc77G6PxHWOJp/kclZr4+5Q=
-k8s.io/component-base v0.27.8 h1:O8YRFv/wWvoo9z62p1N52lq+w5FpzILAlE1h8b9o3K8=
-k8s.io/component-base v0.27.8/go.mod h1:h3uyZl+bFQeuLRz3owfSLaw3JKTrn6gmbvybkkW2z+I=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-aggregator v0.27.8 h1:BgAxJByvinQ4C041xhPpiIwZF7LQqMBvKzCdllAiZ8I=
-k8s.io/kube-aggregator v0.27.8/go.mod h1:FOc8GF4BDVFJ69QpUNSMmrfLbaouQNdu1xW+Fqm/VTE=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
-k8s.io/kubectl v0.27.8 h1:VipG0f9E1kGRGJYm2/kNv188RgDduvx1g2q1b20niHg=
-k8s.io/kubectl v0.27.8/go.mod h1:ZufZqfI5V7oBuGFALJHoTxypO0fewOwbadr4saUkRKo=
-k8s.io/kubernetes v1.27.8 h1:K848lTo/D0jvrxUlTvw4nNADixbhXLHgKNDP/KlFGy8=
-k8s.io/kubernetes v1.27.8/go.mod h1:PUXXrx0IhAi+kI9BMDqNJHUnLndVv9W0DkriqyjuJOs=
+k8s.io/api v0.28.6 h1:yy6u9CuIhmg55YvF/BavPBBXB+5QicB64njJXxVnzLo=
+k8s.io/api v0.28.6/go.mod h1:AM6Ys6g9MY3dl/XNaNfg/GePI0FT7WBGu8efU/lirAo=
+k8s.io/apiextensions-apiserver v0.28.6 h1:myB3iG/3v3jqCg28JDbOefu4sH2/erNEXgytRzJKBOo=
+k8s.io/apiextensions-apiserver v0.28.6/go.mod h1:qlp6xRKBgyRhe5AYc81TQpLx4kLNK8/sGQUOwMkVjRk=
+k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0=
+k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA=
+k8s.io/cli-runtime v0.28.6 h1:bDH2+ZbHBK3NORGmIygj/zWOkVd/hGWg9RqAa5c/Ev0=
+k8s.io/cli-runtime v0.28.6/go.mod h1:KFk67rlb7Pxh15uLbYGBUlW7ZUcpl7IM1GnHtskrcWA=
+k8s.io/client-go v0.28.6 h1:Gge6ziyIdafRchfoBKcpaARuz7jfrK1R1azuwORIsQI=
+k8s.io/client-go v0.28.6/go.mod h1:+nu0Yp21Oeo/cBCsprNVXB2BfJTV51lFfe5tXl2rUL8=
+k8s.io/component-base v0.28.6 h1:G4T8VrcQ7xZou3by/fY5NU5mfxOBlWaivS2lPrEltAo=
+k8s.io/component-base v0.28.6/go.mod h1:Dg62OOG3ALu2P4nAG00UdsuHoNLQJ5VsUZKQlLDcS+E=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-aggregator v0.28.6 h1:opRVDw+inLPIyAqG9Fu3+EYWcmbTHOHJNrmuKoeuzQM=
+k8s.io/kube-aggregator v0.28.6/go.mod h1:NXzqtkCuAfv/modgRbAkPdfUZF+koazCy8Qrs8L+WyE=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
+k8s.io/kubectl v0.28.6 h1:46O3gGJYlpqy7wtwYlggieemyIcuZqmflnQVDci3MgY=
+k8s.io/kubectl v0.28.6/go.mod h1:FS5ugZhi3kywpMQSCnp8MN+gctdFHJACzC6mH3fZ6lc=
+k8s.io/kubernetes v1.28.6 h1:Nn2fXNjaqmKyXeFq6verbdqzlj1aqUpBcyeC1OhRFa4=
+k8s.io/kubernetes v1.28.6/go.mod h1:0qpyGJTR3blkbQOmZA3Z0u1VDZJNxJM8ifLUVNJN0X8=
 k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
 k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
-sigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA=
-sigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw=
-sigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA=
-sigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=
+sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
+sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY=
+sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U=
+sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag=
 sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
 sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
-sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
+sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
+sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/internal/framework/provider/functions/decode.go b/internal/framework/provider/functions/decode.go
new file mode 100644
index 00000000..aaac1de4
--- /dev/null
+++ b/internal/framework/provider/functions/decode.go
@@ -0,0 +1,120 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions
+
+import (
+	"context"
+	"fmt"
+	"math/big"
+	"regexp"
+
+	"github.com/hashicorp/terraform-plugin-framework/attr"
+	"github.com/hashicorp/terraform-plugin-framework/diag"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	"sigs.k8s.io/yaml"
+)
+
+var documentSeparator = regexp.MustCompile(`(:?^|\s*\n)---\s*`)
+
+func decode(ctx context.Context, manifest string) (v types.Tuple, diags diag.Diagnostics) {
+	docs := documentSeparator.Split(manifest, -1)
+	dtypes := []attr.Type{}
+	dvalues := []attr.Value{}
+	diags = diag.Diagnostics{}
+
+	for _, d := range docs {
+		var data map[string]any
+		err := yaml.Unmarshal([]byte(d), &data)
+		if err != nil {
+			diags.Append(diag.NewErrorDiagnostic("Invalid YAML document", err.Error()))
+			return
+		}
+
+		if len(data) == 0 {
+			diags.Append(diag.NewWarningDiagnostic("Empty document", "encountered a YAML document with no values"))
+			continue
+		}
+
+		if err := validateKubernetesManifest(data); err != nil {
+			diags.Append(diag.NewErrorDiagnostic("Invalid Kubernetes manifest", err.Error()))
+			return
+		}
+
+		obj, d := decodeScalar(ctx, data)
+		diags.Append(d...)
+		if diags.HasError() {
+			return
+		}
+		dtypes = append(dtypes, obj.Type(ctx))
+		dvalues = append(dvalues, obj)
+	}
+
+	return types.TupleValue(dtypes, dvalues)
+}
+
+func decodeMapping(ctx context.Context, m map[string]any) (attr.Value, diag.Diagnostics) {
+	vm := make(map[string]attr.Value, len(m))
+	tm := make(map[string]attr.Type, len(m))
+
+	for k, v := range m {
+		vv, diags := decodeScalar(ctx, v)
+		if diags.HasError() {
+			return nil, diags
+		}
+		vm[k] = vv
+		tm[k] = vv.Type(ctx)
+	}
+
+	return types.ObjectValue(tm, vm)
+}
+
+func decodeSequence(ctx context.Context, s []any) (attr.Value, diag.Diagnostics) {
+	vl := make([]attr.Value, len(s))
+	tl := make([]attr.Type, len(s))
+
+	for i, v := range s {
+		vv, diags := decodeScalar(ctx, v)
+		if diags.HasError() {
+			return nil, diags
+		}
+		vl[i] = vv
+		tl[i] = vv.Type(ctx)
+	}
+
+	return types.TupleValue(tl, vl)
+}
+
+func decodeScalar(ctx context.Context, m any) (value attr.Value, diags diag.Diagnostics) {
+	switch v := m.(type) {
+	case nil:
+		value = types.DynamicNull()
+	case float64:
+		value = types.NumberValue(big.NewFloat(float64(v)))
+	case bool:
+		value = types.BoolValue(v)
+	case string:
+		value = types.StringValue(v)
+	case []any:
+		return decodeSequence(ctx, v)
+	case map[string]any:
+		return decodeMapping(ctx, v)
+	default:
+		diags.Append(diag.NewErrorDiagnostic("failed to decode", fmt.Sprintf("unexpected type: %T for value %#v", v, v)))
+	}
+	return
+}
+
+func validateKubernetesManifest(m map[string]any) error {
+	// NOTE: a Kubernetes manifest should have:
+	//       - an apiVersion
+	//       - a kind
+	//       - a metadata field
+	for _, k := range []string{"apiVersion", "kind", "metadata"} {
+		_, ok := m[k]
+		if !ok {
+			return fmt.Errorf("missing field %q", k)
+		}
+	}
+	return nil
+}
diff --git a/internal/framework/provider/functions/encode.go b/internal/framework/provider/functions/encode.go
new file mode 100644
index 00000000..b34fbb7a
--- /dev/null
+++ b/internal/framework/provider/functions/encode.go
@@ -0,0 +1,153 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/hashicorp/terraform-plugin-framework/attr"
+	"github.com/hashicorp/terraform-plugin-framework/diag"
+	"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
+
+	"sigs.k8s.io/yaml"
+)
+
+func encodeValue(v attr.Value) (any, error) {
+	if v.IsNull() {
+		return nil, nil
+	}
+
+	switch vv := v.(type) {
+	case basetypes.StringValue:
+		return vv.ValueString(), nil
+	case basetypes.NumberValue:
+		f, _ := vv.ValueBigFloat().Float64()
+		return f, nil
+	case basetypes.BoolValue:
+		return vv.ValueBool(), nil
+	case basetypes.ObjectValue:
+		return encodeObject(vv)
+	case basetypes.TupleValue:
+		return encodeTuple(vv)
+	case basetypes.MapValue:
+		return encodeMap(vv)
+	case basetypes.ListValue:
+		return encodeList(vv)
+	case basetypes.SetValue:
+		return encodeSet(vv)
+	default:
+		return nil, fmt.Errorf("tried to encode unsupported type: %T: %v", v, vv)
+	}
+}
+
+func encodeSet(sv basetypes.SetValue) ([]any, error) {
+	elems := sv.Elements()
+	size := len(elems)
+	l := make([]any, size)
+	for i := 0; i < size; i++ {
+		var err error
+		l[i], err = encodeValue(elems[i])
+		if err != nil {
+			return nil, err
+		}
+	}
+	return l, nil
+}
+
+func encodeList(lv basetypes.ListValue) ([]any, error) {
+	elems := lv.Elements()
+	size := len(elems)
+	l := make([]any, size)
+	for i := 0; i < size; i++ {
+		var err error
+		l[i], err = encodeValue(elems[i])
+		if err != nil {
+			return nil, err
+		}
+	}
+	return l, nil
+}
+
+func encodeTuple(tv basetypes.TupleValue) ([]any, error) {
+	elems := tv.Elements()
+	size := len(elems)
+	l := make([]any, size)
+	for i := 0; i < size; i++ {
+		var err error
+		l[i], err = encodeValue(elems[i])
+		if err != nil {
+			return nil, err
+		}
+	}
+	return l, nil
+}
+
+func encodeObject(ov basetypes.ObjectValue) (map[string]any, error) {
+	attrs := ov.Attributes()
+	m := make(map[string]any, len(attrs))
+	for k, v := range attrs {
+		var err error
+		m[k], err = encodeValue(v)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return m, nil
+}
+
+func encodeMap(mv basetypes.MapValue) (map[string]any, error) {
+	elems := mv.Elements()
+	m := make(map[string]any, len(elems))
+	for k, v := range elems {
+		var err error
+		m[k], err = encodeValue(v)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return m, nil
+}
+
+func marshal(m map[string]any) (encoded string, diags diag.Diagnostics) {
+	if err := validateKubernetesManifest(m); err != nil {
+		diags.Append(diag.NewErrorDiagnostic("Invalid Kubernetes manifest", err.Error()))
+		return
+	}
+	b, err := yaml.Marshal(m)
+	if err != nil {
+		diags.Append(diag.NewErrorDiagnostic("Error marshalling yaml", err.Error()))
+		return
+	}
+	return string(b), nil
+}
+
+func encode(v attr.Value) (encoded string, diags diag.Diagnostics) {
+	val, err := encodeValue(v)
+	if err != nil {
+		return "", diag.Diagnostics{diag.NewErrorDiagnostic("Error decoding manifest", err.Error())}
+	}
+
+	if m, ok := val.(map[string]any); ok {
+		return marshal(m)
+	} else if l, ok := val.([]any); ok {
+		for _, vv := range l {
+			m, ok := vv.(map[string]any)
+			if !ok {
+				diags.Append(diag.NewErrorDiagnostic(
+					"List of manifests contained an invalid resource", fmt.Sprintf("value doesn't seem to be a manifest: %#v", vv)))
+			}
+			s, diags := marshal(m)
+			if diags.HasError() {
+				return "", diags
+			}
+			encoded = strings.Join([]string{encoded, s}, "---\n")
+		}
+		return string(encoded), nil
+	}
+
+	diags.Append(diag.NewErrorDiagnostic(
+		"Invalid manifest", fmt.Sprintf("value doesn't seem to be a manifest: %#v", val)))
+	return
+}
diff --git a/internal/framework/provider/functions/manifest_decode.go b/internal/framework/provider/functions/manifest_decode.go
new file mode 100644
index 00000000..2c42be6c
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_decode.go
@@ -0,0 +1,64 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions
+
+import (
+	"context"
+
+	"github.com/hashicorp/terraform-plugin-framework/function"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ function.Function = ManifestDecodeFunction{}
+
+func NewManifestDecodeFunction() function.Function {
+	return &ManifestDecodeFunction{}
+}
+
+type ManifestDecodeFunction struct{}
+
+func (f ManifestDecodeFunction) Metadata(_ context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
+	resp.Name = "manifest_decode"
+}
+
+func (f ManifestDecodeFunction) Definition(_ context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
+	resp.Definition = function.Definition{
+		Summary:             "Decode a Kubernetes YAML manifest",
+		MarkdownDescription: "Given a YAML text containing a Kubernetes manifest, will decode and return an object representation of that resource.",
+		Parameters: []function.Parameter{
+			function.StringParameter{
+				Name:                "manifest",
+				MarkdownDescription: "The YAML text for a Kubernetes manifest",
+			},
+		},
+		Return: function.DynamicReturn{},
+	}
+}
+
+func (f ManifestDecodeFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
+	var manifest string
+
+	resp.Error = req.Arguments.Get(ctx, &manifest)
+	if resp.Error != nil {
+		return
+	}
+
+	tv, diags := decode(ctx, manifest)
+	if diags.HasError() {
+		resp.Error = function.FuncErrorFromDiags(ctx, diags)
+		return
+	}
+
+	elems := tv.Elements()
+	if len(elems) == 0 {
+		resp.Error = function.NewFuncError("Invalid manifest: YAML document is empty")
+		return
+	} else if len(elems) > 1 {
+		resp.Error = function.NewFuncError("YAML manifest contains multiple resources: use decode_manifest_multi to decode manifests containing more than one resource")
+		return
+	}
+
+	dynamResp := types.DynamicValue(elems[0])
+	resp.Error = resp.Result.Set(ctx, &dynamResp)
+}
diff --git a/internal/framework/provider/functions/manifest_decode_multi.go b/internal/framework/provider/functions/manifest_decode_multi.go
new file mode 100644
index 00000000..b3f3fec7
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_decode_multi.go
@@ -0,0 +1,55 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions
+
+import (
+	"context"
+
+	"github.com/hashicorp/terraform-plugin-framework/function"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ function.Function = ManifestDecodeMultiFunction{}
+
+func NewManifestDecodeMultiFunction() function.Function {
+	return &ManifestDecodeMultiFunction{}
+}
+
+type ManifestDecodeMultiFunction struct{}
+
+func (f ManifestDecodeMultiFunction) Metadata(_ context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
+	resp.Name = "manifest_decode_multi"
+}
+
+func (f ManifestDecodeMultiFunction) Definition(_ context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
+	resp.Definition = function.Definition{
+		Summary:             "Decode a Kubernetes YAML manifest containing multiple resources",
+		MarkdownDescription: "Given a YAML text containing a Kubernetes manifest with multiple resources, will decode the manifest and return a tuple of object representations for each resource.",
+		Parameters: []function.Parameter{
+			function.StringParameter{
+				Name:                "manifest",
+				MarkdownDescription: "The YAML plaintext for a Kubernetes manifest",
+			},
+		},
+		Return: function.DynamicReturn{},
+	}
+}
+
+func (f ManifestDecodeMultiFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
+	var manifest string
+
+	resp.Error = req.Arguments.Get(ctx, &manifest)
+	if resp.Error != nil {
+		return
+	}
+
+	tv, diags := decode(ctx, manifest)
+	if diags.HasError() {
+		resp.Error = function.FuncErrorFromDiags(ctx, diags)
+		return
+	}
+
+	dynamResp := types.DynamicValue(tv)
+	resp.Error = resp.Result.Set(ctx, &dynamResp)
+}
diff --git a/internal/framework/provider/functions/manifest_encode.go b/internal/framework/provider/functions/manifest_encode.go
new file mode 100644
index 00000000..7c474d1f
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_encode.go
@@ -0,0 +1,56 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions
+
+import (
+	"context"
+
+	"github.com/hashicorp/terraform-plugin-framework/function"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ function.Function = ManifestEncodeFunction{}
+
+func NewManifestEncodeFunction() function.Function {
+	return &ManifestEncodeFunction{}
+}
+
+type ManifestEncodeFunction struct{}
+
+func (f ManifestEncodeFunction) Metadata(_ context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
+	resp.Name = "manifest_encode"
+}
+
+func (f ManifestEncodeFunction) Definition(_ context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
+	resp.Definition = function.Definition{
+		Summary:             "Encode an object to Kubernetes YAML",
+		MarkdownDescription: "Given an object representation of a Kubernetes manifest, will encode and return a YAML string for that resource.",
+		Parameters: []function.Parameter{
+			function.DynamicParameter{
+				Name:                "manifest",
+				MarkdownDescription: "The object representation of a Kubernetes manifest",
+			},
+		},
+		Return: function.StringReturn{},
+	}
+}
+
+func (f ManifestEncodeFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
+	var manifest types.Dynamic
+
+	resp.Error = req.Arguments.Get(ctx, &manifest)
+	if resp.Error != nil {
+		return
+	}
+
+	uv := manifest.UnderlyingValue()
+	s, diags := encode(uv)
+	if diags.HasError() {
+		resp.Error = function.FuncErrorFromDiags(ctx, diags)
+		return
+	}
+
+	svalue := types.StringValue(s)
+	resp.Error = resp.Result.Set(ctx, &svalue)
+}
diff --git a/internal/framework/provider/provider.go b/internal/framework/provider/provider.go
index bbfd63ed..97776044 100644
--- a/internal/framework/provider/provider.go
+++ b/internal/framework/provider/provider.go
@@ -7,14 +7,19 @@ import (
 	"context"
 
 	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/function"
 	"github.com/hashicorp/terraform-plugin-framework/provider"
 	"github.com/hashicorp/terraform-plugin-framework/provider/schema"
 	"github.com/hashicorp/terraform-plugin-framework/resource"
 	"github.com/hashicorp/terraform-plugin-framework/types"
+	pfunctions "github.com/hashicorp/terraform-provider-kubernetes/internal/framework/provider/functions"
 )
 
 // Ensure KubernetesProvider satisfies various provider interfaces.
-var _ provider.Provider = &KubernetesProvider{}
+var (
+	_ provider.Provider              = &KubernetesProvider{}
+	_ provider.ProviderWithFunctions = &KubernetesProvider{}
+)
 
 // KubernetesProvider defines the provider implementation.
 type KubernetesProvider struct {
@@ -186,6 +191,14 @@ func (p *KubernetesProvider) DataSources(ctx context.Context) []func() datasourc
 	return []func() datasource.DataSource{}
 }
 
+func (p *KubernetesProvider) Functions(ctx context.Context) []func() function.Function {
+	return []func() function.Function{
+		pfunctions.NewManifestDecodeFunction,
+		pfunctions.NewManifestDecodeMultiFunction,
+		pfunctions.NewManifestEncodeFunction,
+	}
+}
+
 func New(version string) provider.Provider {
 	return &KubernetesProvider{
 		version: version,
diff --git a/kubernetes/data_source_kubernetes_config_map_v1.go b/kubernetes/data_source_kubernetes_config_map_v1.go
index c65cf9fb..70f8d9f0 100644
--- a/kubernetes/data_source_kubernetes_config_map_v1.go
+++ b/kubernetes/data_source_kubernetes_config_map_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -54,6 +55,9 @@ func dataSourceKubernetesConfigMapV1Read(ctx context.Context, d *schema.Resource
 	log.Printf("[INFO] Reading config map %s", metadata.Name)
 	cfgMap, err := conn.CoreV1().ConfigMaps(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_endpoints_v1.go b/kubernetes/data_source_kubernetes_endpoints_v1.go
index 05c4833f..95ca313a 100644
--- a/kubernetes/data_source_kubernetes_endpoints_v1.go
+++ b/kubernetes/data_source_kubernetes_endpoints_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -45,6 +46,9 @@ func dataSourceKubernetesEndpointsV1Read(ctx context.Context, d *schema.Resource
 	log.Printf("[INFO] Reading endpoints %s", metadata.Name)
 	ep, err := conn.CoreV1().Endpoints(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.Errorf("Failed to read endpoint because: %s", err)
 	}
diff --git a/kubernetes/data_source_kubernetes_ingress.go b/kubernetes/data_source_kubernetes_ingress.go
index dd5f5dcd..e0d4210f 100644
--- a/kubernetes/data_source_kubernetes_ingress.go
+++ b/kubernetes/data_source_kubernetes_ingress.go
@@ -10,6 +10,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	networking "k8s.io/api/networking/v1beta1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -151,6 +152,9 @@ func dataSourceKubernetesIngressRead(ctx context.Context, d *schema.ResourceData
 	log.Printf("[INFO] Reading ingress %s", metadata.Name)
 	ing, err := conn.ExtensionsV1beta1().Ingresses(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_ingress_v1.go b/kubernetes/data_source_kubernetes_ingress_v1.go
index 1aa2865b..b7988c7d 100644
--- a/kubernetes/data_source_kubernetes_ingress_v1.go
+++ b/kubernetes/data_source_kubernetes_ingress_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	networking "k8s.io/api/networking/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -162,6 +163,9 @@ func dataSourceKubernetesIngressV1Read(ctx context.Context, d *schema.ResourceDa
 	log.Printf("[INFO] Reading ingress %s", metadata.Name)
 	ing, err := conn.NetworkingV1().Ingresses(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
index 9e29bcbd..44d8949b 100644
--- a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
+++ b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -124,6 +125,9 @@ func dataSourceKubernetesMutatingWebhookConfigurationV1Read(ctx context.Context,
 	log.Printf("[INFO] Reading mutating webhook configuration %s", metadata.Name)
 	cfg, err := conn.AdmissionregistrationV1().MutatingWebhookConfigurations().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_namespace_v1.go b/kubernetes/data_source_kubernetes_namespace_v1.go
index 06b7de5e..6843d37f 100644
--- a/kubernetes/data_source_kubernetes_namespace_v1.go
+++ b/kubernetes/data_source_kubernetes_namespace_v1.go
@@ -10,6 +10,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -51,6 +52,9 @@ func dataSourceKubernetesNamespaceV1Read(ctx context.Context, d *schema.Resource
 
 	namespace, err := conn.CoreV1().Namespaces().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_nodes.go b/kubernetes/data_source_kubernetes_nodes.go
index 9231f95a..172475f9 100644
--- a/kubernetes/data_source_kubernetes_nodes.go
+++ b/kubernetes/data_source_kubernetes_nodes.go
@@ -12,6 +12,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 )
@@ -89,6 +90,9 @@ func dataSourceKubernetesNodesRead(ctx context.Context, d *schema.ResourceData,
 	log.Printf("[INFO] Listing nodes")
 	nodesRaw, err := conn.CoreV1().Nodes().List(ctx, listOptions)
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		return diag.FromErr(err)
 	}
 	nodes := make([]interface{}, len(nodesRaw.Items))
diff --git a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
index 92771fd5..bfb717b4 100644
--- a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
+++ b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -105,6 +106,9 @@ func dataSourceKubernetesPersistentVolumeClaimV1Read(ctx context.Context, d *sch
 	log.Printf("[INFO] Reading persistent volume claim %s", metadata.Name)
 	claim, err := conn.CoreV1().PersistentVolumeClaims(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_pod_v1.go b/kubernetes/data_source_kubernetes_pod_v1.go
index c944d0aa..ca2eeb3d 100644
--- a/kubernetes/data_source_kubernetes_pod_v1.go
+++ b/kubernetes/data_source_kubernetes_pod_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -55,6 +56,9 @@ func dataSourceKubernetesPodV1Read(ctx context.Context, d *schema.ResourceData,
 	log.Printf("[INFO] Reading pod %s", metadata.Name)
 	pod, err := conn.CoreV1().Pods(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_secret_v1.go b/kubernetes/data_source_kubernetes_secret_v1.go
index 49e6261e..1eed4cce 100644
--- a/kubernetes/data_source_kubernetes_secret_v1.go
+++ b/kubernetes/data_source_kubernetes_secret_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -61,6 +62,9 @@ func dataSourceKubernetesSecretV1Read(ctx context.Context, d *schema.ResourceDat
 	log.Printf("[INFO] Reading secret %s", metadata.Name)
 	secret, err := conn.CoreV1().Secrets(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		return diag.FromErr(err)
 	}
 	log.Printf("[INFO] Received secret: %#v", secret.ObjectMeta)
diff --git a/kubernetes/data_source_kubernetes_service_account_v1.go b/kubernetes/data_source_kubernetes_service_account_v1.go
index 8dadbb2f..5e29e2ac 100644
--- a/kubernetes/data_source_kubernetes_service_account_v1.go
+++ b/kubernetes/data_source_kubernetes_service_account_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -69,6 +70,10 @@ func dataSourceKubernetesServiceAccountV1Read(ctx context.Context, d *schema.Res
 	metadata := expandMetadata(d.Get("metadata").([]interface{}))
 	sa, err := conn.CoreV1().ServiceAccounts(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			d.SetId(buildId(sa.ObjectMeta))
+			return nil
+		}
 		return diag.Errorf("Unable to fetch service account from Kubernetes: %s", err)
 	}
 
@@ -84,6 +89,9 @@ func dataSourceKubernetesServiceAccountV1Read(ctx context.Context, d *schema.Res
 	log.Printf("[INFO] Reading service account %s", metadata.Name)
 	svcAcc, err := conn.CoreV1().ServiceAccounts(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		diagMsg = append(diagMsg, diag.FromErr(err)...)
 		return diagMsg
diff --git a/kubernetes/data_source_kubernetes_service_v1.go b/kubernetes/data_source_kubernetes_service_v1.go
index 8999de84..df37a3df 100644
--- a/kubernetes/data_source_kubernetes_service_v1.go
+++ b/kubernetes/data_source_kubernetes_service_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -257,6 +258,9 @@ func dataSourceKubernetesServiceV1Read(ctx context.Context, d *schema.ResourceDa
 	log.Printf("[INFO] Reading service %s", metadata.Name)
 	svc, err := conn.CoreV1().Services(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_storage_class_v1.go b/kubernetes/data_source_kubernetes_storage_class_v1.go
index 19d1bcf6..e23d065c 100644
--- a/kubernetes/data_source_kubernetes_storage_class_v1.go
+++ b/kubernetes/data_source_kubernetes_storage_class_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -100,6 +101,9 @@ func dataSourceKubernetesStorageClassV1Read(ctx context.Context, d *schema.Resou
 	log.Printf("[INFO] Reading storage class %s", metadata.Name)
 	storageClass, err := conn.StorageV1().StorageClasses().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/schema_cron_job_spec_v1.go b/kubernetes/schema_cron_job_spec_v1.go
index d59c4ec1..1a98ed8d 100644
--- a/kubernetes/schema_cron_job_spec_v1.go
+++ b/kubernetes/schema_cron_job_spec_v1.go
@@ -30,7 +30,7 @@ func cronJobSpecFieldsV1() map[string]*schema.Schema {
 			MaxItems:    1,
 			Elem: &schema.Resource{
 				Schema: map[string]*schema.Schema{
-					"metadata": namespacedMetadataSchema("jobTemplateSpec", true),
+					"metadata": namespacedMetadataSchemaIsTemplate("jobTemplateSpec", true, true),
 					"spec": {
 						Type:        schema.TypeList,
 						Description: "Specification of the desired behavior of the job",
diff --git a/kubernetes/schema_cron_job_spec_v1beta1.go b/kubernetes/schema_cron_job_spec_v1beta1.go
index e504a8e3..75d52e9e 100644
--- a/kubernetes/schema_cron_job_spec_v1beta1.go
+++ b/kubernetes/schema_cron_job_spec_v1beta1.go
@@ -30,7 +30,7 @@ func cronJobSpecFieldsV1Beta1() map[string]*schema.Schema {
 			MaxItems:    1,
 			Elem: &schema.Resource{
 				Schema: map[string]*schema.Schema{
-					"metadata": metadataSchema("jobTemplateSpec", true),
+					"metadata": namespacedMetadataSchemaIsTemplate("jobTemplateSpec", true, true),
 					"spec": {
 						Type:        schema.TypeList,
 						Description: "Specification of the desired behavior of the job",
diff --git a/kubernetes/schema_job_spec.go b/kubernetes/schema_job_spec.go
index 82a66e70..4fcb6b97 100644
--- a/kubernetes/schema_job_spec.go
+++ b/kubernetes/schema_job_spec.go
@@ -91,6 +91,72 @@ func jobSpecFields(specUpdatable bool) map[string]*schema.Schema {
 			ValidateFunc: validateNonNegativeInteger,
 			Description:  "Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
 		},
+		"pod_failure_policy": {
+			Type:        schema.TypeList,
+			Optional:    true,
+			ForceNew:    true,
+			MaxItems:    1,
+			Description: "Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
+			Elem: &schema.Resource{
+				Schema: map[string]*schema.Schema{
+					"rule": {
+						Type:        schema.TypeList,
+						Description: "A label query over volumes to consider for binding.",
+						Required:    true,
+						Elem: &schema.Resource{
+							Schema: map[string]*schema.Schema{
+								"action": {
+									Type:     schema.TypeString,
+									Optional: true,
+								},
+								"on_exit_codes": {
+									Type:     schema.TypeList,
+									Optional: true,
+									MaxItems: 1,
+									Elem: &schema.Resource{
+										Schema: map[string]*schema.Schema{
+											"container_name": {
+												Type:     schema.TypeString,
+												Optional: true,
+											},
+											"operator": {
+												Type:     schema.TypeString,
+												Optional: true,
+											},
+											"values": {
+												Type:     schema.TypeList,
+												Required: true,
+												MinItems: 1,
+												MaxItems: 255,
+												Elem: &schema.Schema{Type: schema.TypeInt,
+													ValidateFunc: validation.IntNotInSlice([]int{0})},
+											},
+										},
+									},
+								},
+								"on_pod_condition": {
+									Type:     schema.TypeList,
+									Optional: true,
+									Elem: &schema.Resource{
+										Schema: map[string]*schema.Schema{
+											"status": {
+												Type:     schema.TypeString,
+												Optional: true,
+												Default:  "True",
+											},
+											"type": {
+												Type:     schema.TypeString,
+												Optional: true,
+											},
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
 		// This field is immutable in Jobs.
 		"selector": {
 			Type:        schema.TypeList,
diff --git a/kubernetes/schema_pod_spec.go b/kubernetes/schema_pod_spec.go
index 50103582..c760b58c 100644
--- a/kubernetes/schema_pod_spec.go
+++ b/kubernetes/schema_pod_spec.go
@@ -4,6 +4,8 @@
 package kubernetes
 
 import (
+	"fmt"
+
 	corev1 "k8s.io/api/core/v1"
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -495,6 +497,15 @@ func podSpecFields(isUpdatable, isComputed bool) map[string]*schema.Schema {
 			Description: "describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints.",
 			Elem: &schema.Resource{
 				Schema: map[string]*schema.Schema{
+					"match_label_keys": {
+						Type:        schema.TypeSet,
+						Description: "is a set of pod label keys to select the pods over which spreading will be calculated.",
+						Optional:    true,
+						ForceNew:    !isUpdatable,
+						Elem: &schema.Schema{
+							Type: schema.TypeString,
+						},
+					},
 					"max_skew": {
 						Type:         schema.TypeInt,
 						Description:  "describes the degree to which pods may be unevenly distributed.",
@@ -502,6 +513,27 @@ func podSpecFields(isUpdatable, isComputed bool) map[string]*schema.Schema {
 						Default:      1,
 						ValidateFunc: validation.IntAtLeast(1),
 					},
+					"min_domains": {
+						Type:         schema.TypeInt,
+						Description:  "indicates a minimum number of eligible domains.",
+						Optional:     true,
+						ForceNew:     !isUpdatable,
+						ValidateFunc: validation.IntAtLeast(1),
+					},
+					"node_affinity_policy": {
+						Type:         schema.TypeString,
+						Description:  "indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew.",
+						Optional:     true,
+						ForceNew:     !isUpdatable,
+						ValidateFunc: validation.StringInSlice([]string{string(corev1.NodeInclusionPolicyHonor), string(corev1.NodeInclusionPolicyIgnore)}, false),
+					},
+					"node_taints_policy": {
+						Type:         schema.TypeString,
+						Description:  "indicates how we will treat node taints when calculating pod topology spread skew.",
+						Optional:     true,
+						ForceNew:     !isUpdatable,
+						ValidateFunc: validation.StringInSlice([]string{string(corev1.NodeInclusionPolicyHonor), string(corev1.NodeInclusionPolicyIgnore)}, false),
+					},
 					"topology_key": {
 						Type:        schema.TypeString,
 						Description: "the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology.",
@@ -707,6 +739,15 @@ func volumeSchema(isUpdatable bool) *schema.Resource {
 		},
 	}
 
+	validEmptyDirMediums := []string{
+		string(corev1.StorageMediumDefault),
+		string(corev1.StorageMediumMemory),
+		string(corev1.StorageMediumHugePages),
+		// This is possibly not an exhaustive list, but it does cover the
+		// common cases from x86_64 architectures.
+		string(corev1.StorageMediumHugePagesPrefix) + "2Mi",
+		string(corev1.StorageMediumHugePagesPrefix) + "1Gi",
+	}
 	v["empty_dir"] = &schema.Schema{
 		Type:        schema.TypeList,
 		Description: "EmptyDir represents a temporary directory that shares a pod's lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir",
@@ -715,15 +756,12 @@ func volumeSchema(isUpdatable bool) *schema.Resource {
 		Elem: &schema.Resource{
 			Schema: map[string]*schema.Schema{
 				"medium": {
-					Type:        schema.TypeString,
-					Description: `What type of storage medium should back this directory. The default is "" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir`,
-					Optional:    true,
-					Default:     "",
-					ForceNew:    !isUpdatable,
-					ValidateFunc: validation.StringInSlice([]string{
-						string(corev1.StorageMediumDefault),
-						string(corev1.StorageMediumMemory),
-					}, false),
+					Type:         schema.TypeString,
+					Description:  fmt.Sprintf(`What type of storage medium should back this directory. The default is "" which means to use the node's default medium. Must be one of %q. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir`, validEmptyDirMediums),
+					Optional:     true,
+					Default:      "",
+					ForceNew:     !isUpdatable,
+					ValidateFunc: validation.StringInSlice(validEmptyDirMediums, false),
 				},
 				"size_limit": {
 					Type:             schema.TypeString,
diff --git a/kubernetes/schema_pod_template.go b/kubernetes/schema_pod_template.go
index eba00b5a..1e8127e9 100644
--- a/kubernetes/schema_pod_template.go
+++ b/kubernetes/schema_pod_template.go
@@ -11,7 +11,7 @@ import (
 
 func podTemplateFields(owner string) map[string]*schema.Schema {
 	s := map[string]*schema.Schema{
-		"metadata": namespacedMetadataSchema(owner, true),
+		"metadata": namespacedMetadataSchemaIsTemplate(owner, true, true),
 		"spec": {
 			Type:        schema.TypeList,
 			Description: fmt.Sprintf("Spec of the pods owned by the %s", owner),
diff --git a/kubernetes/structure_job.go b/kubernetes/structure_job.go
index 517a4c4c..029456f2 100644
--- a/kubernetes/structure_job.go
+++ b/kubernetes/structure_job.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	batchv1 "k8s.io/api/batch/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/utils/ptr"
 )
 
@@ -38,6 +39,10 @@ func flattenJobV1Spec(in batchv1.JobSpec, d *schema.ResourceData, meta interface
 		att["parallelism"] = *in.Parallelism
 	}
 
+	if in.PodFailurePolicy != nil {
+		att["pod_failure_policy"] = flattenPodFailurePolicy(in.PodFailurePolicy)
+	}
+
 	if in.Selector != nil {
 		att["selector"] = flattenLabelSelector(in.Selector)
 	}
@@ -91,6 +96,10 @@ func expandJobV1Spec(j []interface{}) (batchv1.JobSpec, error) {
 		obj.Parallelism = ptr.To(int32(v))
 	}
 
+	if v, ok := in["pod_failure_policy"].([]interface{}); ok && len(v) > 0 {
+		obj.PodFailurePolicy = expandPodFailurePolicy(v)
+	}
+
 	if v, ok := in["selector"].([]interface{}); ok && len(v) > 0 {
 		obj.Selector = expandLabelSelector(v)
 	}
@@ -112,6 +121,157 @@ func expandJobV1Spec(j []interface{}) (batchv1.JobSpec, error) {
 	return obj, nil
 }
 
+func expandPodFailurePolicy(l []interface{}) *batchv1.PodFailurePolicy {
+	obj := &batchv1.PodFailurePolicy{}
+	if len(l) == 0 || l[0] == nil {
+		return obj
+	}
+	in := l[0].(map[string]interface{})
+
+	if v, ok := in["rule"].([]interface{}); ok && len(v) > 0 {
+		rules := expandPodFailurePolicyRules(v)
+		obj.Rules = rules
+	}
+	return obj
+}
+
+func expandPodFailurePolicyRules(l []interface{}) []batchv1.PodFailurePolicyRule {
+	obj := make([]batchv1.PodFailurePolicyRule, len(l))
+	if len(l) == 0 || l[0] == nil {
+		return obj
+	}
+	for i, rule := range l {
+		objRule := &batchv1.PodFailurePolicyRule{}
+
+		r := rule.(map[string]interface{})
+
+		if v, ok := r["action"].(string); ok && v != "" {
+			objRule.Action = batchv1.PodFailurePolicyAction(v)
+		}
+
+		if v, ok := r["on_exit_codes"].([]interface{}); ok && len(v) > 0 {
+			onExitCodes := expandPodFailurePolicyOnExitCodesRequirement(v)
+			objRule.OnExitCodes = onExitCodes
+		}
+
+		if v, ok := r["on_pod_condition"].([]interface{}); ok && len(v) > 0 {
+			podConditions := expandPodFailurePolicyOnPodConditionsPattern(v)
+			objRule.OnPodConditions = podConditions
+		}
+
+		obj[i] = *objRule
+	}
+
+	return obj
+}
+
+func expandPodFailurePolicyOnExitCodesRequirement(l []interface{}) *batchv1.PodFailurePolicyOnExitCodesRequirement {
+	obj := &batchv1.PodFailurePolicyOnExitCodesRequirement{}
+	if len(l) == 0 || l[0] == nil {
+		return obj
+	}
+	in := l[0].(map[string]interface{})
+
+	if v, ok := in["container_name"].(string); ok && v != "" {
+		obj.ContainerName = &v
+	}
+
+	if v, ok := in["operator"].(string); ok && v != "" {
+		obj.Operator = batchv1.PodFailurePolicyOnExitCodesOperator(v)
+	}
+
+	if v, ok := in["values"].([]interface{}); ok && len(v) > 0 {
+		vals := make([]int32, len(v))
+		for i := 0; i < len(v); i++ {
+			vals[i] = int32(v[i].(int))
+		}
+
+		obj.Values = vals
+	}
+
+	return obj
+}
+
+func expandPodFailurePolicyOnPodConditionsPattern(l []interface{}) []batchv1.PodFailurePolicyOnPodConditionsPattern {
+	obj := make([]batchv1.PodFailurePolicyOnPodConditionsPattern, len(l))
+	if len(l) == 0 || l[0] == nil {
+		return obj
+	}
+	for i, condition := range l {
+		objCondition := &batchv1.PodFailurePolicyOnPodConditionsPattern{}
+		c := condition.(map[string]interface{})
+		if v, ok := c["status"].(string); ok && v != "" {
+			objCondition.Status = v1.ConditionStatus(v)
+		}
+
+		if v, ok := c["type"].(string); ok && v != "" {
+			objCondition.Type = v1.PodConditionType(v)
+		}
+		obj[i] = *objCondition
+	}
+	return obj
+}
+
+func flattenPodFailurePolicy(in *batchv1.PodFailurePolicy) []interface{} {
+	att := make(map[string]interface{})
+	if len(in.Rules) > 0 {
+		att["rule"] = flattenPodFailurePolicyRules(in.Rules)
+	}
+	return []interface{}{att}
+}
+
+func flattenPodFailurePolicyRules(in []batchv1.PodFailurePolicyRule) []interface{} {
+	att := make([]interface{}, len(in))
+
+	for i, r := range in {
+		m := make(map[string]interface{})
+		m["action"] = r.Action
+		if r.OnExitCodes != nil {
+			m["on_exit_codes"] = flattenPodFailurePolicyOnExitCodes(r.OnExitCodes)
+		}
+		if r.OnPodConditions != nil {
+			m["on_pod_condition"] = flattenPodFailurePolicyOnPodConditions(r.OnPodConditions)
+		}
+		att[i] = m
+	}
+
+	return att
+}
+
+func flattenPodFailurePolicyOnExitCodes(in *batchv1.PodFailurePolicyOnExitCodesRequirement) []interface{} {
+	att := make(map[string]interface{})
+	if *in.ContainerName != "" {
+		att["container_name"] = *in.ContainerName
+	}
+	att["operator"] = in.Operator
+	if len(in.Values) > 0 {
+		vals := make([]int, len(in.Values))
+		for i := 0; i < len(vals); i++ {
+			vals[i] = int(in.Values[i])
+		}
+		att["values"] = vals
+	}
+
+	return []interface{}{att}
+}
+
+func flattenPodFailurePolicyOnPodConditions(in []batchv1.PodFailurePolicyOnPodConditionsPattern) []interface{} {
+	att := make([]interface{}, len(in))
+
+	for i, r := range in {
+		m := make(map[string]interface{})
+		if r.Status != "" {
+			m["status"] = r.Status
+		}
+		if r.Type != "" {
+			m["type"] = r.Type
+		}
+		att[i] = m
+	}
+
+	return att
+}
+
 func patchJobV1Spec(pathPrefix, prefix string, d *schema.ResourceData) PatchOperations {
 	ops := make([]PatchOperation, 0)
 
@@ -147,6 +307,13 @@ func patchJobV1Spec(pathPrefix, prefix string, d *schema.ResourceData) PatchOper
 		})
 	}
 
+	if d.HasChange(prefix + "pod_failure_policy") {
+		ops = append(ops, &ReplaceOperation{
+			Path:  pathPrefix + "/podFailurePolicy",
+			Value: expandPodFailurePolicy(d.Get(prefix + "pod_failure_policy").([]interface{})),
+		})
+	}
+
 	return ops
 }
 
diff --git a/kubernetes/structures.go b/kubernetes/structures.go
index a62531f7..02c9c398 100644
--- a/kubernetes/structures.go
+++ b/kubernetes/structures.go
@@ -135,20 +135,21 @@ func flattenMetadataFields(meta metav1.ObjectMeta) []interface{} {
 }
 
 func flattenMetadata(meta metav1.ObjectMeta, d *schema.ResourceData, providerMetadata interface{}) []interface{} {
-	metadata := expandMetadata(d.Get("metadata").([]interface{}))
+	metadataAnnotations := d.Get("metadata.0.annotations").(map[string]interface{})
+	metadataLabels := d.Get("metadata.0.labels").(map[string]interface{})
 
 	ignoreAnnotations := providerMetadata.(kubeClientsets).IgnoreAnnotations
-	removeInternalKeys(meta.Annotations, metadata.Annotations)
-	removeKeys(meta.Annotations, metadata.Annotations, ignoreAnnotations)
+	removeInternalKeys(meta.Annotations, metadataAnnotations)
+	removeKeys(meta.Annotations, metadataAnnotations, ignoreAnnotations)
 
 	ignoreLabels := providerMetadata.(kubeClientsets).IgnoreLabels
-	removeInternalKeys(meta.Labels, metadata.Labels)
-	removeKeys(meta.Labels, metadata.Labels, ignoreLabels)
+	removeInternalKeys(meta.Labels, metadataLabels)
+	removeKeys(meta.Labels, metadataLabels, ignoreLabels)
 
 	return flattenMetadataFields(meta)
 }
 
-func removeInternalKeys(m map[string]string, d map[string]string) {
+func removeInternalKeys(m map[string]string, d map[string]interface{}) {
 	for k := range m {
 		if isInternalKey(k) && !isKeyInMap(k, d) {
 			delete(m, k)
@@ -158,7 +159,7 @@ func removeInternalKeys(m map[string]string, d map[string]string) {
 
 // removeKeys removes given Kubernetes metadata(annotations and labels) keys.
 // In that case, they won't be available in the TF state file and will be ignored during apply/plan operations.
-func removeKeys(m map[string]string, d map[string]string, ignoreKubernetesMetadataKeys []string) {
+func removeKeys(m map[string]string, d map[string]interface{}, ignoreKubernetesMetadataKeys []string) {
 	for k := range m {
 		if ignoreKey(k, ignoreKubernetesMetadataKeys) && !isKeyInMap(k, d) {
 			delete(m, k)
@@ -166,7 +167,7 @@ func removeKeys(m map[string]string, d map[string]string, ignoreKubernetesMetada
 	}
 }
 
-func isKeyInMap(key string, d map[string]string) bool {
+func isKeyInMap(key string, d map[string]interface{}) bool {
 	_, ok := d[key]
 	return ok
 }
diff --git a/kubernetes/structures_pod.go b/kubernetes/structures_pod.go
index 5d572453..eeb5b5d3 100644
--- a/kubernetes/structures_pod.go
+++ b/kubernetes/structures_pod.go
@@ -331,9 +331,21 @@ func flattenTopologySpreadConstraints(tsc []v1.TopologySpreadConstraint) []inter
 		if v.TopologyKey != "" {
 			obj["topology_key"] = v.TopologyKey
 		}
+		if len(v.MatchLabelKeys) != 0 {
+			obj["match_label_keys"] = newStringSet(schema.HashString, v.MatchLabelKeys)
+		}
 		if v.MaxSkew != 0 {
 			obj["max_skew"] = v.MaxSkew
 		}
+		if v.MinDomains != nil && *v.MinDomains != 0 {
+			obj["min_domains"] = int(*v.MinDomains)
+		}
+		if v.NodeAffinityPolicy != nil && *v.NodeAffinityPolicy != "" {
+			obj["node_affinity_policy"] = string(*v.NodeAffinityPolicy)
+		}
+		if v.NodeTaintsPolicy != nil && *v.NodeAffinityPolicy != "" {
+			obj["node_taints_policy"] = string(*v.NodeTaintsPolicy)
+		}
 		if v.WhenUnsatisfiable != "" {
 			obj["when_unsatisfiable"] = string(v.WhenUnsatisfiable)
 		}
@@ -1493,9 +1505,21 @@ func expandTopologySpreadConstraints(tsc []interface{}) []v1.TopologySpreadConst
 			ts[i].WhenUnsatisfiable = v1.UnsatisfiableConstraintAction(value)
 		}
 
+		if value, ok := m["match_label_keys"].(*schema.Set); ok && value != nil {
+			ts[i].MatchLabelKeys = sliceOfString(value.List())
+		}
 		if value, ok := m["max_skew"].(int); ok {
 			ts[i].MaxSkew = int32(value)
 		}
+		if value, ok := m["min_domains"].(int); ok && value != 0 {
+			ts[i].MinDomains = ptr.To(int32(value))
+		}
+		if value, ok := m["node_affinity_policy"].(string); ok && value != "" {
+			ts[i].NodeAffinityPolicy = ptr.To(v1.NodeInclusionPolicy(value))
+		}
+		if value, ok := m["node_taints_policy"].(string); ok && value != "" {
+			ts[i].NodeTaintsPolicy = ptr.To(v1.NodeInclusionPolicy(value))
+		}
 
 	}
 	return ts
diff --git a/manifest/morph/scaffold.go b/manifest/morph/scaffold.go
index 657a987a..853a3bc4 100644
--- a/manifest/morph/scaffold.go
+++ b/manifest/morph/scaffold.go
@@ -23,6 +23,7 @@ func DeepUnknown(t tftypes.Type, v tftypes.Value, p *tftypes.AttributePath) (tft
 		atts := t.(tftypes.Object).AttributeTypes
 		var vals map[string]tftypes.Value
 		ovals := make(map[string]tftypes.Value, len(atts))
+		otypes := make(map[string]tftypes.Type, len(atts))
 		err := v.As(&vals)
 		if err != nil {
 			return tftypes.Value{}, p.NewError(err)
@@ -34,11 +35,9 @@ func DeepUnknown(t tftypes.Type, v tftypes.Value, p *tftypes.AttributePath) (tft
 				return tftypes.Value{}, np.NewError(err)
 			}
 			ovals[name] = nv
-			if nv.Type().Is(tftypes.Tuple{}) {
-				atts[name] = nv.Type()
-			}
+			otypes[name] = nv.Type()
 		}
-		return tftypes.NewValue(tftypes.Object{AttributeTypes: atts}, ovals), nil
+		return tftypes.NewValue(tftypes.Object{AttributeTypes: otypes}, ovals), nil
 	case t.Is(tftypes.Map{}):
 		if v.IsNull() {
 			return tftypes.NewValue(t, tftypes.UnknownValue), nil
diff --git a/manifest/provider/datasource.go b/manifest/provider/datasource.go
index 5362c1b9..a4331018 100644
--- a/manifest/provider/datasource.go
+++ b/manifest/provider/datasource.go
@@ -130,7 +130,7 @@ func (s *RawProviderServer) ReadPluralDataSource(ctx context.Context, req *tfpro
 	if err != nil {
 		resp.Diagnostics = append(resp.Diagnostics, &tfprotov5.Diagnostic{
 			Severity: tfprotov5.DiagnosticSeverityError,
-			Summary:  "Failed to save resource state",
+			Summary:  "Failed to save resource state", // FIX ME
 			Detail:   err.Error(),
 		})
 		return resp, nil
@@ -188,7 +188,7 @@ func (s *RawProviderServer) ReadPluralDataSource(ctx context.Context, req *tfpro
 		if err != nil {
 			resp.Diagnostics = append(resp.Diagnostics, &tfprotov5.Diagnostic{
 				Severity: tfprotov5.DiagnosticSeverityError,
-				Summary:  "Failed to save resource state",
+				Summary:  "Failed to save resource state", // FIX ME
 				Detail:   err.Error(),
 			})
 			return resp, nil
@@ -325,7 +325,7 @@ func (s *RawProviderServer) ReadSingularDataSource(ctx context.Context, req *tfp
 	if err != nil {
 		resp.Diagnostics = append(resp.Diagnostics, &tfprotov5.Diagnostic{
 			Severity: tfprotov5.DiagnosticSeverityError,
-			Summary:  "Failed to save resource state",
+			Summary:  "Failed to save resource state", // FIX ME
 			Detail:   err.Error(),
 		})
 		return resp, nil
@@ -378,7 +378,7 @@ func (s *RawProviderServer) ReadSingularDataSource(ctx context.Context, req *tfp
 	if err != nil {
 		resp.Diagnostics = append(resp.Diagnostics, &tfprotov5.Diagnostic{
 			Severity: tfprotov5.DiagnosticSeverityError,
-			Summary:  "Failed to save resource state",
+			Summary:  "Failed to save resource state", // FIX ME
 			Detail:   err.Error(),
 		})
 		return resp, nil
diff --git a/manifest/provider/server.go b/manifest/provider/server.go
index f2d9ba1f..cc7e8e9c 100644
--- a/manifest/provider/server.go
+++ b/manifest/provider/server.go
@@ -54,7 +54,23 @@ func (s *RawProviderServer) PrepareProviderConfig(ctx context.Context, req *tfpr
 // GetMetadata function
 func (s *RawProviderServer) GetMetadata(ctx context.Context, req *tfprotov5.GetMetadataRequest) (*tfprotov5.GetMetadataResponse, error) {
 	s.logger.Trace("[GetMetadata][Request]\n%s\n", dump(*req))
-	resp := &tfprotov5.GetMetadataResponse{}
+
+	sch := GetProviderResourceSchema()
+	rs := make([]tfprotov5.ResourceMetadata, 0, len(sch))
+	for k := range sch {
+		rs = append(rs, tfprotov5.ResourceMetadata{TypeName: k})
+	}
+
+	sch = GetProviderDataSourceSchema()
+	ds := make([]tfprotov5.DataSourceMetadata, 0, len(sch))
+	for k := range sch {
+		ds = append(ds, tfprotov5.DataSourceMetadata{TypeName: k})
+	}
+
+	resp := &tfprotov5.GetMetadataResponse{
+		Resources:   rs,
+		DataSources: ds,
+	}
 	return resp, nil
 }
 
diff --git a/website/docs/d/nodes.html.markdown b/website/docs/d/nodes.html.markdown
index e4a8a279..2e1e28d6 100644
--- a/website/docs/d/nodes.html.markdown
+++ b/website/docs/d/nodes.html.markdown
@@ -107,7 +107,7 @@ The following arguments are supported:
 * `machine_id` - Machine ID reported by the node see [main(5)
   machine-id](http://man7.org/linux/man-pages/man5/machine-id.5.html) for more info.
 * `system_uuid` - System UUID reported by the node. This field is
-  specific to [Red Hat hosts](https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid)
+  specific to Red Hat hosts.
 * `boot_id` - Boot ID reported by the node.
 * `kernel_version` - Kernel Version reported by the node from `uname -r`
 * `os_image` - OS Image reported by the node from `/etc/os-release`
diff --git a/website/docs/functions/manifest_decode.html.markdown b/website/docs/functions/manifest_decode.html.markdown
new file mode 100644
index 00000000..b6651737
--- /dev/null
+++ b/website/docs/functions/manifest_decode.html.markdown
@@ -0,0 +1,48 @@
+---
+subcategory: ""
+layout: "kubernetes"
+page_title: "manifest_decode function"
+description: |-
+  Decode a Kubernetes YAML manifest 
+---
+
+# function: manifest_decode
+
+Given a YAML text containing a Kubernetes manifest, will decode and return an object representation of that resource.
+
+## Example Usage
+
+```hcl
+# Configuration using provider functions must include required_providers configuration.
+terraform {
+  required_providers {
+    kubernetes = {
+      source = "hashicorp/kubernetes"
+      # Setting the provider version is a strongly recommended practice
+      # version = "..."
+    }
+  }
+  # Provider functions require Terraform 1.8 and later.
+  required_version = ">= 1.8.0"
+}
+
+output "example_output" {
+  value = provider::kubernetes::manifest_decode(file("manifest.yaml"))
+}
+```
+
+## Signature
+
+```text
+manifest_decode(manifest string) object
+```
+
+## Arguments
+
+
+1. `manifest` (String) The YAML text for a Kubernetes manifest
+
+
+## Return Type
+
+The `object` returned from `manifest_decode` is dynamic and will mirror the structure of the YAML manifest supplied. 
diff --git a/website/docs/functions/manifest_decode_multi.html.markdown b/website/docs/functions/manifest_decode_multi.html.markdown
new file mode 100644
index 00000000..b7ad390e
--- /dev/null
+++ b/website/docs/functions/manifest_decode_multi.html.markdown
@@ -0,0 +1,48 @@
+---
+subcategory: ""
+layout: "kubernetes"
+page_title: "manifest_decode_multi function"
+description: |-
+  Decode a Kubernetes YAML manifest containing multiple resources
+---
+
+# function: manifest_decode_multi
+
+Given a YAML text containing a Kubernetes manifest with multiple resources, will decode the manifest and return a tuple of object representations for each resource.
+
+## Example Usage
+
+```hcl
+# Configuration using provider functions must include required_providers configuration.
+terraform {
+  required_providers {
+    kubernetes = {
+      source = "hashicorp/kubernetes"
+      # Setting the provider version is a strongly recommended practice
+      # version = "..."
+    }
+  }
+  # Provider functions require Terraform 1.8 and later.
+  required_version = ">= 1.8.0"
+}
+
+output "example_output" {
+  value = provider::kubernetes::manifest_decode_multi(file("manifest.yaml"))
+}
+```
+
+## Signature
+
+```text
+manifest_decode_multi(manifest string) tuple
+```
+
+## Arguments
+
+
+1. `manifest` (String) The YAML text for a Kubernetes manifest containing multiple resources
+
+
+## Return Type
+
+The `tuple` returned from `manifest_decode_multi` will contain dynamic objects that mirror the structure of the resources in YAML manifest supplied. 
diff --git a/website/docs/functions/manifest_encode.html.markdown b/website/docs/functions/manifest_encode.html.markdown
new file mode 100644
index 00000000..0237894c
--- /dev/null
+++ b/website/docs/functions/manifest_encode.html.markdown
@@ -0,0 +1,61 @@
+---
+subcategory: ""
+layout: "kubernetes"
+page_title: "manifest_encode function"
+description: |-
+  Decode a Kubernetes YAML manifest containing multiple resources
+---
+
+# function: manifest_encode
+
+Given an object representation of a Kubernetes manifest, will encode and return a YAML string for that resource.
+
+## Example Usage
+
+```hcl
+# Configuration using provider functions must include required_providers configuration.
+terraform {
+  required_providers {
+    kubernetes = {
+      source = "hashicorp/kubernetes"
+      # Setting the provider version is a strongly recommended practice
+      # version = "..."
+    }
+  }
+  # Provider functions require Terraform 1.8 and later.
+  required_version = ">= 1.8.0"
+}
+
+locals {
+  manifest = {
+    apiVersion = "v1"
+    kind       = "ConfigMap"
+    metadata = {
+      name = "example"
+    }
+    data = {
+      EXAMPLE = "example"
+    }
+  }
+}
+
+output "example_output" {
+  value = provider::kubernetes::manifest_encode(local.manifest)
+}
+```
+
+## Signature
+
+```text
+manifest_encode(manifest object) string
+```
+
+## Arguments
+
+
+1. `manifest` (String) The object representation of a Kubernetes manifest
+
+
+## Return Type
+
+The `string` returned from `manifest_encode` will contain the YAML encoded Kubernetes manifest.
diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown
index 1080f529..c6cd842d 100644
--- a/website/docs/index.html.markdown
+++ b/website/docs/index.html.markdown
@@ -116,7 +116,9 @@ Find more comprehensive `in-cluster` config example [here](https://github.com/ha
 
 ## Exec plugins
 
-Some cloud providers have short-lived authentication tokens that can expire relatively quickly. To ensure the Kubernetes provider is receiving valid credentials, an exec-based plugin can be used to fetch a new token before initializing the provider. For example, on EKS, the command `eks get-token` can be used:
+Some cloud providers have short-lived authentication tokens that can expire relatively quickly. To ensure the Kubernetes provider is receiving valid credentials, an exec-based plugin can be used to fetch a new token before each Terraform operation. For example, on EKS, the command `eks get-token` can be used:
+
+~> IMPORTANT: DO NOT mix `exec` blocks with other credential attributes such as `token` or `client_certificate` in the provider configuration. This leads to undefined behaviour and there is no guarantee about which credential will actually be used.
 
 ```hcl
 provider "kubernetes" {
@@ -136,12 +138,29 @@ For further reading, see these examples which demonstrate different approaches t
 
 ## Ignore Kubernetes annotations and labels
 
-In certain cases, external systems can add and modify resources annotations and labels for their own purposes. However, Terraform will remove them since they are not presented in the code. It also might be hard to update code accordingly to stay tuned with the changes that come outside. In order to address this `ignore_annotations` and `ignore_labels` attributes were introduced on the provider level. They allow Terraform to ignore certain annotations and labels across all resources. Please bear in mind, that all data sources remain unaffected and the provider always returns all labels and annotations, in spite of the `ignore_annotations` and `ignore_labels` settings. The same is applicable for the pod and job definitions that fall under templates.
+In certain cases, external systems can add and modify resources annotations and labels for their own purposes. However, Terraform will remove them since they are not presented in the code. It also might be hard to update code accordingly to stay tuned with the changes that come outside. In order to address this `ignore_annotations` and `ignore_labels` attributes were introduced on the provider level. They allow Terraform to ignore certain annotations and labels across all resources.
 
 Both attributes support RegExp to match metadata objects more effectively.
 
+~> **Note:** RegExp will only work on root metadata objects. It's currently not possible to use RegExp for ignoring annotations/labels in metadata objects that are nested such as `spec.template.metadata[0].annotations["..."]`.
+
+Please keep in mind that all data sources remain unaffected, and the provider always returns all labels and annotations, despite the `ignore_annotations` and `ignore_labels` settings. The same applies to the pod and job definitions that fall under templates. To ignore certain annotations and/or labels on the template level, please use the `ignore_changes` feature of the [lifecycle](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) meta-argument.
+
 ### Examples
 
+The following example demonstrates how to ignore changes related to the `kubectl.kubernetes.io/restartedAt` annotation that were made in the upstream Kubernetes object:
+
+```hcl
+resource "kubernetes_deployment_v1" "this" {
+  // omit the resource config
+  lifecycle {
+    ignore_changes = [
+      spec[0].template[0].metadata[0].annotations["kubectl.kubernetes.io/restartedAt"],
+    ]
+  }
+}
+```
+
 The following example demonstrates how to ignore particular annotation keys:
 
 ```hcl
@@ -189,5 +208,5 @@ The following arguments are supported:
     * `command` - (Required) Command to execute.
     * `args` - (Optional) List of arguments to pass when executing the plugin.
     * `env` - (Optional) Map of environment variables to set when executing the plugin.
-* `ignore_annotations` - (Optional) List of Kubernetes metadata annotations to ignore across all resources handled by this provider for situations where external systems are managing certain resource annotations. Each item is a regular expression.
-* `ignore_labels` - (Optional) List of Kubernetes metadata labels to ignore across all resources handled by this provider for situations where external systems are managing certain resource labels. Each item is a regular expression.
+* `ignore_annotations` - (Optional) List of Kubernetes metadata annotations to ignore across all resources handled by this provider for situations where external systems are managing certain resource annotations. This option does not affect annotations within a template block. Each item is a regular expression.
+* `ignore_labels` - (Optional) List of Kubernetes metadata labels to ignore across all resources handled by this provider for situations where external systems are managing certain resource labels. This option does not affect annotations within a template block. Each item is a regular expression.
diff --git a/website/docs/r/cron_job.html.markdown b/website/docs/r/cron_job.html.markdown
index 35cb7085..adb9dc69 100644
--- a/website/docs/r/cron_job.html.markdown
+++ b/website/docs/r/cron_job.html.markdown
@@ -15,6 +15,8 @@ description: |-
   Note: All CronJob `schedule` times are based on the timezone of the master where the job is initiated.
   For instructions on creating and working with cron jobs, and for an example of a spec file for a cron job, see [Kubernetes reference](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/).
 
+~> NOTE: With the release of Kubernetes v1.25, CronJob batch/v1beta1 has been removed. You can read more information about migrating to batch/v1 in the [Kubernetes 1.25 migration guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#cronjob-v125).
+
 ## Example Usage
 
 ```hcl
@@ -99,6 +101,14 @@ The following arguments are supported:
 * `metadata` - (Required) Standard object's metadata of the jobs created from this template. For more info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata
 * `spec` - (Required) Specification of the desired behavior of the job. For more info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
 
+### `metadata`
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
 ### `spec`
 
 #### Arguments
@@ -107,11 +117,42 @@ The following arguments are supported:
 * `backoff_limit` - (Optional) Specifies the number of retries before marking this job failed. Defaults to 6
 * `completions` - (Optional) Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `manual_selector` - (Optional) Controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
+* `pod_failure_policy` - (Optional) Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.
 * `parallelism` - (Optional) Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when `((.spec.completions - .status.successful) < .spec.parallelism)`, i.e. when the work left to do is less than max parallelism. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `selector` - (Optional) A label query over pods that should match the pod count. Normally, the system sets this field for you. For more info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
 * `template` - (Optional) Describes the pod that will be created when executing a job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `ttl_seconds_after_finished` - (Optional) ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.
 
+### `pod_failure_policy`
+
+#### Arguments
+
+* `rule` - (Required) A list of pod failure policy rules. The rules are evaluated in order. Once a rule matches a Pod failure, the remaining of the rules are ignored.
+
+### `rule`
+
+#### Arguments
+
+* `action` - (Optional) Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are: - FailJob: indicates that the pod's job is marked as Failed and all running pods are terminated. - FailIndex: indicates that the pod's index is marked as Failed and will not be restarted.
+* `on_exit_codes` - (Optional) Represents the requirement on the container exit codes.
+* `on_pod_condition` - (Optional) Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition.
+
+### `on_exit_codes`
+
+#### Arguments
+
+* `container_name` - (Optional) Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.
+* `operator` - (Optional) Represents the relationship between the container exit code(s) and the specified values.
+* `values` - (Required) Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator.
+
+### `on_pod_condition`
+
+#### Arguments
+
+* `status` - (Optional) Specifies the required Pod condition status. To match a pod condition it is required that the specified status equals the pod condition status. Defaults to True.
+* `type` - (Optional) Specifies the required Pod condition type. To match a pod condition it is required that specified type equals the pod condition type.
+
+
 ### `selector`
 
 #### Arguments
diff --git a/website/docs/r/cron_job_v1.html.markdown b/website/docs/r/cron_job_v1.html.markdown
index a239b339..b7503f73 100644
--- a/website/docs/r/cron_job_v1.html.markdown
+++ b/website/docs/r/cron_job_v1.html.markdown
@@ -101,6 +101,14 @@ The following arguments are supported:
 * `metadata` - (Required) Standard object's metadata of the jobs created from this template. For more info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata
 * `spec` - (Required) Specification of the desired behavior of the job. For more info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
 
+### `metadata`
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
 ### `spec`
 
 #### Arguments
@@ -109,11 +117,41 @@ The following arguments are supported:
 * `backoff_limit` - (Optional) Specifies the number of retries before marking this job failed. Defaults to 6
 * `completions` - (Optional) Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `manual_selector` - (Optional) Controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
+* `pod_failure_policy` - (Optional) Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.
 * `parallelism` - (Optional) Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when `((.spec.completions - .status.successful) < .spec.parallelism)`, i.e. when the work left to do is less than max parallelism. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `selector` - (Optional) A label query over pods that should match the pod count. Normally, the system sets this field for you. For more info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
 * `template` - (Optional) Describes the pod that will be created when executing a job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `ttl_seconds_after_finished` - (Optional) ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.
 
+### `pod_failure_policy`
+
+#### Arguments
+
+* `rule` - (Required) A list of pod failure policy rules. The rules are evaluated in order. Once a rule matches a Pod failure, the remaining of the rules are ignored.
+
+### `rule`
+
+#### Arguments
+
+* `action` - (Optional) Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are: - FailJob: indicates that the pod's job is marked as Failed and all running pods are terminated. - FailIndex: indicates that the pod's index is marked as Failed and will not be restarted.
+* `on_exit_codes` - (Optional) Represents the requirement on the container exit codes.
+* `on_pod_condition` - (Optional) Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition.
+
+### `on_exit_codes`
+
+#### Arguments
+
+* `container_name` - (Optional) Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.
+* `operator` - (Optional) Represents the relationship between the container exit code(s) and the specified values.
+* `values` - (Required) Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator.
+
+### `on_pod_condition`
+
+#### Arguments
+
+* `status` - (Optional) Specifies the required Pod condition status. To match a pod condition it is required that the specified status equals the pod condition status. Defaults to True.
+* `type` - (Optional) Specifies the required Pod condition type. To match a pod condition it is required that specified type equals the pod condition type.
+
 ### `selector`
 
 #### Arguments
diff --git a/website/docs/r/daemon_set_v1.html.markdown b/website/docs/r/daemon_set_v1.html.markdown
index 91345516..7891961f 100644
--- a/website/docs/r/daemon_set_v1.html.markdown
+++ b/website/docs/r/daemon_set_v1.html.markdown
@@ -136,6 +136,16 @@ The following arguments are supported:
 * `metadata` - (Required) Standard object's metadata. For more info see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata.
 * `spec` - (Required) Specification of the desired behavior of the pod. For more info see https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
 
+### template `metadata`
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
+Please see the [Pod resource](pod_v1.html#metadata) for reference.
+
 ### template `spec`
 
 #### Arguments
diff --git a/website/docs/r/daemonset.html.markdown b/website/docs/r/daemonset.html.markdown
index 015ea1eb..0ba9d938 100644
--- a/website/docs/r/daemonset.html.markdown
+++ b/website/docs/r/daemonset.html.markdown
@@ -136,6 +136,16 @@ The following arguments are supported:
 * `metadata` - (Required) Standard object's metadata. For more info see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata.
 * `spec` - (Required) Specification of the desired behavior of the pod. For more info see https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
 
+### template `metadata`
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
+Please see the [Pod resource](pod_v1.html#metadata) for reference.
+
 ### template `spec`
 
 #### Arguments
diff --git a/website/docs/r/job.html.markdown b/website/docs/r/job.html.markdown
index 80976736..2491e204 100644
--- a/website/docs/r/job.html.markdown
+++ b/website/docs/r/job.html.markdown
@@ -109,12 +109,42 @@ The following arguments are supported:
 * `backoff_limit` - (Optional) Specifies the number of retries before marking this job failed. Defaults to 6
 * `completions` - (Optional) Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `completion_mode` - (Optional) Specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`. For more info see [Kubernetes reference](https://kubernetes.io/docs/concepts/workloads/controllers/job/#completion-mode).
+* `pod_failure_policy` - (Optional) Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.
 * `manual_selector` - (Optional) Controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
 * `parallelism` - (Optional) Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when `((.spec.completions - .status.successful) < .spec.parallelism)`, i.e. when the work left to do is less than max parallelism. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `selector` - (Optional) A label query over pods that should match the pod count. Normally, the system sets this field for you. For more info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
 * `template` - (Optional) Describes the pod that will be created when executing a job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `ttl_seconds_after_finished` - (Optional) ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.
 
+### `pod_failure_policy`
+
+#### Arguments
+
+* `rule` - (Required) A list of pod failure policy rules. The rules are evaluated in order. Once a rule matches a Pod failure, the remaining of the rules are ignored.
+
+### `rule`
+
+#### Arguments
+
+* `action` - (Optional) Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are: - FailJob: indicates that the pod's job is marked as Failed and all running pods are terminated. - FailIndex: indicates that the pod's index is marked as Failed and will not be restarted.
+* `on_exit_codes` - (Optional) Represents the requirement on the container exit codes.
+* `on_pod_condition` - (Optional) Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition.
+
+### `on_exit_codes`
+
+#### Arguments
+
+* `container_name` - (Optional) Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.
+* `operator` - (Optional) Represents the relationship between the container exit code(s) and the specified values.
+* `values` - (Required) Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator.
+
+### `on_pod_condition`
+
+#### Arguments
+
+* `status` - (Optional) Specifies the required Pod condition status. To match a pod condition it is required that the specified status equals the pod condition status. Defaults to True.
+* `type` - (Optional) Specifies the required Pod condition type. To match a pod condition it is required that specified type equals the pod condition type.
+
 ### `selector`
 
 #### Arguments
diff --git a/website/docs/r/job_v1.html.markdown b/website/docs/r/job_v1.html.markdown
index a8d33668..1163b236 100644
--- a/website/docs/r/job_v1.html.markdown
+++ b/website/docs/r/job_v1.html.markdown
@@ -110,11 +110,41 @@ The following arguments are supported:
 * `completions` - (Optional) Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `completion_mode` - (Optional) Specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`. For more info see [Kubernetes reference](https://kubernetes.io/docs/concepts/workloads/controllers/job/#completion-mode).
 * `manual_selector` - (Optional) Controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
+* `pod_failure_policy` - (Optional) Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.
 * `parallelism` - (Optional) Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when `((.spec.completions - .status.successful) < .spec.parallelism)`, i.e. when the work left to do is less than max parallelism. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `selector` - (Optional) A label query over pods that should match the pod count. Normally, the system sets this field for you. For more info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
 * `template` - (Optional) Describes the pod that will be created when executing a job. For more info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
 * `ttl_seconds_after_finished` - (Optional) ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.
 
+### `pod_failure_policy`
+
+#### Arguments
+
+* `rule` - (Required) A list of pod failure policy rules. The rules are evaluated in order. Once a rule matches a Pod failure, the remaining of the rules are ignored.
+
+### `rule`
+
+#### Arguments
+
+* `action` - (Optional) Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are: - FailJob: indicates that the pod's job is marked as Failed and all running pods are terminated. - FailIndex: indicates that the pod's index is marked as Failed and will not be restarted.
+* `on_exit_codes` - (Optional) Represents the requirement on the container exit codes.
+* `on_pod_condition` - (Optional) Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition.
+
+### `on_exit_codes`
+
+#### Arguments
+
+* `container_name` - (Optional) Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.
+* `operator` - (Optional) Represents the relationship between the container exit code(s) and the specified values.
+* `values` - (Required) Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator.
+
+### `on_pod_condition`
+
+#### Arguments
+
+* `status` - (Optional) Specifies the required Pod condition status. To match a pod condition it is required that the specified status equals the pod condition status. Defaults to True.
+* `type` - (Optional) Specifies the required Pod condition type. To match a pod condition it is required that specified type equals the pod condition type.
+
 ### `selector`
 
 #### Arguments
diff --git a/website/docs/r/pod.html.markdown b/website/docs/r/pod.html.markdown
index 75a23a8c..e43d706a 100644
--- a/website/docs/r/pod.html.markdown
+++ b/website/docs/r/pod.html.markdown
@@ -863,7 +863,11 @@ The `items` block supports the following:
 
 #### Arguments
 
+* `match_label_keys` - (Optional) Is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. The same key is forbidden to exist in both `match_label_keys` and `label_selector`. `match_label_keys` cannot be set when `label_selector` isn't set. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against `label_selector`.
 * `max_skew` - (Optional) Describes the degree to which pods may be unevenly distributed. Default value is `1`.
+* `min_domains` - (Optional) Indicates a minimum number of eligible domains. Must be number greater than `0`. When set, `when_unsatisfiable` must be set to `DoNotSchedule`.
+* `node_affinity_policy` - (Optional) Indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Valid values are `Honor` and `Ignore`. When unset, behavior defaults to `Honor`.
+* `node_taints_policy` - (Optional) Indicates how we will treat node taints when calculating pod topology spread skew. Valid values are `Honor` and `Ignore`. When unset, behavior defaults to `Ignore`.
 * `topology_key` - (Optional) The key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology.
 * `when_unsatisfiable` - (Optional) Indicates how to deal with a pod if it doesn't satisfy the spread constraint. Valid values are `DoNotSchedule` and `ScheduleAnyway`. Default value is `DoNotSchedule`.
 * `label_selector` - (Optional) A label query over a set of resources, in this case pods.
diff --git a/website/docs/r/pod_v1.html.markdown b/website/docs/r/pod_v1.html.markdown
index b43826b8..c45044e4 100644
--- a/website/docs/r/pod_v1.html.markdown
+++ b/website/docs/r/pod_v1.html.markdown
@@ -852,7 +852,11 @@ The `items` block supports the following:
 
 #### Arguments
 
+* `match_label_keys` - (Optional) Is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. The same key is forbidden to exist in both `match_label_keys` and `label_selector`. `match_label_keys` cannot be set when `label_selector` isn't set. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against `label_selector`.
 * `max_skew` - (Optional) Describes the degree to which pods may be unevenly distributed. Default value is `1`.
+* `min_domains` - (Optional) Indicates a minimum number of eligible domains. Must be number greater than `0`. When set, `when_unsatisfiable` must be set to `DoNotSchedule`.
+* `node_affinity_policy` - (Optional) Indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Valid values are `Honor` and `Ignore`. When unset, behavior defaults to `Honor`.
+* `node_taints_policy` - (Optional) Indicates how we will treat node taints when calculating pod topology spread skew. Valid values are `Honor` and `Ignore`. When unset, behavior defaults to `Ignore`.
 * `topology_key` - (Optional) The key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology.
 * `when_unsatisfiable` - (Optional) Indicates how to deal with a pod if it doesn't satisfy the spread constraint. Valid values are `DoNotSchedule` and `ScheduleAnyway`. Default value is `DoNotSchedule`.
 * `label_selector` - (Optional) A label query over a set of resources, in this case pods.
diff --git a/website/docs/r/secret.html.markdown b/website/docs/r/secret.html.markdown
index 53c0bc30..f50d02e9 100644
--- a/website/docs/r/secret.html.markdown
+++ b/website/docs/r/secret.html.markdown
@@ -90,9 +90,12 @@ resource "kubernetes_secret" "example" {
     annotations = {
       "kubernetes.io/service-account.name" = "my-service-account"
     }
+
+    generate_name = "my-service-account-"
   }
 
-  type = "kubernetes.io/service-account-token"
+  type                           = "kubernetes.io/service-account-token"
+  wait_for_service_account_token = true
 }
 ```
 
diff --git a/website/docs/r/secret_v1.html.markdown b/website/docs/r/secret_v1.html.markdown
index 55c491de..c56e7713 100644
--- a/website/docs/r/secret_v1.html.markdown
+++ b/website/docs/r/secret_v1.html.markdown
@@ -90,9 +90,12 @@ resource "kubernetes_secret_v1" "example" {
     annotations = {
       "kubernetes.io/service-account.name" = "my-service-account"
     }
+
+    generate_name = "my-service-account-"
   }
 
-  type = "kubernetes.io/service-account-token"
+  type                           = "kubernetes.io/service-account-token"
+  wait_for_service_account_token = true
 }
 ```
 
diff --git a/website/docs/r/service_account.html.markdown b/website/docs/r/service_account.html.markdown
index c2193c2a..7d533f68 100644
--- a/website/docs/r/service_account.html.markdown
+++ b/website/docs/r/service_account.html.markdown
@@ -19,15 +19,19 @@ resource "kubernetes_service_account" "example" {
   metadata {
     name = "terraform-example"
   }
-  secret {
-    name = "${kubernetes_secret.example.metadata.0.name}"
-  }
 }
 
 resource "kubernetes_secret" "example" {
   metadata {
-    name = "terraform-example"
+    annotations = {
+      "kubernetes.io/service-account.name" = kubernetes_service_account.example.metadata.0.name
+    }
+
+    generate_name = "terraform-example-"
   }
+
+  type                           = "kubernetes.io/service-account-token"
+  wait_for_service_account_token = true
 }
 ```
 
diff --git a/website/docs/r/service_account_v1.html.markdown b/website/docs/r/service_account_v1.html.markdown
index 8e8eb97a..729c5b16 100644
--- a/website/docs/r/service_account_v1.html.markdown
+++ b/website/docs/r/service_account_v1.html.markdown
@@ -19,15 +19,19 @@ resource "kubernetes_service_account_v1" "example" {
   metadata {
     name = "terraform-example"
   }
-  secret {
-    name = "${kubernetes_secret_v1.example.metadata.0.name}"
-  }
 }
 
 resource "kubernetes_secret_v1" "example" {
   metadata {
-    name = "terraform-example"
+    annotations = {
+      "kubernetes.io/service-account.name" = kubernetes_service_account_v1.example.metadata.0.name
+    }
+
+    generate_name = "terraform-example-"
   }
+
+  type                           = "kubernetes.io/service-account-token"
+  wait_for_service_account_token = true
 }
 ```
 
diff --git a/website/docs/r/stateful_set.html.markdown b/website/docs/r/stateful_set.html.markdown
index cc5a06fc..25ca0334 100644
--- a/website/docs/r/stateful_set.html.markdown
+++ b/website/docs/r/stateful_set.html.markdown
@@ -279,13 +279,25 @@ The following arguments are supported:
 
 ## Nested Blocks
 
+### `spec.template.metadata`
+
+#### Arguments
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
+Please see the [Pod resource](pod_v1.html#metadata) for reference.
+
 ### `spec.template.spec`
 
 #### Arguments
 
 These arguments are the same as the for the `spec` block of a Pod.
 
-Please see the [Pod resource](pod.html#spec) for reference.
+Please see the [Pod resource](pod_v1.html#spec) for reference.
 
 ## Nested Blocks
 
diff --git a/website/docs/r/stateful_set_v1.html.markdown b/website/docs/r/stateful_set_v1.html.markdown
index ab832c96..6666e0e7 100644
--- a/website/docs/r/stateful_set_v1.html.markdown
+++ b/website/docs/r/stateful_set_v1.html.markdown
@@ -279,13 +279,25 @@ The following arguments are supported:
 
 ## Nested Blocks
 
+### `spec.template.metadata`
+
+#### Arguments
+
+These arguments are the same as the for the `metadata` block of a Pod with a few exceptions:
+
+* When `spec.template.metadata.namespace` does not have a default value, it is empty if not set.
+
+* The `spec.template.metadata.namespace` is a stub field that does not affect the namespace in which the Pod will be created. The Pod will be created in the same namespace as the main resource. However, modifying this field will force the resource recreation.
+
+Please see the [Pod resource](pod_v1.html#metadata) for reference.
+
 ### `spec.template.spec`
 
 #### Arguments
 
 These arguments are the same as the for the `spec` block of a Pod.
 
-Please see the [Pod resource](pod.html#spec) for reference.
+Please see the [Pod resource](pod_v1.html#spec) for reference.
 
 ## Nested Blocks
 



Test patch:
diff --git a/internal/framework/provider/functions/functions_test.go b/internal/framework/provider/functions/functions_test.go
new file mode 100644
index 00000000..5877d443
--- /dev/null
+++ b/internal/framework/provider/functions/functions_test.go
@@ -0,0 +1,14 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions_test
+
+import (
+	"github.com/hashicorp/terraform-plugin-framework/providerserver"
+	"github.com/hashicorp/terraform-plugin-go/tfprotov5"
+	"github.com/hashicorp/terraform-provider-kubernetes/internal/framework/provider"
+)
+
+var testAccProtoV5ProviderFactories = map[string]func() (tfprotov5.ProviderServer, error){
+	"kubernetes": providerserver.NewProtocol5WithError(provider.New("test")),
+}
diff --git a/internal/framework/provider/functions/manifest_decode_multi_test.go b/internal/framework/provider/functions/manifest_decode_multi_test.go
new file mode 100644
index 00000000..016596bb
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_decode_multi_test.go
@@ -0,0 +1,221 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions_test
+
+import (
+	"fmt"
+	"math/big"
+	"os"
+	"path"
+	"regexp"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+	"github.com/hashicorp/terraform-plugin-testing/knownvalue"
+	"github.com/hashicorp/terraform-plugin-testing/statecheck"
+)
+
+func TestManifestDecodeMulti(t *testing.T) {
+	t.Parallel()
+
+	outputName := "test"
+
+	resource.UnitTest(t, resource.TestCase{
+		ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testManifestDecodeMultiConfig("testdata/decode_single.yaml"),
+				ConfigStateChecks: []statecheck.StateCheck{
+					statecheck.ExpectKnownOutputValue(outputName, knownvalue.ListExact([]knownvalue.Check{
+						knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"apiVersion": knownvalue.StringExact("v1"),
+							"data": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"configfile": knownvalue.StringExact("---\ntest: document\n"),
+							}),
+							"kind": knownvalue.StringExact("ConfigMap"),
+							"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"annotations": knownvalue.Null(),
+								"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"test": knownvalue.StringExact("test---label"),
+								}),
+								"name": knownvalue.StringExact("test-configmap"),
+							}),
+							"status": knownvalue.Null(),
+						}),
+					})),
+				},
+			},
+			{
+				Config: testManifestDecodeMultiConfig("testdata/decode_multi.yaml"),
+				ConfigStateChecks: []statecheck.StateCheck{
+					statecheck.ExpectKnownOutputValue(outputName, knownvalue.ListExact([]knownvalue.Check{
+						knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"apiVersion": knownvalue.StringExact("apps/v1"),
+							"kind":       knownvalue.StringExact("DaemonSet"),
+							"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"k8s-app": knownvalue.StringExact("fluentd-logging"),
+								}),
+								"name":      knownvalue.StringExact("fluentd-elasticsearch"),
+								"namespace": knownvalue.StringExact("kube-system"),
+							}),
+							"spec": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"selector": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"matchLabels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"name": knownvalue.StringExact("fluentd-elasticsearch"),
+									}),
+								}),
+								"template": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+											"name": knownvalue.StringExact("fluentd-elasticsearch"),
+										}),
+									}),
+									"spec": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"containers": knownvalue.ListExact([]knownvalue.Check{knownvalue.ObjectExact(map[string]knownvalue.Check{
+											"image": knownvalue.StringExact("quay.io/fluentd_elasticsearch/fluentd:v2.5.2"),
+											"name":  knownvalue.StringExact("fluentd-elasticsearch"),
+											"resources": knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"limits": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"cpu":    knownvalue.NumberExact(big.NewFloat(1.5)),
+													"memory": knownvalue.StringExact("200Mi"),
+												}),
+												"requests": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"cpu":    knownvalue.Int64Exact(1),
+													"memory": knownvalue.StringExact("200Mi"),
+												}),
+											}),
+											"volumeMounts": knownvalue.ListExact([]knownvalue.Check{knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"mountPath": knownvalue.StringExact("/var/log"),
+												"name":      knownvalue.StringExact("varlog"),
+											})}),
+										})}),
+										"terminationGracePeriodSeconds": knownvalue.Int64Exact(30),
+										"tolerations": knownvalue.ListExact([]knownvalue.Check{
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"effect":   knownvalue.StringExact("NoSchedule"),
+												"key":      knownvalue.StringExact("node-role.kubernetes.io/control-plane"),
+												"operator": knownvalue.StringExact("Exists"),
+											}),
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"effect":   knownvalue.StringExact("NoSchedule"),
+												"key":      knownvalue.StringExact("node-role.kubernetes.io/master"),
+												"operator": knownvalue.StringExact("Exists"),
+											}),
+										}),
+										"volumes": knownvalue.ListExact([]knownvalue.Check{
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"hostPath": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"path": knownvalue.StringExact("/var/log"),
+												}),
+												"name": knownvalue.StringExact("varlog"),
+											}),
+										}),
+									}),
+								}),
+							}),
+						}),
+						knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"apiVersion": knownvalue.StringExact("v1"),
+							"data": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"configfile": knownvalue.StringExact("---\ntest: document"),
+								"immutable":  knownvalue.Bool(false),
+							}),
+							"kind": knownvalue.StringExact("ConfigMap"),
+							"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"test": knownvalue.StringExact("test---label"),
+								}),
+								"name":      knownvalue.StringExact("test-configmap"),
+								"namespace": knownvalue.StringExact("kube-system"),
+							}),
+						}),
+						knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"apiVersion": knownvalue.StringExact("apps/v1"),
+							"kind":       knownvalue.StringExact("DaemonSet"),
+							"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"k8s-app": knownvalue.StringExact("fluentd-logging"),
+								}),
+								"name":      knownvalue.StringExact("fluentd-elasticsearch2"),
+								"namespace": knownvalue.StringExact("kube-system"),
+							}),
+							"spec": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"selector": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"matchLabels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"name": knownvalue.StringExact("fluentd-elasticsearch"),
+									}),
+								}),
+								"template": knownvalue.ObjectExact(map[string]knownvalue.Check{
+									"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+											"name":      knownvalue.StringExact("fluentd-elasticsearch"),
+											"something": knownvalue.StringExact("helloworld"),
+										}),
+									}),
+									"spec": knownvalue.ObjectExact(map[string]knownvalue.Check{
+										"containers": knownvalue.ListExact([]knownvalue.Check{knownvalue.ObjectExact(map[string]knownvalue.Check{
+											"image": knownvalue.StringExact("quay.io/fluentd_elasticsearch/fluentd:v2.5.2"),
+											"name":  knownvalue.StringExact("fluentd-elasticsearch"),
+											"resources": knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"limits": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"memory": knownvalue.StringExact("200Mi"),
+												}),
+												"requests": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"cpu":    knownvalue.StringExact("100m"),
+													"memory": knownvalue.StringExact("200Mi"),
+												}),
+											}),
+											"volumeMounts": knownvalue.ListExact([]knownvalue.Check{knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"mountPath": knownvalue.StringExact("/var/log"),
+												"name":      knownvalue.StringExact("varlog"),
+											})}),
+										})}),
+										"terminationGracePeriodSeconds": knownvalue.Int64Exact(30),
+										"tolerations": knownvalue.ListExact([]knownvalue.Check{
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"effect":   knownvalue.StringExact("NoSchedule"),
+												"key":      knownvalue.StringExact("node-role.kubernetes.io/control-plane"),
+												"operator": knownvalue.StringExact("Exists"),
+											}),
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"effect":   knownvalue.StringExact("NoSchedule"),
+												"key":      knownvalue.StringExact("node-role.kubernetes.io/master"),
+												"operator": knownvalue.StringExact("Exists"),
+											}),
+										}),
+										"volumes": knownvalue.ListExact([]knownvalue.Check{
+											knownvalue.ObjectExact(map[string]knownvalue.Check{
+												"hostPath": knownvalue.ObjectExact(map[string]knownvalue.Check{
+													"path": knownvalue.StringExact("/var/log"),
+												}),
+												"name": knownvalue.StringExact("varlog"),
+											}),
+										}),
+									}),
+								}),
+							}),
+						}),
+					})),
+				},
+			},
+			{
+				Config:      testManifestDecodeMultiConfig("testdata/decode_manifest_invalid.yaml"),
+				ExpectError: regexp.MustCompile(`Invalid\s+Kubernetes\s+manifest`),
+			},
+			{
+				Config:      testManifestDecodeMultiConfig("testdata/decode_manifest_invalid_syntax.yaml"),
+				ExpectError: regexp.MustCompile(`Invalid\s+YAML\s+document`),
+			},
+		},
+	})
+}
+
+func testManifestDecodeMultiConfig(filename string) string {
+	cwd, _ := os.Getwd()
+	return fmt.Sprintf(`
+output "test" {
+  value = provider::kubernetes::manifest_decode_multi(file(%q))
+}`, path.Join(cwd, filename))
+}
diff --git a/internal/framework/provider/functions/manifest_decode_test.go b/internal/framework/provider/functions/manifest_decode_test.go
new file mode 100644
index 00000000..4a2d9e64
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_decode_test.go
@@ -0,0 +1,70 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions_test
+
+import (
+	"fmt"
+	"os"
+	"path"
+	"regexp"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+	"github.com/hashicorp/terraform-plugin-testing/knownvalue"
+	"github.com/hashicorp/terraform-plugin-testing/statecheck"
+)
+
+func TestManifestDecode(t *testing.T) {
+	t.Parallel()
+
+	outputName := "test"
+
+	resource.UnitTest(t, resource.TestCase{
+		ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testManifestDecodeConfig("testdata/decode_single.yaml"),
+				ConfigStateChecks: []statecheck.StateCheck{
+					statecheck.ExpectKnownOutputValue(outputName, knownvalue.ObjectExact(map[string]knownvalue.Check{
+						"apiVersion": knownvalue.StringExact("v1"),
+						"data": knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"configfile": knownvalue.StringExact("---\ntest: document\n"),
+						}),
+						"kind": knownvalue.StringExact("ConfigMap"),
+						"metadata": knownvalue.ObjectExact(map[string]knownvalue.Check{
+							"annotations": knownvalue.Null(),
+							"labels": knownvalue.ObjectExact(map[string]knownvalue.Check{
+								"test": knownvalue.StringExact("test---label"),
+							}),
+							"name": knownvalue.StringExact("test-configmap"),
+						}),
+						"status": knownvalue.Null(),
+					})),
+				},
+			},
+		},
+	})
+}
+
+func TestManifestDecode_ErrorOnMulti(t *testing.T) {
+	t.Parallel()
+
+	resource.UnitTest(t, resource.TestCase{
+		ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config:      testManifestDecodeConfig("testdata/decode_multi.yaml"),
+				ExpectError: regexp.MustCompile(`YAML\s+manifest\s+contains\s+multiple\s+resources`),
+			},
+		},
+	})
+}
+
+func testManifestDecodeConfig(filename string) string {
+	cwd, _ := os.Getwd()
+	return fmt.Sprintf(`
+output "test" {
+  value = provider::kubernetes::manifest_decode(file(%q))
+}`, path.Join(cwd, filename))
+}
diff --git a/internal/framework/provider/functions/manifest_encode_test.go b/internal/framework/provider/functions/manifest_encode_test.go
new file mode 100644
index 00000000..9a4c131c
--- /dev/null
+++ b/internal/framework/provider/functions/manifest_encode_test.go
@@ -0,0 +1,219 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+package functions_test
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestManifestEncode(t *testing.T) {
+	t.Parallel()
+
+	outputName := "test"
+
+	resource.UnitTest(t, resource.TestCase{
+		ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testManifestEncodeConfig(),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckOutput(outputName, `apiVersion: v1
+data:
+  test: test
+kind: ConfigMap
+metadata:
+  name: test
+  namespace: null
+`),
+				),
+			},
+		},
+	})
+}
+
+func TestManifestEncodeMulti(t *testing.T) {
+	t.Parallel()
+
+	outputName := "test"
+
+	resource.UnitTest(t, resource.TestCase{
+		ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testManifestEncodeMultiConfig(),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckOutput(outputName, `---
+apiVersion: v1
+data:
+  test: test
+immutable: false
+kind: ConfigMap
+metadata:
+  name: test
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  labels:
+    k8s-app: fluentd-logging
+  name: fluentd-elasticsearch2
+  namespace: kube-system
+spec:
+  selector:
+    matchLabels:
+      name: fluentd-elasticsearch
+  template:
+    metadata:
+      labels:
+        name: fluentd-elasticsearch
+        something: helloworld
+    spec:
+      containers:
+      - image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
+        name: fluentd-elasticsearch
+        resources:
+          limits:
+            cpu: 1.5
+            memory: 200Mi
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        volumeMounts:
+        - mountPath: /var/log
+          name: varlog
+      terminationGracePeriodSeconds: 30
+      tolerations:
+      - effect: NoSchedule
+        key: node-role.kubernetes.io/control-plane
+        operator: Exists
+      - effect: NoSchedule
+        key: node-role.kubernetes.io/master
+        operator: Exists
+      volumes:
+      - hostPath:
+          path: /var/log
+        name: varlog
+`),
+				),
+			},
+		},
+	})
+}
+
+func testManifestEncodeConfig() string {
+	return `
+locals {
+  single_manifest = {
+    apiVersion = "v1"
+    kind       = "ConfigMap"
+    metadata   = {
+      name = "test"
+      namespace = null
+    }
+    data = {
+      "test" = "test"
+    }
+  }
+}
+
+output "test" {
+  value = provider::kubernetes::manifest_encode(local.single_manifest)
+}`
+}
+
+func testManifestEncodeMultiConfig() string {
+	return `
+locals {
+  multi_manifest = [
+    {
+      apiVersion = "v1"
+      kind       = "ConfigMap"
+      metadata   = {
+        name = "test"
+      }
+      data = {
+        "test" = "test"
+      }
+      immutable = false
+    },
+    {
+      apiVersion = "apps/v1"
+      kind = "DaemonSet"
+      metadata = {
+        name      = "fluentd-elasticsearch2"
+        namespace = "kube-system"
+        labels    = {
+          "k8s-app" = "fluentd-logging"
+        }
+      }
+      spec = {
+        selector = {
+          matchLabels = {
+            name = "fluentd-elasticsearch"
+          }
+        }
+        template = {
+          metadata = {
+            labels = {
+              "something" = "helloworld"
+              "name"      = "fluentd-elasticsearch"
+            }
+          }
+          spec = {
+            tolerations = [
+              {
+                key      = "node-role.kubernetes.io/control-plane"
+                operator = "Exists"
+                effect   = "NoSchedule"
+              },
+              {
+                key      = "node-role.kubernetes.io/master"
+                operator = "Exists"
+                effect   = "NoSchedule"
+              }
+            ]
+            containers = [
+              {
+                name      = "fluentd-elasticsearch"
+                image     = "quay.io/fluentd_elasticsearch/fluentd:v2.5.2"
+                resources = {
+                  limits = {
+                    cpu    = 1.5
+                    memory = "200Mi"
+                  }
+                  requests = {
+                    cpu    = "100m"
+                    memory = "200Mi"
+                  }
+                }
+                volumeMounts = [
+                  {
+                    mountPath = "/var/log"
+                    name      = "varlog"
+                  }
+                ]
+              }
+            ]
+            terminationGracePeriodSeconds = 30
+            volumes = [
+              {
+                name = "varlog"
+                hostPath = {
+                  path = "/var/log"
+                }
+              }
+            ]
+          }
+        }
+      }
+    }
+  ]
+}
+
+output "test" {
+  value = provider::kubernetes::manifest_encode(local.multi_manifest)
+}`
+}
diff --git a/internal/framework/provider/functions/testdata/decode_manifest_invalid.yaml b/internal/framework/provider/functions/testdata/decode_manifest_invalid.yaml
new file mode 100644
index 00000000..c04e64f5
--- /dev/null
+++ b/internal/framework/provider/functions/testdata/decode_manifest_invalid.yaml
@@ -0,0 +1,7 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+---
+this: is
+not: a
+kubernetes: manifest
diff --git a/internal/framework/provider/functions/testdata/decode_manifest_invalid_syntax.yaml b/internal/framework/provider/functions/testdata/decode_manifest_invalid_syntax.yaml
new file mode 100644
index 00000000..950820f5
--- /dev/null
+++ b/internal/framework/provider/functions/testdata/decode_manifest_invalid_syntax.yaml
@@ -0,0 +1,14 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+--
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: test-configmap
+  labels:
+    test: "test---label"
+ &data:
+  configfile: |
+    ---
+    test: document
diff --git a/internal/framework/provider/functions/testdata/decode_multi.yaml b/internal/framework/provider/functions/testdata/decode_multi.yaml
new file mode 100644
index 00000000..b59897ea
--- /dev/null
+++ b/internal/framework/provider/functions/testdata/decode_multi.yaml
@@ -0,0 +1,119 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+# test comment
+---
+# test comment
+---
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: fluentd-elasticsearch
+  namespace: kube-system
+  labels:
+    k8s-app: fluentd-logging
+spec:
+  selector:
+    matchLabels:
+      name: fluentd-elasticsearch
+  template:
+    metadata:
+      labels:
+        name: fluentd-elasticsearch
+    spec:
+      tolerations:
+      # these tolerations are to have the daemonset runnable on control plane nodes
+      # remove them if your control plane nodes should not run pods
+      - key: node-role.kubernetes.io/control-plane
+        operator: Exists
+        effect: NoSchedule
+      - key: node-role.kubernetes.io/master
+        operator: Exists
+        effect: NoSchedule
+      containers:
+      - name: fluentd-elasticsearch
+        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
+        resources:
+          limits:
+            cpu: 1.5
+            memory: 200Mi
+          requests:
+            cpu: 1
+            memory: 200Mi
+        volumeMounts:
+        - name: varlog
+          mountPath: /var/log
+      # it may be desirable to set a high priority class to ensure that a DaemonSet Pod
+      # preempts running Pods
+      # priorityClassName: important
+      terminationGracePeriodSeconds: 30
+      volumes:
+      - name: varlog
+        hostPath:
+          path: /var/log
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: test-configmap
+  namespace: kube-system
+  labels:
+    test: "test---label"
+data:
+  immutable: false
+  configfile: |
+    ---
+    test: document
+
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: fluentd-elasticsearch2
+  namespace: kube-system
+  labels:
+    k8s-app: fluentd-logging
+spec:
+  selector:
+    matchLabels:
+      name: fluentd-elasticsearch
+  template:
+    metadata:
+      labels:
+        something: "helloworld"
+        name: fluentd-elasticsearch
+    spec:
+      tolerations:
+      # these tolerations are to have the daemonset runnable on control plane nodes
+      # remove them if your control plane nodes should not run pods
+      - key: node-role.kubernetes.io/control-plane
+        operator: Exists
+        effect: NoSchedule
+      - key: node-role.kubernetes.io/master
+        operator: Exists
+        effect: NoSchedule
+      containers:
+      - name: fluentd-elasticsearch
+        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
+        resources:
+          limits:
+            memory: 200Mi
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        volumeMounts:
+        - name: varlog
+          mountPath: /var/log
+      # it may be desirable to set a high priority class to ensure that a DaemonSet Pod
+      # preempts running Pods
+      # priorityClassName: important
+      terminationGracePeriodSeconds: 30
+      volumes:
+      - name: varlog
+        hostPath:
+          path: /var/log
+---    
+---
+# test comment
+---
diff --git a/internal/framework/provider/functions/testdata/decode_single.yaml b/internal/framework/provider/functions/testdata/decode_single.yaml
new file mode 100644
index 00000000..2c89d46c
--- /dev/null
+++ b/internal/framework/provider/functions/testdata/decode_single.yaml
@@ -0,0 +1,16 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: test-configmap
+  annotations: null
+  labels:
+    test: "test---label"
+data:
+  configfile: |
+    ---
+    test: document
+status:
diff --git a/kubernetes/data_source_kubernetes_config_map_v1_test.go b/kubernetes/data_source_kubernetes_config_map_v1_test.go
index 8e74e979..4edd022c 100644
--- a/kubernetes/data_source_kubernetes_config_map_v1_test.go
+++ b/kubernetes/data_source_kubernetes_config_map_v1_test.go
@@ -47,6 +47,25 @@ func TestAccKubernetesDataSourceConfigMapV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceConfigMapV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_config_map_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-config-map-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{ // Use the data source to read the existing resource.
+				Config: testAccKubernetesDataSourceConfigMapV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "data.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 // testAccKubernetesDataSourceConfigMapConfig_basic provides the terraform config
 // used to test basic functionality of the config_map data source.
 func testAccKubernetesDataSourceConfigMapV1_basic(name string) string {
@@ -82,3 +101,12 @@ func testAccKubernetesDataSourceConfigMapV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceConfigMapV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_config_map_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_endpoints_v1_test.go b/kubernetes/data_source_kubernetes_endpoints_v1_test.go
index a5139f98..bc11cfed 100644
--- a/kubernetes/data_source_kubernetes_endpoints_v1_test.go
+++ b/kubernetes/data_source_kubernetes_endpoints_v1_test.go
@@ -60,6 +60,26 @@ func TestAccKubernetesDataSourceEndpointsV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceEndpointsV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_endpoints_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-endpoint-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesEndpointV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceEndpointsV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "subset.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceEndpointsV1_read() string {
 	return `data "kubernetes_endpoints_v1" "test" {
   metadata {
@@ -68,3 +88,12 @@ func testAccKubernetesDataSourceEndpointsV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceEndpointsV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_endpoints_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_ingress_test.go b/kubernetes/data_source_kubernetes_ingress_test.go
index e859da34..3897e7b4 100644
--- a/kubernetes/data_source_kubernetes_ingress_test.go
+++ b/kubernetes/data_source_kubernetes_ingress_test.go
@@ -68,6 +68,28 @@ func TestAccKubernetesDataSourceIngress_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceIngress_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_ingress.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-ingress-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+			skipIfClusterVersionGreaterThanOrEqual(t, "1.22.0")
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceIngress_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceIngress_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_ingress" "test" {
   metadata {
@@ -104,3 +126,12 @@ func testAccKubernetesDataSourceIngress_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceIngress_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_ingress" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_ingress_v1_test.go b/kubernetes/data_source_kubernetes_ingress_v1_test.go
index 8f542d19..495f90df 100644
--- a/kubernetes/data_source_kubernetes_ingress_v1_test.go
+++ b/kubernetes/data_source_kubernetes_ingress_v1_test.go
@@ -70,6 +70,28 @@ func TestAccKubernetesDataSourceIngressV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceIngressV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_ingress_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-ingress-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+			skipIfClusterVersionLessThan(t, "1.22.0")
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceIngressV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceIngressV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_ingress_v1" "test" {
   metadata {
@@ -115,3 +137,12 @@ func testAccKubernetesDataSourceIngressV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceIngressV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_ingress_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
index 6b3c4c76..e85f6a9b 100644
--- a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
+++ b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
@@ -101,6 +101,26 @@ func TestAccKubernetesDataSourceMutatingWebhookConfigurationV1_basic(t *testing.
 	})
 }
 
+func TestAccKubernetesDataSourceMutatingWebhookConfigurationV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_mutating_webhook_configuration_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-webhook-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceMutatingWebhookConfigurationV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "webhook.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_mutating_webhook_configuration_v1" "test" {
   metadata {
@@ -141,3 +161,12 @@ func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_mutating_webhook_configuration_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_namespace_v1_test.go b/kubernetes/data_source_kubernetes_namespace_v1_test.go
index bf259514..8da98962 100644
--- a/kubernetes/data_source_kubernetes_namespace_v1_test.go
+++ b/kubernetes/data_source_kubernetes_namespace_v1_test.go
@@ -4,8 +4,10 @@
 package kubernetes
 
 import (
+	"fmt"
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 )
 
@@ -31,6 +33,24 @@ func TestAccKubernetesDataSourceNamespaceV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceNamespaceV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_namespace_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-namespace-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceNamespaceV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceNamespaceV1_basic() string {
 	return `data "kubernetes_namespace_v1" "test" {
   metadata {
@@ -39,3 +59,12 @@ func testAccKubernetesDataSourceNamespaceV1_basic() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceNamespaceV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_namespace_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_nodes_test.go b/kubernetes/data_source_kubernetes_nodes_test.go
index 36b5832a..d733fa11 100644
--- a/kubernetes/data_source_kubernetes_nodes_test.go
+++ b/kubernetes/data_source_kubernetes_nodes_test.go
@@ -50,6 +50,23 @@ func TestAccKubernetesDataSourceNodes_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceNodes_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_nodes.test"
+	checkFuncs := resource.ComposeAggregateTestCheckFunc(
+		resource.TestCheckResourceAttr(dataSourceName, "nodes.#", "0"),
+	)
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceNodes_nonexistent(),
+				Check:  checkFuncs,
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceNodes_basic() string {
 	return `data "kubernetes_nodes" "test" {}
 `
@@ -65,3 +82,14 @@ func testAccKubernetesDataSourceNodes_labels() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceNodes_nonexistent() string {
+	return `data "kubernetes_nodes" "test" {
+  metadata {
+    labels = {
+      "ceci-n.est-pas" = "une-node"
+    }
+  }
+}
+`
+}
diff --git a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
index 325bd757..33019a68 100644
--- a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
+++ b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
@@ -56,6 +56,25 @@ func TestAccKubernetesDataSourcePersistentVolumeClaimV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourcePersistentVolumeClaimV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_persistent_volume_claim_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-pvc-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{ // The first apply creates the resource. The second apply reads the resource using the data source.
+				Config: testAccKubernetesDataSourcePersistentVolumeClaimV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourcePersistentVolumeClaimV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_persistent_volume_claim_v1" "test" {
   metadata {
@@ -98,3 +117,12 @@ func testAccKubernetesDataSourcePersistentVolumeClaimV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourcePersistentVolumeClaimV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_persistent_volume_claim_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_pod_v1_test.go b/kubernetes/data_source_kubernetes_pod_v1_test.go
index e8230131..b01d428f 100644
--- a/kubernetes/data_source_kubernetes_pod_v1_test.go
+++ b/kubernetes/data_source_kubernetes_pod_v1_test.go
@@ -40,6 +40,25 @@ func TestAccKubernetesDataSourcePodV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourcePodV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_pod_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-pod-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourcePodV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourcePodV1_basic(name, imageName string) string {
 	return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" {
   metadata {
@@ -63,3 +82,12 @@ func testAccKubernetesDataSourcePodV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourcePodV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_pod_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_secret_v1_test.go b/kubernetes/data_source_kubernetes_secret_v1_test.go
index 2a2ba84c..05b585dd 100644
--- a/kubernetes/data_source_kubernetes_secret_v1_test.go
+++ b/kubernetes/data_source_kubernetes_secret_v1_test.go
@@ -81,6 +81,25 @@ func TestAccKubernetesDataSourceSecretV1_generateName(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceSecretV1_not_found(t *testing.T) {
+	name := fmt.Sprintf("ceci-n.est-pas-une-secret-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	datasourceName := "data.kubernetes_secret_v1.test"
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceSecretV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(datasourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(datasourceName, "data.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceSecretV1_generateName(generate_name string) string {
 	return fmt.Sprintf(`resource "kubernetes_secret_v1" "test" {
   metadata {
@@ -147,3 +166,12 @@ func testAccKubernetesDataSourceSecretV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceSecretV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_secret_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_service_account_v1_test.go b/kubernetes/data_source_kubernetes_service_account_v1_test.go
index ebdb5cfc..fd80fde5 100644
--- a/kubernetes/data_source_kubernetes_service_account_v1_test.go
+++ b/kubernetes/data_source_kubernetes_service_account_v1_test.go
@@ -80,6 +80,26 @@ func TestAccKubernetesDataSourceServiceAccountV1_default_secret(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceServiceAccountV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_service_account_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-service-account-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceServiceAccountV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "secret.#", "0"),
+					resource.TestCheckResourceAttr(dataSourceName, "image_pull_secret.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceServiceAccountV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_service_account_v1" "test" {
   metadata {
@@ -162,3 +182,12 @@ func testAccKubernetesDataSourceServiceAccountV1_default_secret_read(name string
 }
 `, name)
 }
+
+func testAccKubernetesDataSourceServiceAccountV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_service_account_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_service_v1_test.go b/kubernetes/data_source_kubernetes_service_v1_test.go
index 4e9f24a3..31bd1bf5 100644
--- a/kubernetes/data_source_kubernetes_service_v1_test.go
+++ b/kubernetes/data_source_kubernetes_service_v1_test.go
@@ -83,6 +83,26 @@ func TestAccKubernetesDataSourceServiceV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceServiceV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_service_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-service-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesConfig_ignoreAnnotations() +
+					testAccKubernetesDataSourceServiceV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceServiceV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_service_v1" "test" {
   metadata {
@@ -118,3 +138,12 @@ func testAccKubernetesDataSourceServiceV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceServiceV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_service_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_storage_class_v1_test.go b/kubernetes/data_source_kubernetes_storage_class_v1_test.go
index 633b32fc..c1a6f89b 100644
--- a/kubernetes/data_source_kubernetes_storage_class_v1_test.go
+++ b/kubernetes/data_source_kubernetes_storage_class_v1_test.go
@@ -73,6 +73,26 @@ func TestAccKubernetesDataSourceStorageClassV1_minikube(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceStorageClassV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_storage_class_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-storage-class-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t); skipIfNotRunningInKind(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceStorageClassV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "mount_options.#", "0"),
+					resource.TestCheckResourceAttr(dataSourceName, "parameters.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 func TestAccKubernetesDataSourceStorageClassV1_gke(t *testing.T) {
 	resourceName := "kubernetes_storage_class_v1.test"
 	dataSourceName := "data.kubernetes_storage_class_v1.test"
@@ -178,3 +198,12 @@ func testAccKubernetesDataSourceStorageClassV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceStorageClassV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_storage_class_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/resource_kubernetes_cron_job_v1_test.go b/kubernetes/resource_kubernetes_cron_job_v1_test.go
index 76f4bcac..b4442242 100644
--- a/kubernetes/resource_kubernetes_cron_job_v1_test.go
+++ b/kubernetes/resource_kubernetes_cron_job_v1_test.go
@@ -52,7 +52,6 @@ func TestAccKubernetesCronJobV1_basic(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "spec.0.successful_jobs_history_limit", "10"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.suspend", "true"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.metadata.0.annotations.cluster-autoscaler.kubernetes.io/safe-to-evict", "false"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.metadata.0.namespace", "ns-test"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.parallelism", "1"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.backoff_limit", "2"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.template.0.metadata.0.annotations.controller.kubernetes.io/pod-deletion-cost", "10000"),
@@ -76,11 +75,6 @@ func TestAccKubernetesCronJobV1_basic(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "spec.0.starting_deadline_seconds", "0"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.successful_jobs_history_limit", "3"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.suspend", "false"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.parallelism", "2"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.backoff_limit", "6"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.template.0.spec.0.container.0.name", "hello"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.template.0.metadata.#", "1"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.template.0.metadata.0.labels.%", "1"),
 					testAccCheckKubernetesCronJobV1ForceNew(&conf1, &conf2, false),
 				),
 			},
@@ -134,6 +128,97 @@ func TestAccKubernetesCronJobV1_extra(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesCronJobV1_minimalWithTemplateNamespace(t *testing.T) {
+	var conf1, conf2 batchv1.CronJob
+
+	name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_cron_job_v1.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		IDRefreshName:     resourceName,
+		IDRefreshIgnore:   []string{"metadata.0.resource_version"},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesCronJobV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesCronJobV1ConfigMinimal(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.metadata.0.namespace", ""),
+				),
+			},
+			{
+				Config: testAccKubernetesCronJobV1ConfigMinimalWithJobTemplateNamespace(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Exists(resourceName, &conf2),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttrSet(resourceName, "spec.0.job_template.0.metadata.0.namespace"),
+					testAccCheckKubernetesCronJobV1ForceNew(&conf1, &conf2, true),
+				),
+			},
+		},
+	})
+}
+
+func TestAccKubernetesCronJobV1_minimalWithPodFailurePolicy(t *testing.T) {
+	var conf1, conf2 batchv1.CronJob
+
+	name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_cron_job_v1.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		IDRefreshName:     resourceName,
+		IDRefreshIgnore:   []string{"metadata.0.resource_version"},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesCronJobV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesCronJobV1ConfigMinimal(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.metadata.0.namespace", ""),
+				),
+			},
+			{
+				Config: testAccKubernetesCronJobV1ConfigMinimalWithPodFailurePolicy(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Exists(resourceName, &conf2),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.#", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.action", "FailJob"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.container_name", "test"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.#", "3"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.0", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.1", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.2", "42"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.1.action", "Ignore"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.type", "DisruptionTarget"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.status", "False"),
+					testAccCheckKubernetesCronJobV1ForceNew(&conf1, &conf2, true),
+				),
+			},
+		},
+	})
+}
+
 func testAccCheckKubernetesCronJobV1Destroy(s *terraform.State) error {
 	conn, err := testAccProvider.Meta().(KubeClientsets).MainClientset()
 
@@ -212,7 +297,6 @@ func testAccKubernetesCronJobV1Config_basic(name, imageName string) string {
         annotations = {
           "cluster-autoscaler.kubernetes.io/safe-to-evict" = "false"
         }
-        namespace = "ns-test"
       }
       spec {
         backoff_limit = 2
@@ -244,9 +328,7 @@ func testAccKubernetesCronJobV1Config_modified(name, imageName string) string {
   spec {
     schedule = "1 0 * * *"
     job_template {
-      metadata {
-        namespace = "ns-test"
-      }
+      metadata {}
       spec {
         parallelism = 2
         template {
@@ -336,7 +418,7 @@ func testAccKubernetesCronJobV1Config_extraModified(name, imageName string) stri
 func testAccCheckKubernetesCronJobV1ForceNew(old, new *batchv1.CronJob, wantNew bool) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		if wantNew {
-			if old.ObjectMeta.UID != new.ObjectMeta.UID {
+			if old.ObjectMeta.UID == new.ObjectMeta.UID {
 				return fmt.Errorf("Expecting forced replacement")
 			}
 		} else {
@@ -347,3 +429,109 @@ func testAccCheckKubernetesCronJobV1ForceNew(old, new *batchv1.CronJob, wantNew
 		return nil
 	}
 }
+
+func testAccKubernetesCronJobV1ConfigMinimal(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_cron_job_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    schedule = "*/1 * * * *"
+    job_template {
+      metadata {}
+      spec {
+        template {
+          metadata {}
+          spec {
+            container {
+              name    = "test"
+              image   = "%s"
+              command = ["sleep", "5"]
+            }
+            termination_grace_period_seconds = 1
+          }
+        }
+      }
+    }
+  }
+}
+`, name, imageName)
+}
+
+func testAccKubernetesCronJobV1ConfigMinimalWithPodFailurePolicy(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_cron_job_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    schedule = "*/1 * * * *"
+    job_template {
+      metadata {}
+      spec {
+        pod_failure_policy {
+          rule {
+            action = "FailJob"
+            on_exit_codes {
+              container_name = "test"
+              operator       = "In"
+              values         = [1, 2, 42]
+            }
+          }
+          rule {
+            action = "Ignore"
+            on_pod_condition {
+              status = "False"
+              type   = "DisruptionTarget"
+            }
+          }
+        }
+        template {
+          metadata {}
+          spec {
+
+            container {
+              name    = "test"
+              image   = "%s"
+              command = ["sleep", "5"]
+            }
+            termination_grace_period_seconds = 1
+          }
+        }
+      }
+    }
+  }
+}
+`, name, imageName)
+}
+
+func testAccKubernetesCronJobV1ConfigMinimalWithJobTemplateNamespace(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_cron_job_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    schedule = "*/1 * * * *"
+    job_template {
+      metadata {
+        // The namespace field is just a stub and does not influence where the Pod will be created.
+        // The Pod will be created within the same Namespace as the Cron Job resource.
+        namespace = "fake" // Doesn't have to exist.
+      }
+      spec {
+        template {
+          metadata {}
+          spec {
+            container {
+              name    = "test"
+              image   = "%s"
+              command = ["sleep", "1"]
+            }
+            termination_grace_period_seconds = 1
+          }
+        }
+      }
+    }
+  }
+}
+`, name, imageName)
+}
diff --git a/kubernetes/resource_kubernetes_cron_job_v1beta1_test.go b/kubernetes/resource_kubernetes_cron_job_v1beta1_test.go
index ff045e77..33da6e7c 100644
--- a/kubernetes/resource_kubernetes_cron_job_v1beta1_test.go
+++ b/kubernetes/resource_kubernetes_cron_job_v1beta1_test.go
@@ -126,6 +126,50 @@ func TestAccKubernetesCronJobV1Beta1_extra(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesCronJobV1Beta1_minimalWithTemplateNamespace(t *testing.T) {
+	var conf1, conf2 batchv1beta1.CronJob
+
+	name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_cron_job.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+			skipIfClusterVersionGreaterThanOrEqual(t, "1.25.0")
+		},
+		IDRefreshName:     resourceName,
+		IDRefreshIgnore:   []string{"metadata.0.resource_version"},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesCronJobV1Beta1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesCronJobV1Beta1ConfigMinimal(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Beta1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.job_template.0.metadata.0.namespace", ""),
+				),
+			},
+			{
+				Config: testAccKubernetesCronJobV1Beta1ConfigMinimalWithJobTemplateNamespace(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesCronJobV1Beta1Exists(resourceName, &conf2),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttrSet(resourceName, "spec.0.job_template.0.metadata.0.namespace"),
+					testAccCheckKubernetesCronJobV1Beta1ForceNew(&conf1, &conf2, true),
+				),
+			},
+		},
+	})
+}
+
 func testAccCheckKubernetesCronJobV1Beta1Destroy(s *terraform.State) error {
 	conn, err := testAccProvider.Meta().(KubeClientsets).MainClientset()
 
@@ -322,3 +366,63 @@ func testAccCheckKubernetesCronJobV1Beta1ForceNew(old, new *batchv1beta1.CronJob
 		return nil
 	}
 }
+
+func testAccKubernetesCronJobV1Beta1ConfigMinimal(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_cron_job" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    schedule = "*/1 * * * *"
+    job_template {
+      metadata {}
+      spec {
+        template {
+          metadata {}
+          spec {
+            container {
+              name    = "test"
+              image   = "%s"
+              command = ["sleep", "5"]
+            }
+          }
+        }
+      }
+    }
+  }
+}
+`, name, imageName)
+}
+
+func testAccKubernetesCronJobV1Beta1ConfigMinimalWithJobTemplateNamespace(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_cron_job" "test" {
+  metadata {
+    name = "%s"
+  }
+
+  spec {
+    schedule = "*/1 * * * *"
+
+    job_template {
+      metadata {
+        // The namespace field is just a stub and does not influence where the Pod will be created.
+        // The Pod will be created within the same Namespace as the Cron Job resource.
+        namespace = "fake" // Doesn't have to exist.
+      }
+      spec {
+        template {
+          metadata {}
+          spec {
+            container {
+              name    = "test"
+              image   = "%s"
+              command = ["sleep", "5"]
+            }
+          }
+        }
+      }
+    }
+  }
+}
+`, name, imageName)
+}
diff --git a/kubernetes/resource_kubernetes_daemon_set_v1_test.go b/kubernetes/resource_kubernetes_daemon_set_v1_test.go
index 49590c60..711c166f 100644
--- a/kubernetes/resource_kubernetes_daemon_set_v1_test.go
+++ b/kubernetes/resource_kubernetes_daemon_set_v1_test.go
@@ -393,6 +393,46 @@ func TestAccKubernetesDaemonSetV1_with_resource_requirements(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDaemonSetV1_minimalWithTemplateNamespace(t *testing.T) {
+	var conf1, conf2 appsv1.DaemonSet
+	name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_daemon_set_v1.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		IDRefreshName:     resourceName,
+		IDRefreshIgnore:   []string{"metadata.0.resource_version"},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesDaemonSetV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDaemonSetV1Config_minimal(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesDaemonSetV1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.0.namespace", ""),
+				),
+			},
+			{
+				Config: testAccKubernetesDaemonSetV1ConfigMinimalWithTemplateNamespace(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesDaemonSetV1Exists(resourceName, &conf2),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttrSet(resourceName, "spec.0.template.0.metadata.0.namespace"),
+					testAccCheckKubernetesDaemonSetV1ForceNew(&conf1, &conf2, true),
+				),
+			},
+		},
+	})
+}
+
 func testAccCheckKubernetesDaemonSetV1Destroy(s *terraform.State) error {
 	conn, err := testAccProvider.Meta().(KubeClientsets).MainClientset()
 
@@ -449,6 +489,21 @@ func testAccCheckKubernetesDaemonSetV1Exists(n string, obj *appsv1.DaemonSet) re
 	}
 }
 
+func testAccCheckKubernetesDaemonSetV1ForceNew(old, new *appsv1.DaemonSet, wantNew bool) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		if wantNew {
+			if old.ObjectMeta.UID == new.ObjectMeta.UID {
+				return fmt.Errorf("Expecting new resource for DaemonSet %s", old.ObjectMeta.UID)
+			}
+		} else {
+			if old.ObjectMeta.UID != new.ObjectMeta.UID {
+				return fmt.Errorf("Expecting DaemonSet UIDs to be the same: expected %s got %s", old.ObjectMeta.UID, new.ObjectMeta.UID)
+			}
+		}
+		return nil
+	}
+}
+
 func testAccKubernetesDaemonSetV1Config_minimal(name, imageName string) string {
 	return fmt.Sprintf(`resource "kubernetes_daemon_set_v1" "test" {
   metadata {
@@ -1091,3 +1146,37 @@ func testAccKubernetesDaemonSetV1ConfigWithResourceRequirementsRequestsOnly(depl
 }
 `, deploymentName, imageName)
 }
+
+func testAccKubernetesDaemonSetV1ConfigMinimalWithTemplateNamespace(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_daemon_set_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    selector {
+      match_labels = {
+        foo = "bar"
+      }
+    }
+    template {
+      metadata {
+        // The namespace field is just a stub and does not influence where the Pod will be created.
+        // The Pod will be created within the same Namespace as the Daemon Set resource.
+        namespace = "fake" // Doesn't have to exist.
+        labels = {
+          foo = "bar"
+        }
+      }
+      spec {
+        container {
+          image   = "%s"
+          name    = "tf-acc-test"
+          command = ["sleep", "300"]
+        }
+        termination_grace_period_seconds = 1
+      }
+    }
+  }
+}
+`, name, imageName)
+}
diff --git a/kubernetes/resource_kubernetes_deployment_v1_test.go b/kubernetes/resource_kubernetes_deployment_v1_test.go
index 41786efb..d93c7164 100644
--- a/kubernetes/resource_kubernetes_deployment_v1_test.go
+++ b/kubernetes/resource_kubernetes_deployment_v1_test.go
@@ -820,6 +820,33 @@ func TestAccKubernetesDeploymentV1_with_empty_dir_volume(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDeploymentV1_with_empty_dir_huge_page(t *testing.T) {
+	var conf appsv1.Deployment
+
+	imageName := busyboxImage
+	deploymentName := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_deployment_v1.test"
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesDeploymentV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDeploymentV1ConfigWithEmptyDirHugePage(deploymentName, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesDeploymentV1Exists(resourceName, &conf),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.image", imageName),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.volume_mount.#", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.volume_mount.0.mount_path", "/cache"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.volume_mount.0.name", "cache-volume"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.volume.0.empty_dir.0.medium", "HugePages-1Gi"),
+				),
+			},
+		},
+	})
+}
+
 func TestAccKubernetesDeploymentV1Update_basic(t *testing.T) {
 	var conf1, conf2 appsv1.Deployment
 	resourceName := "kubernetes_deployment_v1.test"
@@ -2608,6 +2635,59 @@ func testAccKubernetesDeploymentV1ConfigWithEmptyDirVolumes(deploymentName, imag
 `, deploymentName, imageName)
 }
 
+func testAccKubernetesDeploymentV1ConfigWithEmptyDirHugePage(deploymentName, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_deployment_v1" "test" {
+  metadata {
+    name = "%s"
+
+    labels = {
+      Test = "TfAcceptanceTest"
+    }
+  }
+
+  spec {
+    replicas = 0 # We request zero replicas, since the K8S backing this test may not have huge pages available.
+    selector {
+      match_labels = {
+        Test = "TfAcceptanceTest"
+      }
+    }
+
+    template {
+      metadata {
+        labels = {
+          Test = "TfAcceptanceTest"
+        }
+      }
+
+      spec {
+        container {
+          image   = "%s"
+          name    = "containername"
+          command = ["sleep", "300"]
+
+          volume_mount {
+            mount_path = "/cache"
+            name       = "cache-volume"
+          }
+        }
+
+        volume {
+          name = "cache-volume"
+
+          empty_dir {
+            medium = "HugePages-1Gi"
+          }
+        }
+
+        termination_grace_period_seconds = 1
+      }
+    }
+  }
+}
+`, deploymentName, imageName)
+}
+
 func testAccKubernetesDeploymentV1ConfigWithEmptyDirVolumesModified(deploymentName, imageName string) string {
 	return fmt.Sprintf(`resource "kubernetes_deployment_v1" "test" {
   metadata {
diff --git a/kubernetes/resource_kubernetes_job_v1_test.go b/kubernetes/resource_kubernetes_job_v1_test.go
index 75a1f825..fc190352 100644
--- a/kubernetes/resource_kubernetes_job_v1_test.go
+++ b/kubernetes/resource_kubernetes_job_v1_test.go
@@ -77,6 +77,16 @@ func TestAccKubernetesJobV1_basic(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.name", "hello"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.image", imageName),
 					resource.TestCheckResourceAttr(resourceName, "wait_for_completion", "false"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.#", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.action", "FailJob"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.container_name", "hello"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.#", "3"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.0", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.1", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.2", "42"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.action", "Ignore"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.type", "DisruptionTarget"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.status", "False"),
 				),
 			},
 			{
@@ -131,6 +141,16 @@ func TestAccKubernetesJobV1_update(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.image", imageName),
 					resource.TestCheckResourceAttr(resourceName, "wait_for_completion", "false"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.manual_selector", "false"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.#", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.action", "FailJob"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.container_name", "hello"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.#", "3"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.0", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.1", "2"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.0.on_exit_codes.0.values.2", "42"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.action", "Ignore"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.type", "DisruptionTarget"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.pod_failure_policy.0.rule.1.on_pod_condition.0.status", "False"),
 				),
 			},
 			{
@@ -307,6 +327,23 @@ func testAccKubernetesJobV1Config_basic(name, imageName string) string {
     backoff_limit           = 10
     completions             = 4
     parallelism             = 2
+    pod_failure_policy {
+      rule {
+        action = "FailJob"
+        on_exit_codes {
+          container_name = "hello"
+          operator       = "In"
+          values         = [1, 2, 42]
+        }
+      }
+      rule {
+        action = "Ignore"
+        on_pod_condition {
+          status = "False"
+          type   = "DisruptionTarget"
+        }
+      }
+    }
     template {
       metadata {}
       spec {
@@ -334,6 +371,23 @@ func testAccKubernetesJobV1Config_updateMutableFields(name, imageName, activeDea
     completions             = 4
     manual_selector         = %s
     parallelism             = %s
+    pod_failure_policy {
+      rule {
+        action = "FailJob"
+        on_exit_codes {
+          container_name = "hello"
+          operator       = "In"
+          values         = [1, 2, 42]
+        }
+      }
+      rule {
+        action = "Ignore"
+        on_pod_condition {
+          status = "False"
+          type   = "DisruptionTarget"
+        }
+      }
+    }
     template {
       metadata {}
       spec {
diff --git a/kubernetes/resource_kubernetes_pod_v1_test.go b/kubernetes/resource_kubernetes_pod_v1_test.go
index a4daab04..3a71b902 100644
--- a/kubernetes/resource_kubernetes_pod_v1_test.go
+++ b/kubernetes/resource_kubernetes_pod_v1_test.go
@@ -1440,7 +1440,6 @@ func TestAccKubernetesPodV1_topologySpreadConstraint(t *testing.T) {
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck: func() {
 			testAccPreCheck(t)
-			skipIfClusterVersionGreaterThanOrEqual(t, "1.17.0")
 		},
 		ProviderFactories: testAccProviderFactories,
 		CheckDestroy:      testAccCheckKubernetesPodV1Destroy,
@@ -1450,7 +1449,10 @@ func TestAccKubernetesPodV1_topologySpreadConstraint(t *testing.T) {
 				Check: resource.ComposeAggregateTestCheckFunc(
 					testAccCheckKubernetesPodV1Exists(resourceName, &conf1),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.#", "1"),
+					resource.TestCheckTypeSetElemAttr(resourceName, "spec.0.topology_spread_constraint.0.match_label_keys.*", "pod-template-hash"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.max_skew", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.node_affinity_policy", "Ignore"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.node_taints_policy", "Honor"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.topology_key", "topology.kubernetes.io/zone"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.when_unsatisfiable", "ScheduleAnyway"),
 				),
@@ -1465,6 +1467,38 @@ func TestAccKubernetesPodV1_topologySpreadConstraint(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesPodV1_topologySpreadConstraintMinDomains(t *testing.T) {
+	var conf1 api.Pod
+
+	podName := acctest.RandomWithPrefix("tf-acc-test")
+	resourceName := "kubernetes_pod_v1.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+		},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesPodV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesPodV1TopologySpreadConstraintConfigMinDomains(podName, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesPodV1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.#", "1"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.topology_spread_constraint.0.min_domains", "1"),
+				),
+			},
+			{
+				ResourceName:            resourceName,
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"metadata.0.resource_version"},
+			},
+		},
+	})
+}
+
 func TestAccKubernetesPodV1_runtimeClassName(t *testing.T) {
 	var conf1 api.Pod
 
@@ -3219,9 +3253,12 @@ func testAccKubernetesPodV1TopologySpreadConstraintConfig(podName, imageName str
       name  = "containername"
     }
     topology_spread_constraint {
-      max_skew           = 1
-      topology_key       = "topology.kubernetes.io/zone"
-      when_unsatisfiable = "ScheduleAnyway"
+      match_label_keys     = ["pod-template-hash"]
+      max_skew             = 1
+      node_affinity_policy = "Ignore"
+      node_taints_policy   = "Honor"
+      topology_key         = "topology.kubernetes.io/zone"
+      when_unsatisfiable   = "ScheduleAnyway"
       label_selector {
         match_labels = {
           "app.kubernetes.io/instance" = "terraform-example"
@@ -3233,6 +3270,30 @@ func testAccKubernetesPodV1TopologySpreadConstraintConfig(podName, imageName str
 `, podName, imageName)
 }
 
+func testAccKubernetesPodV1TopologySpreadConstraintConfigMinDomains(podName, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    container {
+      image = "%s"
+      name  = "containername"
+    }
+    topology_spread_constraint {
+      min_domains  = 1
+      topology_key = "kubernetes.io/hostname"
+      label_selector {
+        match_labels = {
+          "test" = "test"
+        }
+      }
+    }
+  }
+}
+`, podName, imageName)
+}
+
 func testAccKubernetesPodV1ConfigRuntimeClassName(name, imageName, runtimeHandler string) string {
 	return fmt.Sprintf(`resource "kubernetes_runtime_class_v1" "test" {
   metadata {
diff --git a/kubernetes/resource_kubernetes_stateful_set_v1_test.go b/kubernetes/resource_kubernetes_stateful_set_v1_test.go
index 71f58ac9..aa0d5356 100644
--- a/kubernetes/resource_kubernetes_stateful_set_v1_test.go
+++ b/kubernetes/resource_kubernetes_stateful_set_v1_test.go
@@ -85,7 +85,6 @@ func TestAccKubernetesStatefulSetV1_basic(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.#", "1"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.0.labels.%", "1"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.0.labels.app", "ss-test"),
-					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.0.namespace", "ns-test"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.name", "ss-test"),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.image", imageName),
 					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.port.0.container_port", "80"),
@@ -326,6 +325,47 @@ func TestAccKubernetesStatefulSetV1_waitForRollout(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesStatefulSetV1_minimalWithTemplateNamespace(t *testing.T) {
+	var conf1, conf2 appsv1.StatefulSet
+
+	name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resourceName := "kubernetes_stateful_set_v1.test"
+	imageName := busyboxImage
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		IDRefreshName:     resourceName,
+		IDRefreshIgnore:   []string{"metadata.0.resource_version"},
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesStatefulSetV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesStatefulSetV1ConfigMinimal(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesStatefulSetV1Exists(resourceName, &conf1),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.metadata.0.namespace", ""),
+				),
+			},
+			{
+				Config: testAccKubernetesStatefulSetV1ConfigMinimalWithTemplateNamespace(name, imageName),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					testAccCheckKubernetesStatefulSetV1Exists(resourceName, &conf2),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
+					resource.TestCheckResourceAttrSet(resourceName, "metadata.0.namespace"),
+					resource.TestCheckResourceAttrSet(resourceName, "spec.0.template.0.metadata.0.namespace"),
+					testAccCheckKubernetesStatefulSetForceNew(&conf1, &conf2, true),
+				),
+			},
+		},
+	})
+}
+
 func testAccCheckKubernetesStatefulSetForceNew(old, new *appsv1.StatefulSet, wantNew bool) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		if wantNew {
@@ -504,7 +544,6 @@ func testAccKubernetesStatefulSetV1ConfigBasic(name, imageName string) string {
         labels = {
           app = "ss-test"
         }
-        namespace = "ns-test"
       }
 
       spec {
@@ -1246,3 +1285,38 @@ func testAccKubernetesStatefulSetV1ConfigUpdatePersistentVolumeClaimRetentionPol
 }
 `, name, imageName)
 }
+
+func testAccKubernetesStatefulSetV1ConfigMinimalWithTemplateNamespace(name, imageName string) string {
+	return fmt.Sprintf(`resource "kubernetes_stateful_set_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+  spec {
+    selector {
+      match_labels = {
+        app = "ss-test"
+      }
+    }
+    service_name = "ss-test-service"
+    template {
+      metadata {
+        // The namespace field is just a stub and does not influence where the Pod will be created.
+        // The Pod will be created within the same Namespace as the Stateful Set resource.
+        namespace = "fake" // Doesn't have to exist.
+        labels = {
+          app = "ss-test"
+        }
+      }
+      spec {
+        container {
+          name    = "ss-test"
+          image   = "%s"
+          command = ["sleep", "300"]
+        }
+        termination_grace_period_seconds = 1
+      }
+    }
+  }
+}
+`, name, imageName)
+}
diff --git a/manifest/test/acceptance/datasource_resources_test.go b/manifest/test/acceptance/datasource_resources_test.go
new file mode 100644
index 00000000..76761d89
--- /dev/null
+++ b/manifest/test/acceptance/datasource_resources_test.go
@@ -0,0 +1,132 @@
+// Copyright (c) HashiCorp, Inc.
+// SPDX-License-Identifier: MPL-2.0
+
+//go:build acceptance
+// +build acceptance
+
+package acceptance
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/go-hclog"
+	"github.com/hashicorp/terraform-provider-kubernetes/manifest/provider"
+	"github.com/hashicorp/terraform-provider-kubernetes/manifest/test/helper/kubernetes"
+	tfstatehelper "github.com/hashicorp/terraform-provider-kubernetes/manifest/test/helper/state"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/utils/ptr"
+)
+
+func TestDataSourceKubernetesResources_DiffTuples(t *testing.T) {
+	ctx := context.Background()
+
+	reattachInfo, err := provider.ServeTest(ctx, hclog.Default(), t)
+	if err != nil {
+		t.Errorf("Failed to create provider instance: %q", err)
+	}
+
+	name := randName()
+	namespace := randName()
+
+	tf := tfhelper.RequireNewWorkingDir(ctx, t)
+	tf.SetReattachInfo(ctx, reattachInfo)
+	defer func() {
+		tf.Destroy(ctx)
+		tf.Close()
+		k8shelper.AssertResourceDoesNotExist(t, "v1", "namespaces", name)
+	}()
+
+	// Create a Namespace to provision the rest of the resources in it.
+	k8shelper.CreateNamespace(t, namespace)
+	defer k8shelper.DeleteResource(t, namespace, kubernetes.NewGroupVersionResource("v1", "namespaces"))
+
+	// Create Pods to use a data source.
+	// The only difference between the two pods is the number of VolumeMounts(tuples) that will be created.
+	// This is necessary to ensure that DeepUnknown doesn't mutate object type when iterates over items.
+	// kubernetes_manifest failed to create pods with volumes, thus create them manually.
+	k8shelper.AssertNamespacedResourceDoesNotExist(t, "v1", "pods", namespace, name)
+
+	volumes := []corev1.Volume{
+		{
+			Name: "config",
+			VolumeSource: corev1.VolumeSource{
+				EmptyDir: &corev1.EmptyDirVolumeSource{},
+			},
+		},
+	}
+	podSpecs := []corev1.PodSpec{
+		{
+			TerminationGracePeriodSeconds: ptr.To(int64(1)),
+			Containers: []corev1.Container{
+				{
+					Name:    "this",
+					Image:   "busybox",
+					Command: []string{"sleep", "infinity"},
+					VolumeMounts: []corev1.VolumeMount{
+						{
+							Name:      "config",
+							MountPath: "/config-a",
+						},
+						{
+							Name:      "config",
+							MountPath: "/config-b",
+						},
+					},
+				},
+			},
+			Volumes: volumes,
+		},
+		{
+			TerminationGracePeriodSeconds: ptr.To(int64(1)),
+			Containers: []corev1.Container{
+				{
+					Name:    "this",
+					Image:   "busybox",
+					Command: []string{"sleep", "infinity"},
+					VolumeMounts: []corev1.VolumeMount{
+						{
+							Name:      "config",
+							MountPath: "/config-a",
+						},
+						{
+							Name:      "config",
+							MountPath: "/config-b",
+						},
+						{
+							Name:      "config",
+							MountPath: "/config-c",
+						},
+					},
+				},
+			},
+			Volumes: volumes,
+		},
+	}
+
+	for i, ps := range podSpecs {
+		k8shelper.CreatePod(t, fmt.Sprintf("%s-%d", name, i), namespace, ps)
+	}
+
+	// Get pods
+	tfvars := TFVARS{
+		"namespace": namespace,
+	}
+	tfconfig := loadTerraformConfig(t, "DataSourceResources/pods_data_source.tf", tfvars)
+	tf.SetConfig(ctx, tfconfig)
+	tf.Init(ctx)
+	err = tf.Apply(ctx)
+	if err != nil {
+		t.Fatal(err.Error())
+	}
+
+	st, err := tf.State(ctx)
+	if err != nil {
+		t.Fatalf("Failed to retrieve terraform state: %q", err)
+	}
+	tfstate := tfstatehelper.NewHelper(st)
+
+	// check the data source
+	tfstate.AssertAttributeLen(t, "data.kubernetes_resources.pods.objects", len(podSpecs))
+}
diff --git a/manifest/test/acceptance/testdata/ComputedFields/webhook/go.mod b/manifest/test/acceptance/testdata/ComputedFields/webhook/go.mod
index da2356c4..56c42b22 100644
--- a/manifest/test/acceptance/testdata/ComputedFields/webhook/go.mod
+++ b/manifest/test/acceptance/testdata/ComputedFields/webhook/go.mod
@@ -5,27 +5,27 @@ go 1.21
 require (
 	github.com/sirupsen/logrus v1.9.3
 	github.com/slok/kubewebhook/v2 v2.5.0
-	k8s.io/apimachinery v0.27.7
+	k8s.io/apimachinery v0.28.6
 )
 
 require (
-	github.com/go-logr/logr v1.2.3 // indirect
+	github.com/go-logr/logr v1.2.4 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
-	golang.org/x/net v0.17.0 // indirect
-	golang.org/x/sys v0.13.0 // indirect
-	golang.org/x/text v0.13.0 // indirect
+	golang.org/x/net v0.19.0 // indirect
+	golang.org/x/sys v0.15.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
 	gomodules.xyz/jsonpatch/v3 v3.0.1 // indirect
 	gomodules.xyz/orderedmap v0.1.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	k8s.io/api v0.25.11 // indirect
 	k8s.io/client-go v0.25.5 // indirect
-	k8s.io/klog/v2 v2.90.1 // indirect
-	k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
+	k8s.io/klog/v2 v2.100.1 // indirect
+	k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect
diff --git a/manifest/test/acceptance/testdata/ComputedFields/webhook/go.sum b/manifest/test/acceptance/testdata/ComputedFields/webhook/go.sum
index 50ce5c6d..628517d2 100644
--- a/manifest/test/acceptance/testdata/ComputedFields/webhook/go.sum
+++ b/manifest/test/acceptance/testdata/ComputedFields/webhook/go.sum
@@ -5,8 +5,8 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
 github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
 github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@@ -39,8 +39,8 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -52,8 +52,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
+golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -61,12 +61,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -92,14 +92,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 k8s.io/api v0.25.11 h1:4mjYDfE3yp22jrytjH0knwgzjXKkxHX4D01ZCAazvZM=
 k8s.io/api v0.25.11/go.mod h1:bK4UvD4bthtutNlvensrfBX21PRQ/vs2cIYggHkOOAo=
-k8s.io/apimachinery v0.27.7 h1:Gxgtb7Y/Rsu8ymgmUEaiErkxa6RY4oTd8kNUI6SUR58=
-k8s.io/apimachinery v0.27.7/go.mod h1:jBGQgTjkw99ef6q5hv1YurDd3BqKDk9YRxmX0Ozo0i8=
+k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0=
+k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA=
 k8s.io/client-go v0.25.5 h1:7QWVK0Ph4bLn0UwotPTc2FTgm8shreQXyvXnnHDd8rE=
 k8s.io/client-go v0.25.5/go.mod h1:bOeoaUUdpyz3WDFGo+Xm3nOQFh2KuYXRDwrvbAPtFQA=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
 sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
diff --git a/manifest/test/acceptance/testdata/DataSourceResources/pods_data_source.tf b/manifest/test/acceptance/testdata/DataSourceResources/pods_data_source.tf
new file mode 100644
index 00000000..c420c2f4
--- /dev/null
+++ b/manifest/test/acceptance/testdata/DataSourceResources/pods_data_source.tf
@@ -0,0 +1,8 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+data "kubernetes_resources" "pods" {
+  kind        = "Pod"
+  api_version = "v1"
+  namespace   = var.namespace
+}
diff --git a/manifest/test/helper/kubernetes/kubernetes_helper.go b/manifest/test/helper/kubernetes/kubernetes_helper.go
index 8ddcb768..021bd0d8 100644
--- a/manifest/test/helper/kubernetes/kubernetes_helper.go
+++ b/manifest/test/helper/kubernetes/kubernetes_helper.go
@@ -12,7 +12,9 @@ import (
 	"log"
 	"testing"
 
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -23,8 +25,6 @@ import (
 	"k8s.io/client-go/tools/clientcmd"
 	k8sretry "k8s.io/client-go/util/retry"
 	"k8s.io/kubectl/pkg/scheme"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 // Helper is a Kubernetes dynamic client wrapped with a set of helper functions
@@ -119,6 +119,28 @@ func (k *Helper) CreateConfigMap(t *testing.T, name string, namespace string, da
 	}
 }
 
+// CreatePod creates a new Pod
+func (k *Helper) CreatePod(t *testing.T, name, namespace string, podSpec corev1.PodSpec) {
+	t.Helper()
+
+	pod := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": "v1",
+			"kind":       "Pod",
+			"metadata": map[string]interface{}{
+				"name":      name,
+				"namespace": namespace,
+			},
+			"spec": podSpec,
+		},
+	}
+	gvr := NewGroupVersionResource("v1", "pods")
+	_, err := k.dynClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), pod, metav1.CreateOptions{})
+	if err != nil {
+		t.Fatalf("Failed to create pod %q/%q: %v", namespace, name, err)
+	}
+}
+
 // DeleteResource deletes a resource referred to by the name and GVK
 func (k *Helper) DeleteResource(t *testing.T, name string, gvr schema.GroupVersionResource) {
 	t.Helper()