Ignored YAML tag - go

I have config.yml file:
vcenter:
connection: https
hostname: vcenter.mydomain.lan
username: readonlyauto#vsphere.local
password: mypasspord
port: 443
EsxiExcludeDatastores:
- datastore1
- datastore2
EsxiExcludeDatastores2:
datastores:
- datastore1
- datastore2
I'm trying to parse it with "gopkg.in/yaml.v2"
I created struct:
type FileConfig struct {
Vcenter struct {
ConnectionType string `yaml:"connection"`
Hostname string `yaml:"hostname"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Port int `yaml:"port"`
} `yaml:"vcenter"`
EsxiExcludeDatastores struct {
Datastores []string `yaml:"EsxiExcludeDatastores"`
}
EsxiExcludeDatastores2 struct {
Datastores []string `yaml:"datastores"`
} `yaml:"EsxiExcludeDatastores2"`
}
var AppConfig FileConfig
After parsing, I print results:
fmt.Println("Num of EsxiExcludeDatastores.Datastores = ", len(AppConfig.EsxiExcludeDatastores.Datastores))
fmt.Println("Num of EsxiExcludeDatastores2.Datastores = ", len(AppConfig.EsxiExcludeDatastores2.Datastores))
Num of EsxiExcludeDatastores.Datastores = 0
Num of EsxiExcludeDatastores2.Datastores = 2
Can you help me, where I did mistake in EsxiExcludeDatastores struct? As you see, everything is fine with EsxiExcludeDatastores2, but EsxiExcludeDatastores is empty.
I tried to do this in different ways, but with no result ...

You're almost there.
To "promote" yaml struct tag(s) to the "parent" field, add:
EsxiExcludeDatastores struct {
Datastores []string `yaml:"EsxiExcludeDatastores"`
} `yaml:",inline"` // <- this
https://play.golang.org/p/S7QxGaspTyN
From the yaml.v2 docs, a struct tag that uses the inline flag does the following:
Inline the field, which must be a struct or a map, causing all of its
fields or keys to be processed as if they were part of the outer
struct. For maps, keys must not conflict with the yaml keys of other
struct fields.

Related

golang: declaring a camelcase in a struct declaration

I'm trying to read a yaml file via golang.
But the "matchLabels" sub-struct is not being recognized
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test
spec:
replicas: 3
selector:
matchLabels:
app: web
struct
type myData struct {
Apivesion string `yaml:"apiVersion"`
Kind string
Metadata struct {
Name string
Labels struct {
App string
}
}
Spec struct {
Replicas int64
Selector struct {
Matchlabels struct {
App string
}
}
}
}
Expectation
&{apps/v1 Deployment {nginx-deploy {test}} {3 {{web}}}}
Result
&{apps/v1 Deployment {nginx-deploy {test}} {3 {{}}}}
Fix didn't work:
Matchlabels struct `yaml:"matchLabels"` {
Cerise Limón gave the answer in a comment:
Field tags follow the type:
Matchlabels struct { App string }
`yaml:"matchLabels"`
I don't think you implemented the suggested answer correctly, see where the tag is:
type myData struct {
Apivesion string `yaml:"apiVersion"`
Kind string
Metadata struct {
Name string
Labels struct {
App string
}
}
Spec struct {
Replicas int64
Selector struct {
Matchlabels struct {
App string
} `yaml:"matchLabels"`
}
}
}
See also: https://go.dev/play/p/yd9c-iBz2yL
type AutoGenerated struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata struct {
Name string `yaml:"name"`
Labels struct {
App string `yaml:"app"`
} `yaml:"labels"`
} `yaml:"metadata"`
Spec struct {
Replicas int `yaml:"replicas"`
Selector struct {
MatchLabels struct {
App string `yaml:"app"`
} `yaml:"matchLabels"`
} `yaml:"selector"`
} `yaml:"spec"`
}
You can use this tool, it is really helpful:
https://zhwt.github.io/yaml-to-go/

Go Testing define custom structure

I've followed the structure in a tf file, can you help me to create a proper structure, as I'm new to Go.
Here is tf
ipv4 = {
cidrblock = "10.0.0.0/16"
secondary = [
{
cidrs = "20.0.0.0/16"
enabled = true
},
{
cidrs = "30.0.0.0/16"
enabled = true
}
]
}
So I've an object of strings, as well a list of objects in the main object. I could make a primitive type, for example:
type ipv4 struct {
cidrblock string
cidrs string
enabled bool
}
type ipv6 struct {
border string
generate bool
}
type Sets struct {
Name string
IPv4 *ipv4
IPv6 *ipv6
Tags map[string]string
Tenancy string
}
But I would really like to have a complex structure
you can do something like this:
type ipv4 struct {
cidrblock string
secondary []ipv4secondary
}
type ipv4secondary struct {
cidrblock string
enabled bool
}
and use it as this:
example := ipv4{
cidrblock: "10.0.0.0/16",
secondary: []ipv4secondary{
ipv4secondary{cidrblock: "20.0.0.0/16", enabled: true},
ipv4secondary{cidrblock: "30.0.0.0/16", enabled: true},
},
}
here is the example: https://go.dev/play/p/U7o0BbAis9T

In golang, nested structures are not encoding into httpresponse

In my golang code, I use net/http and gorilla mux.
In the function below, when I encode the nested structure variable, the http response shows blank "{}". However, if I encode only one of the non-nested struct's they show up ok.
Can you please help how I can send the nested-structure in http-response? Thank you
func getNestedStruct(w http.ResponseWriter, r *http.Request) {
type User1 struct {
ID int `json:"Id1"`
Email string `json:"Email1"`
Password string `json:"Password1"`
}
type User2 struct {
ID int `json:"Id2"`
Email string `json:"Email2"`
}
type Users struct {
MyUser1 User1 `json:"User1"`
MyUser2 User2 `json:"User1"`
}
var myUser1 User1
var myUser2 User2
var myUsers Users
myUser1.ID = 1
myUser1.Email = "user1#email.com"
myUser1.Password = "user1"
myUser2.ID = 2
myUser2.Email = "user2#email.com"
myUsers.MyUser1 = myUser1
myUsers.MyUser2 = myUser2
// these print without issues
log.Printf("getNestedStruct: Struct User1: ", myUser1)
log.Printf("getNestedStruct: Struct User2: ", myUser2)
log.Printf("getNestedStruct: Nested Struct Users: ", myUsers)
// This does not work --> shows {} in http response
json.NewEncoder(w).Encode(myUsers)
// This works:
//json.NewEncoder(w).Encode(myUser1)
}
MyUser1 & MyUser2 both have the same JSON key. Giving different keys should work
type Users struct {
MyUser1 User1 `json:"User1"`
MyUser2 User2 `json:"User2"`
}

Golang - Missing expression error on structs

type Old struct {
UserID int `json:"user_ID"`
Data struct {
Address string `json:"address"`
} `json:"old_data"`
}
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: { // from here it says missing expression
Address: old.Data.Address,
},
}
}
What is "missing expression" error when using structs?
I am transforming old object to a new one. I minified them just to get straight to the point but the transformation is much more complex. The UserID field for example works great. But when I use struct (which intended to be a JSON object in the end) the Goland IDE screams "missing expression" and the compiler says "missing type in composite literal" on this line. What I am doing wrong? Maybe should I use something else instead of struct? Please help.
Data is an anonymous struct, so you need to write it like this:
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
(playground link)
I think it'd be cleanest to create a named Address struct.
You're defining Data as an inline struct. When assigning values to it, you must first put the inline declaration:
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
Hence it is generally better to define a separate type for Data, just like User.

Go create struct from XML

Please see this playground: https://play.golang.org/p/FOMWqhjdneg
As you can see I have a XML response which I want to unmarshal into a Product struct. The XML has an "assetBlock" which contains nested nodes and extract data to Product struct. Any help would be appreciated
You need to make a struct for AssetBlock and all of the types below it, I've done it up to group to show you what I mean:
https://play.golang.org/p/vj_CkneHuLd
type Product struct {
GlobalID string `xml:"globalId"`
Title string `xml:"title"`
ChunkID int `xml:"gpcChunkId"`
AssetBlock assetBlock `xml:"assetBlock"`
}
type assetBlock struct {
Images images `xml:"images"`
}
type images struct {
GroupList groupList `xml:"groupList"`
}
type groupList struct {
Groups []group `xml:"group"`
}
type group struct {
Usage string `xml:"usage"`
Size string `xml:"size"`
}

Resources