sigs.k8s.io/cluster-api-provider-azure@v1.17.0/azure/services/networkinterfaces/spec.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package networkinterfaces
    18  
    19  import (
    20  	"context"
    21  	"strconv"
    22  
    23  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4"
    24  	"github.com/pkg/errors"
    25  	"k8s.io/utils/ptr"
    26  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    27  	"sigs.k8s.io/cluster-api-provider-azure/azure"
    28  	"sigs.k8s.io/cluster-api-provider-azure/azure/converters"
    29  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus"
    30  )
    31  
    32  // NICSpec defines the specification for a Network Interface.
    33  type NICSpec struct {
    34  	Name                      string
    35  	ResourceGroup             string
    36  	Location                  string
    37  	ExtendedLocation          *infrav1.ExtendedLocationSpec
    38  	SubscriptionID            string
    39  	MachineName               string
    40  	SubnetName                string
    41  	VNetName                  string
    42  	VNetResourceGroup         string
    43  	StaticIPAddress           string
    44  	PublicLBName              string
    45  	PublicLBAddressPoolName   string
    46  	PublicLBNATRuleName       string
    47  	InternalLBName            string
    48  	InternalLBAddressPoolName string
    49  	PublicIPName              string
    50  	AcceleratedNetworking     *bool
    51  	IPv6Enabled               bool
    52  	EnableIPForwarding        bool
    53  	SKU                       *resourceskus.SKU
    54  	DNSServers                []string
    55  	AdditionalTags            infrav1.Tags
    56  	ClusterName               string
    57  	IPConfigs                 []IPConfig
    58  }
    59  
    60  // IPConfig defines the specification for an IP address configuration.
    61  type IPConfig struct {
    62  	PrivateIP       *string
    63  	PublicIPAddress *string
    64  }
    65  
    66  // ResourceName returns the name of the network interface.
    67  func (s *NICSpec) ResourceName() string {
    68  	return s.Name
    69  }
    70  
    71  // ResourceGroupName returns the name of the resource group.
    72  func (s *NICSpec) ResourceGroupName() string {
    73  	return s.ResourceGroup
    74  }
    75  
    76  // OwnerResourceName is a no-op for network interfaces.
    77  func (s *NICSpec) OwnerResourceName() string {
    78  	return ""
    79  }
    80  
    81  // Parameters returns the parameters for the network interface.
    82  func (s *NICSpec) Parameters(ctx context.Context, existing interface{}) (parameters interface{}, err error) {
    83  	if existing != nil {
    84  		if _, ok := existing.(armnetwork.Interface); !ok {
    85  			return nil, errors.Errorf("%T is not an armnetwork.Interface", existing)
    86  		}
    87  		// network interface already exists
    88  		return nil, nil
    89  	}
    90  
    91  	primaryIPConfig := &armnetwork.InterfaceIPConfigurationPropertiesFormat{
    92  		Primary: ptr.To(true),
    93  	}
    94  
    95  	subnet := &armnetwork.Subnet{
    96  		ID: ptr.To(azure.SubnetID(s.SubscriptionID, s.VNetResourceGroup, s.VNetName, s.SubnetName)),
    97  	}
    98  	primaryIPConfig.Subnet = subnet
    99  
   100  	primaryIPConfig.PrivateIPAllocationMethod = ptr.To(armnetwork.IPAllocationMethodDynamic)
   101  	if s.StaticIPAddress != "" {
   102  		primaryIPConfig.PrivateIPAllocationMethod = ptr.To(armnetwork.IPAllocationMethodStatic)
   103  		primaryIPConfig.PrivateIPAddress = ptr.To(s.StaticIPAddress)
   104  	}
   105  
   106  	backendAddressPools := []*armnetwork.BackendAddressPool{}
   107  	if s.PublicLBName != "" {
   108  		if s.PublicLBAddressPoolName != "" {
   109  			backendAddressPools = append(backendAddressPools,
   110  				&armnetwork.BackendAddressPool{
   111  					ID: ptr.To(azure.AddressPoolID(s.SubscriptionID, s.ResourceGroup, s.PublicLBName, s.PublicLBAddressPoolName)),
   112  				})
   113  		}
   114  		if s.PublicLBNATRuleName != "" {
   115  			primaryIPConfig.LoadBalancerInboundNatRules = []*armnetwork.InboundNatRule{
   116  				{
   117  					ID: ptr.To(azure.NATRuleID(s.SubscriptionID, s.ResourceGroup, s.PublicLBName, s.PublicLBNATRuleName)),
   118  				},
   119  			}
   120  		}
   121  	}
   122  	if s.InternalLBName != "" && s.InternalLBAddressPoolName != "" {
   123  		backendAddressPools = append(backendAddressPools,
   124  			&armnetwork.BackendAddressPool{
   125  				ID: ptr.To(azure.AddressPoolID(s.SubscriptionID, s.ResourceGroup, s.InternalLBName, s.InternalLBAddressPoolName)),
   126  			})
   127  	}
   128  	primaryIPConfig.LoadBalancerBackendAddressPools = backendAddressPools
   129  
   130  	if s.PublicIPName != "" {
   131  		primaryIPConfig.PublicIPAddress = &armnetwork.PublicIPAddress{
   132  			ID: ptr.To(azure.PublicIPID(s.SubscriptionID, s.ResourceGroup, s.PublicIPName)),
   133  		}
   134  	}
   135  
   136  	if s.AcceleratedNetworking == nil {
   137  		// set accelerated networking to the capability of the VMSize
   138  		if s.SKU == nil {
   139  			return nil, errors.New("unable to get required network interface SKU from machine cache")
   140  		}
   141  
   142  		accelNet := s.SKU.HasCapability(resourceskus.AcceleratedNetworking)
   143  		s.AcceleratedNetworking = &accelNet
   144  	}
   145  
   146  	dnsSettings := armnetwork.InterfaceDNSSettings{}
   147  	if len(s.DNSServers) > 0 {
   148  		dnsSettings.DNSServers = azure.PtrSlice(&s.DNSServers)
   149  	}
   150  
   151  	ipConfigurations := []*armnetwork.InterfaceIPConfiguration{
   152  		{
   153  			Name:       ptr.To("pipConfig"),
   154  			Properties: primaryIPConfig,
   155  		},
   156  	}
   157  
   158  	// Build additional IPConfigs if more than 1 is specified
   159  	for i := 1; i < len(s.IPConfigs); i++ {
   160  		c := s.IPConfigs[i]
   161  		newIPConfigPropertiesFormat := &armnetwork.InterfaceIPConfigurationPropertiesFormat{}
   162  		newIPConfigPropertiesFormat.Subnet = subnet
   163  		config := &armnetwork.InterfaceIPConfiguration{
   164  			Name:       ptr.To(s.Name + "-" + strconv.Itoa(i)),
   165  			Properties: newIPConfigPropertiesFormat,
   166  		}
   167  		if c.PrivateIP != nil && *c.PrivateIP != "" {
   168  			config.Properties.PrivateIPAllocationMethod = ptr.To(armnetwork.IPAllocationMethodStatic)
   169  			config.Properties.PrivateIPAddress = c.PrivateIP
   170  		} else {
   171  			config.Properties.PrivateIPAllocationMethod = ptr.To(armnetwork.IPAllocationMethodDynamic)
   172  		}
   173  
   174  		if c.PublicIPAddress != nil && *c.PublicIPAddress != "" {
   175  			config.Properties.PublicIPAddress = &armnetwork.PublicIPAddress{
   176  				Properties: &armnetwork.PublicIPAddressPropertiesFormat{
   177  					PublicIPAllocationMethod: ptr.To(armnetwork.IPAllocationMethodStatic),
   178  					IPAddress:                c.PublicIPAddress,
   179  				},
   180  			}
   181  		} else if c.PublicIPAddress != nil {
   182  			config.Properties.PublicIPAddress = &armnetwork.PublicIPAddress{
   183  				Properties: &armnetwork.PublicIPAddressPropertiesFormat{
   184  					PublicIPAllocationMethod: ptr.To(armnetwork.IPAllocationMethodDynamic),
   185  				},
   186  			}
   187  		}
   188  		config.Properties.Primary = ptr.To(false)
   189  		ipConfigurations = append(ipConfigurations, config)
   190  	}
   191  	if s.IPv6Enabled {
   192  		ipv6Config := &armnetwork.InterfaceIPConfiguration{
   193  			Name: ptr.To("ipConfigv6"),
   194  			Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
   195  				PrivateIPAddressVersion: ptr.To(armnetwork.IPVersionIPv6),
   196  				Primary:                 ptr.To(false),
   197  				Subnet:                  &armnetwork.Subnet{ID: subnet.ID},
   198  			},
   199  		}
   200  
   201  		ipConfigurations = append(ipConfigurations, ipv6Config)
   202  	}
   203  
   204  	return armnetwork.Interface{
   205  		Location:         ptr.To(s.Location),
   206  		ExtendedLocation: converters.ExtendedLocationToNetworkSDK(s.ExtendedLocation),
   207  		Properties: &armnetwork.InterfacePropertiesFormat{
   208  			EnableAcceleratedNetworking: s.AcceleratedNetworking,
   209  			IPConfigurations:            ipConfigurations,
   210  			DNSSettings:                 &dnsSettings,
   211  			EnableIPForwarding:          ptr.To(s.EnableIPForwarding),
   212  		},
   213  		Tags: converters.TagsToMap(infrav1.Build(infrav1.BuildParams{
   214  			ClusterName: s.ClusterName,
   215  			Lifecycle:   infrav1.ResourceLifecycleOwned,
   216  			Name:        ptr.To(s.Name),
   217  			Additional:  s.AdditionalTags,
   218  		})),
   219  	}, nil
   220  }