parametrize and check storage account type, location

This commit is contained in:
Dmitry Shmulevich 2018-09-13 13:36:18 -07:00
Родитель 257229739c
Коммит 0f16c7acdd
11 изменённых файлов: 168 добавлений и 143 удалений

Просмотреть файл

@ -104,7 +104,7 @@ func (gc *generateCmd) run() error {
log.Fatalf("failed to initialize template generator: %s", err.Error())
}
template, parameters, certsGenerated, err := templateGenerator.GenerateTemplate(gc.oe, engine.DefaultGeneratorCode, false)
template, parameters, certsGenerated, err := templateGenerator.GenerateTemplate(gc.oe, api.DefaultGeneratorCode, false)
if err != nil {
log.Fatalf("error generating template %s: %s", gc.apimodelPath, err.Error())
os.Exit(1)

Просмотреть файл

@ -61,15 +61,11 @@
"type": "string"
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Premium_LRS"
],
{{GetStorageAccountTypes}}
"metadata": {
"description": "Type of managed disk to create"
}
},
"type": "string"
},
"fqdnEndpointSuffix":{
"defaultValue": "cloudapp.azure.com",
@ -86,7 +82,8 @@
"type": "string"
},
"location": {
"defaultValue": "{{GetLocation}}",
"defaultValue": "[resourceGroup().location]",
{{GetAllowedLocations}}
"metadata": {
"description": "Sets the location for all resources in the cluster"
},

Просмотреть файл

@ -1,5 +1,10 @@
package api
import (
"fmt"
"strings"
)
const (
OsUbuntu1604 = "UbuntuServer_16.04"
OsWindows2016 = "WindowsServer_2016"
@ -7,7 +12,20 @@ const (
OsImageDefault = OsUbuntu1604
)
// OSImage represent Azure OS Image
const (
// DefaultGeneratorCode specifies the source generator of the cluster template.
DefaultGeneratorCode = "oe-engine"
// DefaultStaticIP specifies default static IP address
DefaultStaticIP = "10.0.0.4"
// DefaultSubnet specifies default subnet
DefaultSubnet = "10.0.0.0/24"
// DefaultStorageAccountType specifies default storage account type
DefaultStorageAccountType = "Standard_LRS"
// DefaultPackageBaseURL specifies default package base URL
DefaultPackageBaseURL = "https://oedownload.blob.core.windows.net/binaries"
)
// OSImage represents Azure OS Image
type OSImage struct {
Publisher string
Offer string
@ -16,23 +34,115 @@ type OSImage struct {
IsWindows bool
}
var OsImageMap map[string]OSImage
func init() {
OsImageMap = map[string]OSImage{
OsUbuntu1604: {
Publisher: "microsoft-azure-compute",
Offer: "azureconfidentialcompute",
SKU: "acc-ubuntu-16",
Version: "latest",
IsWindows: false,
},
OsWindows2016: {
Publisher: "MicrosoftWindowsServer",
Offer: "WindowsServer",
SKU: "2016-Datacenter",
Version: "latest",
IsWindows: true,
},
}
// OsImageMap contains supported OS images
var OsImageMap = map[string]OSImage{
OsUbuntu1604: {
Publisher: "microsoft-azure-compute",
Offer: "azureconfidentialcompute",
SKU: "acc-ubuntu-16",
Version: "latest",
IsWindows: false,
},
OsWindows2016: {
Publisher: "MicrosoftWindowsServer",
Offer: "WindowsServer",
SKU: "2016-Datacenter",
Version: "latest",
IsWindows: true,
},
}
// AllowedLocations provides supported azure regions
var AllowedLocations = []string{
"eastus",
"westeurope",
}
// AllowedVMSizes provides supported VM sizes
var AllowedVMSizes = []string{
"Standard_DC2s",
"Standard_DC4s",
}
// AllowedStorageAccountTypes provides supported storage account types
var AllowedStorageAccountTypes = []string{
"Standard_LRS",
"Premium_LRS",
"Standard_RAGRS",
}
func getAllowedValues(vals []string) string {
strFormat := `"allowedValues": [
"%s"
],
`
return fmt.Sprintf(strFormat, strings.Join(vals, "\",\n \""))
}
func getDefaultValue(def string) string {
strFormat := `"defaultValue": "%s",
`
return fmt.Sprintf(strFormat, def)
}
func getAllowedDefaultValues(vals []string, def string) string {
return getAllowedValues(vals) + getDefaultValue(def)
}
// GetAllowedLocations returns allowed locations
func GetAllowedLocations() string {
return getAllowedValues(AllowedLocations)
}
// GetAllowedVMSizes returns allowed sizes for VM
func GetAllowedVMSizes() string {
return getAllowedValues(AllowedVMSizes)
}
// GetStorageAccountTypes returns allowed and default storage account types
func GetStorageAccountTypes() string {
return getAllowedDefaultValues(AllowedStorageAccountTypes, DefaultStorageAccountType)
}
// GetOSImageNames returns allowed and default OS image name
func GetOSImageNames() string {
osNames := []string{}
for name := range OsImageMap {
osNames = append(osNames, name)
}
return getAllowedDefaultValues(osNames, OsImageDefault)
}
// GetOSImageReferences returns image references
func GetOSImageReferences() string {
osRefs := []string{}
osRefFormat := `"%s": {
"publisher": "%s",
"offer": "%s",
"sku": "%s",
"version": "%s"
}`
for osname, img := range OsImageMap {
osRefs = append(osRefs, fmt.Sprintf(osRefFormat, osname, img.Publisher, img.Offer, img.SKU, img.Version))
}
strFormat := `"imageReference": {
%s
},
`
return fmt.Sprintf(strFormat, strings.Join(osRefs, ",\n "))
}
// GetVMPlan returns VM plan
func GetVMPlan(osImageName string) string {
img, ok := OsImageMap[osImageName]
if !ok {
return ""
}
strFormat := `"plan": {
"name": "%s",
"publisher": "%s",
"product": "%s"
},`
return fmt.Sprintf(strFormat, img.SKU, img.Publisher, img.Offer)
}

Просмотреть файл

@ -64,6 +64,7 @@ type WindowsProfile struct {
// MasterProfile represents the definition of the master cluster
type MasterProfile struct {
OSImageName string `json:"osImageName"`
StorageType string `json:"storageAccountType"`
DNSPrefix string `json:"dnsPrefix"`
VMSize string `json:"vmSize"`
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`

Просмотреть файл

@ -1,6 +1,7 @@
package api
import (
"strings"
"fmt"
"net"
"net/url"
@ -74,6 +75,18 @@ func (a *Properties) validateMasterProfile() error {
return fmt.Errorf("OS image '%s' is not supported", m.OSImageName)
}
}
if len(m.StorageType) > 0 {
found := false
for _, t := range AllowedStorageAccountTypes {
if t == m.StorageType {
found = true
break
}
}
if !found {
return fmt.Errorf("Storage account type '%s' is not included in supported [%s]", m.StorageType, strings.Join(AllowedStorageAccountTypes, ","))
}
}
if len(m.DNSPrefix) > 0 {
if err := validateDNSName(m.DNSPrefix); err != nil {
return err

Просмотреть файл

@ -1,73 +0,0 @@
package engine
import (
"fmt"
"strings"
"github.com/Microsoft/oe-engine/pkg/api"
)
// AzureLocations provides all azure regions in prod.
// Related powershell to refresh this list:
// Get-AzureRmLocation | Select-Object -Property Location
var AzureLocations = []string{
"eastus",
}
// GetAllowedVMSizes returns allowed sizes for VM
func GetAllowedVMSizes() string {
return ` "allowedValues": [
"Standard_DC2s",
"Standard_DC4s",
"Standard_B1s"
],
`
}
// GetOSImageNames returns allowed sizes and default OS image name
func GetOSImageNames() string {
osNames := []string{}
for k := range api.OsImageMap {
osNames = append(osNames, fmt.Sprintf(`"%s"`, k))
}
strFormat := ` "allowedValues": [
%s
],
"defaultValue": "%s",
`
return fmt.Sprintf(strFormat, strings.Join(osNames, ",\n "), api.OsImageDefault)
}
// GetOSImageReferences returns image references
func GetOSImageReferences() string {
osRefs := []string{}
osRefFormat := `"%s": {
"publisher": "%s",
"offer": "%s",
"sku": "%s",
"version": "%s"
}`
for osname, img := range api.OsImageMap {
osRefs = append(osRefs, fmt.Sprintf(osRefFormat, osname, img.Publisher, img.Offer, img.SKU, img.Version))
}
strFormat := `"imageReference": {
%s
},
`
return fmt.Sprintf(strFormat, strings.Join(osRefs, ",\n "))
}
// GetVMPlan returns VM plan
func GetVMPlan(osImageName string) string {
img, ok := api.OsImageMap[osImageName]
if !ok {
return ""
}
strFormat := `"plan": {
"name": "%s",
"publisher": "%s",
"product": "%s"
},`
return fmt.Sprintf(strFormat, img.SKU, img.Publisher, img.Offer)
}

Просмотреть файл

@ -1,16 +1,5 @@
package engine
const (
// DefaultGeneratorCode specifies the source generator of the cluster template.
DefaultGeneratorCode = "oe-engine"
// DefaultStaticIP specifies default static IP address
DefaultStaticIP = "192.168.255.5"
// DefaultSubnet specifies default subnet
DefaultSubnet = "192.168.255.0/24"
// DefaultPackageBaseURL specifies default package base URL
DefaultPackageBaseURL = "https://oedownload.blob.core.windows.net/binaries"
)
const (
baseFile = "accbase.t"
vars = "vars.t"

Просмотреть файл

@ -12,7 +12,7 @@ import (
// setPropertiesDefaults for the container Properties, returns true if certs are generated
func setPropertiesDefaults(oe *api.OpenEnclave, isUpgrade bool) {
if len(oe.PackageBaseURL) == 0 {
oe.PackageBaseURL = DefaultPackageBaseURL
oe.PackageBaseURL = api.DefaultPackageBaseURL
}
if oe.Properties.MasterProfile == nil {
oe.Properties.MasterProfile = &api.MasterProfile{}
@ -30,10 +30,10 @@ func setMasterNetworkDefaults(a *api.Properties, isUpgrade bool) {
}
if !a.MasterProfile.IsCustomVNET() {
a.MasterProfile.Subnet = DefaultSubnet
a.MasterProfile.Subnet = api.DefaultSubnet
// StaticIP is not reset if it is upgrade and some value already exists
if !isUpgrade || len(a.MasterProfile.StaticIP) == 0 {
a.MasterProfile.StaticIP = DefaultStaticIP
a.MasterProfile.StaticIP = api.DefaultStaticIP
}
}

Просмотреть файл

@ -10,7 +10,12 @@ func getParameters(cs *api.OpenEnclave, generatorCode string) (paramsMap, error)
parametersMap := paramsMap{}
// Common Parameters
addValue(parametersMap, "location", location)
if len(cs.Location) > 0 {
addValue(parametersMap, "location", location)
}
if len(properties.MasterProfile.StorageType) > 0 {
addValue(parametersMap, "storageAccountType", properties.MasterProfile.StorageType)
}
addValue(parametersMap, "adminUsername", properties.LinuxProfile.AdminUsername)

Просмотреть файл

@ -145,16 +145,19 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.OpenEnclave) template.Fun
return fmt.Sprintf("\"customData\": \"[base64(concat('#cloud-config\\n\\n', '%s'))]\",", str)
},
"GetAllowedVMSizes": func() string {
return GetAllowedVMSizes()
return api.GetAllowedVMSizes()
},
"GetStorageAccountTypes": func() string {
return api.GetStorageAccountTypes()
},
"GetOSImageNames": func() string {
return GetOSImageNames()
return api.GetOSImageNames()
},
"GetOSImageReferences": func() string {
return GetOSImageReferences()
return api.GetOSImageReferences()
},
"GetVMPlan": func(s string) string {
return GetVMPlan(s)
return api.GetVMPlan(s)
},
"Base64": func(s string) string {
return base64.StdEncoding.EncodeToString([]byte(s))
@ -162,8 +165,8 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.OpenEnclave) template.Fun
"WriteLinkedTemplatesForExtensions": func() string {
return ""
},
"GetLocation": func() string {
return cs.Location
"GetAllowedLocations": func() string {
return api.GetAllowedLocations()
},
"WrapAsVariable": func(s string) string {
return fmt.Sprintf("',variables('%s'),'", s)

Просмотреть файл

@ -1,33 +1,13 @@
package transform
import (
"encoding/json"
"fmt"
"io/ioutil"
"testing"
"github.com/Microsoft/oe-engine/pkg/helpers"
. "github.com/onsi/gomega"
"github.com/sirupsen/logrus"
)
func TestNormalizeForVMSSScaling(t *testing.T) {
RegisterTestingT(t)
logger := logrus.New().WithField("testName", "TestNormalizeForVMSSScaling")
fileContents, e := ioutil.ReadFile("./transformtestfiles/oe_template.json")
Expect(e).To(BeNil())
expectedFileContents, e := ioutil.ReadFile("./transformtestfiles/oe_scale_template.json")
Expect(e).To(BeNil())
templateJSON := string(fileContents)
var template interface{}
json.Unmarshal([]byte(templateJSON), &template)
templateMap := template.(map[string]interface{})
transformer := Transformer{}
e = transformer.NormalizeForVMSSScaling(logger, templateMap)
Expect(e).To(BeNil())
ValidateTemplate(templateMap, expectedFileContents, "TestNormalizeForVMSSScaling")
}
func ValidateTemplate(templateMap map[string]interface{}, expectedFileContents []byte, testFileName string) {
output, e := helpers.JSONMarshal(templateMap, false)
Expect(e).To(BeNil())