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)
}
|