|
|
|
@@ -100,8 +100,10 @@ func (self *SAzureClient) getDefaultClient() (*autorest.Client, error) {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
client.Authorizer = authorizer
|
|
|
|
|
// client.RequestInspector = LogRequest()
|
|
|
|
|
// client.ResponseInspector = LogResponse()
|
|
|
|
|
if DEBUG {
|
|
|
|
|
client.RequestInspector = LogRequest()
|
|
|
|
|
client.ResponseInspector = LogResponse()
|
|
|
|
|
}
|
|
|
|
|
return &client, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -110,7 +112,7 @@ func (self *SAzureClient) jsonRequest(method, url string, body string) (jsonutil
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return jsonRequest(cli, method, self.domain, url, body)
|
|
|
|
|
return jsonRequest(cli, method, self.domain, url, self.subscriptionId, body)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) Get(resourceId string, params []string, retVal interface{}) error {
|
|
|
|
@@ -125,7 +127,7 @@ func (self *SAzureClient) Get(resourceId string, params []string, retVal interfa
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, path, "")
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, path, self.subscriptionId, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -145,7 +147,7 @@ func (self *SAzureClient) ListVmSizes(location string) (jsonutils.JSONObject, er
|
|
|
|
|
return nil, fmt.Errorf("need subscription id")
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/locations/%s/vmSizes", self.subscriptionId, location)
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, url, "")
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) ListClassicDisks() (jsonutils.JSONObject, error) {
|
|
|
|
@@ -157,7 +159,7 @@ func (self *SAzureClient) ListClassicDisks() (jsonutils.JSONObject, error) {
|
|
|
|
|
return nil, fmt.Errorf("need subscription id")
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("/subscriptions/%s/services/disks", self.subscriptionId)
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, url, "")
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) ListAll(resourceType string, retVal interface{}) error {
|
|
|
|
@@ -172,7 +174,7 @@ func (self *SAzureClient) ListAll(resourceType string, retVal interface{}) error
|
|
|
|
|
if len(resourceType) > 0 {
|
|
|
|
|
url += fmt.Sprintf("/providers/%s", resourceType)
|
|
|
|
|
}
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, "")
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -187,7 +189,7 @@ func (self *SAzureClient) ListSubscriptions() (jsonutils.JSONObject, error) {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, "/subscriptions", "")
|
|
|
|
|
return jsonRequest(cli, "GET", self.domain, "/subscriptions", self.subscriptionId, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) List(golbalResource string, retVal interface{}) error {
|
|
|
|
@@ -202,7 +204,7 @@ func (self *SAzureClient) List(golbalResource string, retVal interface{}) error
|
|
|
|
|
if len(self.subscriptionId) > 0 && len(golbalResource) > 0 {
|
|
|
|
|
url += fmt.Sprintf("/%s", golbalResource)
|
|
|
|
|
}
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, "")
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -218,7 +220,7 @@ func (self *SAzureClient) ListByTypeWithResourceGroup(resourceGroupName string,
|
|
|
|
|
return fmt.Errorf("Missing subscription Info")
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s", self.subscriptionId, resourceGroupName, Type)
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, "")
|
|
|
|
|
body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -230,7 +232,7 @@ func (self *SAzureClient) Delete(resourceId string) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
_, err = jsonRequest(cli, "DELETE", self.domain, resourceId, "")
|
|
|
|
|
_, err = jsonRequest(cli, "DELETE", self.domain, resourceId, self.subscriptionId, "")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -240,7 +242,7 @@ func (self *SAzureClient) PerformAction(resourceId string, action string, body s
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("%s/%s", resourceId, action)
|
|
|
|
|
return jsonRequest(cli, "POST", self.domain, url, body)
|
|
|
|
|
return jsonRequest(cli, "POST", self.domain, url, self.subscriptionId, body)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) fetchResourceGroup(cli *autorest.Client, location string) error {
|
|
|
|
@@ -255,7 +257,7 @@ func (self *SAzureClient) fetchResourceGroup(cli *autorest.Client, location stri
|
|
|
|
|
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, fmt.Sprintf(`{"name": "Default", "location": "%s"}`, location))
|
|
|
|
|
body, err := jsonRequest(cli, "PUT", self.domain, _url, self.subscriptionId, fmt.Sprintf(`{"name": "Default", "location": "%s"}`, location))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -281,6 +283,18 @@ func (self *SAzureClient) checkParams(body jsonutils.JSONObject, params []string
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AzureErrorDetail struct {
|
|
|
|
|
Code string `json:"code,omitempty"`
|
|
|
|
|
Message string `json:"message,omitempty"`
|
|
|
|
|
Target string `json:"target,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AzureError struct {
|
|
|
|
|
Code string `json:"code,omitempty"`
|
|
|
|
|
Details []AzureErrorDetail `json:"details,omitempty"`
|
|
|
|
|
Message string `json:"message,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) Create(body jsonutils.JSONObject, retVal interface{}) error {
|
|
|
|
|
cli, err := self.getDefaultClient()
|
|
|
|
|
if err != nil {
|
|
|
|
@@ -301,11 +315,14 @@ func (self *SAzureClient) Create(body jsonutils.JSONObject, retVal interface{})
|
|
|
|
|
return fmt.Errorf("Create Default resourceGroup error?")
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s", self.subscriptionId, self.ressourceGroups[0].Name, params["type"], params["name"])
|
|
|
|
|
result, err := jsonRequest(cli, "PUT", self.domain, url, body.String())
|
|
|
|
|
result, err := jsonRequest(cli, "PUT", self.domain, url, self.subscriptionId, body.String())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return result.Unmarshal(retVal)
|
|
|
|
|
if retVal != nil {
|
|
|
|
|
return result.Unmarshal(retVal)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) CheckNameAvailability(Type string, body string) (jsonutils.JSONObject, error) {
|
|
|
|
@@ -317,7 +334,7 @@ func (self *SAzureClient) CheckNameAvailability(Type string, body string) (jsonu
|
|
|
|
|
return nil, fmt.Errorf("Missing subscription ID")
|
|
|
|
|
}
|
|
|
|
|
url := fmt.Sprintf("/subscriptions/%s/providers/%s/checkNameAvailability", self.subscriptionId, Type)
|
|
|
|
|
return jsonRequest(cli, "POST", self.domain, url, body)
|
|
|
|
|
return jsonRequest(cli, "POST", self.domain, url, self.subscriptionId, body)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{}) error {
|
|
|
|
@@ -326,7 +343,7 @@ func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{})
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
url, err := body.GetString("id")
|
|
|
|
|
result, err := jsonRequest(cli, "PUT", self.domain, url, body.String())
|
|
|
|
|
result, err := jsonRequest(cli, "PUT", self.domain, url, self.subscriptionId, body.String())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@@ -336,8 +353,86 @@ func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{})
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func jsonRequest(client *autorest.Client, method, domain, baseUrl string, body string) (jsonutils.JSONObject, error) {
|
|
|
|
|
return _jsonRequest(client, method, domain, baseUrl, body)
|
|
|
|
|
func waitRegisterComplete(client *autorest.Client, domain, subscriptionId string, serviceType string) error {
|
|
|
|
|
for i := 1; i < 10; i++ {
|
|
|
|
|
result, err := _jsonRequest(client, "GET", domain, fmt.Sprintf("/subscriptions/%s/providers", subscriptionId), "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
value, err := result.GetArray("value")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for _, v := range value {
|
|
|
|
|
namespace, _ := v.GetString("namespace")
|
|
|
|
|
if namespace == serviceType {
|
|
|
|
|
state, _ := v.GetString("registrationState")
|
|
|
|
|
if state == "Registered" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
log.Debugf("service %s state %s waite %d second ...", serviceType, state, i*10)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(time.Second * time.Duration(i*10))
|
|
|
|
|
}
|
|
|
|
|
return fmt.Errorf("wait service %s register timeout", serviceType)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func registerService(client *autorest.Client, domain, subscriptionId string, serviceType string) error {
|
|
|
|
|
registryUrl := fmt.Sprintf("/subscriptions/%s/providers/%s/register", subscriptionId, serviceType)
|
|
|
|
|
result, err := _jsonRequest(client, "POST", domain, registryUrl, "")
|
|
|
|
|
if err != nil || result.Contains("error") {
|
|
|
|
|
return fmt.Errorf("failed to register %s service", serviceType)
|
|
|
|
|
}
|
|
|
|
|
if state, _ := result.GetString("registrationState"); state == "Registered" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return waitRegisterComplete(client, domain, subscriptionId, serviceType)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func recoverFromError(client *autorest.Client, domain, subscriptionId string, azureErr AzureError) bool {
|
|
|
|
|
switch azureErr.Code {
|
|
|
|
|
case "SubscriptionNotRegistered":
|
|
|
|
|
services := []string{"Microsoft.Network"}
|
|
|
|
|
for _, service := range services {
|
|
|
|
|
if err := registerService(client, domain, subscriptionId, service); err != nil {
|
|
|
|
|
log.Errorf("register %s error: %v", service, err)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
case "MissingSubscriptionRegistration":
|
|
|
|
|
for _, detail := range azureErr.Details {
|
|
|
|
|
log.Errorf("The subscription is not registered to use namespace '%s', try register it", detail.Target)
|
|
|
|
|
if err := registerService(client, domain, subscriptionId, detail.Target); err != nil {
|
|
|
|
|
log.Errorf("register %s error: %v", detail.Target, err)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func jsonRequest(client *autorest.Client, method, domain, baseUrl string, subscriptionId string, body string) (jsonutils.JSONObject, error) {
|
|
|
|
|
result, err := _jsonRequest(client, method, domain, baseUrl, body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if result.Contains("error") {
|
|
|
|
|
azureError := AzureError{}
|
|
|
|
|
if err := result.Unmarshal(&azureError, "error"); err != nil {
|
|
|
|
|
return nil, fmt.Errorf(result.String())
|
|
|
|
|
}
|
|
|
|
|
if recoverFromError(client, domain, subscriptionId, azureError) {
|
|
|
|
|
return _jsonRequest(client, method, domain, baseUrl, body)
|
|
|
|
|
}
|
|
|
|
|
log.Errorf("Azure %s request: %s \nbody: %s error: %v", method, baseUrl, body, result.String())
|
|
|
|
|
return nil, fmt.Errorf(result.String())
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func waitForComplatetion(client *autorest.Client, req *http.Request, resp *http.Response, timeout time.Duration) (jsonutils.JSONObject, error) {
|
|
|
|
@@ -464,15 +559,7 @@ func _jsonRequest(client *autorest.Client, method, domain, baseURL, body string)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
_data := strings.Replace(string(data), "\r", "", -1)
|
|
|
|
|
result, err = jsonutils.Parse([]byte(_data))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if result.Contains("error") {
|
|
|
|
|
log.Errorf("Azure %s request: %s \nbody: %s error: %v", req.Method, req.URL.String(), body, result.String())
|
|
|
|
|
return nil, fmt.Errorf(result.String())
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
return jsonutils.Parse([]byte(_data))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (self *SAzureClient) UpdateAccount(tenantId, secret, envName string) error {
|
|
|
|
|