go

how to convert generic types to go map


I am trying to work with vault sdk. I am reading the keys saved in this secret path as follows:

secret, err := v.client.Secrets.KvV2Read(ctx, secretPath, vaultClient.WithMountPath(mPath))

But when I am trying to get a specific key of it like this:

value, ok := secret.Data[secretKey]

I get this error.

Invalid operation: 'secret.Data[secretKey]' (type 'T' does not support indexing)

I know I can marshal and unmarshal the secretData as follows to convert it to a map[string]interface{}:

var mapData map[string]interface{}

inrec, err := json.Marshal(secret.Data)
if err != nil {
    return "", fmt.Errorf("unable to marshal secret: %v", err)
}

if err := json.Unmarshal(inrec, &mapData); err != nil {
    return "", fmt.Errorf("unable to unmarshal secret: %v", err)
}

But is there any better way to do this conversion?

I have tried marshal/unmarshal in order to do the conversion and it worked. But I am searching for a more efficient way.


Solution

  • secret.Data is not a map[string]interface{}, it's a struct.

    The actual key-value pairs you're trying to access are in secret.Data.Data.

    You can directly index into the inner Data field, instead of trying to assert or marshal:

    value, ok := secret.Data.Data[secretKey]
    
    if !ok {
        return "", fmt.Errorf("key %q not found in secret data", secretKey)
    }
    

    This kinda avoids the unnecessary marshaling and unmarshaling.