File: locality.go

package info (click to toggle)
golang-github-scaleway-scaleway-sdk-go 1.0.0~beta12-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,000 kB
  • sloc: javascript: 160; sh: 70; makefile: 3
file content (215 lines) | stat: -rw-r--r-- 5,479 bytes parent folder | download
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package scw

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/scaleway/scaleway-sdk-go/internal/errors"
	"github.com/scaleway/scaleway-sdk-go/logger"
	"github.com/scaleway/scaleway-sdk-go/validation"
)

// localityPartsSeparator is the separator used in Zone and Region
const localityPartsSeparator = "-"

// Zone is an availability zone
type Zone string

const (
	// ZoneFrPar1 represents the fr-par-1 zone
	ZoneFrPar1 = Zone("fr-par-1")
	// ZoneFrPar2 represents the fr-par-2 zone
	ZoneFrPar2 = Zone("fr-par-2")
	// ZoneFrPar3 represents the fr-par-3 zone
	ZoneFrPar3 = Zone("fr-par-3")
	// ZoneNlAms1 represents the nl-ams-1 zone
	ZoneNlAms1 = Zone("nl-ams-1")
	// ZoneNlAms2 represents the nl-ams-2 zone
	ZoneNlAms2 = Zone("nl-ams-2")
	// ZonePlWaw1 represents the pl-waw-1 zone
	ZonePlWaw1 = Zone("pl-waw-1")
	// ZonePlWaw2 represents the pl-waw-2 zone
	ZonePlWaw2 = Zone("pl-waw-2")
)

var (
	// AllZones is an array that list all zones
	AllZones = []Zone{
		ZoneFrPar1,
		ZoneFrPar2,
		ZoneFrPar3,
		ZoneNlAms1,
		ZoneNlAms2,
		ZonePlWaw1,
		ZonePlWaw2,
	}
)

// Exists checks whether a zone exists
func (zone Zone) Exists() bool {
	for _, z := range AllZones {
		if z == zone {
			return true
		}
	}
	return false
}

// String returns a Zone as a string
func (zone Zone) String() string {
	return string(zone)
}

// Region returns the parent Region for the Zone.
// Manipulates the string directly to allow unlisted zones formatted as xx-yyy-z.
func (zone Zone) Region() (Region, error) {
	zoneStr := zone.String()
	if !validation.IsZone(zoneStr) {
		return "", fmt.Errorf("invalid zone '%v'", zoneStr)
	}
	zoneParts := strings.Split(zoneStr, localityPartsSeparator)
	return Region(strings.Join(zoneParts[:2], localityPartsSeparator)), nil
}

// Region is a geographical location
type Region string

const (
	// RegionFrPar represents the fr-par region
	RegionFrPar = Region("fr-par")
	// RegionNlAms represents the nl-ams region
	RegionNlAms = Region("nl-ams")
	// RegionPlWaw represents the pl-waw region
	RegionPlWaw = Region("pl-waw")
)

var (
	// AllRegions is an array that list all regions
	AllRegions = []Region{
		RegionFrPar,
		RegionNlAms,
		RegionPlWaw,
	}
)

// Exists checks whether a region exists
func (region Region) Exists() bool {
	for _, r := range AllRegions {
		if r == region {
			return true
		}
	}
	return false
}

// GetZones is a function that returns the zones for the specified region
func (region Region) GetZones() []Zone {
	switch region {
	case RegionFrPar:
		return []Zone{ZoneFrPar1, ZoneFrPar2, ZoneFrPar3}
	case RegionNlAms:
		return []Zone{ZoneNlAms1, ZoneNlAms2}
	case RegionPlWaw:
		return []Zone{ZonePlWaw1, ZonePlWaw2}
	default:
		return []Zone{}
	}
}

// ParseZone parses a string value into a Zone and returns an error if it has a bad format.
func ParseZone(zone string) (Zone, error) {
	switch zone {
	case "par1":
		// would be triggered by API market place
		// logger.Warningf("par1 is a deprecated name for zone, use fr-par-1 instead")
		return ZoneFrPar1, nil
	case "ams1":
		// would be triggered by API market place
		// logger.Warningf("ams1 is a deprecated name for zone, use nl-ams-1 instead")
		return ZoneNlAms1, nil
	default:
		if !validation.IsZone(zone) {
			zones := []string(nil)
			for _, z := range AllZones {
				zones = append(zones, string(z))
			}
			return "", errors.New("bad zone format, available zones are: %s", strings.Join(zones, ", "))
		}

		newZone := Zone(zone)
		if !newZone.Exists() {
			logger.Infof("%s is an unknown zone\n", newZone)
		}
		return newZone, nil
	}
}

// UnmarshalJSON implements the Unmarshaler interface for a Zone.
// this to call ParseZone on the string input and return the correct Zone object.
func (zone *Zone) UnmarshalJSON(input []byte) error {
	// parse input value as string
	var stringValue string
	err := json.Unmarshal(input, &stringValue)
	if err != nil {
		return err
	}

	// parse string as Zone
	*zone, err = ParseZone(stringValue)
	if err != nil {
		return err
	}
	return nil
}

// ParseRegion parses a string value into a Region and returns an error if it has a bad format.
func ParseRegion(region string) (Region, error) {
	switch region {
	case "par1":
		// would be triggered by API market place
		// logger.Warningf("par1 is a deprecated name for region, use fr-par instead")
		return RegionFrPar, nil
	case "ams1":
		// would be triggered by API market place
		// logger.Warningf("ams1 is a deprecated name for region, use nl-ams instead")
		return RegionNlAms, nil
	default:
		if !validation.IsRegion(region) {
			regions := []string(nil)
			for _, r := range AllRegions {
				regions = append(regions, string(r))
			}
			return "", errors.New("bad region format, available regions are: %s", strings.Join(regions, ", "))
		}

		newRegion := Region(region)
		if !newRegion.Exists() {
			logger.Infof("%s is an unknown region\n", newRegion)
		}
		return newRegion, nil
	}
}

// UnmarshalJSON implements the Unmarshaler interface for a Region.
// this to call ParseRegion on the string input and return the correct Region object.
func (region *Region) UnmarshalJSON(input []byte) error {
	// parse input value as string
	var stringValue string
	err := json.Unmarshal(input, &stringValue)
	if err != nil {
		return err
	}

	// parse string as Region
	*region, err = ParseRegion(stringValue)
	if err != nil {
		return err
	}
	return nil
}

// String returns a Region as a string
func (region Region) String() string {
	return string(region)
}