зеркало из https://github.com/microsoft/oe-engine.git
add selection of image reference (#3)
This commit is contained in:
Родитель
adb5adf774
Коммит
83c2d23824
|
@ -54,46 +54,22 @@
|
|||
"type": "string"
|
||||
},
|
||||
"osImageName": {
|
||||
"defaultValue": "",
|
||||
{{GetOSImageNames}}
|
||||
"metadata": {
|
||||
"description": "Name of a Linux OS image. Needs to be used in conjuction with osImageResourceGroup."
|
||||
"description": "OS image name"
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"osImageResourceGroup": {
|
||||
"defaultValue": "",
|
||||
"storageAccountType": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_LRS",
|
||||
"allowedValues": [
|
||||
"Standard_LRS",
|
||||
"Premium_LRS"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Resource group of a Linux OS image. Needs to be used in conjuction with osImageName."
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"osImageOffer": {
|
||||
"defaultValue": "azureconfidentialcompute",
|
||||
"metadata": {
|
||||
"description": "Linux OS image type."
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"defaultValue": "microsoft-azure-compute",
|
||||
"metadata": {
|
||||
"description": "OS image publisher."
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"osImageSKU": {
|
||||
"defaultValue": "acc-ubuntu-16",
|
||||
"metadata": {
|
||||
"description": "OS image SKU."
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"osImageVersion": {
|
||||
"defaultValue": "latest",
|
||||
"metadata": {
|
||||
"description": "OS image version."
|
||||
},
|
||||
"type": "string"
|
||||
"description": "Type of managed disk to create"
|
||||
}
|
||||
},
|
||||
"fqdnEndpointSuffix":{
|
||||
"defaultValue": "cloudapp.azure.com",
|
||||
|
|
|
@ -1,29 +1,3 @@
|
|||
{{if .MasterProfile.IsStorageAccount}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionStorage')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"location": "[variables('location')]",
|
||||
"name": "[variables('masterStorageAccountName')]",
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('vmSize')].storageAccountType]"
|
||||
},
|
||||
"type": "Microsoft.Storage/storageAccounts"
|
||||
},
|
||||
{{end}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionStorage')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"location": "[variables('location')]",
|
||||
"name": "[variables('masterStorageAccountExhibitorName')]",
|
||||
"properties": {
|
||||
"accountType": "Standard_LRS"
|
||||
},
|
||||
"type": "Microsoft.Storage/storageAccounts"
|
||||
},
|
||||
{{if not .MasterProfile.IsCustomVNET}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
|
@ -207,11 +181,7 @@
|
|||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('vmName'), '-nic')]",
|
||||
{{if .MasterProfile.IsStorageAccount}}
|
||||
"[variables('masterStorageAccountName')]",
|
||||
{{end}}
|
||||
"[variables('masterStorageAccountExhibitorName')]"
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('vmName'), '-nic')]"
|
||||
],
|
||||
"tags":
|
||||
{
|
||||
|
@ -219,11 +189,7 @@
|
|||
},
|
||||
"location": "[variables('location')]",
|
||||
"name": "[variables('vmName')]",
|
||||
"plan": {
|
||||
"name": "[parameters('osImageSKU')]",
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"product": "[variables('osImageOffer')]"
|
||||
},
|
||||
{{GetVMPlan .MasterProfile.OSImageName}}
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('vmSize')]"
|
||||
|
@ -256,24 +222,16 @@
|
|||
{{end}}
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "[variables('osImageVersion')]"
|
||||
},
|
||||
"imageReference": "[variables('imageReference')[parameters('osImageName')]]",
|
||||
"osDisk": {
|
||||
"caching": "ReadWrite"
|
||||
,"createOption": "FromImage"
|
||||
{{if .MasterProfile.IsStorageAccount}}
|
||||
,"name": "[concat(variables('vmName'),'-osdisk')]"
|
||||
,"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('masterStorageAccountName')),variables('apiVersionStorage')).primaryEndpoints.blob,'vhds/',variables('vmName'),'-osdisk.vhd')]"
|
||||
}
|
||||
{{end}}
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage",
|
||||
{{if ne .MasterProfile.OSDiskSizeGB 0}}
|
||||
,"diskSizeGB": {{.MasterProfile.OSDiskSizeGB}}
|
||||
"diskSizeGB": {{.MasterProfile.OSDiskSizeGB}},
|
||||
{{end}}
|
||||
"managedDisk": {
|
||||
"storageAccountType": "[parameters('storageAccountType')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
53
parts/vars.t
53
parts/vars.t
|
@ -39,24 +39,6 @@
|
|||
"masterNSGID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('masterNSGName'))]",
|
||||
"masterNSGName": "[concat('acc-nsg-', variables('nameSuffix'))]",
|
||||
"masterPublicIPAddressName": "[concat('acc-ip-', variables('dnsNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
"apiVersionStorage": "2015-06-15",
|
||||
|
||||
"storageAccountBaseName": "[uniqueString(concat(variables('dnsNamePrefix'),variables('location')))]",
|
||||
"masterStorageAccountExhibitorName": "[concat(variables('storageAccountBaseName'), 'exhb0')]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
{{if .HasStorageAccountDisks}}
|
||||
"maxVMsPerStorageAccount": 20,
|
||||
"maxStorageAccountsPerAgent": "[div(variables('maxVMsPerPool'),variables('maxVMsPerStorageAccount'))]",
|
||||
"dataStorageAccountPrefixSeed": 97,
|
||||
"storageAccountPrefixes": [ "0", "6", "c", "i", "o", "u", "1", "7", "d", "j", "p", "v", "2", "8", "e", "k", "q", "w", "3", "9", "f", "l", "r", "x", "4", "a", "g", "m", "s", "y", "5", "b", "h", "n", "t", "z" ],
|
||||
"storageAccountPrefixesCount": "[length(variables('storageAccountPrefixes'))]",
|
||||
{{GetSizeMap}},
|
||||
{{else}}
|
||||
"storageAccountPrefixes": [],
|
||||
{{end}}
|
||||
{{if .MasterProfile.IsStorageAccount}}
|
||||
"masterStorageAccountName": "[concat(variables('storageAccountBaseName'), 'mstr0')]",
|
||||
{{end}}
|
||||
{{if .MasterProfile.IsCustomVNET}}
|
||||
"vnetSubnetID": "[parameters('vnetSubnetID')]",
|
||||
{{else}}
|
||||
|
@ -70,42 +52,11 @@
|
|||
"vmName": "[concat('acc-', variables('nameSuffix'))]",
|
||||
"vmSize": "[parameters('vmSize')]",
|
||||
"nameSuffix": "[parameters('nameSuffix')]",
|
||||
"osImageOffer": "[parameters('osImageOffer')]",
|
||||
"osImagePublisher": "[parameters('osImagePublisher')]",
|
||||
"osImageSKU": "[parameters('osImageSKU')]",
|
||||
"osImageVersion": "[parameters('osImageVersion')]",
|
||||
{{GetOSImageReferences}}
|
||||
"sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]",
|
||||
"sshRSAPublicKey": "[parameters('sshRSAPublicKey')]",
|
||||
"locations": [
|
||||
"[resourceGroup().location]",
|
||||
"[parameters('location')]"
|
||||
],
|
||||
"location": "[variables('locations')[mod(add(2,length(parameters('location'))),add(1,length(parameters('location'))))]]",
|
||||
"masterSshInboundNatRuleIdPrefix": "[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('vmName'))]",
|
||||
"masterLbInboundNatRules": [
|
||||
[
|
||||
{
|
||||
"id": "[concat(variables('masterSshInboundNatRuleIdPrefix'),'0')]"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"id": "[concat(variables('masterSshInboundNatRuleIdPrefix'),'1')]"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"id": "[concat(variables('masterSshInboundNatRuleIdPrefix'),'2')]"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"id": "[concat(variables('masterSshInboundNatRuleIdPrefix'),'3')]"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"id": "[concat(variables('masterSshInboundNatRuleIdPrefix'),'4')]"
|
||||
}
|
||||
]
|
||||
]
|
||||
"location": "[variables('locations')[mod(add(2,length(parameters('location'))),add(1,length(parameters('location'))))]]"
|
||||
|
|
|
@ -32,20 +32,18 @@ func (a *Apiloader) DeserializeOpenEnclave(contents []byte, validate, isUpdate b
|
|||
return oe, err
|
||||
}
|
||||
|
||||
// LoadOpenEnclave loads an ACS Cluster API Model, validates it, and returns the unversioned representation
|
||||
// LoadOpenEnclave loads and validates an OE API Model
|
||||
func (a *Apiloader) LoadOpenEnclave(contents []byte, validate, isUpdate bool) (*OpenEnclave, error) {
|
||||
oe := &OpenEnclave{}
|
||||
|
||||
if e := json.Unmarshal(contents, oe); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
if e := checkJSONKeys(contents, reflect.TypeOf(*oe)); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
/*if e := OpenEnclave.Properties.Validate(isUpdate); validate && e != nil {
|
||||
if e := oe.Properties.Validate(isUpdate); validate && e != nil {
|
||||
return nil, e
|
||||
}*/
|
||||
}
|
||||
return oe, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package common
|
||||
|
||||
// validation values
|
||||
const (
|
||||
// MinAgentCount are the minimum number of agents per agent pool
|
||||
MinAgentCount = 1
|
||||
// MaxAgentCount are the maximum number of agents per agent pool
|
||||
MaxAgentCount = 100
|
||||
// MinPort specifies the minimum tcp port to open
|
||||
MinPort = 1
|
||||
// MaxPort specifies the maximum tcp port to open
|
||||
MaxPort = 65535
|
||||
// MaxDisks specifies the maximum attached disks to add to the cluster
|
||||
MaxDisks = 4
|
||||
// MinDiskSizeGB specifies the minimum attached disk size
|
||||
MinDiskSizeGB = 1
|
||||
// MaxDiskSizeGB specifies the maximum attached disk size
|
||||
MaxDiskSizeGB = 1023
|
||||
// MinIPAddressCount specifies the minimum number of IP addresses per network interface
|
||||
MinIPAddressCount = 1
|
||||
// MaxIPAddressCount specifies the maximum number of IP addresses per network interface
|
||||
MaxIPAddressCount = 256
|
||||
)
|
||||
|
||||
// Availability profiles
|
||||
const (
|
||||
// AvailabilitySet means that the vms are in an availability set
|
||||
AvailabilitySet = "AvailabilitySet"
|
||||
// VirtualMachineScaleSets means that the vms are in a virtual machine scaleset
|
||||
VirtualMachineScaleSets = "VirtualMachineScaleSets"
|
||||
)
|
||||
|
||||
// storage profiles
|
||||
const (
|
||||
// StorageAccount means that the nodes use raw storage accounts for their os and attached volumes
|
||||
StorageAccount = "StorageAccount"
|
||||
// ManagedDisks means that the nodes use managed disks for their os and attached volumes
|
||||
ManagedDisks = "ManagedDisks"
|
||||
)
|
|
@ -6,6 +6,13 @@ import (
|
|||
validator "gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
const (
|
||||
// MinDiskSizeGB specifies the minimum attached disk size
|
||||
MinDiskSizeGB = 1
|
||||
// MaxDiskSizeGB specifies the maximum attached disk size
|
||||
MaxDiskSizeGB = 1023
|
||||
)
|
||||
|
||||
// HandleValidationErrors is the helper function to catch validator.ValidationError
|
||||
// based on Namespace of the error, and return customized error message.
|
||||
func HandleValidationErrors(e validator.ValidationErrors) error {
|
||||
|
@ -13,18 +20,12 @@ func HandleValidationErrors(e validator.ValidationErrors) error {
|
|||
ns := err.Namespace()
|
||||
switch ns {
|
||||
case "Properties.MasterProfile", "Properties.MasterProfile.DNSPrefix", "Properties.MasterProfile.VMSize",
|
||||
"Properties.LinuxProfile", "Properties.ServicePrincipalProfile.ClientID",
|
||||
"Properties.LinuxProfile",
|
||||
"Properties.WindowsProfile.AdminUsername",
|
||||
"Properties.WindowsProfile.AdminPassword":
|
||||
return fmt.Errorf("missing %s", ns)
|
||||
case "Properties.MasterProfile.Count":
|
||||
return fmt.Errorf("MasterProfile count needs to be 1, 3, or 5")
|
||||
case "Properties.MasterProfile.OSDiskSizeGB":
|
||||
return fmt.Errorf("Invalid os disk size of %d specified. The range of valid values are [%d, %d]", err.Value().(int), MinDiskSizeGB, MaxDiskSizeGB)
|
||||
case "Properties.MasterProfile.IPAddressCount":
|
||||
return fmt.Errorf("MasterProfile.IPAddressCount needs to be in the range [%d,%d]", MinIPAddressCount, MaxIPAddressCount)
|
||||
case "Properties.MasterProfile.StorageProfile":
|
||||
return fmt.Errorf("Unknown storageProfile '%s'. Specify either %s or %s", err.Value().(string), StorageAccount, ManagedDisks)
|
||||
}
|
||||
return fmt.Errorf("Namespace %s is not caught, %+v", ns, e)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver"
|
||||
)
|
||||
|
@ -101,81 +100,6 @@ func GetMaxVersion(versions []string, preRelease bool) string {
|
|||
return highest.String()
|
||||
}
|
||||
|
||||
//GetValidPatchVersion gets the current valid patch version for the minor version of the passed in version
|
||||
func GetValidPatchVersion(orchType, orchVer string, hasWindows bool) string {
|
||||
if orchVer == "" {
|
||||
return RationalizeReleaseAndVersion(
|
||||
orchType,
|
||||
"",
|
||||
"",
|
||||
hasWindows)
|
||||
}
|
||||
|
||||
// check if the current version is valid, this allows us to have multiple supported patch versions in the future if we need it
|
||||
version := RationalizeReleaseAndVersion(
|
||||
orchType,
|
||||
"",
|
||||
orchVer,
|
||||
hasWindows)
|
||||
|
||||
if version == "" {
|
||||
sv, err := semver.Make(orchVer)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
sr := fmt.Sprintf("%d.%d", sv.Major, sv.Minor)
|
||||
|
||||
version = RationalizeReleaseAndVersion(
|
||||
orchType,
|
||||
sr,
|
||||
"",
|
||||
hasWindows)
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
// RationalizeReleaseAndVersion return a version when it can be rationalized from the input, otherwise ""
|
||||
func RationalizeReleaseAndVersion(orchType, orchRel, orchVer string, hasWindows bool) (version string) {
|
||||
// ignore "v" prefix in orchestrator version and release: "v1.8.0" is equivalent to "1.8.0", "v1.9" is equivalent to "1.9"
|
||||
orchVer = strings.TrimPrefix(orchVer, "v")
|
||||
orchRel = strings.TrimPrefix(orchRel, "v")
|
||||
supportedVersions, defaultVersion := GetSupportedVersions(orchType, hasWindows)
|
||||
if supportedVersions == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if orchRel == "" && orchVer == "" {
|
||||
return defaultVersion
|
||||
}
|
||||
|
||||
if orchVer == "" {
|
||||
// Try to get latest version matching the release
|
||||
version = GetLatestPatchVersion(orchRel, supportedVersions)
|
||||
return version
|
||||
} else if orchRel == "" {
|
||||
// Try to get version the same with orchVer
|
||||
version = ""
|
||||
for _, ver := range supportedVersions {
|
||||
if ver == orchVer {
|
||||
version = ver
|
||||
break
|
||||
}
|
||||
}
|
||||
return version
|
||||
}
|
||||
// Try to get latest version matching the release
|
||||
version = ""
|
||||
for _, ver := range supportedVersions {
|
||||
sv, _ := semver.Make(ver)
|
||||
sr := fmt.Sprintf("%d.%d", sv.Major, sv.Minor)
|
||||
if sr == orchRel && ver == orchVer {
|
||||
version = ver
|
||||
break
|
||||
}
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
// GetLatestPatchVersion gets the most recent patch version from a list of semver versions given a major.minor string
|
||||
func GetLatestPatchVersion(majorMinor string, versionsList []string) (version string) {
|
||||
// Try to get latest version matching the release
|
||||
|
|
|
@ -1,50 +1,38 @@
|
|||
package api
|
||||
|
||||
// the OSTypes supported by vlabs
|
||||
const (
|
||||
Windows OSType = "Windows"
|
||||
Linux OSType = "Linux"
|
||||
OsUbuntu1604 = "UbuntuServer_16.04"
|
||||
OsWindows2016 = "WindowsServer_2016"
|
||||
|
||||
OsImageDefault = OsUbuntu1604
|
||||
)
|
||||
|
||||
// the LinuxDistros supported by vlabs
|
||||
const (
|
||||
Ubuntu Distro = "ubuntu"
|
||||
)
|
||||
// OSImage represent Azure OS Image
|
||||
type OSImage struct {
|
||||
Publisher string
|
||||
Offer string
|
||||
SKU string
|
||||
Version string
|
||||
IsWindows bool
|
||||
}
|
||||
|
||||
// validation values
|
||||
const (
|
||||
// MinAgentCount are the minimum number of agents per agent pool
|
||||
MinAgentCount = 1
|
||||
// MaxAgentCount are the maximum number of agents per agent pool
|
||||
MaxAgentCount = 100
|
||||
// MinPort specifies the minimum tcp port to open
|
||||
MinPort = 1
|
||||
// MaxPort specifies the maximum tcp port to open
|
||||
MaxPort = 65535
|
||||
// MaxDisks specifies the maximum attached disks to add to the cluster
|
||||
MaxDisks = 4
|
||||
)
|
||||
var OsImageMap map[string]OSImage
|
||||
|
||||
// Availability profiles
|
||||
const (
|
||||
// AvailabilitySet means that the vms are in an availability set
|
||||
AvailabilitySet = "AvailabilitySet"
|
||||
// VirtualMachineScaleSets means that the vms are in a virtual machine scaleset
|
||||
VirtualMachineScaleSets = "VirtualMachineScaleSets"
|
||||
// ScaleSetPriorityRegular is the default ScaleSet Priority
|
||||
ScaleSetPriorityRegular = "Regular"
|
||||
// ScaleSetPriorityLow means the ScaleSet will use Low-priority VMs
|
||||
ScaleSetPriorityLow = "Low"
|
||||
// ScaleSetEvictionPolicyDelete is the default Eviction Policy for Low-priority VM ScaleSets
|
||||
ScaleSetEvictionPolicyDelete = "Delete"
|
||||
// ScaleSetEvictionPolicyDeallocate means a Low-priority VM ScaleSet will deallocate, rather than delete, VMs.
|
||||
ScaleSetEvictionPolicyDeallocate = "Deallocate"
|
||||
)
|
||||
|
||||
// storage profiles
|
||||
const (
|
||||
// StorageAccount means that the nodes use raw storage accounts for their os and attached volumes
|
||||
StorageAccount = "StorageAccount"
|
||||
// ManagedDisks means that the nodes use managed disks for their os and attached volumes
|
||||
ManagedDisks = "ManagedDisks"
|
||||
)
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ type LinuxProfile struct {
|
|||
PublicKeys []PublicKey `json:"publicKeys"`
|
||||
} `json:"ssh"`
|
||||
Secrets []KeyVaultSecrets `json:"secrets,omitempty"`
|
||||
Distro Distro `json:"distro,omitempty"`
|
||||
ScriptRootURL string `json:"scriptroot,omitempty"`
|
||||
CustomSearchDomain *CustomSearchDomain `json:"customSearchDomain,omitempty"`
|
||||
CustomNodesDNS *CustomNodesDNS `json:"CustomNodesDNS,omitempty"`
|
||||
|
@ -62,27 +61,18 @@ type WindowsProfile struct {
|
|||
Secrets []KeyVaultSecrets `json:"secrets,omitempty"`
|
||||
}
|
||||
|
||||
// ImageReference represents a reference to an Image resource in Azure.
|
||||
type ImageReference struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ResourceGroup string `json:"resourceGroup,omitempty"`
|
||||
}
|
||||
|
||||
// MasterProfile represents the definition of the master cluster
|
||||
type MasterProfile struct {
|
||||
DNSPrefix string `json:"dnsPrefix"`
|
||||
VMSize string `json:"vmSize"`
|
||||
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`
|
||||
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
|
||||
VnetCidr string `json:"vnetCidr,omitempty"`
|
||||
StaticIP string `json:"staticIP,omitempty"`
|
||||
Subnet string `json:"subnet"`
|
||||
IPAddressCount int `json:"ipAddressCount,omitempty"`
|
||||
StorageProfile string `json:"storageProfile,omitempty"`
|
||||
HTTPSourceAddressPrefix string `json:"HTTPSourceAddressPrefix,omitempty"`
|
||||
Distro Distro `json:"distro,omitempty"`
|
||||
Accessible bool `json:"accessible,omitempty"`
|
||||
ImageRef *ImageReference `json:"imageReference,omitempty"`
|
||||
OSImageName string `json:"osImageName"`
|
||||
DNSPrefix string `json:"dnsPrefix"`
|
||||
VMSize string `json:"vmSize"`
|
||||
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"`
|
||||
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
|
||||
VnetCidr string `json:"vnetCidr,omitempty"`
|
||||
StaticIP string `json:"staticIP,omitempty"`
|
||||
Subnet string `json:"subnet"`
|
||||
HTTPSourceAddressPrefix string `json:"HTTPSourceAddressPrefix,omitempty"`
|
||||
Accessible bool `json:"accessible,omitempty"`
|
||||
|
||||
FQDN string `json:"fqdn,omitempty"`
|
||||
}
|
||||
|
@ -133,45 +123,16 @@ type KeyVaultCertificate struct {
|
|||
// OSType represents OS types of agents
|
||||
type OSType string
|
||||
|
||||
// Distro represents Linux distro to use for Linux VMs
|
||||
type Distro string
|
||||
|
||||
// HasWindows returns true if the cluster contains windows
|
||||
func (p *Properties) HasWindows() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasManagedDisks returns true if the cluster contains Managed Disks
|
||||
func (p *Properties) HasManagedDisks() bool {
|
||||
if p.MasterProfile != nil && p.MasterProfile.StorageProfile == ManagedDisks {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasStorageAccountDisks returns true if the cluster contains Storage Account Disks
|
||||
func (p *Properties) HasStorageAccountDisks() bool {
|
||||
if p.MasterProfile != nil && p.MasterProfile.StorageProfile == StorageAccount {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCustomVNET returns true if the customer brought their own VNET
|
||||
func (m *MasterProfile) IsCustomVNET() bool {
|
||||
return len(m.VnetSubnetID) > 0
|
||||
}
|
||||
|
||||
// IsManagedDisks returns true if the master specified managed disks
|
||||
func (m *MasterProfile) IsManagedDisks() bool {
|
||||
return m.StorageProfile == ManagedDisks
|
||||
}
|
||||
|
||||
// IsStorageAccount returns true if the master specified storage account
|
||||
func (m *MasterProfile) IsStorageAccount() bool {
|
||||
return m.StorageProfile == StorageAccount
|
||||
}
|
||||
|
||||
// HasSecrets returns true if the customer specified secrets to install
|
||||
func (w *WindowsProfile) HasSecrets() bool {
|
||||
return len(w.Secrets) > 0
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
||||
"github.com/Microsoft/oe-engine/pkg/api/common"
|
||||
validator "gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
var (
|
||||
validate *validator.Validate
|
||||
keyvaultIDRegex *regexp.Regexp
|
||||
labelValueRegex *regexp.Regexp
|
||||
labelKeyRegex *regexp.Regexp
|
||||
)
|
||||
|
||||
const (
|
||||
labelKeyPrefixMaxLength = 253
|
||||
labelValueFormat = "^([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"
|
||||
labelKeyFormat = "^(([a-zA-Z0-9-]+[.])*[a-zA-Z0-9-]+[/])?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"
|
||||
)
|
||||
|
||||
func init() {
|
||||
validate = validator.New()
|
||||
keyvaultIDRegex = regexp.MustCompile(`^/subscriptions/\S+/resourceGroups/\S+/providers/Microsoft.KeyVault/vaults/[^/\s]+$`)
|
||||
labelValueRegex = regexp.MustCompile(labelValueFormat)
|
||||
labelKeyRegex = regexp.MustCompile(labelKeyFormat)
|
||||
}
|
||||
|
||||
// Validate implements APIObject
|
||||
func (a *Properties) Validate(isUpdate bool) error {
|
||||
if e := validate.Struct(a); e != nil {
|
||||
return handleValidationErrors(e.(validator.ValidationErrors))
|
||||
}
|
||||
if a.LinuxProfile != nil && a.WindowsProfile != nil {
|
||||
return fmt.Errorf("Linux and Windows profiles are mutually exclusive")
|
||||
}
|
||||
if e := a.validateMasterProfile(); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := a.validateLinuxProfile(); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := a.validateWindowsProfile(); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := a.validateVNET(); e != nil {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleValidationErrors(e validator.ValidationErrors) error {
|
||||
// Override any version specific validation error message
|
||||
// common.HandleValidationErrors if the validation error message is general
|
||||
return common.HandleValidationErrors(e)
|
||||
}
|
||||
|
||||
func (a *Properties) validateMasterProfile() error {
|
||||
m := a.MasterProfile
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if len(m.StaticIP) > 0 {
|
||||
if net.ParseIP(m.StaticIP) == nil {
|
||||
return fmt.Errorf("StaticIP '%s' is an invalid IP address", m.StaticIP)
|
||||
}
|
||||
}
|
||||
if len(m.OSImageName) > 0 {
|
||||
if _, ok := OsImageMap[m.OSImageName]; !ok {
|
||||
return fmt.Errorf("OS image '%s' is not supported", m.OSImageName)
|
||||
}
|
||||
}
|
||||
if len(m.DNSPrefix) > 0 {
|
||||
if err := validateDNSName(m.DNSPrefix); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Properties) validateLinuxProfile() error {
|
||||
if a.LinuxProfile == nil {
|
||||
return nil
|
||||
}
|
||||
if e := validate.Var(a.LinuxProfile.SSH.PublicKeys[0].KeyData, "required"); e != nil {
|
||||
return fmt.Errorf("KeyData in LinuxProfile.SSH.PublicKeys cannot be empty string")
|
||||
}
|
||||
return validateKeyVaultSecrets(a.LinuxProfile.Secrets, false)
|
||||
}
|
||||
|
||||
func (a *Properties) validateWindowsProfile() error {
|
||||
if a.WindowsProfile == nil {
|
||||
return nil
|
||||
}
|
||||
if e := validate.Var(a.WindowsProfile.AdminPassword, "required"); e != nil {
|
||||
return fmt.Errorf("WindowsProfile.AdminPassword cannot be empty string")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Properties) validateVNET() error {
|
||||
isCustomVNET := a.MasterProfile.IsCustomVNET()
|
||||
|
||||
if isCustomVNET {
|
||||
_, _, _, _, e := common.GetVNETSubnetIDComponents(a.MasterProfile.VnetSubnetID)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
statisIP := net.ParseIP(a.MasterProfile.StaticIP)
|
||||
if statisIP == nil {
|
||||
return fmt.Errorf("MasterProfile.StaticIP (with VNET Subnet specification) '%s' is an invalid IP address", a.MasterProfile.StaticIP)
|
||||
}
|
||||
|
||||
if a.MasterProfile.VnetCidr != "" {
|
||||
_, _, err := net.ParseCIDR(a.MasterProfile.VnetCidr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("MasterProfile.VnetCidr '%s' contains invalid cidr notation", a.MasterProfile.VnetCidr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateKeyVaultSecrets(secrets []KeyVaultSecrets, requireCertificateStore bool) error {
|
||||
for _, s := range secrets {
|
||||
if len(s.VaultCertificates) == 0 {
|
||||
return fmt.Errorf("Invalid KeyVaultSecrets must have no empty VaultCertificates")
|
||||
}
|
||||
if s.SourceVault == nil {
|
||||
return fmt.Errorf("missing SourceVault in KeyVaultSecrets")
|
||||
}
|
||||
if s.SourceVault.ID == "" {
|
||||
return fmt.Errorf("KeyVaultSecrets must have a SourceVault.ID")
|
||||
}
|
||||
for _, c := range s.VaultCertificates {
|
||||
if _, e := url.Parse(c.CertificateURL); e != nil {
|
||||
return fmt.Errorf("Certificate url was invalid. received error %s", e)
|
||||
}
|
||||
if e := validateName(c.CertificateStore, "KeyVaultCertificate.CertificateStore"); requireCertificateStore && e != nil {
|
||||
return fmt.Errorf("%s for certificates in a WindowsProfile", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate ensures that the WindowsProfile is valid
|
||||
func (w *WindowsProfile) Validate(orchestratorType string) error {
|
||||
if e := validate.Var(w.AdminUsername, "required"); e != nil {
|
||||
return fmt.Errorf("WindowsProfile.AdminUsername is required, when agent pool specifies windows")
|
||||
}
|
||||
if e := validate.Var(w.AdminPassword, "required"); e != nil {
|
||||
return fmt.Errorf("WindowsProfile.AdminPassword is required, when agent pool specifies windows")
|
||||
}
|
||||
return validateKeyVaultSecrets(w.Secrets, true)
|
||||
}
|
||||
|
||||
func validateName(name string, label string) error {
|
||||
if name == "" {
|
||||
return fmt.Errorf("%s must be a non-empty value", label)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validatePoolName(poolName string) error {
|
||||
// we will cap at length of 12 and all lowercase letters since this makes up the VMName
|
||||
poolNameRegex := `^([a-z][a-z0-9]{0,11})$`
|
||||
re, err := regexp.Compile(poolNameRegex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
submatches := re.FindStringSubmatch(poolName)
|
||||
if len(submatches) != 2 {
|
||||
return fmt.Errorf("pool name '%s' is invalid. A pool name must start with a lowercase letter, have max length of 12, and only have characters a-z0-9", poolName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDNSName(dnsName string) error {
|
||||
dnsNameRegex := `^([A-Za-z][A-Za-z0-9-]{1,43}[A-Za-z0-9])$`
|
||||
re, err := regexp.Compile(dnsNameRegex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !re.MatchString(dnsName) {
|
||||
return fmt.Errorf("DNS name '%s' is invalid. The DNS name must contain between 3 and 45 characters. The name can contain only letters, numbers, and hyphens. The name must start with a letter and must end with a letter or a number (length was %d)", dnsName, len(dnsName))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateUniquePorts(ports []int, name string) error {
|
||||
portMap := make(map[int]bool)
|
||||
for _, port := range ports {
|
||||
if _, ok := portMap[port]; ok {
|
||||
return fmt.Errorf("agent profile '%s' has duplicate port '%d', ports must be unique", name, port)
|
||||
}
|
||||
portMap[port] = true
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,12 @@
|
|||
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
|
||||
|
@ -7,7 +14,7 @@ var AzureLocations = []string{
|
|||
"eastus",
|
||||
}
|
||||
|
||||
// GetAllowedVMSizes returns the agent allowed sizes
|
||||
// GetAllowedVMSizes returns allowed sizes for VM
|
||||
func GetAllowedVMSizes() string {
|
||||
return ` "allowedValues": [
|
||||
"Standard_DC2s",
|
||||
|
@ -17,624 +24,50 @@ func GetAllowedVMSizes() string {
|
|||
`
|
||||
}
|
||||
|
||||
// GetSizeMap returns the size / storage map
|
||||
func GetSizeMap() string {
|
||||
return ` "vmSizesMap": {
|
||||
"Standard_A0": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A1": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A10": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A11": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A1_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A2_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A2m_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A4": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A4_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A4m_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A5": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A6": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A7": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A8": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A8_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A8m_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_A9": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_B1ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_B1s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_B2ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_B2s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_B4ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_B8ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D1": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D11": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D11_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D11_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D12": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D12_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D12_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D13": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D13_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D13_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D14": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D14_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D14_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D15_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D16_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D16s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D1_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D2_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D2_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D2_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D2s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D32_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D32s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D3_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D3_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D4": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D4_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D4_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D4_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D4s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D5_v2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D5_v2_Promo": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D64_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D64s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_D8_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_D8s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS1": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS11": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS11-1_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS11_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS11_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS12": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS12-1_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS12-2_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS12_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS12_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS13": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS13-2_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS13-4_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS13_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS13_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS14": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS14-4_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS14-8_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS14_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS14_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS15_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS1_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS2_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS2_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS3_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS3_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS4": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS4_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS4_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS5_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_DS5_v2_Promo": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E16-4s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E16-8s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E16_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E16s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E2_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E2s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E32-16s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E32-8s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E32_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E32s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E4-2s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E4_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E4s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E64-16s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E64-32s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E64_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E64i_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E64is_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E64s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E8-2s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E8-4s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_E8_v3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_E8s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F1": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_F16": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_F16s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F16s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F1s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_F2s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F2s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F32s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F4": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_F4s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F4s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F64s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F72s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F8": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_F8s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_F8s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_G1": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_G2": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_G3": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_G4": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_G5": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_GS1": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS4": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS4-4": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS4-8": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS5": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS5-16": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_GS5-8": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_H16": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_H16m": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_H16mr": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_H16r": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_H8": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_H8m": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_L16s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_L16s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_L32s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_L4s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_L8s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_L8s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M128": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_M128-32ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M128-64ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M128m": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_M128ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M128s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M16-4ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M16-8ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M16ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M32-16ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M32-8ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M32ls": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M32ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M32ts": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M64": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_M64-16ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M64-32ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M64ls": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M64m": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_M64ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M64s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M8-2ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M8-4ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_M8ms": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC12": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NC12s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC12s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC24": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NC24r": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NC24rs_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC24rs_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC24s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC24s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC6": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NC6s_v2": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NC6s_v3": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_ND12s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_ND24rs": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_ND24s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_ND6s": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"Standard_NV12": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NV24": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"Standard_NV6": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
}
|
||||
}
|
||||
`
|
||||
// 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)
|
||||
}
|
||||
|
|
|
@ -14,11 +14,13 @@ func setPropertiesDefaults(oe *api.OpenEnclave, isUpgrade bool) {
|
|||
if len(oe.PackageBaseURL) == 0 {
|
||||
oe.PackageBaseURL = DefaultPackageBaseURL
|
||||
}
|
||||
setMasterNetworkDefaults(oe.Properties, isUpgrade)
|
||||
setStorageDefaults(oe.Properties)
|
||||
if oe.Properties.MasterProfile == nil {
|
||||
oe.Properties.MasterProfile = &api.MasterProfile{}
|
||||
}
|
||||
if len(oe.Properties.MasterProfile.OSImageName) == 0 {
|
||||
oe.Properties.MasterProfile.OSImageName = api.OsImageDefault
|
||||
}
|
||||
setMasterNetworkDefaults(oe.Properties, isUpgrade)
|
||||
}
|
||||
|
||||
// SetMasterNetworkDefaults for masters
|
||||
|
@ -35,24 +37,11 @@ func setMasterNetworkDefaults(a *api.Properties, isUpgrade bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// Set the default number of IP addresses allocated for masters.
|
||||
if a.MasterProfile.IPAddressCount == 0 {
|
||||
// Allocate one IP address for the node.
|
||||
a.MasterProfile.IPAddressCount = 1
|
||||
}
|
||||
|
||||
if a.MasterProfile.HTTPSourceAddressPrefix == "" {
|
||||
a.MasterProfile.HTTPSourceAddressPrefix = "*"
|
||||
}
|
||||
}
|
||||
|
||||
// setStorageDefaults for agents
|
||||
func setStorageDefaults(a *api.Properties) {
|
||||
if a.MasterProfile != nil && len(a.MasterProfile.StorageProfile) == 0 {
|
||||
a.MasterProfile.StorageProfile = api.ManagedDisks
|
||||
}
|
||||
}
|
||||
|
||||
func combineValues(inputs ...string) string {
|
||||
valueMap := make(map[string]string)
|
||||
for _, input := range inputs {
|
||||
|
|
|
@ -12,21 +12,22 @@ func getParameters(cs *api.OpenEnclave, generatorCode string) (paramsMap, error)
|
|||
// Common Parameters
|
||||
addValue(parametersMap, "location", location)
|
||||
|
||||
//addValue(parametersMap, "fqdnEndpointSuffix", cloudSpecConfig.EndpointConfig.ResourceManagerVMDNSSuffix)
|
||||
addValue(parametersMap, "adminUsername", properties.LinuxProfile.AdminUsername)
|
||||
|
||||
addValue(parametersMap, "dnsNamePrefix", properties.MasterProfile.DNSPrefix)
|
||||
|
||||
if properties.MasterProfile != nil {
|
||||
if properties.MasterProfile.IsCustomVNET() {
|
||||
addValue(parametersMap, "vnetSubnetID", properties.MasterProfile.VnetSubnetID)
|
||||
} else {
|
||||
addValue(parametersMap, "subnet", properties.MasterProfile.Subnet)
|
||||
}
|
||||
addValue(parametersMap, "staticIP", properties.MasterProfile.StaticIP)
|
||||
addValue(parametersMap, "vmSize", properties.MasterProfile.VMSize)
|
||||
if properties.MasterProfile.IsCustomVNET() {
|
||||
addValue(parametersMap, "vnetSubnetID", properties.MasterProfile.VnetSubnetID)
|
||||
} else {
|
||||
addValue(parametersMap, "subnet", properties.MasterProfile.Subnet)
|
||||
}
|
||||
addValue(parametersMap, "staticIP", properties.MasterProfile.StaticIP)
|
||||
addValue(parametersMap, "vmSize", properties.MasterProfile.VMSize)
|
||||
addValue(parametersMap, "osImageName", properties.MasterProfile.OSImageName)
|
||||
|
||||
if properties.LinuxProfile != nil {
|
||||
addValue(parametersMap, "sshRSAPublicKey", properties.LinuxProfile.SSH.PublicKeys[0].KeyData)
|
||||
}
|
||||
addValue(parametersMap, "sshRSAPublicKey", properties.LinuxProfile.SSH.PublicKeys[0].KeyData)
|
||||
|
||||
return parametersMap, nil
|
||||
}
|
||||
|
|
|
@ -145,8 +145,14 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.OpenEnclave) template.Fun
|
|||
"GetAllowedVMSizes": func() string {
|
||||
return GetAllowedVMSizes()
|
||||
},
|
||||
"GetSizeMap": func() string {
|
||||
return GetSizeMap()
|
||||
"GetOSImageNames": func() string {
|
||||
return GetOSImageNames()
|
||||
},
|
||||
"GetOSImageReferences": func() string {
|
||||
return GetOSImageReferences()
|
||||
},
|
||||
"GetVMPlan": func(s string) string {
|
||||
return GetVMPlan(s)
|
||||
},
|
||||
"Base64": func(s string) string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(s))
|
||||
|
|
|
@ -1,28 +1,10 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"github.com/Microsoft/oe-engine/pkg/api"
|
||||
)
|
||||
|
||||
//AzureEndpointConfig describes an Azure endpoint
|
||||
type AzureEndpointConfig struct {
|
||||
ResourceManagerVMDNSSuffix string
|
||||
}
|
||||
|
||||
//AzureOSImageConfig describes an Azure OS image
|
||||
type AzureOSImageConfig struct {
|
||||
ImageOffer string
|
||||
ImageSku string
|
||||
ImagePublisher string
|
||||
ImageVersion string
|
||||
}
|
||||
|
||||
//AzureEnvironmentSpecConfig is the overall configuration differences in different cloud environments.
|
||||
type AzureEnvironmentSpecConfig struct {
|
||||
EndpointConfig AzureEndpointConfig
|
||||
OSImageConfig map[api.Distro]AzureOSImageConfig
|
||||
}
|
||||
|
||||
// KeyVaultID represents a KeyVault instance on Azure
|
||||
type KeyVaultID struct {
|
||||
ID string `json:"id"`
|
||||
|
|
Загрузка…
Ссылка в новой задаче