Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Validation logic backward compatibility support for custom VNET (#2693)
Browse files Browse the repository at this point in the history
* Validation logic backward compatibility support for API models converted from prior v20180331 models.

* Fix check-style.

* Simplify network plugin check.

* Change network plugin "none" to "kubenet", remove agent pool nil check.

* Set default network values in un-versioned model.

* Add defaults for network settings.
  • Loading branch information
JunSun17 authored and jackfrancis committed Apr 17, 2018
1 parent 92f7b29 commit cb36601
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 151 deletions.
9 changes: 1 addition & 8 deletions pkg/acsengine/testdata/agentPoolOnly/v20180331/agents.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@
{
"name": "agentpool1",
"count": 1,
"vmSize": "Standard_D2_v2",
"vnetSubnetID": "/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet"
"vmSize": "Standard_D2_v2"
}
],
"servicePrincipalProfile": {
"clientID": "ServicePrincipalClientID",
"secret": "myServicePrincipalClientSecret"
},
"networkProfile": {
"networkPlugin": "azure",
"serviceCidr": "10.0.0.0/8",
"dnsServiceIP": "10.0.0.10",
"dockerBridgeCidr": "172.17.0.1/32"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"apiVersion": "2018-03-31",
"properties": {
"dnsPrefix": "agents006",
"fqdn": "agents006.azmk8s.io",
"kubernetesVersion": "1.8.7",
"agentPoolProfiles": [
{
"name": "agentpool1",
"count": 1,
"vmSize": "Standard_D2_v2",
"vnetSubnetID": "/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet"
}
],
"servicePrincipalProfile": {
"clientID": "ServicePrincipalClientID",
"secret": "myServicePrincipalClientSecret"
},
"networkProfile": {
"networkPlugin": "azure",
"serviceCidr": "10.0.0.0/8",
"dnsServiceIP": "10.0.0.10",
"dockerBridgeCidr": "172.17.0.1/32"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"apiVersion": "2018-03-31",
"properties": {
"dnsPrefix": "agents006",
"fqdn": "agents006.azmk8s.io",
"kubernetesVersion": "1.8.7",
"agentPoolProfiles": [
{
"name": "agentpool1",
"count": 1,
"vmSize": "Standard_D2_v2",
"vnetSubnetID": "/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet"
}
],
"servicePrincipalProfile": {
"clientID": "ServicePrincipalClientID",
"secret": "myServicePrincipalClientSecret"
},
"networkProfile": {
"networkPlugin": "kubenet"
}
}
}
16 changes: 5 additions & 11 deletions pkg/api/agentPoolOnlyApi/v20180331/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ package v20180331

import "fmt"

// ErrorNilNetworkProfile error
var ErrorNilNetworkProfile = fmt.Errorf("Network profile can not be nil")

// ErrorNilAgentPoolProfile error
var ErrorNilAgentPoolProfile = fmt.Errorf("Agent pool profile can not be nil")
// ErrorInvalidNetworkProfile error
var ErrorInvalidNetworkProfile = fmt.Errorf("ServiceCidr, DNSServiceIP, DockerBridgeCidr should all be empty or neither should be empty")

// ErrorInvalidNetworkPlugin error
var ErrorInvalidNetworkPlugin = fmt.Errorf("Network plugin should be either \"azure\" or \"kubenet\"")
var ErrorInvalidNetworkPlugin = fmt.Errorf("Network plugin should be either Azure or Kubenet")

// ErrorInvalidServiceCidr error
var ErrorInvalidServiceCidr = fmt.Errorf("ServiceCidr is not a valid CIDR")
Expand All @@ -26,11 +23,8 @@ var ErrorDNSServiceIPNotInServiceCidr = fmt.Errorf("DNSServiceIP is not within S
// ErrorDNSServiceIPAlreadyUsed error
var ErrorDNSServiceIPAlreadyUsed = fmt.Errorf("DNSServiceIP can not be the first IP address in ServiceCidr")

// ErrorAgentPoolNoSubnet error
var ErrorAgentPoolNoSubnet = fmt.Errorf("Agent pool does not have subnet defined")

// ErrorKubenetNoCustomization error
var ErrorKubenetNoCustomization = fmt.Errorf("Kubenet does not support ServiceCidr or DNSServiceIP or DockerBridgeCidr customization")
// ErrorAtLeastAgentPoolNoSubnet error
var ErrorAtLeastAgentPoolNoSubnet = fmt.Errorf("At least one agent pool does not have subnet defined")

// ErrorParsingSubnetID error
var ErrorParsingSubnetID = fmt.Errorf("Failed to parse VnetSubnetID")
Expand Down
160 changes: 86 additions & 74 deletions pkg/api/agentPoolOnlyApi/v20180331/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,108 +141,120 @@ func validateVNET(a *Properties) error {

n := a.NetworkProfile

if n == nil {
return ErrorNilNetworkProfile
}
// validate network profile settings
if n != nil {
switch n.NetworkPlugin {
case Azure, Kubenet:
if n.ServiceCidr != "" && n.DNSServiceIP != "" && n.DockerBridgeCidr != "" {
// validate ServiceCidr
_, serviceCidr, err := net.ParseCIDR(n.ServiceCidr)
if err != nil {
return ErrorInvalidServiceCidr
}

if string(n.NetworkPlugin) == string(Azure) {
// validate ServiceCidr
_, serviceCidr, err := net.ParseCIDR(n.ServiceCidr)
if err != nil {
return ErrorInvalidServiceCidr
}
// validate DNSServiceIP
dnsServiceIP := net.ParseIP(n.DNSServiceIP)
if dnsServiceIP == nil {
return ErrorInvalidDNSServiceIP
}

// validate DNSServiceIP
dnsServiceIP := net.ParseIP(n.DNSServiceIP)
if dnsServiceIP == nil {
return ErrorInvalidDNSServiceIP
}
// validate DockerBridgeCidr
_, _, err = net.ParseCIDR(n.DockerBridgeCidr)
if err != nil {
return ErrorInvalidDockerBridgeCidr
}

// validate DockerBridgeCidr
_, _, err = net.ParseCIDR(n.DockerBridgeCidr)
if err != nil {
return ErrorInvalidDockerBridgeCidr
}
// validate DNSServiceIP is within ServiceCidr
if !serviceCidr.Contains(dnsServiceIP) {
return ErrorDNSServiceIPNotInServiceCidr
}

// validate DNSServiceIP is within ServiceCidr
if !serviceCidr.Contains(dnsServiceIP) {
return ErrorDNSServiceIPNotInServiceCidr
// validate DNSServiceIP is not the first IP in ServiceCidr. The first IP is reserved for redirect svc.
kubernetesServiceIP, err := common.CidrStringFirstIP(n.ServiceCidr)
if err != nil {
return ErrorInvalidServiceCidr
}
if dnsServiceIP.String() == kubernetesServiceIP.String() {
return ErrorDNSServiceIPAlreadyUsed
}
} else if n.ServiceCidr == "" && n.DNSServiceIP == "" && n.DockerBridgeCidr == "" {
// this is a valid case, and no validation needed.
} else {
return ErrorInvalidNetworkProfile
}
default:
return ErrorInvalidNetworkPlugin
}
}

// validate DNSServiceIP is not the first IP in ServiceCidr. The first IP is reserved for redirect svc.
kubernetesServiceIP, err := common.CidrStringFirstIP(n.ServiceCidr)
if err != nil {
return ErrorInvalidServiceCidr
}
if dnsServiceIP.String() == kubernetesServiceIP.String() {
return ErrorDNSServiceIPAlreadyUsed
// validate agent pool custom VNET settings
if a.AgentPoolProfiles != nil {
if e := validateAgentPoolVNET(a.AgentPoolProfiles); e != nil {
return e
}
}

if a.AgentPoolProfiles == nil {
return ErrorNilAgentPoolProfile
}
return nil
}

// validate custom VNET logic
if isCustomVNET(a.AgentPoolProfiles) {
var subscription string
var resourceGroup string
var vnet string
func validateAgentPoolVNET(a []*AgentPoolProfile) error {

for _, agentPool := range a.AgentPoolProfiles {
// validate subscription, resource group and vnet are the same among subnets
subnetSubscription, subnetResourceGroup, subnetVnet, _, err := GetVNETSubnetIDComponents(agentPool.VnetSubnetID)
if err != nil {
return ErrorParsingSubnetID
}
// validate custom VNET logic at agent pool level
if isCustomVNET(a) {
var subscription string
var resourceGroup string
var vnet string

if subscription == "" {
subscription = subnetSubscription
} else {
if subscription != subnetSubscription {
return ErrorSubscriptionNotMatch
}
}
for _, agentPool := range a {
// validate each agent pool has a subnet
if !agentPool.IsCustomVNET() {
return ErrorAtLeastAgentPoolNoSubnet
}

// validate subscription, resource group and vnet are the same among subnets
subnetSubscription, subnetResourceGroup, subnetVnet, _, err := GetVNETSubnetIDComponents(agentPool.VnetSubnetID)
if err != nil {
return ErrorParsingSubnetID
}

if resourceGroup == "" {
resourceGroup = subnetResourceGroup
} else {
if resourceGroup != subnetResourceGroup {
return ErrorResourceGroupNotMatch
}
if subscription == "" {
subscription = subnetSubscription
} else {
if subscription != subnetSubscription {
return ErrorSubscriptionNotMatch
}
}

if vnet == "" {
vnet = subnetVnet
} else {
if vnet != subnetVnet {
return ErrorVnetNotMatch
}
if resourceGroup == "" {
resourceGroup = subnetResourceGroup
} else {
if resourceGroup != subnetResourceGroup {
return ErrorResourceGroupNotMatch
}
}
} else {
return ErrorAgentPoolNoSubnet
}

} else if string(n.NetworkPlugin) == string(Kubenet) {
if n.ServiceCidr != "" || n.DNSServiceIP != "" || n.DockerBridgeCidr != "" {
return ErrorKubenetNoCustomization
if vnet == "" {
vnet = subnetVnet
} else {
if vnet != subnetVnet {
return ErrorVnetNotMatch
}
}
}
} else {
return ErrorInvalidNetworkPlugin
}

return nil
}

// check agent pool subnet, return true as long as one agent pool has a subnet defined.
func isCustomVNET(a []*AgentPoolProfile) bool {

for _, agentPool := range a {
if !agentPool.IsCustomVNET() {
return false
if agentPool.IsCustomVNET() {
return true
}
}

return true
return false
}

// GetVNETSubnetIDComponents extract subscription, resourcegroup, vnetname, subnetname from the vnetSubnetID
Expand Down
Loading

0 comments on commit cb36601

Please sign in to comment.