Skip to content

Commit

Permalink
Add 'domains' endpoint request.
Browse files Browse the repository at this point in the history
  • Loading branch information
externalreality committed May 20, 2018
1 parent 613dc12 commit 5451089
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
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
83 changes: 83 additions & 0 deletions domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2018 Canonical Ltd.
// Licensed under the AGPLv3, 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
}

// implements Domain
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{})

// ttl live is going to be the zero value if it is null. Thus the time
// to live will be zero. Would rather user's check for zero or for nil?
ttl, _ := valid["ttl"].(int)

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 2016 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
}
]
`
7 changes: 7 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,10 @@ type Zone interface {
Description() string
}

type Domain interface {
Name() string
}

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

0 comments on commit 5451089

Please sign in to comment.