зеркало из 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"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||||
"github.com/Azure/go-autorest/autorest"
|
"github.com/Azure/go-autorest/autorest"
|
||||||
"github.com/Azure/go-autorest/autorest/azure"
|
"github.com/Azure/go-autorest/autorest/azure"
|
||||||
"github.com/Azure/msi-dataplane/pkg/dataplane"
|
"github.com/Azure/msi-dataplane/pkg/dataplane"
|
||||||
|
@ -32,7 +33,6 @@ import (
|
||||||
"github.com/Azure/ARO-RP/pkg/metrics"
|
"github.com/Azure/ARO-RP/pkg/metrics"
|
||||||
aroclient "github.com/Azure/ARO-RP/pkg/operator/clientset/versioned"
|
aroclient "github.com/Azure/ARO-RP/pkg/operator/clientset/versioned"
|
||||||
"github.com/Azure/ARO-RP/pkg/operator/deploy"
|
"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/armauthorization"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armmsi"
|
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armmsi"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armnetwork"
|
"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/network"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/privatedns"
|
"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/billing"
|
||||||
|
"github.com/Azure/ARO-RP/pkg/util/blob"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/clienthelper"
|
"github.com/Azure/ARO-RP/pkg/util/clienthelper"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/dns"
|
"github.com/Azure/ARO-RP/pkg/util/dns"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/encryption"
|
"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/refreshable"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/storage"
|
"github.com/Azure/ARO-RP/pkg/util/storage"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/subnet"
|
"github.com/Azure/ARO-RP/pkg/util/subnet"
|
||||||
|
"github.com/Azure/ARO-RP/pkg/util/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
|
@ -105,7 +107,7 @@ type manager struct {
|
||||||
storage storage.Manager
|
storage storage.Manager
|
||||||
subnet subnet.Manager // TODO: use armSubnets instead. https://issues.redhat.com/browse/ARO-4665
|
subnet subnet.Manager // TODO: use armSubnets instead. https://issues.redhat.com/browse/ARO-4665
|
||||||
graph graph.Manager
|
graph graph.Manager
|
||||||
rpBlob azblob.Manager
|
rpBlob blob.Manager
|
||||||
|
|
||||||
ch clienthelper.Interface
|
ch clienthelper.Interface
|
||||||
kubernetescli kubernetes.Interface
|
kubernetescli kubernetes.Interface
|
||||||
|
@ -120,9 +122,10 @@ type manager struct {
|
||||||
arocli aroclient.Interface
|
arocli aroclient.Interface
|
||||||
imageregistrycli imageregistryclient.Interface
|
imageregistrycli imageregistryclient.Interface
|
||||||
|
|
||||||
installViaHive bool
|
installViaHive bool
|
||||||
adoptViaHive bool
|
adoptViaHive bool
|
||||||
hiveClusterManager hive.ClusterManager
|
hiveClusterManager hive.ClusterManager
|
||||||
|
fpServicePrincipalID string
|
||||||
|
|
||||||
aroOperatorDeployer deploy.Operator
|
aroOperatorDeployer deploy.Operator
|
||||||
|
|
||||||
|
@ -162,6 +165,15 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
||||||
return nil, err
|
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())
|
fpCredRPTenant, err := _env.FPNewClientCertificateCredential(_env.TenantID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -172,8 +184,6 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
storage := storage.NewManager(_env, r.SubscriptionID, fpAuthorizer)
|
|
||||||
|
|
||||||
installViaHive, err := _env.LiveConfig().InstallViaHive(ctx)
|
installViaHive, err := _env.LiveConfig().InstallViaHive(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -221,7 +231,12 @@ func New(ctx context.Context, log *logrus.Entry, _env env.Interface, db database
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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() },
|
now: func() time.Time { return time.Now() },
|
||||||
openShiftClusterDocumentVersioner: new(openShiftClusterDocumentVersionerService),
|
openShiftClusterDocumentVersioner: new(openShiftClusterDocumentVersionerService),
|
||||||
platformWorkloadIdentityRolesByVersion: platformWorkloadIdentityRolesByVersion,
|
platformWorkloadIdentityRolesByVersion: platformWorkloadIdentityRolesByVersion,
|
||||||
|
fpServicePrincipalID: fpspID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
if doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
|
"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"
|
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"
|
mgmtfeatures "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features"
|
||||||
"github.com/Azure/go-autorest/autorest"
|
"github.com/Azure/go-autorest/autorest"
|
||||||
|
@ -508,11 +507,11 @@ func (m *manager) Delete(ctx context.Context) error {
|
||||||
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||||
m.log.Printf("deleting OIDC configuration")
|
m.log.Printf("deleting OIDC configuration")
|
||||||
blobContainerURL := oidcbuilder.GenerateBlobContainerURL(m.env)
|
blobContainerURL := oidcbuilder.GenerateBlobContainerURL(m.env)
|
||||||
azBlobClient, err := m.rpBlob.GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{})
|
blobsClient, err := m.rpBlob.GetBlobsClient(blobContainerURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
|
"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"
|
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"
|
mgmtfeatures "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features"
|
||||||
"github.com/Azure/go-autorest/autorest"
|
"github.com/Azure/go-autorest/autorest"
|
||||||
|
@ -25,6 +24,7 @@ import (
|
||||||
|
|
||||||
"github.com/Azure/ARO-RP/pkg/api"
|
"github.com/Azure/ARO-RP/pkg/api"
|
||||||
apisubnet "github.com/Azure/ARO-RP/pkg/api/util/subnet"
|
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/env"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/arm"
|
"github.com/Azure/ARO-RP/pkg/util/arm"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
||||||
|
@ -62,12 +62,12 @@ func (m *manager) createOIDC(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
azBlobClient, err := m.rpBlob.GetAZBlobClient(oidcBuilder.GetBlobContainerURL(), &azblob.ClientOptions{})
|
blobsClient, err := m.rpBlob.GetBlobsClient(oidcBuilder.GetBlobContainerURL())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = oidcBuilder.EnsureOIDCDocs(ctx, azBlobClient)
|
err = oidcBuilder.EnsureOIDCDocs(ctx, blobsClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -191,8 +191,8 @@ func (m *manager) deployBaseResourceTemplate(ctx context.Context) error {
|
||||||
|
|
||||||
resources := []*arm.Resource{
|
resources := []*arm.Resource{
|
||||||
m.storageAccount(clusterStorageAccountName, azureRegion, ocpSubnets, true),
|
m.storageAccount(clusterStorageAccountName, azureRegion, ocpSubnets, true),
|
||||||
m.storageAccountBlobContainer(clusterStorageAccountName, "ignition"),
|
m.storageAccountBlobContainer(clusterStorageAccountName, graph.IgnitionContainer),
|
||||||
m.storageAccountBlobContainer(clusterStorageAccountName, "aro"),
|
m.storageAccountBlobContainer(clusterStorageAccountName, graph.GraphContainer),
|
||||||
m.storageAccount(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, azureRegion, ocpSubnets, true),
|
m.storageAccount(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, azureRegion, ocpSubnets, true),
|
||||||
m.storageAccountBlobContainer(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, "image-registry"),
|
m.storageAccountBlobContainer(m.doc.OpenShiftCluster.Properties.ImageRegistryStorageAccountName, "image-registry"),
|
||||||
m.clusterNSG(infraID, azureRegion),
|
m.clusterNSG(infraID, azureRegion),
|
||||||
|
@ -239,6 +239,14 @@ func (m *manager) deployBaseResourceTemplate(ctx context.Context) error {
|
||||||
t.Resources = append(t.Resources, m.denyAssignment())
|
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)
|
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
|
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.
|
// storageAccount will return storage account resource.
|
||||||
// Legacy storage accounts (public) are not encrypted and cannot be retrofitted.
|
// Legacy storage accounts (public) are not encrypted and cannot be retrofitted.
|
||||||
// The flag controls this behavior in update/create.
|
// The flag controls this behavior in update/create.
|
||||||
|
|
|
@ -4,14 +4,21 @@ package cluster
|
||||||
// Licensed under the Apache License 2.0.
|
// Licensed under the Apache License 2.0.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
mgmtauthorization "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization"
|
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/Azure/go-autorest/autorest/to"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"go.uber.org/mock/gomock"
|
||||||
|
|
||||||
"github.com/Azure/ARO-RP/pkg/api"
|
"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) {
|
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/env"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/arm"
|
"github.com/Azure/ARO-RP/pkg/util/arm"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
"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_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_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
|
||||||
mock_subnet "github.com/Azure/ARO-RP/pkg/util/mocks/subnet"
|
mock_subnet "github.com/Azure/ARO-RP/pkg/util/mocks/subnet"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
|
||||||
|
@ -1436,11 +1437,12 @@ func TestCreateOIDC(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
testOIDCKeyBitSize := 256
|
testOIDCKeyBitSize := 256
|
||||||
|
uploadResponse := azblob.UploadBufferResponse{}
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
name string
|
||||||
oc *api.OpenShiftClusterDocument
|
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
|
wantedOIDCIssuer *api.OIDCIssuer
|
||||||
wantErr string
|
wantErr string
|
||||||
wantBoundServiceAccountSigningKey bool
|
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().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, nil)
|
||||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any()).Return(nil)
|
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any()).Return(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)),
|
wantedOIDCIssuer: pointerutils.ToPtr(api.OIDCIssuer(prodOIDCIssuer)),
|
||||||
wantBoundServiceAccountSigningKey: true,
|
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().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(true)
|
||||||
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
||||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||||
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
||||||
blob.EXPECT().GetContainerProperties(gomock.Any(), resourceGroupName, oidcStorageAccountName, oidcbuilder.WebContainer).Return(containerProperties, nil)
|
blob.EXPECT().GetContainerProperties(gomock.Any(), resourceGroupName, oidcStorageAccountName, oidcbuilder.WebContainer).Return(containerProperties, nil)
|
||||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, nil)
|
||||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any()).Return(nil)
|
blobsClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.DiscoveryDocumentKey), gomock.Any(), nil).Return(uploadResponse, nil)
|
||||||
azblobClient.EXPECT().UploadBuffer(gomock.Any(), "", oidcbuilder.DocumentKey(oidcbuilder.GetBlobName(m.subscriptionDoc.Subscription.Properties.TenantID, clusterID), oidcbuilder.JWKSKey), gomock.Any()).Return(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)),
|
wantedOIDCIssuer: pointerutils.ToPtr(api.OIDCIssuer(devOIDCIssuer)),
|
||||||
wantBoundServiceAccountSigningKey: true,
|
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().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(true)
|
||||||
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
menv.EXPECT().ResourceGroup().Return(resourceGroupName)
|
||||||
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
menv.EXPECT().OIDCStorageAccountName().AnyTimes().Return(oidcStorageAccountName)
|
||||||
|
@ -1559,7 +1561,7 @@ func TestCreateOIDC(t *testing.T) {
|
||||||
wantErr: "generic error",
|
wantErr: "generic error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Fail - azBlobClient creation failure",
|
name: "Fail - blobsClient creation failure",
|
||||||
oc: &api.OpenShiftClusterDocument{
|
oc: &api.OpenShiftClusterDocument{
|
||||||
Key: strings.ToLower(resourceID),
|
Key: strings.ToLower(resourceID),
|
||||||
ID: clusterID,
|
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().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
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,
|
wantBoundServiceAccountSigningKey: false,
|
||||||
wantErr: "generic error",
|
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().FeatureIsSet(env.FeatureRequireOIDCStorageWebEndpoint).Return(false)
|
||||||
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
menv.EXPECT().OIDCKeyBitSize().Return(testOIDCKeyBitSize)
|
||||||
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
menv.EXPECT().OIDCEndpoint().Return(afdEndpoint)
|
||||||
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
menv.EXPECT().OIDCStorageAccountName().Return(oidcStorageAccountName)
|
||||||
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
menv.EXPECT().Environment().Return(&azureclient.PublicCloud)
|
||||||
blob.EXPECT().GetAZBlobClient(blobContainerURL, &azblob.ClientOptions{}).Return(azblobClient, nil)
|
blob.EXPECT().GetBlobsClient(blobContainerURL).Return(blobsClient, 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"))
|
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,
|
wantBoundServiceAccountSigningKey: false,
|
||||||
wantErr: "generic error",
|
wantErr: "generic error",
|
||||||
|
@ -1616,11 +1618,11 @@ func TestCreateOIDC(t *testing.T) {
|
||||||
|
|
||||||
dbOpenShiftClusters, _ := testdatabase.NewFakeOpenShiftClusters()
|
dbOpenShiftClusters, _ := testdatabase.NewFakeOpenShiftClusters()
|
||||||
|
|
||||||
rpBlobManager := mock_azblob.NewMockManager(controller)
|
rpBlobManager := mock_blob.NewMockManager(controller)
|
||||||
env := mock_env.NewMockInterface(controller)
|
env := mock_env.NewMockInterface(controller)
|
||||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||||
if tt.mocks != nil {
|
if tt.mocks != nil {
|
||||||
tt.mocks(rpBlobManager, env, azBlobClient)
|
tt.mocks(rpBlobManager, env, blobsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
f := testdatabase.NewFixture().WithOpenShiftClusters(dbOpenShiftClusters)
|
f := testdatabase.NewFixture().WithOpenShiftClusters(dbOpenShiftClusters)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"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/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/Azure/ARO-RP/pkg/env"
|
"github.com/Azure/ARO-RP/pkg/env"
|
||||||
|
@ -17,6 +17,12 @@ import (
|
||||||
"github.com/Azure/ARO-RP/pkg/util/storage"
|
"github.com/Azure/ARO-RP/pkg/util/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GraphContainer = "aro"
|
||||||
|
GraphBlob = "graph"
|
||||||
|
IgnitionContainer = "ignition"
|
||||||
|
)
|
||||||
|
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
Exists(ctx context.Context, resourceGroup, account string) (bool, error)
|
Exists(ctx context.Context, resourceGroup, account string) (bool, error)
|
||||||
LoadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, 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) {
|
func (m *manager) Exists(ctx context.Context, resourceGroup, account string) (bool, error) {
|
||||||
m.log.Print("checking if graph exists")
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
aro := blobService.GetContainerReference("aro")
|
return blobService.BlobExists(ctx, GraphContainer, GraphBlob)
|
||||||
return aro.GetBlobReference("graph").Exists()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) LoadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, error) {
|
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) {
|
func (m *manager) loadPersisted(ctx context.Context, resourceGroup, account string) (PersistedGraph, error) {
|
||||||
m.log.Print("load persisted graph")
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
aro := blobService.GetContainerReference("aro")
|
rc, err := blobService.DownloadStream(ctx, GraphContainer, GraphBlob, nil)
|
||||||
cluster := aro.GetBlobReference("graph")
|
|
||||||
rc, err := cluster.Get(nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rc.Close()
|
defer rc.Body.Close()
|
||||||
|
|
||||||
b, err := io.ReadAll(rc)
|
b, err := io.ReadAll(rc.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ package cluster
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
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"
|
||||||
azstorage "github.com/Azure/azure-sdk-for-go/storage"
|
|
||||||
|
|
||||||
|
"github.com/Azure/ARO-RP/pkg/cluster/graph"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/stringutils"
|
"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, '/')
|
resourceGroup := stringutils.LastTokenByte(m.doc.OpenShiftCluster.Properties.ClusterProfile.ResourceGroupID, '/')
|
||||||
account := "cluster" + m.doc.OpenShiftCluster.Properties.StorageSuffix
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrapIgn := blobService.GetContainerReference("ignition")
|
return blobService.DeleteContainer(ctx, graph.IgnitionContainer)
|
||||||
_, err = bootstrapIgn.DeleteIfExists(&azstorage.DeleteContainerOptions{})
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ const (
|
||||||
|
|
||||||
func (m *manager) generateWorkloadIdentityResources() (map[string]kruntime.Object, error) {
|
func (m *manager) generateWorkloadIdentityResources() (map[string]kruntime.Object, error) {
|
||||||
if !m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
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{}
|
resources := map[string]kruntime.Object{}
|
||||||
|
|
|
@ -36,7 +36,7 @@ func TestGenerateWorkloadIdentityResources(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "returns error if cluster is not using workload identity",
|
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",
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
"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/arm"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
"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
|
// AccountsClient is a minimal interface for Azure AccountsClient
|
||||||
type AccountsClient interface {
|
type AccountsClient interface {
|
||||||
GetProperties(ctx context.Context, resourceGroupName string, accountName string, options *armstorage.AccountsClientGetPropertiesOptions) (armstorage.AccountsClientGetPropertiesResponse, error)
|
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 {
|
type accountsClient struct {
|
||||||
|
@ -26,18 +24,8 @@ type accountsClient struct {
|
||||||
var _ AccountsClient = &accountsClient{}
|
var _ AccountsClient = &accountsClient{}
|
||||||
|
|
||||||
// NewAccountsClient creates a new AccountsClient
|
// NewAccountsClient creates a new AccountsClient
|
||||||
func NewAccountsClient(environment *azureclient.AROEnvironment, subscriptionID string, credential azcore.TokenCredential) (AccountsClient, error) {
|
func NewAccountsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (AccountsClient, error) {
|
||||||
customRoundTripper := azureclient.NewCustomRoundTripper(http.DefaultTransport)
|
clientFactory, err := armstorage.NewClientFactory(subscriptionID, credential, options)
|
||||||
|
|
||||||
options := arm.ClientOptions{
|
|
||||||
ClientOptions: azcore.ClientOptions{
|
|
||||||
Cloud: environment.Cloud,
|
|
||||||
Transport: &http.Client{
|
|
||||||
Transport: customRoundTripper,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
clientFactory, err := armstorage.NewClientFactory(subscriptionID, credential, &options)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the Apache License 2.0.
|
// Licensed under the Apache License 2.0.
|
||||||
|
|
||||||
//go:generate rm -rf ../mocks/$GOPACKAGE
|
//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
|
//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.
|
// 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:
|
// 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.
|
// Package mock_azblob is a generated GoMock package.
|
||||||
|
@ -14,10 +14,9 @@ import (
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
armstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
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"
|
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.
|
// MockManager is a mock of Manager interface.
|
||||||
|
@ -43,19 +42,19 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder {
|
||||||
return m.recorder
|
return m.recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAZBlobClient mocks base method.
|
// GetBlobClient mocks base method.
|
||||||
func (m *MockManager) GetAZBlobClient(arg0 string, arg1 *azblob0.ClientOptions) (azblob.AZBlobClient, error) {
|
func (m *MockManager) GetBlobClient(arg0 string) (azblob.BlobsClient, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetAZBlobClient", arg0, arg1)
|
ret := m.ctrl.Call(m, "GetBlobClient", arg0)
|
||||||
ret0, _ := ret[0].(azblob.AZBlobClient)
|
ret0, _ := ret[0].(azblob.BlobsClient)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAZBlobClient indicates an expected call of GetAZBlobClient.
|
// GetBlobClient indicates an expected call of GetBlobClient.
|
||||||
func (mr *MockManagerMockRecorder) GetAZBlobClient(arg0, arg1 any) *gomock.Call {
|
func (mr *MockManagerMockRecorder) GetBlobClient(arg0 any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
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.
|
// GetContainerProperties mocks base method.
|
||||||
|
@ -72,54 +71,3 @@ func (mr *MockManagerMockRecorder) GetContainerProperties(arg0, arg1, arg2, arg3
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContainerProperties", reflect.TypeOf((*MockManager)(nil).GetContainerProperties), arg0, arg1, arg2, arg3)
|
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()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProperties", reflect.TypeOf((*MockAccountsClient)(nil).GetProperties), arg0, arg1, arg2, arg3)
|
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.
|
// 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:
|
// 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.
|
// Package mock_storage is a generated GoMock package.
|
||||||
|
@ -11,68 +11,14 @@ package mock_storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
io "io"
|
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
storage0 "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
armstorage "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
|
||||||
storage1 "github.com/Azure/azure-sdk-for-go/storage"
|
|
||||||
gomock "go.uber.org/mock/gomock"
|
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.
|
// MockManager is a mock of Manager interface.
|
||||||
type MockManager struct {
|
type MockManager struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
|
@ -97,10 +43,10 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlobService mocks base method.
|
// 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()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "BlobService", arg0, arg1, arg2, arg3, arg4)
|
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)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
|
|
||||||
"go.uber.org/mock/gomock"
|
"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"
|
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ func TestKeyIDFromPublicKey(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
name string
|
||||||
mocks func(*mock_azblob.MockAZBlobClient)
|
|
||||||
publicKey interface{}
|
publicKey interface{}
|
||||||
wantkid string
|
wantkid string
|
||||||
wantErr string
|
wantErr string
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
||||||
|
|
||||||
"github.com/Azure/ARO-RP/pkg/env"
|
"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 (
|
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)
|
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
|
// Create the OIDC configuration
|
||||||
discoveryDocument := GenerateDiscoveryDocument(b.endpointURL)
|
discoveryDocument := GenerateDiscoveryDocument(b.endpointURL)
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func (b *OIDCBuilder) EnsureOIDCDocs(ctx context.Context, azBlobClient utilazblo
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return populateOidcFolder(ctx, b.directory, discoveryDocument, jwks, azBlobClient)
|
return populateOidcFolder(ctx, b.directory, discoveryDocument, jwks, blobsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *OIDCBuilder) GetEndpointUrl() string {
|
func (b *OIDCBuilder) GetEndpointUrl() string {
|
||||||
|
@ -71,28 +71,31 @@ func (b *OIDCBuilder) GetBlobContainerURL() string {
|
||||||
return b.blobContainerURL
|
return b.blobContainerURL
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateOidcFolder(ctx context.Context, directory string, discoveryDocument string, jwks []byte, azBlobClient utilazblob.AZBlobClient) error {
|
func populateOidcFolder(ctx context.Context, directory string, discoveryDocument string, jwks []byte, blobsClient azblob.BlobsClient) error {
|
||||||
err := azBlobClient.UploadBuffer(
|
_, err := blobsClient.UploadBuffer(
|
||||||
ctx,
|
ctx,
|
||||||
"",
|
"",
|
||||||
DocumentKey(directory, DiscoveryDocumentKey),
|
DocumentKey(directory, DiscoveryDocumentKey),
|
||||||
[]byte(discoveryDocument),
|
[]byte(discoveryDocument),
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return azBlobClient.UploadBuffer(
|
_, err = blobsClient.UploadBuffer(
|
||||||
ctx,
|
ctx,
|
||||||
"",
|
"",
|
||||||
DocumentKey(directory, JWKSKey),
|
DocumentKey(directory, JWKSKey),
|
||||||
jwks,
|
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} {
|
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) {
|
if err != nil && !bloberror.HasCode(err, bloberror.BlobNotFound) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -18,11 +17,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
"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/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
|
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient"
|
"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"
|
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
|
||||||
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||||
)
|
)
|
||||||
|
@ -47,10 +48,11 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
invalidKey := []byte("Invalid Key")
|
invalidKey := []byte("Invalid Key")
|
||||||
|
uploadResponse := azblob.UploadBufferResponse{}
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
name string
|
||||||
mocks func(*mock_azblob.MockAZBlobClient)
|
mocks func(*mock_azblob.MockBlobsClient)
|
||||||
oidcbuilder *OIDCBuilder
|
oidcbuilder *OIDCBuilder
|
||||||
wantErr string
|
wantErr string
|
||||||
}{
|
}{
|
||||||
|
@ -63,13 +65,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
||||||
directory: directoryName,
|
directory: directoryName,
|
||||||
endpointURL: endpointURL,
|
endpointURL: endpointURL,
|
||||||
},
|
},
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().
|
blobsClient.EXPECT().
|
||||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||||
Return(nil)
|
Return(uploadResponse, nil)
|
||||||
azblobClient.EXPECT().
|
blobsClient.EXPECT().
|
||||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any()).
|
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any(), nil).
|
||||||
Return(nil)
|
Return(uploadResponse, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -103,10 +105,10 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
||||||
endpointURL: endpointURL,
|
endpointURL: endpointURL,
|
||||||
directory: directoryName,
|
directory: directoryName,
|
||||||
},
|
},
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().
|
blobsClient.EXPECT().
|
||||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||||
Return(errors.New("generic error"))
|
Return(uploadResponse, errors.New("generic error"))
|
||||||
},
|
},
|
||||||
wantErr: "generic error",
|
wantErr: "generic error",
|
||||||
},
|
},
|
||||||
|
@ -119,13 +121,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
||||||
endpointURL: endpointURL,
|
endpointURL: endpointURL,
|
||||||
directory: directoryName,
|
directory: directoryName,
|
||||||
},
|
},
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().
|
blobsClient.EXPECT().
|
||||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any()).
|
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, DiscoveryDocumentKey), gomock.Any(), nil).
|
||||||
Return(nil)
|
Return(uploadResponse, nil)
|
||||||
azblobClient.EXPECT().
|
blobsClient.EXPECT().
|
||||||
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any()).
|
UploadBuffer(gomock.Any(), "", DocumentKey(directoryName, JWKSKey), gomock.Any(), nil).
|
||||||
Return(errors.New("generic error"))
|
Return(uploadResponse, errors.New("generic error"))
|
||||||
},
|
},
|
||||||
wantErr: "generic error",
|
wantErr: "generic error",
|
||||||
},
|
},
|
||||||
|
@ -145,13 +147,13 @@ func TestEnsureOIDCDocs(t *testing.T) {
|
||||||
controller := gomock.NewController(t)
|
controller := gomock.NewController(t)
|
||||||
defer controller.Finish()
|
defer controller.Finish()
|
||||||
|
|
||||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||||
|
|
||||||
if tt.mocks != nil {
|
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)
|
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||||
|
|
||||||
if tt.oidcbuilder.GetEndpointUrl() != tt.oidcbuilder.endpointURL {
|
if tt.oidcbuilder.GetEndpointUrl() != tt.oidcbuilder.endpointURL {
|
||||||
|
@ -226,39 +228,40 @@ ERROR CODE: Generic Error
|
||||||
Generic Error
|
Generic Error
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
`
|
`
|
||||||
|
deleteResponse := azblob.DeleteBlobResponse{}
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
name string
|
||||||
mocks func(*mock_azblob.MockAZBlobClient)
|
mocks func(*mock_azblob.MockBlobsClient)
|
||||||
wantErr string
|
wantErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Success",
|
name: "Success",
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(nil)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, nil)
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(nil)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Fail - Generic Error when deleting DiscoveryDocument",
|
name: "Fail - Generic Error when deleting DiscoveryDocument",
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrGeneric)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrGeneric)
|
||||||
},
|
},
|
||||||
wantErr: genericErrorMessage,
|
wantErr: genericErrorMessage,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Fail - Generic Error when deleting JWKS",
|
name: "Fail - Generic Error when deleting JWKS",
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrBlobNotFound)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrBlobNotFound)
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(respErrGeneric)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, respErrGeneric)
|
||||||
},
|
},
|
||||||
wantErr: genericErrorMessage,
|
wantErr: genericErrorMessage,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Success - One Blob exists and other doesn't",
|
name: "Success - One Blob exists and other doesn't",
|
||||||
mocks: func(azblobClient *mock_azblob.MockAZBlobClient) {
|
mocks: func(blobsClient *mock_azblob.MockBlobsClient) {
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey)).Return(respErrBlobNotFound)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, DiscoveryDocumentKey), nil).Return(deleteResponse, respErrBlobNotFound)
|
||||||
azblobClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey)).Return(nil)
|
blobsClient.EXPECT().DeleteBlob(ctx, "", DocumentKey(directoryName, JWKSKey), nil).Return(deleteResponse, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
@ -266,13 +269,13 @@ Generic Error
|
||||||
controller := gomock.NewController(t)
|
controller := gomock.NewController(t)
|
||||||
defer controller.Finish()
|
defer controller.Finish()
|
||||||
|
|
||||||
azBlobClient := mock_azblob.NewMockAZBlobClient(controller)
|
blobsClient := mock_azblob.NewMockBlobsClient(controller)
|
||||||
|
|
||||||
if tt.mocks != nil {
|
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)
|
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
|
// 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 {
|
func (service *PlatformWorkloadIdentityRolesByVersionService) PopulatePlatformWorkloadIdentityRolesByVersion(ctx context.Context, oc *api.OpenShiftCluster, dbPlatformWorkloadIdentityRoleSets database.PlatformWorkloadIdentityRoleSets) error {
|
||||||
if !oc.UsesWorkloadIdentity() {
|
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)
|
currentOpenShiftVersion, err := version.ParseVersion(oc.Properties.ClusterProfile.Version)
|
||||||
if err != nil {
|
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",
|
name: "Fail - Exit the func for non MIWI clusters that has no PlatformWorkloadIdentityProfile or ServicePrincipalProfile",
|
||||||
oc: &api.OpenShiftCluster{
|
oc: &api.OpenShiftCluster{
|
||||||
Properties: api.OpenShiftClusterProperties{},
|
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",
|
name: "Success - The role set document found for the cluster version",
|
||||||
|
|
|
@ -4,5 +4,5 @@ package storage
|
||||||
// Licensed under the Apache License 2.0.
|
// Licensed under the Apache License 2.0.
|
||||||
|
|
||||||
//go:generate rm -rf ../mocks/$GOPACKAGE
|
//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
|
//go:generate goimports -local=github.com/Azure/ARO-RP -e -w ../mocks/$GOPACKAGE/$GOPACKAGE.go
|
||||||
|
|
|
@ -5,49 +5,56 @@ package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mgmtstorage "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||||
azstorage "github.com/Azure/azure-sdk-for-go/storage"
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
||||||
"github.com/Azure/go-autorest/autorest"
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
||||||
"github.com/Azure/go-autorest/autorest/date"
|
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/api"
|
||||||
"github.com/Azure/ARO-RP/pkg/env"
|
"github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/armstorage"
|
||||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/storage"
|
"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 {
|
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 {
|
type manager struct {
|
||||||
env env.Core
|
storageAccounts armstorage.AccountsClient
|
||||||
storageAccounts storage.AccountsClient
|
credential azcore.TokenCredential
|
||||||
|
usesWorkloadIdentity bool
|
||||||
|
storageEndpointSuffix string
|
||||||
|
clientOptions *arm.ClientOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager(env env.Core, subscriptionID string, authorizer autorest.Authorizer) Manager {
|
func NewManager(subscriptionID, storageEndpointSuffix string, credential azcore.TokenCredential, usesWorkloadIdentity bool, options *arm.ClientOptions) (m Manager, err error) {
|
||||||
return &manager{
|
var accountsClient armstorage.AccountsClient
|
||||||
env: env,
|
if !usesWorkloadIdentity {
|
||||||
storageAccounts: storage.NewAccountsClient(env.Environment(), subscriptionID, authorizer),
|
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 {
|
func getCorrectErrWhenTooManyRequests(err error) error {
|
||||||
detailedError, ok := err.(autorest.DetailedError)
|
responseError, ok := err.(*azcore.ResponseError)
|
||||||
if !ok {
|
if !ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if detailedError.StatusCode != http.StatusTooManyRequests {
|
if responseError.StatusCode != http.StatusTooManyRequests {
|
||||||
return err
|
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."
|
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
|
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)
|
t := time.Now().UTC().Truncate(time.Second)
|
||||||
res, err := m.storageAccounts.ListAccountSAS(ctx, resourceGroup, account, mgmtstorage.AccountSasParameters{
|
res, err := m.storageAccounts.ListAccountSAS(ctx, resourceGroup, account, storagesdk.AccountSasParameters{
|
||||||
Services: mgmtstorage.ServicesB,
|
Services: to.Ptr(storagesdk.ServicesB),
|
||||||
ResourceTypes: r,
|
ResourceTypes: to.Ptr(r),
|
||||||
Permissions: p,
|
Permissions: to.Ptr(p),
|
||||||
Protocols: mgmtstorage.HTTPProtocolHTTPS,
|
Protocols: to.Ptr(storagesdk.HTTPProtocolHTTPS),
|
||||||
SharedAccessStartTime: &date.Time{Time: t},
|
SharedAccessStartTime: &t,
|
||||||
SharedAccessExpiryTime: &date.Time{Time: t.Add(24 * time.Hour)},
|
SharedAccessExpiryTime: to.Ptr(t.Add(24 * time.Hour)),
|
||||||
})
|
}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, getCorrectErrWhenTooManyRequests(err)
|
return nil, getCorrectErrWhenTooManyRequests(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := url.ParseQuery(*res.AccountSasToken)
|
_, err = url.ParseQuery(*res.AccountSasToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
blobcli := azstorage.NewAccountSASClient(account, v, (*m.env.Environment()).Environment).GetBlobService()
|
sasURL := fmt.Sprintf("%s/?%s", serviceURL, *res.AccountSasToken)
|
||||||
|
return azblob.NewBlobsClientUsingSAS(sasURL, m.clientOptions)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче