feat: switch to containerservice v6

This commit is contained in:
Daniel J. Holmes (jaitaiwan) 2024-10-25 09:53:24 +10:00
Родитель 7708100181
Коммит b67e845302
5 изменённых файлов: 158 добавлений и 69 удалений

7
pkg/env/core.go поставляемый
Просмотреть файл

@ -75,12 +75,15 @@ func (c *core) Logger() *logrus.Entry {
}
func (c *core) NewLiveConfigManager(ctx context.Context) (liveconfig.Manager, error) {
msiAuthorizer, err := c.NewMSIAuthorizer(c.Environment().ResourceManagerScope)
tokenizer, err := c.NewMSITokenCredential()
if err != nil {
return nil, err
}
mcc := containerservice.NewManagedClustersClient(c.Environment(), c.SubscriptionID(), msiAuthorizer)
mcc, err := containerservice.NewDefaultManagedClustersClient(c.Environment(), c.SubscriptionID(), tokenizer)
if err != nil {
return nil, err
}
if c.isLocalDevelopmentMode {
return liveconfig.NewDev(c.Location(), mcc), nil

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

@ -6,19 +6,22 @@ package containerservice
import (
"context"
mgmtcontainerservice "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2021-10-01/containerservice"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
armcontainerservice "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6"
)
// ManagedClustersAddons is a minimal interface for azure ManagedClustersAddons
type ManagedClustersAddons interface {
ListClusterAdminCredentials(ctx context.Context, resourceGroupName string, resourceName string, serverFqdn string) (mgmtcontainerservice.CredentialResults, error)
List(ctx context.Context) (mgmtcontainerservice.ManagedClusterListResultPage, error)
ListClusterAdminCredentials(ctx context.Context, resourceGroupName string, resourceName string) (armcontainerservice.ManagedClustersClientListClusterAdminCredentialsResponse, error)
List(ctx context.Context) *runtime.Pager[armcontainerservice.ManagedClustersClientListResponse]
}
func (r *managedClustersClient) ListClusterAdminCredentials(ctx context.Context, resourceGroupName string, resourceName string, serverFqdn string) (mgmtcontainerservice.CredentialResults, error) {
return r.ManagedClustersClient.ListClusterAdminCredentials(ctx, resourceGroupName, resourceName, serverFqdn)
func (r *managedClustersClient) ListClusterAdminCredentials(ctx context.Context, resourceGroupName string, resourceName string) (armcontainerservice.ManagedClustersClientListClusterAdminCredentialsResponse, error) {
// TODO Determine if options need to be specified below
return r.ManagedClustersClient.ListClusterAdminCredentials(ctx, resourceGroupName, resourceName, nil)
}
func (r *managedClustersClient) List(ctx context.Context) (mgmtcontainerservice.ManagedClusterListResultPage, error) {
return r.ManagedClustersClient.List(ctx)
func (r *managedClustersClient) List(ctx context.Context) *runtime.Pager[armcontainerservice.ManagedClustersClientListResponse] {
// TODO Determine if options need to be specified below
return r.ManagedClustersClient.NewListPager(nil)
}

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

@ -4,8 +4,10 @@ package containerservice
// Licensed under the Apache License 2.0.
import (
mgmtcontainerservice "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2021-10-01/containerservice"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
armcontainerservice "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6"
"github.com/Azure/ARO-RP/pkg/util/azureclient"
)
@ -16,18 +18,45 @@ type ManagedClustersClient interface {
}
type managedClustersClient struct {
mgmtcontainerservice.ManagedClustersClient
*armcontainerservice.ManagedClustersClient
}
var _ ManagedClustersClient = &managedClustersClient{}
// NewDefaultManagedClustersClient creates a new ManagedClustersClient with default options
func NewDefaultManagedClustersClient(environment *azureclient.AROEnvironment, subscriptionId string, tokenizer azcore.TokenCredential) (ManagedClustersClient, error) {
options := arm.ClientOptions{
ClientOptions: azcore.ClientOptions{
Cloud: environment.Cloud,
},
}
return NewManagedClustersClient(subscriptionId, tokenizer, options)
}
// NewManagedClustersClient creates a new ManagedClustersClient
func NewManagedClustersClient(environment *azureclient.AROEnvironment, subscriptionID string, authorizer autorest.Authorizer) ManagedClustersClient {
client := mgmtcontainerservice.NewManagedClustersClientWithBaseURI(environment.ResourceManagerEndpoint, subscriptionID)
client.Authorizer = authorizer
client.Sender = azureclient.DecorateSenderWithLogging(client.Sender)
func NewManagedClustersClient(subscriptionId string, tokenizer azcore.TokenCredential, options arm.ClientOptions) (ManagedClustersClient, error) {
clientFactory, err := armcontainerservice.NewClientFactory(subscriptionId, tokenizer, &options)
if err != nil {
return nil, err
}
client := clientFactory.NewManagedClustersClient()
return &managedClustersClient{
ManagedClustersClient: client,
}
}, nil
}
// Creates a new ManagedClustersClient with specified transport, useful for testing with fakes
// https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/resourcemanager/containerservice/armcontainerservice/fake_example_test.go
func NewManagedClustersClientWithTransport(environment *azureclient.AROEnvironment, subscriptionId string, tokenizer azcore.TokenCredential, transporter policy.Transporter) (ManagedClustersClient, error) {
options := arm.ClientOptions{
ClientOptions: azcore.ClientOptions{
Cloud: environment.Cloud,
Transport: transporter,
},
}
return NewManagedClustersClient(subscriptionId, tokenizer, options)
}

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

@ -9,24 +9,26 @@ import (
"os"
"strings"
mgmtcontainerservice "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2021-10-01/containerservice"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
armcontainerservice "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/containerservice"
)
func getAksClusterByNameAndLocation(ctx context.Context, aksClusters mgmtcontainerservice.ManagedClusterListResultPage, aksClusterName, location string) (*mgmtcontainerservice.ManagedCluster, error) {
for aksClusters.NotDone() {
for _, cluster := range aksClusters.Values() {
if strings.EqualFold(*cluster.Name, aksClusterName) && strings.EqualFold(*cluster.Location, location) {
return &cluster, nil
}
}
err := aksClusters.NextWithContext(ctx)
func getAksClusterByNameAndLocation(ctx context.Context, aksClusters *runtime.Pager[armcontainerservice.ManagedClustersClientListResponse], aksClusterName, location string) (*armcontainerservice.ManagedCluster, error) {
for aksClusters.More() {
nr, err := aksClusters.NextPage(ctx)
if err != nil {
return nil, err
}
for _, cluster := range nr.Value {
if strings.EqualFold(*cluster.Name, aksClusterName) && strings.EqualFold(*cluster.Location, location) {
return cluster, nil
}
}
}
return nil, nil
}
@ -34,10 +36,7 @@ func getAksClusterByNameAndLocation(ctx context.Context, aksClusters mgmtcontain
func getAksShardKubeconfig(ctx context.Context, managedClustersClient containerservice.ManagedClustersClient, location string, shard int) (*rest.Config, error) {
aksClusterName := fmt.Sprintf("aro-aks-cluster-%03d", shard)
aksClusters, err := managedClustersClient.List(ctx)
if err != nil {
return nil, err
}
aksClusters := managedClustersClient.List(ctx)
aksCluster, err := getAksClusterByNameAndLocation(ctx, aksClusters, aksClusterName, location)
if err != nil {
@ -47,18 +46,18 @@ func getAksShardKubeconfig(ctx context.Context, managedClustersClient containers
return nil, fmt.Errorf("failed to find the AKS cluster %s in %s", aksClusterName, location)
}
aksResourceGroup := strings.Replace(*aksCluster.NodeResourceGroup, fmt.Sprintf("-aks%d", shard), "", 1)
aksResourceGroup := strings.Replace(*aksCluster.Properties.NodeResourceGroup, fmt.Sprintf("-aks%d", shard), "", 1)
res, err := managedClustersClient.ListClusterAdminCredentials(ctx, aksResourceGroup, aksClusterName, "public")
res, err := managedClustersClient.ListClusterAdminCredentials(ctx, aksResourceGroup, aksClusterName)
if err != nil {
return nil, err
}
return parseKubeconfig(*res.Kubeconfigs)
return parseKubeconfig(res.Kubeconfigs)
}
func parseKubeconfig(credentials []mgmtcontainerservice.CredentialResult) (*rest.Config, error) {
clientconfig, err := clientcmd.NewClientConfigFromBytes(*credentials[0].Value)
func parseKubeconfig(credentials []*armcontainerservice.CredentialResult) (*rest.Config, error) {
clientconfig, err := clientcmd.NewClientConfigFromBytes(credentials[0].Value)
if err != nil {
return nil, err
}

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

@ -6,69 +6,124 @@ package liveconfig
import (
"context"
"embed"
"errors"
"net/http"
"testing"
mgmtcontainerservice "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2021-10-01/containerservice"
"github.com/Azure/go-autorest/autorest/to"
"go.uber.org/mock/gomock"
azfake "github.com/Azure/azure-sdk-for-go/sdk/azcore/fake"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
armcontainerservice "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6"
fake "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6/fake"
mock_containerservice "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/mgmt/containerservice"
"github.com/Azure/ARO-RP/pkg/util/azureclient"
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/containerservice"
)
//go:embed testdata
var hiveEmbeddedFiles embed.FS
func SetupTestHarness() {
}
func TestProdHiveAdmin(t *testing.T) {
ctx := context.Background()
controller := gomock.NewController(t)
defer controller.Finish()
dummySubscription := "/fake/resource/id"
mcc := mock_containerservice.NewMockManagedClustersClient(controller)
managedClustersList := mgmtcontainerservice.ManagedClusterListResult{
Value: &[]mgmtcontainerservice.ManagedCluster{
{
Name: to.StringPtr("aro-aks-cluster-001"),
Location: to.StringPtr("eastus"),
ManagedClusterProperties: &mgmtcontainerservice.ManagedClusterProperties{
NodeResourceGroup: to.StringPtr("rp-eastus-aks1"),
},
managedClustersList := []*armcontainerservice.ManagedCluster{
{
Name: to.Ptr("aro-aks-cluster-001"),
Location: to.Ptr("eastus"),
Properties: &armcontainerservice.ManagedClusterProperties{
NodeResourceGroup: to.Ptr("rp-eastus-aks1"),
},
{
Name: to.StringPtr("aro-aks-cluster-002"),
Location: to.StringPtr("eastus"),
ManagedClusterProperties: &mgmtcontainerservice.ManagedClusterProperties{
NodeResourceGroup: to.StringPtr("rp-eastus-aks2"),
},
},
{
Name: to.Ptr("aro-aks-cluster-002"),
Location: to.Ptr("eastus"),
Properties: &armcontainerservice.ManagedClusterProperties{
NodeResourceGroup: to.Ptr("rp-eastus-aks2"),
},
},
}
resultPage := mgmtcontainerservice.NewManagedClusterListResultPage(managedClustersList, func(ctx context.Context, mclr mgmtcontainerservice.ManagedClusterListResult) (mgmtcontainerservice.ManagedClusterListResult, error) {
return mgmtcontainerservice.ManagedClusterListResult{}, nil
})
// Note that ".AnyTimes()" is not added to the 'List' function below to ensure it can only
// run once, which ensures that the caching for the credentials is taking place successfully
mcc.EXPECT().List(gomock.Any()).Return(resultPage, nil)
kc, err := hiveEmbeddedFiles.ReadFile("testdata/kubeconfigAdmin")
if err != nil {
t.Fatal(err)
}
kcresp := &[]mgmtcontainerservice.CredentialResult{
kcresp := []*armcontainerservice.CredentialResult{
{
Name: to.StringPtr("admin config"),
Value: to.ByteSlicePtr(kc),
Name: to.Ptr("admin config"),
Value: kc,
},
}
resp := mgmtcontainerservice.CredentialResults{
resp := armcontainerservice.CredentialResults{
Kubeconfigs: kcresp,
}
mcc.EXPECT().ListClusterAdminCredentials(gomock.Any(), "rp-eastus", "aro-aks-cluster-001", "public").Return(resp, nil)
r := armcontainerservice.ManagedClustersClientListClusterAdminCredentialsResponse{
CredentialResults: resp,
}
transporter := fake.ManagedClustersServer{
NewListPager: func(options *armcontainerservice.ManagedClustersClientListOptions) (resp azfake.PagerResponder[armcontainerservice.ManagedClustersClientListResponse]) {
pagerResp := azfake.PagerResponder[armcontainerservice.ManagedClustersClientListResponse]{}
pagerResp.AddPage(http.StatusOK, armcontainerservice.ManagedClustersClientListResponse{
ManagedClusterListResult: armcontainerservice.ManagedClusterListResult{
Value: managedClustersList,
},
}, nil)
return pagerResp
},
ListClusterAdminCredentials: func(ctx context.Context, resourceGroupName, resourceName string, options *armcontainerservice.ManagedClustersClientListClusterAdminCredentialsOptions) (resp azfake.Responder[armcontainerservice.ManagedClustersClientListClusterAdminCredentialsResponse], errResp azfake.ErrorResponder) {
nilErr := azfake.ErrorResponder{}
rResp := azfake.Responder[armcontainerservice.ManagedClustersClientListClusterAdminCredentialsResponse]{}
rResp.SetResponse(http.StatusOK, r, nil)
return rResp, nilErr
},
}
mcc, err := containerservice.NewManagedClustersClientWithTransport(&azureclient.PublicCloud, dummySubscription, &azfake.TokenCredential{}, fake.NewManagedClustersServerTransport(&transporter))
if err != nil {
t.Fatal(err)
}
resultPage := mcc.List(ctx)
if resultPage == nil {
t.Fatal(errors.New("result page is nil"))
}
hasMore := resultPage.More()
if !hasMore {
t.Fatal(errors.New("result page has no results"))
}
results, err := resultPage.NextPage(ctx)
if err != nil {
t.Fatal(err)
}
if len(results.Value) != len(managedClustersList) {
t.Fatal(errors.New("results page has an invalid number of results"))
}
if *results.Value[0].Name != *managedClustersList[0].Name {
t.Logf("expected %s to match %s", *results.Value[0].Name, *managedClustersList[0].Name)
t.Fatal(errors.New("expected name of first managed clusters list to match first page results"))
}
adminCredsResult, err := mcc.ListClusterAdminCredentials(ctx, "rp-eastus", "aro-ak-cluster-001")
if err != nil {
t.Fatal(err)
}
if len(adminCredsResult.CredentialResults.Kubeconfigs) != 1 {
t.Fatal(errors.New("invalid number of credentials returned"))
}
lc := NewProd("eastus", mcc)