> For the complete documentation index, see [llms.txt](https://hossainemruz.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hossainemruz.gitbook.io/notes/kubernetes/untitled/patching-object/restrict-key.md).

# Restrict Key

## How to restrict patch from patching some specific key?

**Problem:**&#x20;

We want to patch an object but we don't want to allow to modify some fields of the object.

**Solution:**

Use `mergepatch.PreconditionFunc`.

What is `PreconditionFunc`?

`PreconditionFunc` asserts that an incompatible change is not present within a patch. It takes generated `patch` and return if either patch is allowed(`true`) or forbidden(`false`) based on key's existent on patch.

```go
type PreconditionFunc func(interface{}) bool
```

[mergepatch](https://github.com/kubernetes/apimachinery/tree/master/pkg/util/mergepatch/util.go) library has two helper function that return `PreconditionFunc`

```go
// RequireKeyUnchanged returns a precondition function that fails if the provided key
// is present in the patch (indicating that its value has changed).
func RequireKeyUnchanged(key string) PreconditionFunc {
	return func(patch interface{}) bool {
		patchMap, ok := patch.(map[string]interface{})
		if !ok {
			return true
		}

		// The presence of key means that its value has been changed, so the test fails.
		_, ok = patchMap[key]
		return !ok
	}
}
```

and

```go
// RequireMetadataKeyUnchanged creates a precondition function that fails
// if the metadata.key is present in the patch (indicating its value
// has changed).
func RequireMetadataKeyUnchanged(key string) PreconditionFunc {
	return func(patch interface{}) bool {
		patchMap, ok := patch.(map[string]interface{})
		if !ok {
			return true
		}
		patchMap1, ok := patchMap["metadata"]
		if !ok {
			return true
		}
		patchMap2, ok := patchMap1.(map[string]interface{})
		if !ok {
			return true
		}
		_, ok = patchMap2[key]
		return !ok
	}
}
```

**Using the above `PreconditonFunc` in** [strategicpatch](https://github.com/kubernetes/apimachinery/tree/master/pkg/util/strategicpatch)

```go
preconditions := []mergepatch.PreconditionFunc{
		mergepatch.RequireKeyUnchanged("apiVersion"),
		mergepatch.RequireMetadataKeyUnchanged("name"),
	}
```

**Creating Custom `PreconditionFunc` for** [jsonpatch](https://github.com/hossainemruz/notebook/blob/master/cloud/kubernetes/github.com/evanphx/json-patch)

```go
patch, err := jsonpatch.CreateMergePatch(curJson, modJson)
if err != nil {
    return nil, err
}
if err := meetPreconditions(patch, preconditions...); err != nil {
    return nil, err
}
```

```go
func meetPreconditions(patch []byte, fns ...mergepatch.PreconditionFunc) error {
    var patchMap map[string]interface{}
    if err := json.Unmarshal(patch, &patchMap); err != nil {
        return fmt.Errorf("failed to unmarshal patch for precondition check: %s", patch)
    }

    for _, fn := range fns {
        if !fn(patchMap) {
            return mergepatch.NewErrPreconditionFailed(patchMap)
        }
    }
    return nil
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hossainemruz.gitbook.io/notes/kubernetes/untitled/patching-object/restrict-key.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
