From abfa4a5a4d8213a4df1bed34e4f88dd026e83791 Mon Sep 17 00:00:00 2001 From: Qu Xuan Date: Tue, 7 Jul 2020 18:38:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dazure=20=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=90=8C=E6=AD=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/models/cloudaccounts.go | 6 +- pkg/multicloud/azure/azure.go | 157 +++++++++++++++++----------- 2 files changed, 100 insertions(+), 63 deletions(-) diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 4b75b15dae..9c799a10b4 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -2447,7 +2447,11 @@ func (self *SCloudaccount) SyncProject(ctx context.Context, userCred mcclient.To } iProject, err := provider.CreateIProject(projectName) if err != nil { - return "", errors.Wrap(err, "CreateIProject") + if errors.Cause(err) != cloudprovider.ErrNotImplemented && errors.Cause(err) != cloudprovider.ErrNotSupported { + logclient.AddSimpleActionLog(self, logclient.ACT_CREATE, err, userCred, false) + return "", errors.Wrap(err, "CreateIProject") + } + return "", nil } extProj, err := ExternalProjectManager.newFromCloudProject(ctx, userCred, self, iProject) if err != nil { diff --git a/pkg/multicloud/azure/azure.go b/pkg/multicloud/azure/azure.go index dede55b493..14d8f32c51 100644 --- a/pkg/multicloud/azure/azure.go +++ b/pkg/multicloud/azure/azure.go @@ -49,10 +49,10 @@ type SAzureClient struct { domain string baseUrl string - ressourceGroups []SResourceGroup - fetchResourceGroups bool - env azureenv.Environment - authorizer autorest.Authorizer + ressourceGroups []SResourceGroup + + env azureenv.Environment + authorizer autorest.Authorizer iregions []cloudprovider.ICloudRegion iBuckets []cloudprovider.ICloudBucket @@ -133,7 +133,11 @@ func NewAzureClient(cfg *AzureClientConfig) (*SAzureClient, error) { AzureClientConfig: cfg, debug: cfg.debug, } - err := client.fetchRegions() + err := client.fetchSubscriptions() + if err != nil { + return nil, errors.Wrap(err, "fetchSubscriptions") + } + err = client.fetchRegions() if err != nil { return nil, errors.Wrap(err, "fetchRegions") } @@ -350,11 +354,19 @@ func (self *SAzureClient) List(golbalResource string, retVal interface{}) error url += fmt.Sprintf("/%s", golbalResource) } - if strings.ToLower(golbalResource) == "resourcegroups" && len(self.subscriptionId) == 0 { // 资源组必须要有订阅id - if len(self.subscriptions) > 0 { - url += fmt.Sprintf("/%s/%s", self.subscriptions[0].SubscriptionId, golbalResource) - } + body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") + if err != nil { + return err } + return body.Unmarshal(retVal, "value") +} + +func (self *SAzureClient) listSubscriptionResource(subscriptionId, resource string, retVal interface{}) error { + cli, err := self.getDefaultClient() + if err != nil { + return err + } + url := fmt.Sprintf("/subscriptions/%s/%s", subscriptionId, resource) body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") if err != nil { return err @@ -401,15 +413,16 @@ func (self *SAzureClient) CreateResourceGroup(name, location string) (*SResource if err != nil { return nil, errors.Wrap(err, "getDefaultClient") } - if len(location) == 0 && len(self.iregions) == 0 { - return nil, fmt.Errorf("missing location info") - } if len(location) == 0 { location = self.iregions[0].GetId() } + subscriptionId, err := self.getDefaultSubscriptionId() + if err != nil { + return nil, errors.Wrap(err, "getDefaultSubscriptionId") + } //Create resourceGroup - _url := fmt.Sprintf("/subscriptions/%s/resourcegroups/%s", self.subscriptionId, name) - _, err = jsonRequest(cli, "PUT", self.domain, _url, self.subscriptionId, fmt.Sprintf(`{"name": "%s", "location": "%s"}`, name, location)) + _url := fmt.Sprintf("/subscriptions/%s/resourcegroups/%s", subscriptionId, name) + _, err = jsonRequest(cli, "PUT", self.domain, _url, subscriptionId, fmt.Sprintf(`{"name": "%s", "location": "%s"}`, name, location)) if err != nil { return nil, errors.Wrap(err, "jsonRequest") } @@ -421,29 +434,27 @@ func (self *SAzureClient) CreateIProject(name string) (cloudprovider.ICloudProje return self.CreateResourceGroup(name, "") } -func (self *SAzureClient) fetchResourceGroup(cli *autorest.Client, location string) error { - if !self.fetchResourceGroups { - self.ressourceGroups = []SResourceGroup{} - err := self.List("resourcegroups", &self.ressourceGroups) - if err != nil { - log.Errorf("failed to list resourceGroups: %v", err) - return err - } - self.fetchResourceGroups = true +func (self *SAzureClient) getResourceGroups() ([]SResourceGroup, error) { + subscriptionId, err := self.getDefaultSubscriptionId() + if err != nil { + return nil, errors.Wrap(err, "getDefaultSubscriptionId") } - if len(self.ressourceGroups) == 0 { - //Create Default resourceGroup - _url := fmt.Sprintf("/subscriptions/%s/resourcegroups/Default", self.subscriptionId) - body, err := jsonRequest(cli, "PUT", self.domain, _url, self.subscriptionId, fmt.Sprintf(`{"name": "Default", "location": "%s"}`, location)) - if err != nil { - return err - } - resourceGroup := SResourceGroup{} - err = body.Unmarshal(&resourceGroup) - if err != nil { - return err - } - self.ressourceGroups = []SResourceGroup{resourceGroup} + resourceGroups := []SResourceGroup{} + err = self.listSubscriptionResource(subscriptionId, "resourcegroups", &resourceGroups) + if err != nil { + return nil, errors.Wrap(err, "listSubscriptionResource") + } + return resourceGroups, nil +} + +func (self *SAzureClient) fetchResourceGroup() error { + if len(self.ressourceGroups) > 0 { + return nil + } + var err error + self.ressourceGroups, err = self.getResourceGroups() + if err != nil { + return errors.Wrap(err, "getResourceGroups") } return nil } @@ -499,19 +510,16 @@ func (self *SAzureClient) getUniqName(cli *autorest.Client, resourceGroup string } func (self *SAzureClient) GetOrCreateResourceGroup(resourceGroup string, location string) error { - if !self.fetchResourceGroups { - cli, err := self.getDefaultClient() - if err != nil { - return errors.Wrap(err, "getDefaultClient") - } - self.fetchResourceGroup(cli, location) + err := self.fetchResourceGroup() + if err != nil { + return errors.Wrap(err, "fetchResourceGroup") } for _, group := range self.ressourceGroups { if strings.ToLower(group.Name) == strings.ToLower(resourceGroup) { return nil } } - _, err := self.CreateResourceGroup(resourceGroup, location) + _, err = self.CreateResourceGroup(resourceGroup, location) return err } @@ -528,8 +536,13 @@ func (self *SAzureClient) CreateWithResourceGroup(resourceGroup string, body jso return fmt.Errorf("Azure create resource failed: %s", err.Error()) } + err = self.fetchResourceGroup() + if err != nil { + return errors.Wrap(err, "fetchResourceGroup") + } + if len(resourceGroup) == 0 { - if !self.fetchResourceGroups || len(self.ressourceGroups) == 0 { + if len(self.ressourceGroups) == 0 { err = self.GetOrCreateResourceGroup("Default", params["location"]) if err != nil { return errors.Wrap(err, "GetOrCreateResourceGroup(Default)") @@ -851,21 +864,41 @@ func _jsonRequest(client *autorest.Client, method, domain, baseURL, body string) return nil }*/ -func (self *SAzureClient) fetchRegions() error { +func (self *SAzureClient) getDefaultSubscriptionId() (string, error) { if len(self.subscriptionId) > 0 { - regions := []SRegion{} - err := self.List("locations", ®ions) - if err != nil { - return err - } - self.iregions = make([]cloudprovider.ICloudRegion, len(regions)) - for i := 0; i < len(regions); i++ { - regions[i].client = self - regions[i].SubscriptionID = self.subscriptionId - self.iregions[i] = ®ions[i] - } + return self.subscriptionId, nil } - return self.fetchSubscriptions() + if len(self.subscriptions) == 0 { + return "", errors.Errorf("no subscriptions found for this azure account") + } + return self.subscriptions[0].SubscriptionId, nil +} + +func (self *SAzureClient) getRegions() ([]SRegion, error) { + subscriptionId, err := self.getDefaultSubscriptionId() + if err != nil { + return nil, errors.Wrap(err, "getDefaultSubscriptionId") + } + regions := []SRegion{} + err = self.listSubscriptionResource(subscriptionId, "locations", ®ions) + if err != nil { + return nil, errors.Wrap(err, "listSubscriptionResource") + } + return regions, nil +} + +func (self *SAzureClient) fetchRegions() error { + regions, err := self.getRegions() + if err != nil { + return errors.Wrap(err, "getRegions") + } + self.iregions = make([]cloudprovider.ICloudRegion, len(regions)) + for i := 0; i < len(regions); i++ { + regions[i].client = self + regions[i].SubscriptionID = self.subscriptionId + self.iregions[i] = ®ions[i] + } + return nil } func (self *SAzureClient) invalidateIBuckets() { @@ -1032,13 +1065,13 @@ func getResourceGroup(id string) string { } func (self *SAzureClient) GetIProjects() ([]cloudprovider.ICloudProject, error) { - resourceGroups := []SResourceGroup{} - if err := self.List("resourcegroups", &resourceGroups); err != nil { - return nil, err + err := self.fetchResourceGroup() + if err != nil { + return nil, errors.Wrap(err, "fetchResourceGroup") } iprojects := []cloudprovider.ICloudProject{} - for i := 0; i < len(resourceGroups); i++ { - iprojects = append(iprojects, &resourceGroups[i]) + for i := 0; i < len(self.ressourceGroups); i++ { + iprojects = append(iprojects, &self.ressourceGroups[i]) } return iprojects, nil }