Skip to content

Commit

Permalink
Gnocchi: implement archive policy Create method (gophercloud#43)
Browse files Browse the repository at this point in the history
* Gnocchi: implement archive policy Create method

Add support for creating Gnocchi archive policies.
Add unit test and example in documentation.

* Gnocchi: use "ArchivePolicyDefinitionOpts" name

Use more broad name for archive policy definition options struct.

* Gnocchi: fix some docs for create ap request

* Archive Policies: add acc test for Create method

Add acceptance test for the Create method and reusable helper
CreateArchivePolicy method.

* Gnocchi Archive Policies: fix inline comments

Fix CreateOptsBuilder and CreateOpts inline comments.
  • Loading branch information
ozerovandrei authored and jtopjian committed Jun 10, 2018
1 parent bcab613 commit 8972859
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 0 deletions.
41 changes: 41 additions & 0 deletions acceptance/gnocchi/metric/v1/archivepolicies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package v1

import (
"testing"

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/utils/gnocchi/metric/v1/archivepolicies"
)

// CreateArchivePolicy will create a Gnocchi archive policy. An error will be returned if the
// archive policy could not be created.
func CreateArchivePolicy(t *testing.T, client *gophercloud.ServiceClient) (*archivepolicies.ArchivePolicy, error) {
policyName := tools.RandomString("TESTACCT-", 8)
createOpts := archivepolicies.CreateOpts{
Name: policyName,
AggregationMethods: []string{
"mean",
"sum",
},
Definition: []archivepolicies.ArchivePolicyDefinitionOpts{
{
Granularity: "1:00:00",
TimeSpan: "30 days, 0:00:00",
},
{
Granularity: "24:00:00",
TimeSpan: "90 days, 0:00:00",
},
},
}

t.Logf("Attempting to create a Gnocchi archive policy")
archivePolicy, err := archivepolicies.Create(client, createOpts).Extract()
if err != nil {
return nil, err
}

t.Logf("Successfully created the Gnocchi archive policy.")
return archivePolicy, nil
}
15 changes: 15 additions & 0 deletions acceptance/gnocchi/metric/v1/archivepolicies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ import (
"github.com/gophercloud/utils/gnocchi/metric/v1/archivepolicies"
)

func TestArchivePoliciesCRUD(t *testing.T) {
client, err := clients.NewGnocchiV1Client()
if err != nil {
t.Fatalf("Unable to create a Gnocchi client: %v", err)
}

archivePolicy, err := CreateArchivePolicy(t, client)
if err != nil {
t.Fatalf("Unable to create a Gnocchi archive policy: %v", err)
}
// defer DeleteArchivePolicy(t, client, archivePolicy.ID)

tools.PrintResource(t, archivePolicy)
}

func TestArchivePoliciesList(t *testing.T) {
client, err := clients.NewGnocchiV1Client()
if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions gnocchi/metric/v1/archivepolicies/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,31 @@ Example of Getting an archive policy
if err != nil {
panic(err)
}
Example of Creating an archive policy
createOpts := archivepolicies.CreateOpts{
BackWindow: 31,
AggregationMethods: []string{
"sum",
"mean",
"count",
},
Definition: []archivepolicies.ArchivePolicyDefinitionOpts{
{
Granularity: "1:00:00",
TimeSpan: "90 days, 0:00:00",
},
{
Granularity: "1 day, 0:00:00",
TimeSpan: "100 days, 0:00:00",
},
},
Name: "test_policy",
}
archivePolicy, err := archivepolicies.Create(gnocchiClient, createOpts).Extract()
if err != nil {
panic(err)
}
*/
package archivepolicies
59 changes: 59 additions & 0 deletions gnocchi/metric/v1/archivepolicies/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,62 @@ func Get(c *gophercloud.ServiceClient, archivePolicyName string) (r GetResult) {
_, r.Err = c.Get(getURL(c, archivePolicyName), &r.Body, nil)
return
}

// CreateOptsBuilder allows extensions to add additional parameters to the Create request.
type CreateOptsBuilder interface {
ToArchivePolicyCreateMap() (map[string]interface{}, error)
}

// CreateOpts specifies parameters of a new Archive Policy.
type CreateOpts struct {
// AggregationMethods is a list of functions used to aggregate
// multiple measures into an aggregate.
AggregationMethods []string `json:"aggregation_methods,omitempty"`

// BackWindow configures number of coarsest periods to keep.
// It allows to process measures that are older
// than the last timestamp period boundary.
BackWindow int `json:"back_window,omitempty"`

// Definition is a list of parameters that configures
// archive policy precision and timespan.
Definition []ArchivePolicyDefinitionOpts `json:"definition"`

// Name is a name of an archive policy.
Name string `json:"name"`
}

// ArchivePolicyDefinitionOpts represents definition of how metrics of new or
// updated Archive Policy will be saved with the selected archive policy.
// It configures precision and timespan.
type ArchivePolicyDefinitionOpts struct {
// Granularity is the level of precision that must be kept when aggregating data.
Granularity string `json:"granularity"`

// Points is a given aggregates or samples in the lifespan of a time series.
// Time series is a list of aggregates ordered by time.
// It can be omitted to allow Gnocchi server to calculate it automatically.
Points *int `json:"points,omitempty"`

// TimeSpan is the time period for which a metric keeps its aggregates.
TimeSpan string `json:"timespan"`
}

// ToArchivePolicyCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToArchivePolicyCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "")
}

// Create requests the creation of a new Gnocchi archive policy on the server.
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToArchivePolicyCreateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{201},
})

return
}
6 changes: 6 additions & 0 deletions gnocchi/metric/v1/archivepolicies/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ type GetResult struct {
commonResult
}

// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Gnocchi archive policy.
type CreateResult struct {
commonResult
}

// ArchivePolicy represents a Gnocchi archive policy.
// Archive policy is an aggregate storage policy attached to a metric.
// It determines how long aggregates will be kept in a metric and how they will be aggregated.
Expand Down
48 changes: 48 additions & 0 deletions gnocchi/metric/v1/archivepolicies/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,51 @@ const ArchivePolicyGetResult = `
"name": "test_policy"
}
`

// ArchivePolicyCreateRequest represents a raw create request.
const ArchivePolicyCreateRequest = `
{
"aggregation_methods": [
"sum",
"mean",
"count"
],
"back_window": 31,
"definition": [
{
"granularity": "1:00:00",
"timespan": "90 days, 0:00:00"
},
{
"granularity": "1 day, 0:00:00",
"timespan": "100 days, 0:00:00"
}
],
"name": "test_policy"
}
`

// ArchivePolicyCreateResponse represents a raw server response from a server to a create request.
const ArchivePolicyCreateResponse = `
{
"aggregation_methods": [
"sum",
"mean",
"count"
],
"back_window": 31,
"definition": [
{
"granularity": "1:00:00",
"points": 2160,
"timespan": "90 days, 0:00:00"
},
{
"granularity": "1 day, 0:00:00",
"points": 100,
"timespan": "100 days, 0:00:00"
}
],
"name": "test_policy"
}
`
60 changes: 60 additions & 0 deletions gnocchi/metric/v1/archivepolicies/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,63 @@ func TestGetArchivePolicy(t *testing.T) {
})
th.AssertEquals(t, s.Name, "test_policy")
}

func TestCreate(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc("/v1/archive_policy", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "POST")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Content-Type", "application/json")
th.TestHeader(t, r, "Accept", "application/json")
th.TestJSONRequest(t, r, ArchivePolicyCreateRequest)

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)

fmt.Fprintf(w, ArchivePolicyCreateResponse)
})

opts := archivepolicies.CreateOpts{
BackWindow: 31,
AggregationMethods: []string{
"sum",
"mean",
"count",
},
Definition: []archivepolicies.ArchivePolicyDefinitionOpts{
{
Granularity: "1:00:00",
TimeSpan: "90 days, 0:00:00",
},
{
Granularity: "1 day, 0:00:00",
TimeSpan: "100 days, 0:00:00",
},
},
Name: "test_policy",
}
s, err := archivepolicies.Create(fake.ServiceClient(), opts).Extract()
th.AssertNoErr(t, err)

th.AssertDeepEquals(t, s.AggregationMethods, []string{
"sum",
"mean",
"count",
})
th.AssertEquals(t, s.BackWindow, 31)
th.AssertDeepEquals(t, s.Definition, []archivepolicies.ArchivePolicyDefinition{
{
Granularity: "1:00:00",
Points: 2160,
TimeSpan: "90 days, 0:00:00",
},
{
Granularity: "1 day, 0:00:00",
Points: 100,
TimeSpan: "100 days, 0:00:00",
},
})
th.AssertEquals(t, s.Name, "test_policy")
}
4 changes: 4 additions & 0 deletions gnocchi/metric/v1/archivepolicies/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ func listURL(c *gophercloud.ServiceClient) string {
func getURL(c *gophercloud.ServiceClient, archivePolicyName string) string {
return resourceURL(c, archivePolicyName)
}

func createURL(c *gophercloud.ServiceClient) string {
return rootURL(c)
}

0 comments on commit 8972859

Please sign in to comment.