github.com/cilium/cilium@v1.16.2/pkg/ipam/allocator/alibabacloud/alibabacloud.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package alibabacloud
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
    11  	"github.com/aliyun/alibaba-cloud-sdk-go/services/vpc"
    12  
    13  	operatorMetrics "github.com/cilium/cilium/operator/metrics"
    14  	operatorOption "github.com/cilium/cilium/operator/option"
    15  	openapi "github.com/cilium/cilium/pkg/alibabacloud/api"
    16  	"github.com/cilium/cilium/pkg/alibabacloud/eni"
    17  	"github.com/cilium/cilium/pkg/alibabacloud/eni/limits"
    18  	"github.com/cilium/cilium/pkg/alibabacloud/metadata"
    19  	apiMetrics "github.com/cilium/cilium/pkg/api/metrics"
    20  	"github.com/cilium/cilium/pkg/ipam"
    21  	"github.com/cilium/cilium/pkg/ipam/allocator"
    22  	ipamMetrics "github.com/cilium/cilium/pkg/ipam/metrics"
    23  	"github.com/cilium/cilium/pkg/logging"
    24  	"github.com/cilium/cilium/pkg/logging/logfields"
    25  	"github.com/cilium/cilium/pkg/metrics"
    26  )
    27  
    28  var log = logging.DefaultLogger.WithField(logfields.LogSubsys, "ipam-allocator-alibaba-cloud")
    29  
    30  // AllocatorAlibabaCloud is an implementation of IPAM allocator interface for AlibabaCloud ENI
    31  type AllocatorAlibabaCloud struct {
    32  	client *openapi.Client
    33  }
    34  
    35  // Init sets up ENI limits based on given options
    36  // Credential ref https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md
    37  func (a *AllocatorAlibabaCloud) Init(ctx context.Context) error {
    38  	var aMetrics openapi.MetricsAPI
    39  
    40  	if operatorOption.Config.EnableMetrics {
    41  		aMetrics = apiMetrics.NewPrometheusMetrics(metrics.Namespace, "alibabacloud", operatorMetrics.Registry)
    42  	} else {
    43  		aMetrics = &apiMetrics.NoOpMetrics{}
    44  	}
    45  
    46  	var err error
    47  	vpcID := operatorOption.Config.AlibabaCloudVPCID
    48  	if vpcID == "" {
    49  		vpcID, err = metadata.GetVPCID(ctx)
    50  		if err != nil {
    51  			return err
    52  		}
    53  	}
    54  	regionID, err := metadata.GetRegionID(ctx)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	vpcClient, err := vpc.NewClientWithProvider(regionID)
    60  	if err != nil {
    61  		return err
    62  	}
    63  	ecsClient, err := ecs.NewClientWithProvider(regionID)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	// Send API requests to "vpc" network endpoints instead of the default "public" network
    68  	// endpoints, so the ECS instance hosting cilium-operator doesn't require public network access
    69  	// to reach alibabacloud API.
    70  	// vpc endpoints are spliced to the format: <product>-<network>.<region_id>.aliyuncs.com
    71  	// e.g. ecs-vpc.cn-shanghai.aliyuncs.com
    72  	// ref https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/11-Endpoint-EN.md
    73  	vpcClient.Network = "vpc"
    74  	ecsClient.Network = "vpc"
    75  
    76  	vpcClient.GetConfig().WithScheme("HTTPS")
    77  	ecsClient.GetConfig().WithScheme("HTTPS")
    78  
    79  	a.client = openapi.NewClient(vpcClient, ecsClient, aMetrics, operatorOption.Config.IPAMAPIQPSLimit,
    80  		operatorOption.Config.IPAMAPIBurst, map[string]string{openapi.VPCID: vpcID})
    81  
    82  	if err := limits.UpdateFromAPI(ctx, a.client); err != nil {
    83  		return fmt.Errorf("unable to update instance type to adapter limits from AlibabaCloud API: %w", err)
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  // Start kicks off ENI allocation, the initial connection to AlibabaCloud
    90  // APIs is done in a blocking manner. Provided this is successful, a controller is
    91  // started to manage allocation based on CiliumNode custom resources
    92  func (a *AllocatorAlibabaCloud) Start(ctx context.Context, getterUpdater ipam.CiliumNodeGetterUpdater) (allocator.NodeEventHandler, error) {
    93  	var iMetrics ipam.MetricsAPI
    94  
    95  	log.Info("Starting AlibabaCloud ENI allocator...")
    96  
    97  	if operatorOption.Config.EnableMetrics {
    98  		iMetrics = ipamMetrics.NewPrometheusMetrics(metrics.Namespace, operatorMetrics.Registry)
    99  	} else {
   100  		iMetrics = &ipamMetrics.NoOpMetrics{}
   101  	}
   102  	instances := eni.NewInstancesManager(a.client)
   103  	nodeManager, err := ipam.NewNodeManager(instances, getterUpdater, iMetrics,
   104  		operatorOption.Config.ParallelAllocWorkers, operatorOption.Config.AlibabaCloudReleaseExcessIPs, false)
   105  	if err != nil {
   106  		return nil, fmt.Errorf("unable to initialize AlibabaCloud node manager: %w", err)
   107  	}
   108  
   109  	if err := nodeManager.Start(ctx); err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	return nodeManager, nil
   114  }