Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'domains' endpoint request. #74

Merged
merged 4 commits into from
May 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,23 @@ func (c *controller) Zones() ([]Zone, error) {
return result, nil
}

// Domains implements Controller
func (c *controller) Domains() ([]Domain, error) {
source, err := c.get("domains")
if err != nil {
return nil, NewUnexpectedError(err)
}
domains, err := readDomains(c.apiVersion, source)
if err != nil {
return nil, errors.Trace(err)
}
var result []Domain
for _, domain := range domains {
result = append(result, domain)
}
return result, nil
}

// DevicesArgs is a argument struct for selecting Devices.
// Only devices that match the specified criteria are returned.
type DevicesArgs struct {
Expand Down
85 changes: 85 additions & 0 deletions domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2018 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package gomaasapi

import (
"github.com/juju/errors"
"github.com/juju/schema"
"github.com/juju/version"
)

type domain struct {
authoritative bool
resourceRecordCount int
ttl *int
resourceURI string
id int
name string
}

// Name implements Domain interface
func (domain *domain) Name() string {
return domain.name
}

func readDomains(controllerVersion version.Number, source interface{}) ([]*domain, error) {
checker := schema.List(schema.StringMap(schema.Any()))
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "domain base schema check failed")
}
valid := coerced.([]interface{})
return readDomainList(valid)
}

func domain_(source map[string]interface{}) (*domain, error) {
fields := schema.Fields{
"authoritative": schema.Bool(),
"resource_record_count": schema.ForceInt(),
"ttl": schema.OneOf(schema.Nil("null"), schema.ForceInt()),
"resource_uri": schema.String(),
"id": schema.ForceInt(),
"name": schema.String(),
}
checker := schema.FieldMap(fields, nil) // no defaults
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "domain schema check failed")
}
valid := coerced.(map[string]interface{})

var ttl *int = nil
if valid["ttl"] != nil {
i := valid["ttl"].(int)
ttl = &i
}

result := &domain{
authoritative: valid["authoritative"].(bool),
id: valid["id"].(int),
name: valid["name"].(string),
resourceRecordCount: valid["resource_record_count"].(int),
resourceURI: valid["resource_uri"].(string),
ttl: ttl,
}

return result, nil
}

// readDomainList expects the values of the sourceList to be string maps.
func readDomainList(sourceList []interface{}) ([]*domain, error) {
result := make([]*domain, 0, len(sourceList))
for i, value := range sourceList {
source, ok := value.(map[string]interface{})
if !ok {
return nil, errors.Errorf("unexpected value for domain %d, %T", i, value)
}
domain, err := domain_(source)
if err != nil {
return nil, errors.Annotatef(err, "domain %d", i)
}
result = append(result, domain)
}
return result, nil
}
46 changes: 46 additions & 0 deletions domain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2018 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package gomaasapi

import (
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"
)

type domainSuite struct{}

var _ = gc.Suite(&domainSuite{})

func (*domainSuite) TestReadDomainsBadSchema(c *gc.C) {
_, err := readDomains(twoDotOh, "something")
c.Assert(err.Error(), gc.Equals, `domain base schema check failed: expected list, got string("something")`)
}

func (*domainSuite) TestReadDomains(c *gc.C) {
domains, err := readDomains(twoDotOh, parseJSON(c, domainResponse))
c.Assert(err, jc.ErrorIsNil)
c.Assert(domains, gc.HasLen, 2)
c.Assert(domains[0].Name(), gc.Equals, "maas")
c.Assert(domains[1].Name(), gc.Equals, "anotherDomain.com")
}

var domainResponse = `
[
{
"authoritative": "true",
"resource_uri": "/MAAS/api/2.0/domains/0/",
"name": "maas",
"id": 0,
"ttl": null,
"resource_record_count": 3
}, {
"authoritative": "true",
"resource_uri": "/MAAS/api/2.0/domains/1/",
"name": "anotherDomain.com",
"id": 1,
"ttl": 10,
"resource_record_count": 3
}
]
`
8 changes: 8 additions & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ type Controller interface {
// file without sending the content of the file, we can return a File
// instance here too.
AddFile(AddFileArgs) error

// Returns the DNS Domain Managed By MAAS
Domains() ([]Domain, error)
}

// File represents a file stored in the MAAS controller.
Expand Down Expand Up @@ -142,6 +145,11 @@ type Zone interface {
Description() string
}

type Domain interface {
// The name of the Domain
Name() string
}

// BootResource is the bomb... find something to say here.
type BootResource interface {
ID() int
Expand Down