diff --git a/openstack/client.go b/openstack/client.go index 35543995e..cf2ac5553 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -233,6 +233,7 @@ func v3auth(client *golangsdk.ProviderClient, endpoint string, opts tokens3.Auth client.TokenID = token.ID if project != nil { client.ProjectID = project.ID + client.DomainID = project.Domain.ID } if opts.CanReauth() { @@ -339,6 +340,7 @@ func v3AKSKAuth(client *golangsdk.ProviderClient, endpoint string, options golan } client.ProjectID = options.ProjectId + client.DomainID = options.DomainID v3Client.ProjectID = options.ProjectId var entries = make([]tokens3.CatalogEntry, 0, 1) @@ -998,6 +1000,12 @@ func NewSDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*go return sc, err } +// NewBSSV1 creates a ServiceClient that may be used to access the BSS service. +func NewBSSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "bssv1") + return sc, err +} + func NewSDKClient(c *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, serviceType string) (*golangsdk.ServiceClient, error) { switch serviceType { case "mls": diff --git a/openstack/ecs/v1/cloudservers/requests.go b/openstack/ecs/v1/cloudservers/requests.go index bc17c9862..eac1f3f26 100644 --- a/openstack/ecs/v1/cloudservers/requests.go +++ b/openstack/ecs/v1/cloudservers/requests.go @@ -182,6 +182,18 @@ func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r JobResul return } +// CreatePrePaid requests a server to be provisioned to the user in the current tenant. +func CreatePrePaid(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r OrderResult) { + reqBody, err := opts.ToServerCreateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Post(createURL(client), reqBody, &r.Body, &golangsdk.RequestOpts{OkCodes: []int{200}}) + return +} + // Get retrieves a particular Server based on its unique ID. func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { _, r.Err = c.Get(getURL(c, id), &r.Body, &golangsdk.RequestOpts{ @@ -216,3 +228,25 @@ func Delete(client *golangsdk.ServiceClient, opts DeleteOpts) (r JobResult) { _, r.Err = client.Post(deleteURL(client), reqBody, &r.Body, &golangsdk.RequestOpts{OkCodes: []int{200}}) return } + +type DeleteOrderOpts struct { + ResourceIds []string `json:"resourceIds" required:"true"` + UnSubType int `json:"unSubType" required:"true"` +} + +// ToServerDeleteOrderMap assembles a request body based on the contents of a +// DeleteOrderOpts. +func (opts DeleteOrderOpts) ToServerDeleteOrderMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// DeleteOrder requests a server to be deleted to the user in the current tenant. +func DeleteOrder(client *golangsdk.ServiceClient, opts DeleteOrderOpts) (r DeleteOrderResult) { + reqBody, err := opts.ToServerDeleteOrderMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(deleteOrderURL(client), reqBody, &r.Body, &golangsdk.RequestOpts{OkCodes: []int{200}}) + return +} diff --git a/openstack/ecs/v1/cloudservers/results_order.go b/openstack/ecs/v1/cloudservers/results_order.go new file mode 100644 index 000000000..76419e50d --- /dev/null +++ b/openstack/ecs/v1/cloudservers/results_order.go @@ -0,0 +1,113 @@ +package cloudservers + +import ( + "fmt" + "time" + + "github.com/huaweicloud/golangsdk" +) + +type OrderResponse struct { + OrderID string `json:"order_id"` +} + +type OrderStatus struct { + ErrorCode string `json:"error_code"` + ErrorMsg string `json:"error_msg"` + Resources []Resource `json:"resources"` +} + +type Resource struct { + Status int `json:"status"` + ResourceId string `json:"resourceId"` +} + +type DeleteOrderResponse struct { + OrderIDs []string `json:"orderIds"` +} + +type OrderResult struct { + golangsdk.Result +} + +type DeleteOrderResult struct { + golangsdk.Result +} + +func (r OrderResult) ExtractOrderResponse() (*OrderResponse, error) { + order := new(OrderResponse) + err := r.ExtractInto(order) + return order, err +} + +func (r DeleteOrderResult) ExtractDeleteOrderResponse() (*DeleteOrderResponse, error) { + order := new(DeleteOrderResponse) + err := r.ExtractInto(order) + return order, err +} + +func (r OrderResult) ExtractOrderStatus() (*OrderStatus, error) { + order := new(OrderStatus) + err := r.ExtractInto(order) + return order, err +} + +func WaitForOrderSuccess(client *golangsdk.ServiceClient, secs int, orderID string) error { + return golangsdk.WaitFor(secs, func() (bool, error) { + order := new(OrderStatus) + _, err := client.Get(orderURL(client, orderID), &order, nil) + if err != nil { + return false, err + } + time.Sleep(5 * time.Second) + instance := order.Resources[0] + + if instance.Status == 1 { + return true, nil + } + if instance.Status == 2 { + err = fmt.Errorf("Order failed: %s.", orderID) + return false, err + } + + return false, nil + }) +} + +func WaitForOrderDeleteSuccess(client *golangsdk.ServiceClient, secs int, orderID string) error { + return golangsdk.WaitFor(secs, func() (bool, error) { + order := new(OrderStatus) + _, err := client.Get(orderURL(client, orderID), &order, nil) + if err != nil { + return false, err + } + time.Sleep(5 * time.Second) + instance := order.Resources[0] + + if instance.Status == 8 { + return true, nil + } + if instance.Status == 2 { + err = fmt.Errorf("Order failed: %s.", orderID) + return false, err + } + + return false, nil + }) +} + +func GetOrderResource(client *golangsdk.ServiceClient, orderID string) (interface{}, error) { + order := new(OrderStatus) + _, err := client.Get(orderURL(client, orderID), &order, nil) + if err != nil { + return false, err + } + instance := order.Resources[0] + if instance.Status == 1 { + if e := instance.ResourceId; e != "" { + return e, nil + } + } + + return nil, fmt.Errorf("Get Order resource ID error.") +} diff --git a/openstack/ecs/v1/cloudservers/urls.go b/openstack/ecs/v1/cloudservers/urls.go index e9074c687..dfa5f5e20 100644 --- a/openstack/ecs/v1/cloudservers/urls.go +++ b/openstack/ecs/v1/cloudservers/urls.go @@ -17,3 +17,11 @@ func getURL(sc *golangsdk.ServiceClient, serverID string) string { func jobURL(sc *golangsdk.ServiceClient, jobId string) string { return sc.ServiceURL("jobs", jobId) } + +func orderURL(sc *golangsdk.ServiceClient, orderId string) string { + return sc.ServiceURL(sc.DomainID, "common/order-mgr/orders-resource", orderId) +} + +func deleteOrderURL(sc *golangsdk.ServiceClient) string { + return sc.ServiceURL(sc.DomainID, "common/order-mgr/resources/delete") +} diff --git a/provider_client.go b/provider_client.go index 322f48619..6c60f118f 100644 --- a/provider_client.go +++ b/provider_client.go @@ -59,6 +59,9 @@ type ProviderClient struct { // ProjectID is the ID of project to which User is authorized. ProjectID string + // DomainID is the ID of project to which User is authorized. + DomainID string + // EndpointLocator describes how this provider discovers the endpoints for // its constituent services. EndpointLocator EndpointLocator