api: endpoints for working with CA roots, agent authorize, etc.
This commit is contained in:
parent
94e7a0a3c1
commit
b5b301aa2a
82
api/agent.go
82
api/agent.go
|
@ -172,6 +172,19 @@ type SampledValue struct {
|
|||
Labels map[string]string
|
||||
}
|
||||
|
||||
// AgentAuthorizeParams are the request parameters for authorizing a request.
|
||||
type AgentAuthorizeParams struct {
|
||||
Target string
|
||||
ClientID string
|
||||
ClientCertSerial string
|
||||
}
|
||||
|
||||
// AgentAuthorize is the response structure for Connect authorization.
|
||||
type AgentAuthorize struct {
|
||||
Authorized bool
|
||||
Reason string
|
||||
}
|
||||
|
||||
// Agent can be used to query the Agent endpoints
|
||||
type Agent struct {
|
||||
c *Client
|
||||
|
@ -505,6 +518,75 @@ func (a *Agent) ForceLeave(node string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ConnectAuthorize is used to authorize an incoming connection
|
||||
// to a natively integrated Connect service.
|
||||
//
|
||||
// TODO(mitchellh): we need to test this better once we have a way to
|
||||
// configure CAs from the API package (when the CA work is done).
|
||||
func (a *Agent) ConnectAuthorize(auth *AgentAuthorizeParams) (*AgentAuthorize, error) {
|
||||
r := a.c.newRequest("POST", "/v1/agent/connect/authorize")
|
||||
r.obj = auth
|
||||
_, resp, err := requireOK(a.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
var out AgentAuthorize
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// ConnectCARoots returns the list of roots.
|
||||
//
|
||||
// TODO(mitchellh): we need to test this better once we have a way to
|
||||
// configure CAs from the API package (when the CA work is done).
|
||||
func (a *Agent) ConnectCARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/agent/connect/ca/roots")
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := requireOK(a.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out CARootList
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &out, qm, nil
|
||||
}
|
||||
|
||||
// ConnectCALeaf gets the leaf certificate for the given service ID.
|
||||
//
|
||||
// TODO(mitchellh): we need to test this better once we have a way to
|
||||
// configure CAs from the API package (when the CA work is done).
|
||||
func (a *Agent) ConnectCALeaf(serviceID string, q *QueryOptions) (*IssuedCert, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/agent/connect/ca/leaf/"+serviceID)
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := requireOK(a.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out IssuedCert
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &out, qm, nil
|
||||
}
|
||||
|
||||
// EnableServiceMaintenance toggles service maintenance mode on
|
||||
// for the given service ID.
|
||||
func (a *Agent) EnableServiceMaintenance(serviceID, reason string) error {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/hashicorp/consul/testutil"
|
||||
"github.com/hashicorp/consul/testutil/retry"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAPI_AgentSelf(t *testing.T) {
|
||||
|
@ -981,3 +982,17 @@ func TestAPI_AgentUpdateToken(t *testing.T) {
|
|||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPI_AgentConnectCARoots_empty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
c, s := makeClient(t)
|
||||
defer s.Stop()
|
||||
|
||||
agent := c.Agent()
|
||||
list, meta, err := agent.ConnectCARoots(nil)
|
||||
require.Nil(err)
|
||||
require.Equal(uint64(0), meta.LastIndex)
|
||||
require.Len(list.Roots, 0)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CARootList is the structure for the results of listing roots.
|
||||
type CARootList struct {
|
||||
ActiveRootID string
|
||||
Roots []*CARoot
|
||||
}
|
||||
|
||||
// CARoot is a single CA within Connect.
|
||||
type CARoot struct {
|
||||
ID string
|
||||
Name string
|
||||
RootCert string
|
||||
Active bool
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
type IssuedCert struct {
|
||||
SerialNumber string
|
||||
CertPEM string
|
||||
PrivateKeyPEM string
|
||||
Service string
|
||||
ServiceURI string
|
||||
ValidAfter time.Time
|
||||
ValidBefore time.Time
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
// Connect can be used to work with endpoints related to Connect, the
|
||||
// feature for securely connecting services within Consul.
|
||||
type Connect struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Health returns a handle to the health endpoints
|
||||
func (c *Client) Connect() *Connect {
|
||||
return &Connect{c}
|
||||
}
|
||||
|
||||
// CARoots queries the list of available roots.
|
||||
func (h *Connect) CARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) {
|
||||
r := h.c.newRequest("GET", "/v1/connect/ca/roots")
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := requireOK(h.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out CARootList
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &out, qm, nil
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// NOTE(mitchellh): we don't have a way to test CA roots yet since there
|
||||
// is no API public way to configure the root certs. This wll be resolved
|
||||
// in the future and we can write tests then. This is tested in agent and
|
||||
// agent/consul which do have internal access to manually create roots.
|
||||
|
||||
func TestAPI_ConnectCARoots_empty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
c, s := makeClient(t)
|
||||
defer s.Stop()
|
||||
|
||||
connect := c.Connect()
|
||||
list, meta, err := connect.CARoots(nil)
|
||||
require.Nil(err)
|
||||
require.Equal(uint64(0), meta.LastIndex)
|
||||
require.Len(list.Roots, 0)
|
||||
}
|
Loading…
Reference in New Issue