зеркало из https://github.com/Azure/ARO-RP.git
Migrate Storage sdk to Track2 for allowing Managed Identity Cluster feature to disable shared access keys (#3878)
* ARO-9711 assign cluster storage blob contributor to fpsp/wimi * ARO-9711 migrate armstorage sdk to track2 * ARO-9711-use-non-account-key-auth-for-blobs-miwi-only * ARO-9711 update mock import to uber mocks * ARO-9711 fix e2e error for blob access * ARO-9711 resolve PR comments * ARO-9711 update Blob Client naming and comments * ARO-9711 resolved comments and removed repeated blobClient * ARO-9711 add clientOptions to blobManager constructor
This commit is contained in:
Родитель
91b9fda3d1
Коммит
3b6426c8c1
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/msi-dataplane/pkg/dataplane"
|
||||
|
@ -32,7 +33,6 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/metrics"
|
||||
aroclient "github.com/Azure/ARO-RP/pkg/operator/clientset/versioned"
|
||||
"github.com/Azure/ARO-RP/pkg/operator/deploy"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azblob"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armauthorization"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armmsi"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armnetwork"
|
||||
|
@ -43,6 +43,7 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/network"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/privatedns"
|
||||
"github.com/Azure/ARO-RP/pkg/util/billing"
|
||||
"github.com/Azure/ARO-RP/pkg/util/blob"
|
||||
"github.com/Azure/ARO-RP/pkg/util/clienthelper"
|
||||
"github.com/Azure/ARO-RP/pkg/util/dns"
|
||||
"github.com/Azure/ARO-RP/pkg/util/encryption"
|
||||
|
@ -51,6 +52,7 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/util/refreshable"
|
||||
"github.com/Azure/ARO-RP/pkg/util/storage"
|
||||
"github.com/Azure/ARO-RP/pkg/util/subnet"
|
||||
"github.com/Azure/ARO-RP/pkg/util/token"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
|
@ -105,7 +107,7 @@ type manager struct {
|
|||
storage storage.Manager
|
||||
subnet subnet.Manager // TODO: use armSubnets instead. https://issues.redhat.com/browse/ARO-4665
|
||||
graph graph.Manager
|
||||
rpBlob azblob.Manager
|
||||
rpBlob blob.Manager
|
||||
|
||||
ch clienthelper.Interface
|
||||
kubernetescli kubernetes.Interface
|
||||
|
@ -120,9 +122,10 @@ type manager struct {
|
|||
arocli aroclient.Interface
|
||||
imageregistrycli imageregistryclient.Interface
|
||||
|
||||
installViaHive bool
|
||||
adoptViaHive bool
|
||||
hiveClusterManager hive.ClusterManager
|
||||
installViaHive bool
|
||||
adoptViaHive bool
|
||||
hiveClusterManager hive.ClusterManager
|
||||
fpServicePrincipalID string
|
||||
|
||||
aroOperatorDeployer deploy.Operator
|
||||
|
||||
|
@ -162,6 +165,15 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
|||
return nil, err
|
||||
}
|
||||
|
||||
t, err := fpCredClusterTenant.GetToken(ctx, policy.TokenRequestOptions{Scopes: []string{_env.Environment().ResourceManagerScope}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fpspID, err := token.GetObjectId(t.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fpCredRPTenant, err := _env.FPNewClientCertificateCredential(_env.TenantID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -172,8 +184,6 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
|||
return nil, err
|
||||
}
|
||||
|
||||
storage := storage.NewManager(_env, r.SubscriptionID, fpAuthorizer)
|
||||
|
||||
installViaHive, err := _env.LiveConfig().InstallViaHive(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -221,7 +231,12 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
|||
return nil, err
|
||||
}
|
||||
|
||||
rpBlob, err := azblob.NewManager(_env.Environment(), _env.SubscriptionID(), msiCredential)
|
||||
storage, err := storage.NewManager(r.SubscriptionID, _env.Environment().StorageEndpointSuffix, fpCredClusterTenant, doc.OpenShiftCluster.UsesWorkloadIdentity(), clientOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rpBlob, err := blob.NewManager(_env.SubscriptionID(), msiCredential, clientOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -285,6 +300,7 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
|||
now: func() time.Time { return time.Now() },
|
||||
openShiftClusterDocumentVersioner: new(openShiftClusterDocumentVersionerService),
|
||||
platformWorkloadIdentityRolesByVersion: platformWorkloadIdentityRolesByVersion,
|
||||
fpServicePrincipalID: fpspID,
|
||||
}
|
||||
|
||||
if doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
mgmtnetwork "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-08-01/network"
|
||||
mgmtfeatures "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
|
@ -508,11 +507,11 @@ func (m *manager) Delete(ctx context.Context) error {
|
|||
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
m.log.Printf("deleting OIDC configuration")
|
||||
blobContainerURL := oidcbuilder.GenerateBlobContainerURL(m.env)
|
||||
azBlobClient, err := m.rpBlob.GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{})
|
||||
blobsClient, err := m.rpBlob.GetBlobsClient(blobContainerURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = oidcbuilder.DeleteOidcFolder(ctx, oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, m.doc.ID), azBlobClient)
|
||||
err = oidcbuilder.DeleteOidcFolder(ctx, oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, m.doc.ID), blobsClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
mgmtnetwork "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-08-01/network"
|
||||
mgmtfeatures "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
|
@ -25,6 +24,7 @@ import (
|
|||
|
||||
"github.com/Azure/ARO-RP/pkg/api"
|
||||
apisubnet "github.com/Azure/ARO-RP/pkg/api/util/subnet"
|
||||
"github.com/Azure/ARO-RP/pkg/cluster/graph"
|
||||
"github.com/Azure/ARO-RP/pkg/env"
|
||||
"github.com/Azure/ARO-RP/pkg/util/arm"
|
||||
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
||||
|
@ -62,12 +62,12 @@ func (m *manager) createOIDC(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
azBlobClient, err := m.rpBlob.GetAZBlobClient(oidcBuilder.GetBlobContainerURL(), &azblob.ClientOptions{})
|
||||
blobsClient, err := m.rpBlob.GetBlobsClient(oidcBuilder.GetBlobContainerURL())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = oidcBuilder.EnsureOIDCDocs(ctx, azBlobClient)
|
||||
err = oidcBuilder.EnsureOIDCDocs(ctx, blobsClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -191,8 +191,8 @@ func (m *manager) deployBaseResourceTemplate(ctx context.Context) error {
|
|||
|
||||
resources := []*arm.Resource{
|
||||
m.storageAccount(clusterStorageAccountName, azureRegion, ocpSubnets, true),
|
||||
m.storageAccountBlobContainer(clusterStorageAccountName, "ignition"),
|
||||
m.storageAccountBlobContainer(clusterStorageAccountName, "aro"),
|
||||
m.storageAccountBlobContainer(clusterStorageAccountName, graph.IgnitionContainer),
|
||||
m.storageAccountBlobContainer(clusterStorageAccountName, graph.GraphContainer),
|
||||
m.storageAccount(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, azureRegion, ocpSubnets, true),
|
||||
m.storageAccountBlobContainer(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, "image-registry"),
|
||||
m.clusterNSG(infraID, azureRegion),
|
||||
|
@ -239,6 +239,14 @@ func (m *manager) deployBaseResourceTemplate(ctx context.Context) error {
|
|||
t.Resources = append(t.Resources, m.denyAssignment())
|
||||
}
|
||||
|
||||
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
storageBlobContributorRBAC, err := m.fpspStorageBlobContributorRBAC(clusterStorageAccountName, m.fpServicePrincipalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Resources = append(t.Resources, storageBlobContributorRBAC)
|
||||
}
|
||||
|
||||
return arm.DeployTemplate(ctx, m.log, m.deployments, resourceGroup, "storage", t, nil)
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,20 @@ func (m *manager) workloadIdentityResourceGroupRBAC(roleID, objID string) *arm.R
|
|||
return r
|
||||
}
|
||||
|
||||
func (m *manager) fpspStorageBlobContributorRBAC(storageAccountName, principalID string) (*arm.Resource, error) {
|
||||
if !m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
return nil, fmt.Errorf("fpspStorageBlobContributorRBAC called for a Cluster Service Principal cluster")
|
||||
}
|
||||
resourceTypeStorageAccount := "Microsoft.Storage/storageAccounts"
|
||||
return rbac.ResourceRoleAssignmentWithName(
|
||||
rbac.RoleStorageBlobDataContributor,
|
||||
fmt.Sprintf("'%s'", principalID),
|
||||
resourceTypeStorageAccount,
|
||||
fmt.Sprintf("'%s'", storageAccountName),
|
||||
fmt.Sprintf("concat('%s', '/Microsoft.Authorization/', guid(resourceId('%s', '%s')))", storageAccountName, resourceTypeStorageAccount, storageAccountName),
|
||||
), nil
|
||||
}
|
||||
|
||||
// storageAccount will return storage account resource.
|
||||
// Legacy storage accounts (public) are not encrypted and cannot be retrofitted.
|
||||
// The flag controls this behavior in update/create.
|
||||
|
|
|
@ -4,14 +4,21 @@ package cluster
|
|||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
mgmtauthorization "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/api"
|
||||
"github.com/Azure/ARO-RP/pkg/util/arm"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
||||
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
|
||||
"github.com/Azure/ARO-RP/pkg/util/rbac"
|
||||
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||
)
|
||||
|
||||
func TestDenyAssignment(t *testing.T) {
|
||||
|
@ -88,3 +95,79 @@ func TestDenyAssignment(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFpspStorageBlobContributorRBAC(t *testing.T) {
|
||||
storageAccountName := "clustertest"
|
||||
fakePrincipalID := "fakeID"
|
||||
resourceType := "Microsoft.Storage/storageAccounts"
|
||||
resourceID := fmt.Sprintf("resourceId('%s', '%s')", resourceType, storageAccountName)
|
||||
tests := []struct {
|
||||
Name string
|
||||
ClusterDocument *api.OpenShiftClusterDocument
|
||||
ExpectedArmResource *arm.Resource
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
Name: "Fail : cluster with ServicePrincipalProfile",
|
||||
ClusterDocument: &api.OpenShiftClusterDocument{
|
||||
OpenShiftCluster: &api.OpenShiftCluster{
|
||||
Properties: api.OpenShiftClusterProperties{
|
||||
ClusterProfile: api.ClusterProfile{
|
||||
ResourceGroupID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-cluster",
|
||||
},
|
||||
ServicePrincipalProfile: &api.ServicePrincipalProfile{
|
||||
SPObjectID: fakeClusterSPObjectId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: "fpspStorageBlobContributorRBAC called for a Cluster Service Principal cluster",
|
||||
},
|
||||
{
|
||||
Name: "Success : cluster with PlatformWorkloadIdentityProfile",
|
||||
ClusterDocument: &api.OpenShiftClusterDocument{
|
||||
OpenShiftCluster: &api.OpenShiftCluster{
|
||||
Properties: api.OpenShiftClusterProperties{
|
||||
PlatformWorkloadIdentityProfile: &api.PlatformWorkloadIdentityProfile{},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedArmResource: &arm.Resource{
|
||||
Resource: mgmtauthorization.RoleAssignment{
|
||||
Name: to.StringPtr("[concat('clustertest', '/Microsoft.Authorization/', guid(" + resourceID + "))]"),
|
||||
Type: to.StringPtr(resourceType + "/providers/roleAssignments"),
|
||||
RoleAssignmentPropertiesWithScope: &mgmtauthorization.RoleAssignmentPropertiesWithScope{
|
||||
Scope: to.StringPtr("[" + resourceID + "]"),
|
||||
RoleDefinitionID: to.StringPtr("[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '" + rbac.RoleStorageBlobDataContributor + "')]"),
|
||||
PrincipalID: to.StringPtr("['" + fakePrincipalID + "']"),
|
||||
PrincipalType: mgmtauthorization.ServicePrincipal,
|
||||
},
|
||||
},
|
||||
APIVersion: azureclient.APIVersion("Microsoft.Authorization"),
|
||||
DependsOn: []string{
|
||||
"[" + resourceID + "]",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
controller := gomock.NewController(t)
|
||||
defer controller.Finish()
|
||||
|
||||
env := mock_env.NewMockInterface(controller)
|
||||
|
||||
m := &manager{
|
||||
doc: tt.ClusterDocument,
|
||||
env: env,
|
||||
}
|
||||
resource, err := m.fpspStorageBlobContributorRBAC(storageAccountName, fakePrincipalID)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
|
||||
if !reflect.DeepEqual(tt.ExpectedArmResource, resource) {
|
||||
t.Error("resultant ARM resource isn't the same as expected.")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,9 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/env"
|
||||
"github.com/Azure/ARO-RP/pkg/util/arm"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
||||
mock_azblob "github.com/Azure/ARO-RP/pkg/util/mocks/azblob"
|
||||
mock_azblob "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/azuresdk/azblob"
|
||||
mock_features "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/mgmt/features"
|
||||
mock_blob "github.com/Azure/ARO-RP/pkg/util/mocks/blob"
|
||||
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
|
||||
mock_subnet "github.com/Azure/ARO-RP/pkg/util/mocks/subnet"
|
||||
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
||||
|
@ -1436,11 +1437,12 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
}
|
||||
testOIDCKeyBitSize := 256
|
||||
uploadResponse := azblob.UploadBufferResponse{}
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
oc *api.OpenShiftClusterDocument
|
||||
mocks func(*mock_azblob.MockManager, *mock_env.MockInterface, *mock_azblob.MockAZBlobClient)
|
||||
mocks func(*mock_blob.MockManager, *mock_env.MockInterface, *mock_azblob.MockBlobsClient)
|
||||
wantedOIDCIssuer *api.OIDCIssuer
|
||||
wantErr string
|
||||
wantBoundServiceAccountSigningKey bool
|
||||
|
@ -1494,15 +1496,15 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
mocks: func(blob *mock_azblob.MockManager, menv *mock_env.MockInterface, azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
mocks: func(blob *mock_blob.MockManager, menv *mock_env.MockInterface, blobsClient *mock_azblob.MockBlobsClient) {
|
||||
menv.EXPECT().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any()).Return(nil)
|
||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any()).Return(nil)
|
||||
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, nil)
|
||||
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||
},
|
||||
wantedOIDCIssuer: pointerutils.ToPtr(api.OIDCIssuer(prodOIDCIssuer)),
|
||||
wantBoundServiceAccountSigningKey: true,
|
||||
|
@ -1521,16 +1523,16 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
mocks: func(blob *mock_azblob.MockManager, menv *mock_env.MockInterface, azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
mocks: func(blob *mock_blob.MockManager, menv *mock_env.MockInterface, blobsClient *mock_azblob.MockBlobsClient) {
|
||||
menv.EXPECT().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(true)
|
||||
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
||||
blob.EXPECT().GetContainerProperties(gomock.Any(), resourceGroupName, oidcStorageAccountName, oidcbuilder.WebContainer).Return(containerProperties, nil)
|
||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any()).Return(nil)
|
||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any()).Return(nil)
|
||||
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, nil)
|
||||
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||
},
|
||||
wantedOIDCIssuer: pointerutils.ToPtr(api.OIDCIssuer(devOIDCIssuer)),
|
||||
wantBoundServiceAccountSigningKey: true,
|
||||
|
@ -1549,7 +1551,7 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
mocks: func(blob *mock_azblob.MockManager, menv *mock_env.MockInterface, azblob *mock_azblob.MockAZBlobClient) {
|
||||
mocks: func(blob *mock_blob.MockManager, menv *mock_env.MockInterface, azblob *mock_azblob.MockBlobsClient) {
|
||||
menv.EXPECT().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(true)
|
||||
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
||||
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
||||
|
@ -1559,7 +1561,7 @@ func TestCreateOIDC(t *testing.T) {
|
|||
wantErr: "generic error",
|
||||
},
|
||||
{
|
||||
name: "Fail - azBlobClient creation failure",
|
||||
name: "Fail - blobsClient creation failure",
|
||||
oc: &api.OpenShiftClusterDocument{
|
||||
Key: strings.ToLower(resourceID),
|
||||
ID: clusterID,
|
||||
|
@ -1572,13 +1574,13 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
mocks: func(blob *mock_azblob.MockManager, menv *mock_env.MockInterface, azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
mocks: func(blob *mock_blob.MockManager, menv *mock_env.MockInterface, blobsClient *mock_azblob.MockBlobsClient) {
|
||||
menv.EXPECT().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, errors.New("generic error"))
|
||||
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, errors.New("generic error"))
|
||||
},
|
||||
wantBoundServiceAccountSigningKey: false,
|
||||
wantErr: "generic error",
|
||||
|
@ -1597,14 +1599,14 @@ func TestCreateOIDC(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
mocks: func(blob *mock_azblob.MockManager, menv *mock_env.MockInterface, azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
mocks: func(blob *mock_blob.MockManager, menv *mock_env.MockInterface, blobsClient *mock_azblob.MockBlobsClient) {
|
||||
menv.EXPECT().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any()).Return(errors.New("generic error"))
|
||||
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, nil)
|
||||
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any(), nil).Return(uploadResponse, errors.New("generic error"))
|
||||
},
|
||||
wantBoundServiceAccountSigningKey: false,
|
||||
wantErr: "generic error",
|
||||
|
@ -1616,11 +1618,11 @@ func TestCreateOIDC(t *testing.T) {
|
|||
|
||||
dbOpenShiftClusters, _ := testdatabase.NewFakeOpenShiftClusters()
|
||||
|
||||
rpBlobManager := mock_azblob.NewMockManager(controller)
|
||||
rpBlobManager := mock_blob.NewMockManager(controller)
|
||||
env := mock_env.NewMockInterface(controller)
|
||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
||||
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||
if tt.mocks != nil {
|
||||
tt.mocks(rpBlobManager, env, azBlobClient)
|
||||
tt.mocks(rpBlobManager, env, blobsClient)
|
||||
}
|
||||
|
||||
f := testdatabase.NewFixture().WithOpenShiftClusters(dbOpenShiftClusters)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"io"
|
||||
"strings"
|
||||
|
||||
mgmtstorage "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/env"
|
||||
|
@ -17,6 +17,12 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/util/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
GraphContainer = "aro"
|
||||
GraphBlob = "graph"
|
||||
IgnitionContainer = "ignition"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
Exists(ctx context.Context, resourceGroup, account string) (bool, error)
|
||||
LoadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, error)
|
||||
|
@ -43,13 +49,12 @@ func NewManager(env env.Interface, log *logrus.Entry, aead encryption.AEAD, stor
|
|||
func (m *manager) Exists(ctx context.Context, resourceGroup, account string) (bool, error) {
|
||||
m.log.Print("checking if graph exists")
|
||||
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, mgmtstorage.Permissions("r"), mgmtstorage.SignedResourceTypesO)
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, armstorage.Permissions("r"), armstorage.SignedResourceTypesO)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
aro := blobService.GetContainerReference("aro")
|
||||
return aro.GetBlobReference("graph").Exists()
|
||||
return blobService.BlobExists(ctx, GraphContainer, GraphBlob)
|
||||
}
|
||||
|
||||
func (m *manager) LoadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, error) {
|
||||
|
@ -73,20 +78,18 @@ func (m *manager) reloadAead(ctx context.Context) (err error) {
|
|||
func (m *manager) loadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, error) {
|
||||
m.log.Print("load persisted graph")
|
||||
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, mgmtstorage.Permissions("r"), mgmtstorage.SignedResourceTypesO)
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, armstorage.Permissions("r"), armstorage.SignedResourceTypesO)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aro := blobService.GetContainerReference("aro")
|
||||
cluster := aro.GetBlobReference("graph")
|
||||
rc, err := cluster.Get(nil)
|
||||
rc, err := blobService.DownloadStream(ctx, GraphContainer, GraphBlob, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
defer rc.Body.Close()
|
||||
|
||||
b, err := io.ReadAll(rc)
|
||||
b, err := io.ReadAll(rc.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ package cluster
|
|||
import (
|
||||
"context"
|
||||
|
||||
mgmtstorage "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
||||
azstorage "github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/cluster/graph"
|
||||
"github.com/Azure/ARO-RP/pkg/util/stringutils"
|
||||
)
|
||||
|
||||
|
@ -38,12 +38,10 @@ func (m *manager) removeBootstrapIgnition(ctx context.Context) error {
|
|||
resourceGroup := stringutils.LastTokenByte(m.doc.OpenShiftCluster.Properties.ClusterProfile.ResourceGroupID, '/')
|
||||
account := "cluster" + m.doc.OpenShiftCluster.Properties.StorageSuffix
|
||||
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, mgmtstorage.Permissions("d"), mgmtstorage.SignedResourceTypesC)
|
||||
blobService, err := m.storage.BlobService(ctx, resourceGroup, account, armstorage.Permissions("d"), armstorage.SignedResourceTypesC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bootstrapIgn := blobService.GetContainerReference("ignition")
|
||||
_, err = bootstrapIgn.DeleteIfExists(&azstorage.DeleteContainerOptions{})
|
||||
return err
|
||||
return blobService.DeleteContainer(ctx, graph.IgnitionContainer)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ const (
|
|||
|
||||
func (m *manager) generateWorkloadIdentityResources() (map[string]kruntime.Object, error) {
|
||||
if !m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
return nil, fmt.Errorf("generateWorkloadIdentityResources called for a CSP cluster")
|
||||
return nil, fmt.Errorf("generateWorkloadIdentityResources called for a Cluster Service Principal cluster")
|
||||
}
|
||||
|
||||
resources := map[string]kruntime.Object{}
|
||||
|
|
|
@ -36,7 +36,7 @@ func TestGenerateWorkloadIdentityResources(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "returns error if cluster is not using workload identity",
|
||||
wantErr: "generateWorkloadIdentityResources called for a CSP cluster",
|
||||
wantErr: "generateWorkloadIdentityResources called for a Cluster Service Principal cluster",
|
||||
},
|
||||
{
|
||||
name: "generates all expected resources",
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
azstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armstorage"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
GetContainerProperties(ctx context.Context, resourceGroupName string, accountName string, containerName string) (azstorage.AccountsClientGetPropertiesResponse, error)
|
||||
GetAZBlobClient(blobContainerURL string, options *azblob.ClientOptions) (AZBlobClient, error)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
cred azcore.TokenCredential
|
||||
account armstorage.AccountsClient
|
||||
}
|
||||
|
||||
func NewManager(environment *azureclient.AROEnvironment, subscriptionID string, credential azcore.TokenCredential) (Manager, error) {
|
||||
accountsClient, err := armstorage.NewAccountsClient(environment, subscriptionID, credential)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &manager{
|
||||
cred: credential,
|
||||
account: accountsClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetContainerProperties(ctx context.Context, resourceGroupName string, accountName string, containerName string) (azstorage.AccountsClientGetPropertiesResponse, error) {
|
||||
return m.account.GetProperties(ctx, resourceGroupName, accountName, &azstorage.AccountsClientGetPropertiesOptions{})
|
||||
}
|
||||
|
||||
func (m *manager) GetAZBlobClient(blobContainerURL string, options *azblob.ClientOptions) (AZBlobClient, error) {
|
||||
return NewAZBlobClient(blobContainerURL, m.cred, options)
|
||||
}
|
||||
|
||||
type AZBlobClient interface {
|
||||
UploadBuffer(ctx context.Context, containerName string, blobName string, buffer []byte) error
|
||||
DeleteBlob(ctx context.Context, containerName string, blobName string) error
|
||||
}
|
||||
|
||||
type azBlobClient struct {
|
||||
client *azblob.Client
|
||||
}
|
||||
|
||||
func NewAZBlobClient(blobContainerURL string, credential azcore.TokenCredential, options *azblob.ClientOptions) (AZBlobClient, error) {
|
||||
client, err := azblob.NewClient(blobContainerURL, credential, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &azBlobClient{client: client}, nil
|
||||
}
|
||||
|
||||
func (azBlobClient *azBlobClient) UploadBuffer(ctx context.Context, containerName string, blobName string, buffer []byte) error {
|
||||
_, err := azBlobClient.client.UploadBuffer(ctx, containerName, blobName, buffer, &azblob.UploadBufferOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (azBlobClient *azBlobClient) DeleteBlob(ctx context.Context, containerName string, blobName string) error {
|
||||
_, err := azBlobClient.client.DeleteBlob(ctx, containerName, blobName, &azblob.DeleteBlobOptions{})
|
||||
return err
|
||||
}
|
|
@ -5,18 +5,16 @@ package armstorage
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"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/resourcemanager/storage/armstorage"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
||||
)
|
||||
|
||||
// AccountsClient is a minimal interface for Azure AccountsClient
|
||||
type AccountsClient interface {
|
||||
GetProperties(ctx context.Context, resourceGroupName string, accountName string, options *armstorage.AccountsClientGetPropertiesOptions) (armstorage.AccountsClientGetPropertiesResponse, error)
|
||||
ListAccountSAS(ctx context.Context, resourceGroupName string, accountName string, parameters armstorage.AccountSasParameters, options *armstorage.AccountsClientListAccountSASOptions) (armstorage.AccountsClientListAccountSASResponse, error)
|
||||
}
|
||||
|
||||
type accountsClient struct {
|
||||
|
@ -26,18 +24,8 @@ type accountsClient struct {
|
|||
var _ AccountsClient = &accountsClient{}
|
||||
|
||||
// NewAccountsClient creates a new AccountsClient
|
||||
func NewAccountsClient(environment *azureclient.AROEnvironment, subscriptionID string, credential azcore.TokenCredential) (AccountsClient, error) {
|
||||
customRoundTripper := azureclient.NewCustomRoundTripper(http.DefaultTransport)
|
||||
|
||||
options := arm.ClientOptions{
|
||||
ClientOptions: azcore.ClientOptions{
|
||||
Cloud: environment.Cloud,
|
||||
Transport: &http.Client{
|
||||
Transport: customRoundTripper,
|
||||
},
|
||||
},
|
||||
}
|
||||
clientFactory, err := armstorage.NewClientFactory(subscriptionID, credential, &options)
|
||||
func NewAccountsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (AccountsClient, error) {
|
||||
clientFactory, err := armstorage.NewClientFactory(subscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package azblob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/storage/azblob"
|
||||
)
|
||||
|
||||
// BlobsClient is a minimal interface for Azure BlobsClient
|
||||
type BlobsClient interface {
|
||||
DownloadStream(ctx context.Context, containerName string, blobName string, o *azblob.DownloadStreamOptions) (azblob.DownloadStreamResponse, error)
|
||||
UploadBuffer(ctx context.Context, containerName string, blobName string, buffer []byte, o *azblob.UploadBufferOptions) (azblob.UploadBufferResponse, error)
|
||||
DeleteBlob(ctx context.Context, containerName string, blobName string, o *azblob.DeleteBlobOptions) (azblob.DeleteBlobResponse, error)
|
||||
BlobsClientAddons
|
||||
}
|
||||
|
||||
type blobsClient struct {
|
||||
*azblob.Client
|
||||
}
|
||||
|
||||
var _ BlobsClient = &blobsClient{}
|
||||
|
||||
// NewBlobsClientUsingSAS creates a new BlobsClient using SAS
|
||||
func NewBlobsClientUsingSAS(sasURL string, options *arm.ClientOptions) (*blobsClient, error) {
|
||||
azBlobOptions := &azblob.ClientOptions{
|
||||
ClientOptions: (*options).ClientOptions,
|
||||
}
|
||||
client, err := azblob.NewClientWithNoCredential(sasURL, azBlobOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &blobsClient{
|
||||
Client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewBlobsClientUsingEntra creates a new BlobsClient Microsoft Entra credentials
|
||||
func NewBlobsClientUsingEntra(serviceURL string, credential azcore.TokenCredential, options *arm.ClientOptions) (*blobsClient, error) {
|
||||
azBlobOptions := &azblob.ClientOptions{
|
||||
ClientOptions: (*options).ClientOptions,
|
||||
}
|
||||
client, err := azblob.NewClient(serviceURL, credential, azBlobOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &blobsClient{
|
||||
Client: client,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package azblob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
||||
)
|
||||
|
||||
type BlobsClientAddons interface {
|
||||
BlobExists(ctx context.Context, container string, blobPath string) (bool, error)
|
||||
DeleteContainer(ctx context.Context, container string) error
|
||||
}
|
||||
|
||||
func (client *blobsClient) BlobExists(ctx context.Context, container string, blobPath string) (bool, error) {
|
||||
blobRef := client.ServiceClient().NewContainerClient(container).NewBlobClient(blobPath)
|
||||
_, err := blobRef.GetProperties(ctx, nil)
|
||||
if err != nil {
|
||||
if bloberror.HasCode(
|
||||
err,
|
||||
bloberror.BlobNotFound,
|
||||
bloberror.ContainerNotFound,
|
||||
bloberror.ResourceNotFound,
|
||||
bloberror.CannotVerifyCopySource,
|
||||
) {
|
||||
return false, nil
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (client *blobsClient) DeleteContainer(ctx context.Context, container string) error {
|
||||
containerRef := client.ServiceClient().NewContainerClient(container)
|
||||
_, err := containerRef.Delete(ctx, nil)
|
||||
if err != nil {
|
||||
if bloberror.HasCode(
|
||||
err,
|
||||
bloberror.ContainerNotFound,
|
||||
bloberror.ResourceNotFound,
|
||||
) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package azblob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
//go:generate rm -rf ../../../../../mocks/azureclient/azuresdk/$GOPACKAGE
|
||||
//go:generate mockgen -destination=../../../mocks/azureclient/azuresdk/$GOPACKAGE/blobs.go -source=blobs.go
|
||||
//go:generate goimports -local=github.com/Azure/ARO-RP -e -w ../../../mocks/azureclient/azuresdk/$GOPACKAGE/blobs.go
|
|
@ -1,8 +1,8 @@
|
|||
package azblob
|
||||
package blob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
//go:generate rm -rf ../mocks/$GOPACKAGE
|
||||
//go:generate mockgen -destination=../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/$GOPACKAGE Manager,AZBlobClient
|
||||
//go:generate mockgen -destination=../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/$GOPACKAGE Manager
|
||||
//go:generate goimports -local=github.com/Azure/ARO-RP -e -w ../mocks/$GOPACKAGE/$GOPACKAGE.go
|
|
@ -0,0 +1,46 @@
|
|||
package blob
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
||||
azstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armstorage"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
GetContainerProperties(ctx context.Context, resourceGroupName string, accountName string, containerName string) (azstorage.AccountsClientGetPropertiesResponse, error)
|
||||
GetBlobsClient(blobContainerURL string) (azblob.BlobsClient, error)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
cred azcore.TokenCredential
|
||||
account armstorage.AccountsClient
|
||||
clientOptions *arm.ClientOptions
|
||||
}
|
||||
|
||||
func NewManager(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (Manager, error) {
|
||||
accountsClient, err := armstorage.NewAccountsClient(subscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &manager{
|
||||
cred: credential,
|
||||
account: accountsClient,
|
||||
clientOptions: options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetContainerProperties(ctx context.Context, resourceGroupName string, accountName string, containerName string) (azstorage.AccountsClientGetPropertiesResponse, error) {
|
||||
return m.account.GetProperties(ctx, resourceGroupName, accountName, &azstorage.AccountsClientGetPropertiesOptions{})
|
||||
}
|
||||
|
||||
func (m *manager) GetBlobsClient(blobContainerURL string) (azblob.BlobsClient, error) {
|
||||
return azblob.NewBlobsClientUsingEntra(blobContainerURL, m.cred, m.clientOptions)
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/Azure/ARO-RP/pkg/util/azblob (interfaces: Manager,AZBlobClient)
|
||||
// Source: github.com/Azure/ARO-RP/pkg/util/azblob (interfaces: Manager)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -destination=../mocks/azblob/azblob.go github.com/Azure/ARO-RP/pkg/util/azblob Manager,AZBlobClient
|
||||
// mockgen -destination=../mocks/azblob/azblob.go github.com/Azure/ARO-RP/pkg/util/azblob Manager
|
||||
//
|
||||
|
||||
// Package mock_azblob is a generated GoMock package.
|
||||
|
@ -14,10 +14,9 @@ import (
|
|||
reflect "reflect"
|
||||
|
||||
armstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
azblob0 "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
|
||||
azblob "github.com/Azure/ARO-RP/pkg/util/azblob"
|
||||
azblob "github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
// MockManager is a mock of Manager interface.
|
||||
|
@ -43,19 +42,19 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder {
|
|||
return m.recorder
|
||||
}
|
||||
|
||||
// GetAZBlobClient mocks base method.
|
||||
func (m *MockManager) GetAZBlobClient(arg0 string, arg1 *azblob0.ClientOptions) (azblob.AZBlobClient, error) {
|
||||
// GetBlobClient mocks base method.
|
||||
func (m *MockManager) GetBlobClient(arg0 string) (azblob.BlobsClient, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAZBlobClient", arg0, arg1)
|
||||
ret0, _ := ret[0].(azblob.AZBlobClient)
|
||||
ret := m.ctrl.Call(m, "GetBlobClient", arg0)
|
||||
ret0, _ := ret[0].(azblob.BlobsClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAZBlobClient indicates an expected call of GetAZBlobClient.
|
||||
func (mr *MockManagerMockRecorder) GetAZBlobClient(arg0, arg1 any) *gomock.Call {
|
||||
// GetBlobClient indicates an expected call of GetBlobClient.
|
||||
func (mr *MockManagerMockRecorder) GetBlobClient(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAZBlobClient", reflect.TypeOf((*MockManager)(nil).GetAZBlobClient), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlobClient", reflect.TypeOf((*MockManager)(nil).GetBlobClient), arg0)
|
||||
}
|
||||
|
||||
// GetContainerProperties mocks base method.
|
||||
|
@ -72,54 +71,3 @@ func (mr *MockManagerMockRecorder) GetContainerProperties(arg0, arg1, arg2, arg3
|
|||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContainerProperties", reflect.TypeOf((*MockManager)(nil).GetContainerProperties), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// MockAZBlobClient is a mock of AZBlobClient interface.
|
||||
type MockAZBlobClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockAZBlobClientMockRecorder
|
||||
}
|
||||
|
||||
// MockAZBlobClientMockRecorder is the mock recorder for MockAZBlobClient.
|
||||
type MockAZBlobClientMockRecorder struct {
|
||||
mock *MockAZBlobClient
|
||||
}
|
||||
|
||||
// NewMockAZBlobClient creates a new mock instance.
|
||||
func NewMockAZBlobClient(ctrl *gomock.Controller) *MockAZBlobClient {
|
||||
mock := &MockAZBlobClient{ctrl: ctrl}
|
||||
mock.recorder = &MockAZBlobClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockAZBlobClient) EXPECT() *MockAZBlobClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DeleteBlob mocks base method.
|
||||
func (m *MockAZBlobClient) DeleteBlob(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteBlob", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteBlob indicates an expected call of DeleteBlob.
|
||||
func (mr *MockAZBlobClientMockRecorder) DeleteBlob(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlob", reflect.TypeOf((*MockAZBlobClient)(nil).DeleteBlob), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// UploadBuffer mocks base method.
|
||||
func (m *MockAZBlobClient) UploadBuffer(arg0 context.Context, arg1, arg2 string, arg3 []byte) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UploadBuffer", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UploadBuffer indicates an expected call of UploadBuffer.
|
||||
func (mr *MockAZBlobClientMockRecorder) UploadBuffer(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadBuffer", reflect.TypeOf((*MockAZBlobClient)(nil).UploadBuffer), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
|
|
@ -54,3 +54,18 @@ func (mr *MockAccountsClientMockRecorder) GetProperties(arg0, arg1, arg2, arg3 a
|
|||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProperties", reflect.TypeOf((*MockAccountsClient)(nil).GetProperties), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ListAccountSAS mocks base method.
|
||||
func (m *MockAccountsClient) ListAccountSAS(arg0 context.Context, arg1, arg2 string, arg3 armstorage.AccountSasParameters, arg4 *armstorage.AccountsClientListAccountSASOptions) (armstorage.AccountsClientListAccountSASResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListAccountSAS", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(armstorage.AccountsClientListAccountSASResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListAccountSAS indicates an expected call of ListAccountSAS.
|
||||
func (mr *MockAccountsClientMockRecorder) ListAccountSAS(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAccountSAS", reflect.TypeOf((*MockAccountsClient)(nil).ListAccountSAS), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: blobs.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -destination=../../../mocks/azureclient/azuresdk/azblob/blobs.go -source=blobs.go
|
||||
//
|
||||
|
||||
// Package mock_azblob is a generated GoMock package.
|
||||
package mock_azblob
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
azblob "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockBlobsClient is a mock of BlobsClient interface.
|
||||
type MockBlobsClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBlobsClientMockRecorder
|
||||
}
|
||||
|
||||
// MockBlobsClientMockRecorder is the mock recorder for MockBlobsClient.
|
||||
type MockBlobsClientMockRecorder struct {
|
||||
mock *MockBlobsClient
|
||||
}
|
||||
|
||||
// NewMockBlobsClient creates a new mock instance.
|
||||
func NewMockBlobsClient(ctrl *gomock.Controller) *MockBlobsClient {
|
||||
mock := &MockBlobsClient{ctrl: ctrl}
|
||||
mock.recorder = &MockBlobsClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockBlobsClient) EXPECT() *MockBlobsClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BlobExists mocks base method.
|
||||
func (m *MockBlobsClient) BlobExists(ctx context.Context, container, blobPath string) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlobExists", ctx, container, blobPath)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlobExists indicates an expected call of BlobExists.
|
||||
func (mr *MockBlobsClientMockRecorder) BlobExists(ctx, container, blobPath any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlobExists", reflect.TypeOf((*MockBlobsClient)(nil).BlobExists), ctx, container, blobPath)
|
||||
}
|
||||
|
||||
// DeleteBlob mocks base method.
|
||||
func (m *MockBlobsClient) DeleteBlob(ctx context.Context, containerName, blobName string, o *azblob.DeleteBlobOptions) (azblob.DeleteBlobResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteBlob", ctx, containerName, blobName, o)
|
||||
ret0, _ := ret[0].(azblob.DeleteBlobResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DeleteBlob indicates an expected call of DeleteBlob.
|
||||
func (mr *MockBlobsClientMockRecorder) DeleteBlob(ctx, containerName, blobName, o any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlob", reflect.TypeOf((*MockBlobsClient)(nil).DeleteBlob), ctx, containerName, blobName, o)
|
||||
}
|
||||
|
||||
// DeleteContainer mocks base method.
|
||||
func (m *MockBlobsClient) DeleteContainer(ctx context.Context, container string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteContainer", ctx, container)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteContainer indicates an expected call of DeleteContainer.
|
||||
func (mr *MockBlobsClientMockRecorder) DeleteContainer(ctx, container any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteContainer", reflect.TypeOf((*MockBlobsClient)(nil).DeleteContainer), ctx, container)
|
||||
}
|
||||
|
||||
// DownloadStream mocks base method.
|
||||
func (m *MockBlobsClient) DownloadStream(ctx context.Context, containerName, blobName string, o *azblob.DownloadStreamOptions) (azblob.DownloadStreamResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DownloadStream", ctx, containerName, blobName, o)
|
||||
ret0, _ := ret[0].(azblob.DownloadStreamResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DownloadStream indicates an expected call of DownloadStream.
|
||||
func (mr *MockBlobsClientMockRecorder) DownloadStream(ctx, containerName, blobName, o any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadStream", reflect.TypeOf((*MockBlobsClient)(nil).DownloadStream), ctx, containerName, blobName, o)
|
||||
}
|
||||
|
||||
// UploadBuffer mocks base method.
|
||||
func (m *MockBlobsClient) UploadBuffer(ctx context.Context, containerName, blobName string, buffer []byte, o *azblob.UploadBufferOptions) (azblob.UploadBufferResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UploadBuffer", ctx, containerName, blobName, buffer, o)
|
||||
ret0, _ := ret[0].(azblob.UploadBufferResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// UploadBuffer indicates an expected call of UploadBuffer.
|
||||
func (mr *MockBlobsClientMockRecorder) UploadBuffer(ctx, containerName, blobName, buffer, o any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadBuffer", reflect.TypeOf((*MockBlobsClient)(nil).UploadBuffer), ctx, containerName, blobName, buffer, o)
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/Azure/ARO-RP/pkg/util/blob (interfaces: Manager)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -destination=../mocks/blob/blob.go github.com/Azure/ARO-RP/pkg/util/blob Manager
|
||||
//
|
||||
|
||||
// Package mock_blob is a generated GoMock package.
|
||||
package mock_blob
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
armstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
|
||||
azblob "github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
// MockManager is a mock of Manager interface.
|
||||
type MockManager struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockManagerMockRecorder
|
||||
}
|
||||
|
||||
// MockManagerMockRecorder is the mock recorder for MockManager.
|
||||
type MockManagerMockRecorder struct {
|
||||
mock *MockManager
|
||||
}
|
||||
|
||||
// NewMockManager creates a new mock instance.
|
||||
func NewMockManager(ctrl *gomock.Controller) *MockManager {
|
||||
mock := &MockManager{ctrl: ctrl}
|
||||
mock.recorder = &MockManagerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockManager) EXPECT() *MockManagerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetBlobsClient mocks base method.
|
||||
func (m *MockManager) GetBlobsClient(arg0 string) (azblob.BlobsClient, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBlobsClient", arg0)
|
||||
ret0, _ := ret[0].(azblob.BlobsClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBlobsClient indicates an expected call of GetBlobsClient.
|
||||
func (mr *MockManagerMockRecorder) GetBlobsClient(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlobsClient", reflect.TypeOf((*MockManager)(nil).GetBlobsClient), arg0)
|
||||
}
|
||||
|
||||
// GetContainerProperties mocks base method.
|
||||
func (m *MockManager) GetContainerProperties(arg0 context.Context, arg1, arg2, arg3 string) (armstorage.AccountsClientGetPropertiesResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetContainerProperties", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(armstorage.AccountsClientGetPropertiesResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetContainerProperties indicates an expected call of GetContainerProperties.
|
||||
func (mr *MockManagerMockRecorder) GetContainerProperties(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContainerProperties", reflect.TypeOf((*MockManager)(nil).GetContainerProperties), arg0, arg1, arg2, arg3)
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/Azure/ARO-RP/pkg/util/storage (interfaces: BlobStorageClient,Manager)
|
||||
// Source: github.com/Azure/ARO-RP/pkg/util/storage (interfaces: Manager)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -destination=../mocks/storage/storage.go github.com/Azure/ARO-RP/pkg/util/storage BlobStorageClient,Manager
|
||||
// mockgen -destination=../mocks/storage/storage.go github.com/Azure/ARO-RP/pkg/util/storage Manager
|
||||
//
|
||||
|
||||
// Package mock_storage is a generated GoMock package.
|
||||
|
@ -11,68 +11,14 @@ package mock_storage
|
|||
|
||||
import (
|
||||
context "context"
|
||||
io "io"
|
||||
reflect "reflect"
|
||||
|
||||
storage0 "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
||||
storage1 "github.com/Azure/azure-sdk-for-go/storage"
|
||||
armstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
|
||||
storage "github.com/Azure/ARO-RP/pkg/util/storage"
|
||||
azblob "github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
// MockBlobStorageClient is a mock of BlobStorageClient interface.
|
||||
type MockBlobStorageClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBlobStorageClientMockRecorder
|
||||
}
|
||||
|
||||
// MockBlobStorageClientMockRecorder is the mock recorder for MockBlobStorageClient.
|
||||
type MockBlobStorageClientMockRecorder struct {
|
||||
mock *MockBlobStorageClient
|
||||
}
|
||||
|
||||
// NewMockBlobStorageClient creates a new mock instance.
|
||||
func NewMockBlobStorageClient(ctrl *gomock.Controller) *MockBlobStorageClient {
|
||||
mock := &MockBlobStorageClient{ctrl: ctrl}
|
||||
mock.recorder = &MockBlobStorageClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockBlobStorageClient) EXPECT() *MockBlobStorageClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockBlobStorageClient) Get(arg0 string) (io.ReadCloser, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", arg0)
|
||||
ret0, _ := ret[0].(io.ReadCloser)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockBlobStorageClientMockRecorder) Get(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockBlobStorageClient)(nil).Get), arg0)
|
||||
}
|
||||
|
||||
// GetContainerReference mocks base method.
|
||||
func (m *MockBlobStorageClient) GetContainerReference(arg0 string) *storage1.Container {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetContainerReference", arg0)
|
||||
ret0, _ := ret[0].(*storage1.Container)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetContainerReference indicates an expected call of GetContainerReference.
|
||||
func (mr *MockBlobStorageClientMockRecorder) GetContainerReference(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContainerReference", reflect.TypeOf((*MockBlobStorageClient)(nil).GetContainerReference), arg0)
|
||||
}
|
||||
|
||||
// MockManager is a mock of Manager interface.
|
||||
type MockManager struct {
|
||||
ctrl *gomock.Controller
|
||||
|
@ -97,10 +43,10 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder {
|
|||
}
|
||||
|
||||
// BlobService mocks base method.
|
||||
func (m *MockManager) BlobService(arg0 context.Context, arg1, arg2 string, arg3 storage0.Permissions, arg4 storage0.SignedResourceTypes) (storage.BlobStorageClient, error) {
|
||||
func (m *MockManager) BlobService(arg0 context.Context, arg1, arg2 string, arg3 armstorage.Permissions, arg4 armstorage.SignedResourceTypes) (azblob.BlobsClient, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlobService", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(storage.BlobStorageClient)
|
||||
ret0, _ := ret[0].(azblob.BlobsClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
mock_azblob "github.com/Azure/ARO-RP/pkg/util/mocks/azblob"
|
||||
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||
)
|
||||
|
||||
|
@ -29,7 +28,6 @@ func TestKeyIDFromPublicKey(t *testing.T) {
|
|||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
mocks func(*mock_azblob.MockAZBlobClient)
|
||||
publicKey interface{}
|
||||
wantkid string
|
||||
wantErr string
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/env"
|
||||
utilazblob "github.com/Azure/ARO-RP/pkg/util/azblob"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -46,7 +46,7 @@ func GenerateBlobContainerURL(env env.Interface) string {
|
|||
return fmt.Sprintf("https://%s.blob.%s/%s", env.OIDCStorageAccountName(), env.Environment().StorageEndpointSuffix, WebContainer)
|
||||
}
|
||||
|
||||
func (b *OIDCBuilder) EnsureOIDCDocs(ctx context.Context, azBlobClient utilazblob.AZBlobClient) error {
|
||||
func (b *OIDCBuilder) EnsureOIDCDocs(ctx context.Context, blobsClient azblob.BlobsClient) error {
|
||||
// Create the OIDC configuration
|
||||
discoveryDocument := GenerateDiscoveryDocument(b.endpointURL)
|
||||
|
||||
|
@ -56,7 +56,7 @@ func (b *OIDCBuilder) EnsureOIDCDocs(ctx context.Context, azBlobClient utilazblo
|
|||
return err
|
||||
}
|
||||
|
||||
return populateOidcFolder(ctx, b.directory, discoveryDocument, jwks, azBlobClient)
|
||||
return populateOidcFolder(ctx, b.directory, discoveryDocument, jwks, blobsClient)
|
||||
}
|
||||
|
||||
func (b *OIDCBuilder) GetEndpointUrl() string {
|
||||
|
@ -71,28 +71,31 @@ func (b *OIDCBuilder) GetBlobContainerURL() string {
|
|||
return b.blobContainerURL
|
||||
}
|
||||
|
||||
func populateOidcFolder(ctx context.Context, directory string, discoveryDocument string, jwks []byte, azBlobClient utilazblob.AZBlobClient) error {
|
||||
err := azBlobClient.UploadBuffer(
|
||||
func populateOidcFolder(ctx context.Context, directory string, discoveryDocument string, jwks []byte, blobsClient azblob.BlobsClient) error {
|
||||
_, err := blobsClient.UploadBuffer(
|
||||
ctx,
|
||||
"",
|
||||
DocumentKey(directory, DiscoveryDocumentKey),
|
||||
[]byte(discoveryDocument),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return azBlobClient.UploadBuffer(
|
||||
_, err = blobsClient.UploadBuffer(
|
||||
ctx,
|
||||
"",
|
||||
DocumentKey(directory, JWKSKey),
|
||||
jwks,
|
||||
nil,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteOidcFolder(ctx context.Context, directory string, azBlobClient utilazblob.AZBlobClient) error {
|
||||
func DeleteOidcFolder(ctx context.Context, directory string, blobsClient azblob.BlobsClient) error {
|
||||
for _, key := range []string{DiscoveryDocumentKey, JWKSKey} {
|
||||
err := azBlobClient.DeleteBlob(ctx, "", DocumentKey(directory, key))
|
||||
_, err := blobsClient.DeleteBlob(ctx, "", DocumentKey(directory, key), nil)
|
||||
if err != nil && !bloberror.HasCode(err, bloberror.BlobNotFound) {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -18,11 +17,13 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
||||
mock_azblob "github.com/Azure/ARO-RP/pkg/util/mocks/azblob"
|
||||
mock_azblob "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/azuresdk/azblob"
|
||||
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
|
||||
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||
)
|
||||
|
@ -47,10 +48,11 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
|||
})
|
||||
|
||||
invalidKey := []byte("Invalid Key")
|
||||
uploadResponse := azblob.UploadBufferResponse{}
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
mocks func(*mock_azblob.MockAZBlobClient)
|
||||
mocks func(*mock_azblob.MockBlobsClient)
|
||||
oidcbuilder *OIDCBuilder
|
||||
wantErr string
|
||||
}{
|
||||
|
@ -63,13 +65,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
|||
directory: directoryName,
|
||||
endpointURL: endpointURL,
|
||||
},
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
||||
Return(nil)
|
||||
azblobClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any()).
|
||||
Return(nil)
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||
Return(uploadResponse, nil)
|
||||
blobsClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any(), nil).
|
||||
Return(uploadResponse, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -103,10 +105,10 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
|||
endpointURL: endpointURL,
|
||||
directory: directoryName,
|
||||
},
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
||||
Return(errors.New("generic error"))
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||
Return(uploadResponse, errors.New("generic error"))
|
||||
},
|
||||
wantErr: "generic error",
|
||||
},
|
||||
|
@ -119,13 +121,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
|||
endpointURL: endpointURL,
|
||||
directory: directoryName,
|
||||
},
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
||||
Return(nil)
|
||||
azblobClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any()).
|
||||
Return(errors.New("generic error"))
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||
Return(uploadResponse, nil)
|
||||
blobsClient.EXPECT().
|
||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any(), nil).
|
||||
Return(uploadResponse, errors.New("generic error"))
|
||||
},
|
||||
wantErr: "generic error",
|
||||
},
|
||||
|
@ -145,13 +147,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
|||
controller := gomock.NewController(t)
|
||||
defer controller.Finish()
|
||||
|
||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
||||
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||
|
||||
if tt.mocks != nil {
|
||||
tt.mocks(azBlobClient)
|
||||
tt.mocks(blobsClient)
|
||||
}
|
||||
|
||||
err = tt.oidcbuilder.EnsureOIDCDocs(ctx, azBlobClient)
|
||||
err = tt.oidcbuilder.EnsureOIDCDocs(ctx, blobsClient)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
|
||||
if tt.oidcbuilder.GetEndpointUrl() != tt.oidcbuilder.endpointURL {
|
||||
|
@ -226,39 +228,40 @@ ERROR CODE: Generic Error
|
|||
Generic Error
|
||||
--------------------------------------------------------------------------------
|
||||
`
|
||||
deleteResponse := azblob.DeleteBlobResponse{}
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
mocks func(*mock_azblob.MockAZBlobClient)
|
||||
mocks func(*mock_azblob.MockBlobsClient)
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "Success",
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(nil)
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(nil)
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, nil)
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fail - Generic Error when deleting DiscoveryDocument",
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrGeneric)
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrGeneric)
|
||||
},
|
||||
wantErr: genericErrorMessage,
|
||||
},
|
||||
{
|
||||
name: "Fail - Generic Error when deleting JWKS",
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrBlobNotFound)
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(respErrGeneric)
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrBlobNotFound)
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, respErrGeneric)
|
||||
},
|
||||
wantErr: genericErrorMessage,
|
||||
},
|
||||
{
|
||||
name: "Success - One Blob exists and other doesn't",
|
||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrBlobNotFound)
|
||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(nil)
|
||||
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrBlobNotFound)
|
||||
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, nil)
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
@ -266,13 +269,13 @@ Generic Error
|
|||
controller := gomock.NewController(t)
|
||||
defer controller.Finish()
|
||||
|
||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
||||
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||
|
||||
if tt.mocks != nil {
|
||||
tt.mocks(azBlobClient)
|
||||
tt.mocks(blobsClient)
|
||||
}
|
||||
|
||||
err := DeleteOidcFolder(ctx, directoryName, azBlobClient)
|
||||
err := DeleteOidcFolder(ctx, directoryName, blobsClient)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func NewPlatformWorkloadIdentityRolesByVersionService() *PlatformWorkloadIdentit
|
|||
// PopulatePlatformWorkloadIdentityRolesByVersion aims to populate platformWorkloadIdentityRoles for current OpenShift minor version and also for UpgradeableTo minor version if provided and is greater than the current version
|
||||
func (service *PlatformWorkloadIdentityRolesByVersionService) PopulatePlatformWorkloadIdentityRolesByVersion(ctx context.Context, oc *api.OpenShiftCluster, dbPlatformWorkloadIdentityRoleSets database.PlatformWorkloadIdentityRoleSets) error {
|
||||
if !oc.UsesWorkloadIdentity() {
|
||||
return fmt.Errorf("PopulatePlatformWorkloadIdentityRolesByVersion called for a CSP cluster")
|
||||
return fmt.Errorf("PopulatePlatformWorkloadIdentityRolesByVersion called for a Cluster Service Principal cluster")
|
||||
}
|
||||
currentOpenShiftVersion, err := version.ParseVersion(oc.Properties.ClusterProfile.Version)
|
||||
if err != nil {
|
||||
|
|
|
@ -34,14 +34,14 @@ func TestNewPlatformWorkloadIdentityRolesByVersion(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantErr: "PopulatePlatformWorkloadIdentityRolesByVersion called for a CSP cluster",
|
||||
wantErr: "PopulatePlatformWorkloadIdentityRolesByVersion called for a Cluster Service Principal cluster",
|
||||
},
|
||||
{
|
||||
name: "Fail - Exit the func for non MIWI clusters that has no PlatformWorkloadIdentityProfile or ServicePrincipalProfile",
|
||||
oc: &api.OpenShiftCluster{
|
||||
Properties: api.OpenShiftClusterProperties{},
|
||||
},
|
||||
wantErr: "PopulatePlatformWorkloadIdentityRolesByVersion called for a CSP cluster",
|
||||
wantErr: "PopulatePlatformWorkloadIdentityRolesByVersion called for a Cluster Service Principal cluster",
|
||||
},
|
||||
{
|
||||
name: "Success - The role set document found for the cluster version",
|
||||
|
|
|
@ -4,5 +4,5 @@ package storage
|
|||
// Licensed under the Apache License 2.0.
|
||||
|
||||
//go:generate rm -rf ../mocks/$GOPACKAGE
|
||||
//go:generate mockgen -destination=../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/$GOPACKAGE BlobStorageClient,Manager
|
||||
//go:generate mockgen -destination=../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/$GOPACKAGE Manager
|
||||
//go:generate goimports -local=github.com/Azure/ARO-RP -e -w ../mocks/$GOPACKAGE/$GOPACKAGE.go
|
||||
|
|
|
@ -5,49 +5,56 @@ package storage
|
|||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mgmtstorage "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
||||
azstorage "github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"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/to"
|
||||
storagesdk "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/api"
|
||||
"github.com/Azure/ARO-RP/pkg/env"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/storage"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armstorage"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azblob"
|
||||
)
|
||||
|
||||
type BlobStorageClient interface {
|
||||
Get(uri string) (io.ReadCloser, error)
|
||||
GetContainerReference(name string) *azstorage.Container
|
||||
}
|
||||
|
||||
type Manager interface {
|
||||
BlobService(ctx context.Context, resourceGroup, account string, p mgmtstorage.Permissions, r mgmtstorage.SignedResourceTypes) (BlobStorageClient, error)
|
||||
BlobService(ctx context.Context, resourceGroup, account string, p storagesdk.Permissions, r storagesdk.SignedResourceTypes) (azblob.BlobsClient, error)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
env env.Core
|
||||
storageAccounts storage.AccountsClient
|
||||
storageAccounts armstorage.AccountsClient
|
||||
credential azcore.TokenCredential
|
||||
usesWorkloadIdentity bool
|
||||
storageEndpointSuffix string
|
||||
clientOptions *arm.ClientOptions
|
||||
}
|
||||
|
||||
func NewManager(env env.Core, subscriptionID string, authorizer autorest.Authorizer) Manager {
|
||||
return &manager{
|
||||
env: env,
|
||||
storageAccounts: storage.NewAccountsClient(env.Environment(), subscriptionID, authorizer),
|
||||
func NewManager(subscriptionID, storageEndpointSuffix string, credential azcore.TokenCredential, usesWorkloadIdentity bool, options *arm.ClientOptions) (m Manager, err error) {
|
||||
var accountsClient armstorage.AccountsClient
|
||||
if !usesWorkloadIdentity {
|
||||
accountsClient, err = armstorage.NewAccountsClient(subscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &manager{
|
||||
storageAccounts: accountsClient,
|
||||
usesWorkloadIdentity: usesWorkloadIdentity,
|
||||
credential: credential,
|
||||
storageEndpointSuffix: storageEndpointSuffix,
|
||||
clientOptions: options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getCorrectErrWhenTooManyRequests(err error) error {
|
||||
detailedError, ok := err.(autorest.DetailedError)
|
||||
responseError, ok := err.(*azcore.ResponseError)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
if detailedError.StatusCode != http.StatusTooManyRequests {
|
||||
if responseError.StatusCode != http.StatusTooManyRequests {
|
||||
return err
|
||||
}
|
||||
msg := "Requests are being throttled due to Azure Storage limits being exceeded. Please visit https://learn.microsoft.com/en-us/azure/openshift/troubleshoot#exceeding-azure-storage-limits for more details."
|
||||
|
@ -66,43 +73,30 @@ func getCorrectErrWhenTooManyRequests(err error) error {
|
|||
return cloudError
|
||||
}
|
||||
|
||||
func (m *manager) BlobService(ctx context.Context, resourceGroup, account string, p mgmtstorage.Permissions, r mgmtstorage.SignedResourceTypes) (BlobStorageClient, error) {
|
||||
func (m *manager) BlobService(ctx context.Context, resourceGroup, account string, p storagesdk.Permissions, r storagesdk.SignedResourceTypes) (blobsClient azblob.BlobsClient, err error) {
|
||||
serviceURL := fmt.Sprintf("https://%s.blob.%s", account, m.storageEndpointSuffix)
|
||||
if m.usesWorkloadIdentity {
|
||||
return azblob.NewBlobsClientUsingEntra(serviceURL, m.credential, m.clientOptions)
|
||||
}
|
||||
|
||||
t := time.Now().UTC().Truncate(time.Second)
|
||||
res, err := m.storageAccounts.ListAccountSAS(ctx, resourceGroup, account, mgmtstorage.AccountSasParameters{
|
||||
Services: mgmtstorage.ServicesB,
|
||||
ResourceTypes: r,
|
||||
Permissions: p,
|
||||
Protocols: mgmtstorage.HTTPProtocolHTTPS,
|
||||
SharedAccessStartTime: &date.Time{Time: t},
|
||||
SharedAccessExpiryTime: &date.Time{Time: t.Add(24 * time.Hour)},
|
||||
})
|
||||
res, err := m.storageAccounts.ListAccountSAS(ctx, resourceGroup, account, storagesdk.AccountSasParameters{
|
||||
Services: to.Ptr(storagesdk.ServicesB),
|
||||
ResourceTypes: to.Ptr(r),
|
||||
Permissions: to.Ptr(p),
|
||||
Protocols: to.Ptr(storagesdk.HTTPProtocolHTTPS),
|
||||
SharedAccessStartTime: &t,
|
||||
SharedAccessExpiryTime: to.Ptr(t.Add(24 * time.Hour)),
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return nil, getCorrectErrWhenTooManyRequests(err)
|
||||
}
|
||||
|
||||
v, err := url.ParseQuery(*res.AccountSasToken)
|
||||
_, err = url.ParseQuery(*res.AccountSasToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blobcli := azstorage.NewAccountSASClient(account, v, (*m.env.Environment()).Environment).GetBlobService()
|
||||
|
||||
return &wrappedStorageClient{&blobcli}, nil
|
||||
}
|
||||
|
||||
type wrappedStorageClient struct {
|
||||
client *azstorage.BlobStorageClient
|
||||
}
|
||||
|
||||
func (c *wrappedStorageClient) GetContainerReference(name string) *azstorage.Container {
|
||||
return c.client.GetContainerReference(name)
|
||||
}
|
||||
|
||||
func (c *wrappedStorageClient) Get(uri string) (io.ReadCloser, error) {
|
||||
parts := strings.Split(uri, "/")
|
||||
|
||||
container := c.client.GetContainerReference(parts[1])
|
||||
b := container.GetBlobReference(parts[2])
|
||||
|
||||
return b.Get(nil)
|
||||
sasURL := fmt.Sprintf("%s/?%s", serviceURL, *res.AccountSasToken)
|
||||
return azblob.NewBlobsClientUsingSAS(sasURL, m.clientOptions)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче