golang-client/volume/v2/volume.go

211 lines
6.6 KiB
Go

// Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
/*
Package volume implements a client library for accessing OpenStack Volume service
Volumes and VolumeDetails can be retrieved using the api.
In addition more complex filtering and sort queries can by using the VolumeQueryParameters.
*/
package v2
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"git.openstack.org/openstack/golang-client/openstack"
"git.openstack.org/openstack/golang-client/util"
)
// Service is a client service that can make
// requests against a OpenStack volume service.
// Below is an example on creating an volume service and getting volumes:
// volumeService := volume.VolumeService{Client: *http.DefaultClient, TokenId: tokenId, Url: "http://volumeservicelocation"}
// volumes:= volumeService.Volumes()
type Service struct {
Session openstack.Session
Client http.Client
URL string
}
// Response is a structure for all properties of
// an volume for a non detailed query
type Response struct {
ID string `json:"id"`
Links []map[string]string `json:"links"`
Name string `json:"name"`
}
// DetailResponse is a structure for all properties of
// an volume for a detailed query
type DetailResponse struct {
ID string `json:"id"`
Attachments []map[string]string `json:"attachments"`
Links []map[string]string `json:"links"`
Metadata map[string]string `json:"metadata"`
Protected bool `json:"protected"`
Status string `json:"status"`
MigrationStatus string `json:"migration_status"`
UserID string `json:"user_id"`
Encrypted bool `json:"encrypted"`
Multiattach bool `json:"multiattach"`
CreatedAt util.RFC8601DateTime `json:"created_at"`
Description string `json:"description"`
Volume_type string `json:"volume_type"`
Name string `json:"name"`
Source_volid string `json:"source_volid"`
Snapshot_id string `json:"snapshot_id"`
Size int64 `json:"size"`
Aavailability_zone string `json:"availability_zone"`
Rreplication_status string `json:"replication_status"`
Consistencygroup_id string `json:"consistencygroup_id"`
}
// QueryParameters is a structure that
// contains the filter, sort, and paging parameters for
// an volume or volumedetail query.
type QueryParameters struct {
All_tenant int64
Marker string
Limit int64
SortKey string
SortDirection SortDirection
}
// SortDirection of the sort, ascending or descending.
type SortDirection string
const (
// Desc specifies the sort direction to be descending.
Desc SortDirection = "desc"
// Asc specifies the sort direction to be ascending.
Asc SortDirection = "asc"
)
// Volumes will issue a get request to OpenStack to retrieve the list of volumes.
func (volumeService Service) Volumes() (volume []Response, err error) {
return volumeService.QueryVolumes(nil)
}
// VolumesDetail will issue a get request to OpenStack to retrieve the list of volumes complete with
// additional details.
func (volumeService Service) VolumesDetail() (volume []DetailResponse, err error) {
return volumeService.QueryVolumesDetail(nil)
}
// QueryVolumes will issue a get request with the specified VolumeQueryParameters to retrieve the list of
// volumes.
func (volumeService Service) QueryVolumes(queryParameters *QueryParameters) ([]Response, error) {
volumesContainer := volumesResponse{}
err := volumeService.queryVolumes(false /*includeDetails*/, &volumesContainer, queryParameters)
if err != nil {
return nil, err
}
return volumesContainer.Volumes, nil
}
// QueryVolumesDetail will issue a get request with the specified QueryParameters to retrieve the list of
// volumes with additional details.
func (volumeService Service) QueryVolumesDetail(queryParameters *QueryParameters) ([]DetailResponse, error) {
volumesDetailContainer := volumesDetailResponse{}
err := volumeService.queryVolumes(true /*includeDetails*/, &volumesDetailContainer, queryParameters)
if err != nil {
return nil, err
}
return volumesDetailContainer.Volumes, nil
}
func (volumeService Service) queryVolumes(includeDetails bool, volumesResponseContainer interface{}, queryParameters *QueryParameters) error {
urlPostFix := "/volumes"
if includeDetails {
urlPostFix = urlPostFix + "/detail"
}
reqURL, err := buildQueryURL(volumeService, queryParameters, urlPostFix)
if err != nil {
return err
}
var headers http.Header = http.Header{}
headers.Set("Accept", "application/json")
resp, err := volumeService.Session.Get(reqURL.String(), nil, &headers)
if err != nil {
return err
}
err = util.CheckHTTPResponseStatusCode(resp)
if err != nil {
return err
}
rbody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.New("aaa")
}
if err = json.Unmarshal(rbody, &volumesResponseContainer); err != nil {
return err
}
return nil
}
func buildQueryURL(volumeService Service, queryParameters *QueryParameters, volumePartialURL string) (*url.URL, error) {
reqURL, err := url.Parse(volumeService.URL)
if err != nil {
return nil, err
}
if queryParameters != nil {
values := url.Values{}
if queryParameters.All_tenant != 0 {
values.Set("all_tenant", fmt.Sprintf("%d", queryParameters.All_tenant))
}
if queryParameters.Limit != 0 {
values.Set("limit", fmt.Sprintf("%d", queryParameters.Limit))
}
if queryParameters.Marker != "" {
values.Set("marker", queryParameters.Marker)
}
if queryParameters.SortKey != "" {
values.Set("sort_key", queryParameters.SortKey)
}
if queryParameters.SortDirection != "" {
values.Set("sort_dir", string(queryParameters.SortDirection))
}
if len(values) > 0 {
reqURL.RawQuery = values.Encode()
}
}
reqURL.Path += volumePartialURL
return reqURL, nil
}
type volumesDetailResponse struct {
Volumes []DetailResponse `json:"volumes"`
}
type volumesResponse struct {
Volumes []Response `json:"volumes"`
}