~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/gomaasapi/link.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the LGPLv3, see LICENCE file for details.
 
3
 
 
4
package gomaasapi
 
5
 
 
6
import (
 
7
        "github.com/juju/errors"
 
8
        "github.com/juju/schema"
 
9
        "github.com/juju/version"
 
10
)
 
11
 
 
12
type link struct {
 
13
        id        int
 
14
        mode      string
 
15
        subnet    *subnet
 
16
        ipAddress string
 
17
}
 
18
 
 
19
// NOTE: not using lowercase L as the receiver as it is a horrible idea.
 
20
// Instead using 'k'.
 
21
 
 
22
// ID implements Link.
 
23
func (k *link) ID() int {
 
24
        return k.id
 
25
}
 
26
 
 
27
// Mode implements Link.
 
28
func (k *link) Mode() string {
 
29
        return k.mode
 
30
}
 
31
 
 
32
// Subnet implements Link.
 
33
func (k *link) Subnet() Subnet {
 
34
        if k.subnet == nil {
 
35
                return nil
 
36
        }
 
37
        return k.subnet
 
38
}
 
39
 
 
40
// IPAddress implements Link.
 
41
func (k *link) IPAddress() string {
 
42
        return k.ipAddress
 
43
}
 
44
 
 
45
func readLinks(controllerVersion version.Number, source interface{}) ([]*link, error) {
 
46
        checker := schema.List(schema.StringMap(schema.Any()))
 
47
        coerced, err := checker.Coerce(source, nil)
 
48
        if err != nil {
 
49
                return nil, WrapWithDeserializationError(err, "link base schema check failed")
 
50
        }
 
51
        valid := coerced.([]interface{})
 
52
 
 
53
        var deserialisationVersion version.Number
 
54
        for v := range linkDeserializationFuncs {
 
55
                if v.Compare(deserialisationVersion) > 0 && v.Compare(controllerVersion) <= 0 {
 
56
                        deserialisationVersion = v
 
57
                }
 
58
        }
 
59
        if deserialisationVersion == version.Zero {
 
60
                return nil, NewUnsupportedVersionError("no link read func for version %s", controllerVersion)
 
61
        }
 
62
        readFunc := linkDeserializationFuncs[deserialisationVersion]
 
63
        return readLinkList(valid, readFunc)
 
64
}
 
65
 
 
66
// readLinkList expects the values of the sourceList to be string maps.
 
67
func readLinkList(sourceList []interface{}, readFunc linkDeserializationFunc) ([]*link, error) {
 
68
        result := make([]*link, 0, len(sourceList))
 
69
        for i, value := range sourceList {
 
70
                source, ok := value.(map[string]interface{})
 
71
                if !ok {
 
72
                        return nil, NewDeserializationError("unexpected value for link %d, %T", i, value)
 
73
                }
 
74
                link, err := readFunc(source)
 
75
                if err != nil {
 
76
                        return nil, errors.Annotatef(err, "link %d", i)
 
77
                }
 
78
                result = append(result, link)
 
79
        }
 
80
        return result, nil
 
81
}
 
82
 
 
83
type linkDeserializationFunc func(map[string]interface{}) (*link, error)
 
84
 
 
85
var linkDeserializationFuncs = map[version.Number]linkDeserializationFunc{
 
86
        twoDotOh: link_2_0,
 
87
}
 
88
 
 
89
func link_2_0(source map[string]interface{}) (*link, error) {
 
90
        fields := schema.Fields{
 
91
                "id":         schema.ForceInt(),
 
92
                "mode":       schema.String(),
 
93
                "subnet":     schema.StringMap(schema.Any()),
 
94
                "ip_address": schema.String(),
 
95
        }
 
96
        defaults := schema.Defaults{
 
97
                "ip_address": "",
 
98
                "subnet":     schema.Omit,
 
99
        }
 
100
        checker := schema.FieldMap(fields, defaults)
 
101
        coerced, err := checker.Coerce(source, nil)
 
102
        if err != nil {
 
103
                return nil, WrapWithDeserializationError(err, "link 2.0 schema check failed")
 
104
        }
 
105
        valid := coerced.(map[string]interface{})
 
106
        // From here we know that the map returned from the schema coercion
 
107
        // contains fields of the right type.
 
108
 
 
109
        var subnet *subnet
 
110
        if value, ok := valid["subnet"]; ok {
 
111
                subnet, err = subnet_2_0(value.(map[string]interface{}))
 
112
                if err != nil {
 
113
                        return nil, errors.Trace(err)
 
114
                }
 
115
        }
 
116
 
 
117
        result := &link{
 
118
                id:        valid["id"].(int),
 
119
                mode:      valid["mode"].(string),
 
120
                subnet:    subnet,
 
121
                ipAddress: valid["ip_address"].(string),
 
122
        }
 
123
        return result, nil
 
124
}