<p>I need to update a secret with specific value,(the secret contain additional data) my question is how I can update just the value and not all the secret data (I don't want to override the existing data). I mean if the secret have additional values I don’t want to override them just the entry <code>foo</code></p>
<pre><code>updSec := v1.Secret{
    TypeMeta: metav1.TypeMeta{},
    ObjectMeta: metav1.ObjectMeta{
        Name:      &quot;d-values&quot;,
        Namespace: &quot;terv”,
    },
    Immutable:  nil,
    Data:       nil,
    StringData: nil,
    Type:       &quot;Opaque&quot;,
}
updSec.Data[“foo”] = newVal
if err := r.Client.Update(ctx, &amp;updSec); err != nil {
    return ctrl.Result{}, err
}
</code></pre>
<p>The issue is that the secret is already exist and here im creating new object and not sure how to do it right ...I need for secret that called <code>d-values</code> just update the <code>newVal</code> for key <code>foo</code></p>
<p><strong>update</strong></p>
<p>when trying the code in the answer after I run the</p>
<p>patch, err := yaml.Marshal(updSec)
the data looks like following
and the patch are failed with error, any idea if its related ?</p>
<p>if I try with the c.Client.Update it works but not with <code>Patch</code> but the Patch is the right way as if I've ties before is should keep them..</p>
<p><a href="https://i.stack.imgur.com/De5zu.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/De5zu.png" alt="enter image description here" /></a></p>

tj holwik
<p>I don't think you can update a single key using the <code>Update</code> method, but you can certainly do that using <code>Patch</code> instead. Here's an example that uses a StrategicMergePatch; it will replace the key <code>val2</code> in a secret with the value <code>newval</code>:</p>
<pre class="lang-golang prettyprint-override"><code>package main

import (
  &quot;context&quot;
  &quot;encoding/json&quot;
  &quot;flag&quot;
  &quot;fmt&quot;
  &quot;path/filepath&quot;

  v1 &quot;k8s.io/api/core/v1&quot;
  metav1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
  &quot;k8s.io/apimachinery/pkg/types&quot;
  &quot;k8s.io/client-go/kubernetes&quot;
  &quot;k8s.io/client-go/tools/clientcmd&quot;
  &quot;k8s.io/client-go/util/homedir&quot;
)

func main() {
  var kubeconfig *string
  var namespace *string
  var secretname *string

  namespace = flag.String(&quot;namespace&quot;, &quot;&quot;, &quot;namespace of secret&quot;)
  secretname = flag.String(&quot;name&quot;, &quot;&quot;, &quot;name of secret&quot;)

  if home := homedir.HomeDir(); home != &quot;&quot; {
    kubeconfig = flag.String(&quot;kubeconfig&quot;, filepath.Join(home, &quot;.kube&quot;, &quot;config&quot;), &quot;(optional) absolute path to the kubeconfig file&quot;)
  } else {
    kubeconfig = flag.String(&quot;kubeconfig&quot;, &quot;&quot;, &quot;absolute path to the kubeconfig file&quot;)
  }

  flag.Parse()

  if *namespace == &quot;&quot; {
    panic(fmt.Errorf(&quot;you must specify a namespace&quot;))
  }

  if *secretname == &quot;&quot; {
    panic(fmt.Errorf(&quot;you must specify a secret name&quot;))
  }

  config, err := clientcmd.BuildConfigFromFlags(&quot;&quot;, *kubeconfig)
  if err != nil {
    panic(err)
  }

  clientset, err := kubernetes.NewForConfig(config)
  if err != nil {
    panic(err)
  }

  secretClient := clientset.CoreV1().Secrets(*namespace)
  ctx := context.TODO()

  updSec := v1.Secret{
    Data: map[string][]byte{
      &quot;val2&quot;: []byte(&quot;newval&quot;),
    },
  }

  payloadBytes, err := json.Marshal(updSec)
  if err != nil {
    panic(err)
  }

  if _, err = secretClient.Patch(ctx, *secretname,
    types.StrategicMergePatchType, payloadBytes, metav1.PatchOptions{}); err != nil {
    panic(err)
  }

  // Fetch updated secret
  sec, err := secretClient.Get(ctx, *secretname, metav1.GetOptions{})
  if err != nil {
    panic(err)
  }
  secJson, err := json.MarshalIndent(sec, &quot;&quot;, &quot;  &quot;)
  if err != nil {
    panic(err)
  }

  fmt.Print(string(secJson))
}
</code></pre>
<p>For example, if I create a secret like this:</p>
<pre><code>kubectl create secret generic \
  --from-literal val1=key1 \
  --from-literal val2=key2 example
</code></pre>
<p>And then run the above code like this:</p>
<pre><code>go run main.go -namespace default -name example
</code></pre>
<p>The code will output the update secret. Looking at the <code>data</code> section, we see:</p>
<pre><code>  &quot;data&quot;: {
    &quot;val1&quot;: &quot;a2V5MQ==&quot;,
    &quot;val2&quot;: &quot;bmV3dmFs&quot;
  },
</code></pre>
<p>And if we decode <code>val2</code> we see:</p>
<pre><code>$ kubectl get secret example -o json | jq '.data.val2|@base64d'
&quot;newval&quot;
</code></pre>
<h2>Using the Operator SDK</h2>
<p>If you're working with the Operator SDK, you can use <code>Update</code> if you're first reading the existing value, like this:</p>
<pre><code>  // Read the existing secret
  secret := &amp;corev1.Secret{}
  if err := r.Get(ctx, req.NamespacedName, secret); err != nil {
    panic(err)
  }

  // Check if it needs to be modified
  val, ok := secret.Data[&quot;val2&quot;]

  // If yes, update the secret with a new value and then write
  // the entire object back with Update
  if !ok || !bytes.Equal(val, []byte(&quot;val2&quot;)) {
    ctxlog.Info(&quot;needs update&quot;, &quot;secret&quot;, secret)
    secret.Data[&quot;val2&quot;] = []byte(&quot;newval&quot;)
    if err := r.Update(ctx, secret); err != nil {
      panic(err)
    }
  }
</code></pre>
<p>You can use the <code>Patch</code> method if you only want to submit a partial update:</p>
<pre><code>  if !ok || !bytes.Equal(val, []byte(&quot;val2&quot;)) {
    ctxlog.Info(&quot;needs update&quot;, &quot;secret&quot;, secret)
    newVal := corev1.Secret{
      Data: map[string][]byte{
        &quot;val2&quot;: []byte(&quot;newval&quot;),
      },
    }

    patch, err := json.Marshal(newVal)
    if err != nil {
      panic(err)
    }

    if err := r.Client.Patch(ctx, secret, client.RawPatch(types.StrategicMergePatchType, patch)); err != nil {
      panic(err)
    }
  }
</code></pre>
<p>This is pretty much identical to the earlier example. There are examples of using the client.Patch method <a href="https://v0-18-x.sdk.operatorframework.io/docs/golang/references/client/#patch" rel="nofollow noreferrer">in the docs</a>, but I'll be honest, I don't find the example very clear.</p>
