df36329238
This commit migrates kuryr_cni to use go mod and updates its Dockerfile. Closes-Bug: #1922235 Change-Id: If8b7c0350c0dcfd3de2735aff2efe9c86bbd4e58
121 lines
2.8 KiB
Go
121 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
)
|
|
|
|
const (
|
|
vod = "versioned_object.data"
|
|
ob = "objects"
|
|
)
|
|
|
|
type VIF struct {
|
|
Network Network `json:"network"`
|
|
Address string `json:"address"`
|
|
VifName string `json:"vif_name"`
|
|
}
|
|
|
|
type Network struct {
|
|
Subnets []Subnet `json:"subnets"`
|
|
}
|
|
|
|
type Route struct {
|
|
Cidr string `json:"cidr"`
|
|
Gateway string `json:"gateway"`
|
|
}
|
|
|
|
type IP struct {
|
|
Address string `json:"address"`
|
|
}
|
|
|
|
type Subnet struct {
|
|
Routes []Route `json:"routes"`
|
|
Ips []IP `json:"ips"`
|
|
Cidr string `json:"cidr"`
|
|
Gateway string `json:"gateway"`
|
|
DNS []string `json:"dns"`
|
|
}
|
|
|
|
func UnmarshalOVO(data []byte, r interface{}) error {
|
|
// Unmarshall into a generic map
|
|
var i map[string]interface{}
|
|
if err := json.Unmarshal(data, &i); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Skip versioned_object.data level
|
|
d := i[vod].(map[string]interface{})
|
|
|
|
p := reflect.ValueOf(r) // this will be a pointer
|
|
v := p.Elem() // dereferences pointer
|
|
t := v.Type() // gets type of the struct
|
|
|
|
// Go over fields of the struct
|
|
for i := 0; i < t.NumField(); i++ {
|
|
// Initial info
|
|
field := t.Field(i)
|
|
fieldVal := v.Field(i)
|
|
key := field.Tag.Get("json")
|
|
|
|
var obj interface{}
|
|
|
|
// Main switch
|
|
switch fieldVal.Kind() {
|
|
case reflect.String:
|
|
// In case of string let's just write it and we're done (hence continue)
|
|
fieldVal.SetString(d[key].(string))
|
|
continue
|
|
case reflect.Slice:
|
|
if reflect.ValueOf(d[key]).Kind() != reflect.Slice {
|
|
// It's a list with next level of "versioned_object.data" and then "objects" keys. Let's flatten this.
|
|
listObj := d[key].(map[string]interface{})
|
|
listData := listObj[vod].(map[string]interface{})
|
|
obj = listData[ob].([]interface{})
|
|
break
|
|
}
|
|
// If we have a slice and d[key] is just a simple list, then struct's approach will work fine, that's
|
|
// why there's this fallthrough.
|
|
fallthrough
|
|
case reflect.Struct:
|
|
// Treat it as struct
|
|
obj = d[key]
|
|
}
|
|
|
|
// For slices and structs marshall that level of JSON, and unmarshall them into the result. The weird
|
|
// approach with reflect.New is forced by how reflections work in golang.
|
|
jsonBytes, err := json.Marshal(obj)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
new := reflect.New(fieldVal.Type())
|
|
inter := new.Interface()
|
|
if err := json.Unmarshal(jsonBytes, &inter); err != nil {
|
|
return err
|
|
}
|
|
fieldVal.Set(new.Elem())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *VIF) UnmarshalJSON(data []byte) error {
|
|
return UnmarshalOVO(data, v)
|
|
}
|
|
|
|
func (v *Network) UnmarshalJSON(data []byte) error {
|
|
return UnmarshalOVO(data, v)
|
|
}
|
|
|
|
func (v *Subnet) UnmarshalJSON(data []byte) error {
|
|
return UnmarshalOVO(data, v)
|
|
}
|
|
|
|
func (v *IP) UnmarshalJSON(data []byte) error {
|
|
return UnmarshalOVO(data, v)
|
|
}
|
|
|
|
func (v *Route) UnmarshalJSON(data []byte) error {
|
|
return UnmarshalOVO(data, v)
|
|
}
|