blob: 6f10cb4e2bdab836aa5de4df5771dd6deccbe3ec [file] [log] [blame]
David K. Bainbridge528b3182017-01-23 08:51:59 -08001// Copyright 2016 Canonical Ltd.
2// Licensed under the LGPLv3, see LICENCE file for details.
3
4package gomaasapi
5
6import (
7 "github.com/juju/errors"
8 "github.com/juju/schema"
9 "github.com/juju/version"
10)
11
12type zone struct {
13 // Add the controller in when we need to do things with the zone.
14 // controller Controller
15
16 resourceURI string
17
18 name string
19 description string
20}
21
22// Name implements Zone.
23func (z *zone) Name() string {
24 return z.name
25}
26
27// Description implements Zone.
28func (z *zone) Description() string {
29 return z.description
30}
31
32func readZones(controllerVersion version.Number, source interface{}) ([]*zone, error) {
33 checker := schema.List(schema.StringMap(schema.Any()))
34 coerced, err := checker.Coerce(source, nil)
35 if err != nil {
36 return nil, errors.Annotatef(err, "zone base schema check failed")
37 }
38 valid := coerced.([]interface{})
39
40 var deserialisationVersion version.Number
41 for v := range zoneDeserializationFuncs {
42 if v.Compare(deserialisationVersion) > 0 && v.Compare(controllerVersion) <= 0 {
43 deserialisationVersion = v
44 }
45 }
46 if deserialisationVersion == version.Zero {
47 return nil, errors.Errorf("no zone read func for version %s", controllerVersion)
48 }
49 readFunc := zoneDeserializationFuncs[deserialisationVersion]
50 return readZoneList(valid, readFunc)
51}
52
53// readZoneList expects the values of the sourceList to be string maps.
54func readZoneList(sourceList []interface{}, readFunc zoneDeserializationFunc) ([]*zone, error) {
55 result := make([]*zone, 0, len(sourceList))
56 for i, value := range sourceList {
57 source, ok := value.(map[string]interface{})
58 if !ok {
59 return nil, errors.Errorf("unexpected value for zone %d, %T", i, value)
60 }
61 zone, err := readFunc(source)
62 if err != nil {
63 return nil, errors.Annotatef(err, "zone %d", i)
64 }
65 result = append(result, zone)
66 }
67 return result, nil
68}
69
70type zoneDeserializationFunc func(map[string]interface{}) (*zone, error)
71
72var zoneDeserializationFuncs = map[version.Number]zoneDeserializationFunc{
73 twoDotOh: zone_2_0,
74}
75
76func zone_2_0(source map[string]interface{}) (*zone, error) {
77 fields := schema.Fields{
78 "name": schema.String(),
79 "description": schema.String(),
80 "resource_uri": schema.String(),
81 }
82 checker := schema.FieldMap(fields, nil) // no defaults
83 coerced, err := checker.Coerce(source, nil)
84 if err != nil {
85 return nil, errors.Annotatef(err, "zone 2.0 schema check failed")
86 }
87 valid := coerced.(map[string]interface{})
88 // From here we know that the map returned from the schema coercion
89 // contains fields of the right type.
90
91 result := &zone{
92 name: valid["name"].(string),
93 description: valid["description"].(string),
94 resourceURI: valid["resource_uri"].(string),
95 }
96 return result, nil
97}