| // Copyright (c) 2016 VMware, Inc. All Rights Reserved. |
| // |
| // This product is licensed to you under the Apache License, Version 2.0 (the "License"). |
| // You may not use this product except in compliance with the License. |
| // |
| // This product may include a number of subcomponents with separate copyright notices and |
| // license terms. Your use of these subcomponents is subject to the terms and conditions |
| // of the subcomponent's license, as noted in the LICENSE file. |
| |
| package photon |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "fmt" |
| "io/ioutil" |
| ) |
| |
| // Contains functionality for tenants API. |
| type TenantsAPI struct { |
| client *Client |
| } |
| |
| // Options for GetResourceTickets API. |
| type ResourceTicketGetOptions struct { |
| Name string `urlParam:"name"` |
| } |
| |
| // Options for GetProjects API. |
| type ProjectGetOptions struct { |
| Name string `urlParam:"name"` |
| } |
| |
| var tenantUrl string = rootUrl + "/tenants" |
| |
| // Returns all tenants on an photon instance. |
| func (api *TenantsAPI) GetAll() (result *Tenants, err error) { |
| uri := api.client.Endpoint + tenantUrl |
| res, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| |
| result = &Tenants{} |
| err = json.Unmarshal(res, result) |
| return |
| } |
| |
| // Creates a tenant. |
| func (api *TenantsAPI) Create(tenantSpec *TenantCreateSpec) (task *Task, err error) { |
| body, err := json.Marshal(tenantSpec) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.Post( |
| api.client.Endpoint+tenantUrl, |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Deletes the tenant with specified ID. Any projects, VMs, disks, etc., owned by the tenant must be deleted first. |
| func (api *TenantsAPI) Delete(id string) (task *Task, err error) { |
| res, err := api.client.restClient.Delete(api.client.Endpoint+tenantUrl+"/"+id, api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Creates a resource ticket on the specified tenant. |
| func (api *TenantsAPI) CreateResourceTicket(tenantId string, spec *ResourceTicketCreateSpec) (task *Task, err error) { |
| body, err := json.Marshal(spec) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.Post( |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/resource-tickets", |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Gets resource tickets for tenant with the specified ID, using options to filter the results. |
| // If options is nil, no filtering will occur. |
| func (api *TenantsAPI) GetResourceTickets(tenantId string, options *ResourceTicketGetOptions) (tickets *ResourceList, err error) { |
| uri := api.client.Endpoint + tenantUrl + "/" + tenantId + "/resource-tickets" |
| if options != nil { |
| uri += getQueryString(options) |
| } |
| res, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| |
| tickets = &ResourceList{} |
| err = json.Unmarshal(res, tickets) |
| return |
| } |
| |
| // Creates a project on the specified tenant. |
| func (api *TenantsAPI) CreateProject(tenantId string, spec *ProjectCreateSpec) (task *Task, err error) { |
| body, err := json.Marshal(spec) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.Post( |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/projects", |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Gets the projects for tenant with the specified ID, using options to filter the results. |
| // If options is nil, no filtering will occur. |
| func (api *TenantsAPI) GetProjects(tenantId string, options *ProjectGetOptions) (result *ProjectList, err error) { |
| uri := api.client.Endpoint + tenantUrl + "/" + tenantId + "/projects" |
| if options != nil { |
| uri += getQueryString(options) |
| } |
| res, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| |
| result = &(ProjectList{}) |
| err = json.Unmarshal(res, result) |
| return |
| } |
| |
| // Gets all tasks with the specified tenant ID, using options to filter the results. |
| // If options is nil, no filtering will occur. |
| func (api *TenantsAPI) GetTasks(id string, options *TaskGetOptions) (result *TaskList, err error) { |
| uri := api.client.Endpoint + tenantUrl + "/" + id + "/tasks" |
| if options != nil { |
| uri += getQueryString(options) |
| } |
| res, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| |
| result = &TaskList{} |
| err = json.Unmarshal(res, result) |
| return |
| } |
| |
| // Gets a tenant with the specified ID or name |
| func (api *TenantsAPI) Get(identity string) (tenant *Tenant, err error) { |
| res, err := api.client.restClient.Get(api.getEntityUrl(identity), api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| res, err = getError(res) |
| tenant = &Tenant{} |
| if res != nil { |
| err = json.NewDecoder(res.Body).Decode(tenant) |
| // ID corresponds to the tenant ID found, return tenant |
| if err == nil { |
| return |
| } |
| } |
| // Find by Name |
| uri := api.client.Endpoint + tenantUrl + "?name=" + identity |
| res2, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions) |
| |
| if err != nil { |
| return |
| } |
| |
| tenants := &Tenants{} |
| err = json.Unmarshal(res2, tenants) |
| if err != nil { |
| return |
| } |
| |
| if len(tenants.Items) < 1 { |
| err = fmt.Errorf("Cannot find a tenant with id or name match %s", identity) |
| return |
| } |
| |
| tenant = &(tenants.Items[0]) |
| return |
| } |
| |
| // Set security groups for this tenant, overwriting any existing ones. |
| func (api *TenantsAPI) SetSecurityGroups(id string, securityGroups *SecurityGroupsSpec) (*Task, error) { |
| return setSecurityGroups(api.client, api.getEntityUrl(id), securityGroups) |
| } |
| |
| func (api *TenantsAPI) getEntityUrl(id string) (url string) { |
| return api.client.Endpoint + tenantUrl + "/" + id |
| } |
| |
| // Get quota for project with the specified ID. |
| func (api *TenantsAPI) GetQuota(tenantId string) (quota *Quota, err error) { |
| uri := api.client.Endpoint + tenantUrl + "/" + tenantId + "/quota" |
| res, err := api.client.restClient.Get(uri, api.client.options.TokenOptions) |
| |
| if err != nil { |
| return |
| } |
| |
| defer res.Body.Close() |
| res, err = getError(res) |
| if err != nil { |
| return |
| } |
| |
| body, err := ioutil.ReadAll(res.Body) |
| |
| quota = &Quota{} |
| err = json.Unmarshal(body, quota) |
| return |
| } |
| |
| // Set (replace) the whole project quota with the quota line items specified in quota spec. |
| func (api *TenantsAPI) SetQuota(tenantId string, spec *QuotaSpec) (task *Task, err error) { |
| task, err = api.modifyQuota("PUT", tenantId, spec) |
| return |
| } |
| |
| // Update portion of the project quota with the quota line items specified in quota spec. |
| func (api *TenantsAPI) UpdateQuota(tenantId string, spec *QuotaSpec) (task *Task, err error) { |
| task, err = api.modifyQuota("PATCH", tenantId, spec) |
| return |
| } |
| |
| // Exclude project quota line items from the specific quota spec. |
| func (api *TenantsAPI) ExcludeQuota(tenantId string, spec *QuotaSpec) (task *Task, err error) { |
| task, err = api.modifyQuota("DELETE", tenantId, spec) |
| return |
| } |
| |
| // A private common function for modifying quota for the specified project with the quota line items specified |
| // in quota spec. |
| func (api *TenantsAPI) modifyQuota(method string, tenantId string, spec *QuotaSpec) (task *Task, err error) { |
| body, err := json.Marshal(spec) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.SendRequestCommon( |
| method, |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/quota", |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Gets IAM Policy of a tenant. |
| func (api *TenantsAPI) GetIam(tenantId string) (policy *[]PolicyEntry, err error) { |
| res, err := api.client.restClient.Get( |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/iam", |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| res, err = getError(res) |
| if err != nil { |
| return |
| } |
| var result []PolicyEntry |
| err = json.NewDecoder(res.Body).Decode(&result) |
| return &result, err |
| } |
| |
| // Sets IAM Policy on a tenant. |
| func (api *TenantsAPI) SetIam(tenantId string, policy *[]PolicyEntry) (task *Task, err error) { |
| body, err := json.Marshal(policy) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.Post( |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/iam", |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |
| |
| // Modifies IAM Policy on a tenant. |
| func (api *TenantsAPI) ModifyIam(tenantId string, policyDelta *PolicyDelta) (task *Task, err error) { |
| body, err := json.Marshal(policyDelta) |
| if err != nil { |
| return |
| } |
| res, err := api.client.restClient.Patch( |
| api.client.Endpoint+tenantUrl+"/"+tenantId+"/iam", |
| "application/json", |
| bytes.NewReader(body), |
| api.client.options.TokenOptions) |
| if err != nil { |
| return |
| } |
| defer res.Body.Close() |
| task, err = getTask(getError(res)) |
| return |
| } |