-
Notifications
You must be signed in to change notification settings - Fork 36
/
vlan.go
154 lines (131 loc) · 3.96 KB
/
vlan.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2016 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package gomaasapi
import (
"github.com/juju/errors"
"github.com/juju/schema"
"github.com/juju/version"
)
type vlan struct {
// Add the controller in when we need to do things with the vlan.
// controller Controller
resourceURI string
id int
name string
fabric string
vid int
mtu int
dhcp bool
primaryRack string
secondaryRack string
}
// ID implements VLAN.
func (v *vlan) ID() int {
return v.id
}
// Name implements VLAN.
func (v *vlan) Name() string {
return v.name
}
// Fabric implements VLAN.
func (v *vlan) Fabric() string {
return v.fabric
}
// VID implements VLAN.
func (v *vlan) VID() int {
return v.vid
}
// MTU implements VLAN.
func (v *vlan) MTU() int {
return v.mtu
}
// DHCP implements VLAN.
func (v *vlan) DHCP() bool {
return v.dhcp
}
// PrimaryRack implements VLAN.
func (v *vlan) PrimaryRack() string {
return v.primaryRack
}
// SecondaryRack implements VLAN.
func (v *vlan) SecondaryRack() string {
return v.secondaryRack
}
func readVLANs(controllerVersion version.Number, source interface{}) ([]*vlan, error) {
checker := schema.List(schema.StringMap(schema.Any()))
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "vlan base schema check failed")
}
valid := coerced.([]interface{})
var deserialisationVersion version.Number
for v := range vlanDeserializationFuncs {
if v.Compare(deserialisationVersion) > 0 && v.Compare(controllerVersion) <= 0 {
deserialisationVersion = v
}
}
if deserialisationVersion == version.Zero {
return nil, errors.Errorf("no vlan read func for version %s", controllerVersion)
}
readFunc := vlanDeserializationFuncs[deserialisationVersion]
return readVLANList(valid, readFunc)
}
func readVLANList(sourceList []interface{}, readFunc vlanDeserializationFunc) ([]*vlan, error) {
result := make([]*vlan, 0, len(sourceList))
for i, value := range sourceList {
source, ok := value.(map[string]interface{})
if !ok {
return nil, errors.Errorf("unexpected value for vlan %d, %T", i, value)
}
vlan, err := readFunc(source)
if err != nil {
return nil, errors.Annotatef(err, "vlan %d", i)
}
result = append(result, vlan)
}
return result, nil
}
type vlanDeserializationFunc func(map[string]interface{}) (*vlan, error)
var vlanDeserializationFuncs = map[version.Number]vlanDeserializationFunc{
twoDotOh: vlan_2_0,
}
func vlan_2_0(source map[string]interface{}) (*vlan, error) {
fields := schema.Fields{
"id": schema.ForceInt(),
"resource_uri": schema.String(),
"name": schema.OneOf(schema.Nil(""), schema.String()),
"fabric": schema.String(),
"vid": schema.ForceInt(),
"mtu": schema.ForceInt(),
"dhcp_on": schema.Bool(),
// racks are not always set.
"primary_rack": schema.OneOf(schema.Nil(""), schema.String()),
"secondary_rack": schema.OneOf(schema.Nil(""), schema.String()),
}
checker := schema.FieldMap(fields, nil)
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "vlan 2.0 schema check failed")
}
valid := coerced.(map[string]interface{})
// From here we know that the map returned from the schema coercion
// contains fields of the right type.
// Since the primary and secondary racks are optional, we use the two
// part cast assignment. If the case fails, then we get the default value
// we care about, which is the empty string.
primary_rack, _ := valid["primary_rack"].(string)
secondary_rack, _ := valid["secondary_rack"].(string)
name, _ := valid["name"].(string)
result := &vlan{
resourceURI: valid["resource_uri"].(string),
id: valid["id"].(int),
name: name,
fabric: valid["fabric"].(string),
vid: valid["vid"].(int),
mtu: valid["mtu"].(int),
dhcp: valid["dhcp_on"].(bool),
primaryRack: primary_rack,
secondaryRack: secondary_rack,
}
return result, nil
}