forked from TrueCloudLab/certificates
Rename SSH methods.
This commit is contained in:
parent
e84489775b
commit
a50d59338e
7 changed files with 94 additions and 85 deletions
|
@ -251,15 +251,15 @@ func (h *caHandler) Route(r Router) {
|
||||||
r.MethodFunc("GET", "/roots", h.Roots)
|
r.MethodFunc("GET", "/roots", h.Roots)
|
||||||
r.MethodFunc("GET", "/federation", h.Federation)
|
r.MethodFunc("GET", "/federation", h.Federation)
|
||||||
// SSH CA
|
// SSH CA
|
||||||
r.MethodFunc("POST", "/ssh/sign", h.SignSSH)
|
r.MethodFunc("POST", "/ssh/sign", h.SSHSign)
|
||||||
r.MethodFunc("GET", "/ssh/keys", h.SSHKeys)
|
r.MethodFunc("GET", "/ssh/roots", h.SSHRoots)
|
||||||
r.MethodFunc("GET", "/ssh/federation", h.SSHFederatedKeys)
|
r.MethodFunc("GET", "/ssh/federation", h.SSHFederation)
|
||||||
r.MethodFunc("POST", "/ssh/config", h.SSHConfig)
|
r.MethodFunc("POST", "/ssh/config", h.SSHConfig)
|
||||||
r.MethodFunc("POST", "/ssh/config/{type}", h.SSHConfig)
|
r.MethodFunc("POST", "/ssh/config/{type}", h.SSHConfig)
|
||||||
|
|
||||||
// For compatibility with old code:
|
// For compatibility with old code:
|
||||||
r.MethodFunc("POST", "/re-sign", h.Renew)
|
r.MethodFunc("POST", "/re-sign", h.Renew)
|
||||||
r.MethodFunc("POST", "/sign-ssh", h.SignSSH)
|
r.MethodFunc("POST", "/sign-ssh", h.SSHSign)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health is an HTTP handler that returns the status of the server.
|
// Health is an HTTP handler that returns the status of the server.
|
||||||
|
|
|
@ -513,7 +513,8 @@ type mockAuthority struct {
|
||||||
getEncryptedKey func(kid string) (string, error)
|
getEncryptedKey func(kid string) (string, error)
|
||||||
getRoots func() ([]*x509.Certificate, error)
|
getRoots func() ([]*x509.Certificate, error)
|
||||||
getFederation func() ([]*x509.Certificate, error)
|
getFederation func() ([]*x509.Certificate, error)
|
||||||
getSSHKeys func() (*authority.SSHKeys, error)
|
getSSHRoots func() (*authority.SSHKeys, error)
|
||||||
|
getSSHFederation func() (*authority.SSHKeys, error)
|
||||||
getSSHConfig func(typ string, data map[string]string) ([]templates.Output, error)
|
getSSHConfig func(typ string, data map[string]string) ([]templates.Output, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,9 +621,16 @@ func (m *mockAuthority) GetFederation() ([]*x509.Certificate, error) {
|
||||||
return m.ret1.([]*x509.Certificate), m.err
|
return m.ret1.([]*x509.Certificate), m.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockAuthority) GetSSHKeys() (*authority.SSHKeys, error) {
|
func (m *mockAuthority) GetSSHRoots() (*authority.SSHKeys, error) {
|
||||||
if m.getSSHKeys != nil {
|
if m.getSSHRoots != nil {
|
||||||
return m.getSSHKeys()
|
return m.getSSHRoots()
|
||||||
|
}
|
||||||
|
return m.ret1.(*authority.SSHKeys), m.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockAuthority) GetSSHFederation() (*authority.SSHKeys, error) {
|
||||||
|
if m.getSSHFederation != nil {
|
||||||
|
return m.getSSHFederation()
|
||||||
}
|
}
|
||||||
return m.ret1.(*authority.SSHKeys), m.err
|
return m.ret1.(*authority.SSHKeys), m.err
|
||||||
}
|
}
|
||||||
|
|
46
api/ssh.go
46
api/ssh.go
|
@ -17,13 +17,13 @@ import (
|
||||||
type SSHAuthority interface {
|
type SSHAuthority interface {
|
||||||
SignSSH(key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
SignSSH(key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||||
SignSSHAddUser(key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error)
|
SignSSHAddUser(key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error)
|
||||||
GetSSHKeys() (*authority.SSHKeys, error)
|
GetSSHRoots() (*authority.SSHKeys, error)
|
||||||
GetSSHFederatedKeys() (*authority.SSHKeys, error)
|
GetSSHFederation() (*authority.SSHKeys, error)
|
||||||
GetSSHConfig(typ string, data map[string]string) ([]templates.Output, error)
|
GetSSHConfig(typ string, data map[string]string) ([]templates.Output, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignSSHRequest is the request body of an SSH certificate request.
|
// SSHSignRequest is the request body of an SSH certificate request.
|
||||||
type SignSSHRequest struct {
|
type SSHSignRequest struct {
|
||||||
PublicKey []byte `json:"publicKey"` //base64 encoded
|
PublicKey []byte `json:"publicKey"` //base64 encoded
|
||||||
OTT string `json:"ott"`
|
OTT string `json:"ott"`
|
||||||
CertType string `json:"certType,omitempty"`
|
CertType string `json:"certType,omitempty"`
|
||||||
|
@ -33,8 +33,8 @@ type SignSSHRequest struct {
|
||||||
AddUserPublicKey []byte `json:"addUserPublicKey,omitempty"`
|
AddUserPublicKey []byte `json:"addUserPublicKey,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the SignSSHRequest.
|
// Validate validates the SSHSignRequest.
|
||||||
func (s *SignSSHRequest) Validate() error {
|
func (s *SSHSignRequest) Validate() error {
|
||||||
switch {
|
switch {
|
||||||
case s.CertType != "" && s.CertType != provisioner.SSHUserCert && s.CertType != provisioner.SSHHostCert:
|
case s.CertType != "" && s.CertType != provisioner.SSHUserCert && s.CertType != provisioner.SSHHostCert:
|
||||||
return errors.Errorf("unknown certType %s", s.CertType)
|
return errors.Errorf("unknown certType %s", s.CertType)
|
||||||
|
@ -47,15 +47,15 @@ func (s *SignSSHRequest) Validate() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignSSHResponse is the response object that returns the SSH certificate.
|
// SSHSignResponse is the response object that returns the SSH certificate.
|
||||||
type SignSSHResponse struct {
|
type SSHSignResponse struct {
|
||||||
Certificate SSHCertificate `json:"crt"`
|
Certificate SSHCertificate `json:"crt"`
|
||||||
AddUserCertificate *SSHCertificate `json:"addUserCrt,omitempty"`
|
AddUserCertificate *SSHCertificate `json:"addUserCrt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHKeysResponse represents the response object that returns the SSH user and
|
// SSHRootsResponse represents the response object that returns the SSH user and
|
||||||
// host keys.
|
// host keys.
|
||||||
type SSHKeysResponse struct {
|
type SSHRootsResponse struct {
|
||||||
UserKeys []SSHPublicKey `json:"userKey,omitempty"`
|
UserKeys []SSHPublicKey `json:"userKey,omitempty"`
|
||||||
HostKeys []SSHPublicKey `json:"hostKey,omitempty"`
|
HostKeys []SSHPublicKey `json:"hostKey,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -170,11 +170,11 @@ type SSHConfigResponse struct {
|
||||||
HostTemplates []Template `json:"hostTemplates,omitempty"`
|
HostTemplates []Template `json:"hostTemplates,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignSSH is an HTTP handler that reads an SignSSHRequest with a one-time-token
|
// SSHSign is an HTTP handler that reads an SignSSHRequest with a one-time-token
|
||||||
// (ott) from the body and creates a new SSH certificate with the information in
|
// (ott) from the body and creates a new SSH certificate with the information in
|
||||||
// the request.
|
// the request.
|
||||||
func (h *caHandler) SignSSH(w http.ResponseWriter, r *http.Request) {
|
func (h *caHandler) SSHSign(w http.ResponseWriter, r *http.Request) {
|
||||||
var body SignSSHRequest
|
var body SSHSignRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := ReadJSON(r.Body, &body); err != nil {
|
||||||
WriteError(w, BadRequest(errors.Wrap(err, "error reading request body")))
|
WriteError(w, BadRequest(errors.Wrap(err, "error reading request body")))
|
||||||
return
|
return
|
||||||
|
@ -232,16 +232,16 @@ func (h *caHandler) SignSSH(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
JSON(w, &SignSSHResponse{
|
JSON(w, &SSHSignResponse{
|
||||||
Certificate: SSHCertificate{cert},
|
Certificate: SSHCertificate{cert},
|
||||||
AddUserCertificate: addUserCertificate,
|
AddUserCertificate: addUserCertificate,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHKeys is an HTTP handler that returns the SSH public keys for user and host
|
// SSHRoots is an HTTP handler that returns the SSH public keys for user and host
|
||||||
// certificates.
|
// certificates.
|
||||||
func (h *caHandler) SSHKeys(w http.ResponseWriter, r *http.Request) {
|
func (h *caHandler) SSHRoots(w http.ResponseWriter, r *http.Request) {
|
||||||
keys, err := h.Authority.GetSSHKeys()
|
keys, err := h.Authority.GetSSHRoots()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteError(w, InternalServerError(err))
|
WriteError(w, InternalServerError(err))
|
||||||
return
|
return
|
||||||
|
@ -252,7 +252,7 @@ func (h *caHandler) SSHKeys(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := new(SSHKeysResponse)
|
resp := new(SSHRootsResponse)
|
||||||
for _, k := range keys.HostKeys {
|
for _, k := range keys.HostKeys {
|
||||||
resp.HostKeys = append(resp.HostKeys, SSHPublicKey{PublicKey: k})
|
resp.HostKeys = append(resp.HostKeys, SSHPublicKey{PublicKey: k})
|
||||||
}
|
}
|
||||||
|
@ -263,10 +263,10 @@ func (h *caHandler) SSHKeys(w http.ResponseWriter, r *http.Request) {
|
||||||
JSON(w, resp)
|
JSON(w, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHFederatedKeys is an HTTP handler that returns the federated SSH public
|
// SSHFederation is an HTTP handler that returns the federated SSH public keys
|
||||||
// keys for user and host certificates.
|
// for user and host certificates.
|
||||||
func (h *caHandler) SSHFederatedKeys(w http.ResponseWriter, r *http.Request) {
|
func (h *caHandler) SSHFederation(w http.ResponseWriter, r *http.Request) {
|
||||||
keys, err := h.Authority.GetSSHFederatedKeys()
|
keys, err := h.Authority.GetSSHFederation()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteError(w, NotFound(err))
|
WriteError(w, NotFound(err))
|
||||||
return
|
return
|
||||||
|
@ -277,7 +277,7 @@ func (h *caHandler) SSHFederatedKeys(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := new(SSHKeysResponse)
|
resp := new(SSHRootsResponse)
|
||||||
for _, k := range keys.HostKeys {
|
for _, k := range keys.HostKeys {
|
||||||
resp.HostKeys = append(resp.HostKeys, SSHPublicKey{PublicKey: k})
|
resp.HostKeys = append(resp.HostKeys, SSHPublicKey{PublicKey: k})
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ func TestSignSSHRequest_Validate(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
s := &SignSSHRequest{
|
s := &SSHSignRequest{
|
||||||
PublicKey: tt.fields.PublicKey,
|
PublicKey: tt.fields.PublicKey,
|
||||||
OTT: tt.fields.OTT,
|
OTT: tt.fields.OTT,
|
||||||
CertType: tt.fields.CertType,
|
CertType: tt.fields.CertType,
|
||||||
|
@ -235,7 +235,7 @@ func TestSignSSHRequest_Validate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_caHandler_SignSSH(t *testing.T) {
|
func Test_caHandler_SSHSign(t *testing.T) {
|
||||||
user, err := getSignedUserCertificate()
|
user, err := getSignedUserCertificate()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
host, err := getSignedHostCertificate()
|
host, err := getSignedHostCertificate()
|
||||||
|
@ -244,17 +244,17 @@ func Test_caHandler_SignSSH(t *testing.T) {
|
||||||
userB64 := base64.StdEncoding.EncodeToString(user.Marshal())
|
userB64 := base64.StdEncoding.EncodeToString(user.Marshal())
|
||||||
hostB64 := base64.StdEncoding.EncodeToString(host.Marshal())
|
hostB64 := base64.StdEncoding.EncodeToString(host.Marshal())
|
||||||
|
|
||||||
userReq, err := json.Marshal(SignSSHRequest{
|
userReq, err := json.Marshal(SSHSignRequest{
|
||||||
PublicKey: user.Key.Marshal(),
|
PublicKey: user.Key.Marshal(),
|
||||||
OTT: "ott",
|
OTT: "ott",
|
||||||
})
|
})
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
hostReq, err := json.Marshal(SignSSHRequest{
|
hostReq, err := json.Marshal(SSHSignRequest{
|
||||||
PublicKey: host.Key.Marshal(),
|
PublicKey: host.Key.Marshal(),
|
||||||
OTT: "ott",
|
OTT: "ott",
|
||||||
})
|
})
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
userAddReq, err := json.Marshal(SignSSHRequest{
|
userAddReq, err := json.Marshal(SSHSignRequest{
|
||||||
PublicKey: user.Key.Marshal(),
|
PublicKey: user.Key.Marshal(),
|
||||||
OTT: "ott",
|
OTT: "ott",
|
||||||
AddUserPublicKey: user.Key.Marshal(),
|
AddUserPublicKey: user.Key.Marshal(),
|
||||||
|
@ -299,7 +299,7 @@ func Test_caHandler_SignSSH(t *testing.T) {
|
||||||
|
|
||||||
req := httptest.NewRequest("POST", "http://example.com/ssh/sign", bytes.NewReader(tt.req))
|
req := httptest.NewRequest("POST", "http://example.com/ssh/sign", bytes.NewReader(tt.req))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
h.SignSSH(logging.NewResponseLogger(w), req)
|
h.SSHSign(logging.NewResponseLogger(w), req)
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
|
|
||||||
if res.StatusCode != tt.statusCode {
|
if res.StatusCode != tt.statusCode {
|
||||||
|
@ -320,7 +320,7 @@ func Test_caHandler_SignSSH(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_caHandler_SSHKeys(t *testing.T) {
|
func Test_caHandler_SSHRoots(t *testing.T) {
|
||||||
user, err := ssh.NewPublicKey(sshUserKey.Public())
|
user, err := ssh.NewPublicKey(sshUserKey.Public())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
userB64 := base64.StdEncoding.EncodeToString(user.Marshal())
|
userB64 := base64.StdEncoding.EncodeToString(user.Marshal())
|
||||||
|
@ -336,22 +336,23 @@ func Test_caHandler_SSHKeys(t *testing.T) {
|
||||||
body []byte
|
body []byte
|
||||||
statusCode int
|
statusCode int
|
||||||
}{
|
}{
|
||||||
{"ok", &authority.SSHKeys{HostKey: host, UserKey: user}, nil, []byte(fmt.Sprintf(`{"userKey":"%s","hostKey":"%s"}`, userB64, hostB64)), http.StatusOK},
|
{"ok", &authority.SSHKeys{HostKeys: []ssh.PublicKey{host}, UserKeys: []ssh.PublicKey{user}}, nil, []byte(fmt.Sprintf(`{"userKey":["%s"],"hostKey":["%s"]}`, userB64, hostB64)), http.StatusOK},
|
||||||
{"user", &authority.SSHKeys{UserKey: user}, nil, []byte(fmt.Sprintf(`{"userKey":"%s"}`, userB64)), http.StatusOK},
|
{"user", &authority.SSHKeys{UserKeys: []ssh.PublicKey{user}}, nil, []byte(fmt.Sprintf(`{"userKey":["%s"]}`, userB64)), http.StatusOK},
|
||||||
{"host", &authority.SSHKeys{HostKey: host}, nil, []byte(fmt.Sprintf(`{"hostKey":"%s"}`, hostB64)), http.StatusOK},
|
{"host", &authority.SSHKeys{HostKeys: []ssh.PublicKey{host}}, nil, []byte(fmt.Sprintf(`{"hostKey":["%s"]}`, hostB64)), http.StatusOK},
|
||||||
{"error", nil, fmt.Errorf("an error"), nil, http.StatusNotFound},
|
{"empty", &authority.SSHKeys{}, nil, nil, http.StatusNotFound},
|
||||||
|
{"error", nil, fmt.Errorf("an error"), nil, http.StatusInternalServerError},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
h := New(&mockAuthority{
|
h := New(&mockAuthority{
|
||||||
getSSHKeys: func() (*authority.SSHKeys, error) {
|
getSSHRoots: func() (*authority.SSHKeys, error) {
|
||||||
return tt.keys, tt.keysErr
|
return tt.keys, tt.keysErr
|
||||||
},
|
},
|
||||||
}).(*caHandler)
|
}).(*caHandler)
|
||||||
|
|
||||||
req := httptest.NewRequest("GET", "http://example.com/ssh/keys", http.NoBody)
|
req := httptest.NewRequest("GET", "http://example.com/ssh/keys", http.NoBody)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
h.SSHKeys(logging.NewResponseLogger(w), req)
|
h.SSHRoots(logging.NewResponseLogger(w), req)
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
|
|
||||||
if res.StatusCode != tt.statusCode {
|
if res.StatusCode != tt.statusCode {
|
||||||
|
|
|
@ -87,16 +87,16 @@ type SSHKeys struct {
|
||||||
HostKeys []ssh.PublicKey
|
HostKeys []ssh.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSSHKeys returns the SSH User and Host public keys.
|
// GetSSHRoots returns the SSH User and Host public keys.
|
||||||
func (a *Authority) GetSSHKeys() (*SSHKeys, error) {
|
func (a *Authority) GetSSHRoots() (*SSHKeys, error) {
|
||||||
return &SSHKeys{
|
return &SSHKeys{
|
||||||
HostKeys: a.sshCAHostCerts,
|
HostKeys: a.sshCAHostCerts,
|
||||||
UserKeys: a.sshCAUserCerts,
|
UserKeys: a.sshCAUserCerts,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSSHFederatedKeys returns the public keys for federated SSH signers.
|
// GetSSHFederation returns the public keys for federated SSH signers.
|
||||||
func (a *Authority) GetSSHFederatedKeys() (*SSHKeys, error) {
|
func (a *Authority) GetSSHFederation() (*SSHKeys, error) {
|
||||||
return &SSHKeys{
|
return &SSHKeys{
|
||||||
HostKeys: a.sshCAHostFederatedCerts,
|
HostKeys: a.sshCAHostFederatedCerts,
|
||||||
UserKeys: a.sshCAUserFederatedCerts,
|
UserKeys: a.sshCAUserFederatedCerts,
|
||||||
|
|
64
ca/client.go
64
ca/client.go
|
@ -373,28 +373,6 @@ func (c *Client) Sign(req *api.SignRequest) (*api.SignResponse, error) {
|
||||||
return &sign, nil
|
return &sign, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignSSH performs the SSH certificate sign request to the CA and returns the
|
|
||||||
// api.SignSSHResponse struct.
|
|
||||||
func (c *Client) SignSSH(req *api.SignSSHRequest) (*api.SignSSHResponse, error) {
|
|
||||||
body, err := json.Marshal(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error marshaling request")
|
|
||||||
}
|
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/sign"})
|
|
||||||
resp, err := c.client.Post(u.String(), "application/json", bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "client POST %s failed", u)
|
|
||||||
}
|
|
||||||
if resp.StatusCode >= 400 {
|
|
||||||
return nil, readError(resp.Body)
|
|
||||||
}
|
|
||||||
var sign api.SignSSHResponse
|
|
||||||
if err := readJSON(resp.Body, &sign); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
|
||||||
}
|
|
||||||
return &sign, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renew performs the renew request to the CA and returns the api.SignResponse
|
// Renew performs the renew request to the CA and returns the api.SignResponse
|
||||||
// struct.
|
// struct.
|
||||||
func (c *Client) Renew(tr http.RoundTripper) (*api.SignResponse, error) {
|
func (c *Client) Renew(tr http.RoundTripper) (*api.SignResponse, error) {
|
||||||
|
@ -527,10 +505,32 @@ func (c *Client) Federation() (*api.FederationResponse, error) {
|
||||||
return &federation, nil
|
return &federation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHKeys performs the get /ssh/keys request to the CA and returns the
|
// SSHSign performs the POST /ssh/sign request to the CA and returns the
|
||||||
// api.SSHKeysResponse struct.
|
// api.SSHSignResponse struct.
|
||||||
func (c *Client) SSHKeys() (*api.SSHKeysResponse, error) {
|
func (c *Client) SSHSign(req *api.SSHSignRequest) (*api.SSHSignResponse, error) {
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/keys"})
|
body, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error marshaling request")
|
||||||
|
}
|
||||||
|
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/sign"})
|
||||||
|
resp, err := c.client.Post(u.String(), "application/json", bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "client POST %s failed", u)
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return nil, readError(resp.Body)
|
||||||
|
}
|
||||||
|
var sign api.SSHSignResponse
|
||||||
|
if err := readJSON(resp.Body, &sign); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
|
}
|
||||||
|
return &sign, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSHRoots performs the GET /ssh/roots request to the CA and returns the
|
||||||
|
// api.SSHRootsResponse struct.
|
||||||
|
func (c *Client) SSHRoots() (*api.SSHRootsResponse, error) {
|
||||||
|
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/roots"})
|
||||||
resp, err := c.client.Get(u.String())
|
resp, err := c.client.Get(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "client GET %s failed", u)
|
return nil, errors.Wrapf(err, "client GET %s failed", u)
|
||||||
|
@ -538,7 +538,7 @@ func (c *Client) SSHKeys() (*api.SSHKeysResponse, error) {
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
return nil, readError(resp.Body)
|
return nil, readError(resp.Body)
|
||||||
}
|
}
|
||||||
var keys api.SSHKeysResponse
|
var keys api.SSHRootsResponse
|
||||||
if err := readJSON(resp.Body, &keys); err != nil {
|
if err := readJSON(resp.Body, &keys); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
}
|
}
|
||||||
|
@ -546,8 +546,8 @@ func (c *Client) SSHKeys() (*api.SSHKeysResponse, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHFederation performs the get /ssh/federation request to the CA and returns
|
// SSHFederation performs the get /ssh/federation request to the CA and returns
|
||||||
// the api.SSHKeysResponse struct.
|
// the api.SSHRootsResponse struct.
|
||||||
func (c *Client) SSHFederation() (*api.SSHKeysResponse, error) {
|
func (c *Client) SSHFederation() (*api.SSHRootsResponse, error) {
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/federation"})
|
u := c.endpoint.ResolveReference(&url.URL{Path: "/ssh/federation"})
|
||||||
resp, err := c.client.Get(u.String())
|
resp, err := c.client.Get(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -556,15 +556,15 @@ func (c *Client) SSHFederation() (*api.SSHKeysResponse, error) {
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
return nil, readError(resp.Body)
|
return nil, readError(resp.Body)
|
||||||
}
|
}
|
||||||
var keys api.SSHKeysResponse
|
var keys api.SSHRootsResponse
|
||||||
if err := readJSON(resp.Body, &keys); err != nil {
|
if err := readJSON(resp.Body, &keys); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
}
|
}
|
||||||
return &keys, nil
|
return &keys, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHConfig performs the POST request to the CA to get the ssh configuration
|
// SSHConfig performs the POST /ssh/config request to the CA to get the ssh
|
||||||
// templates.
|
// configuration templates.
|
||||||
func (c *Client) SSHConfig(req *api.SSHConfigRequest) (*api.SSHConfigResponse, error) {
|
func (c *Client) SSHConfig(req *api.SSHConfigRequest) (*api.SSHConfigResponse, error) {
|
||||||
body, err := json.Marshal(req)
|
body, err := json.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -722,15 +722,15 @@ func TestClient_Federation(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_SSHKeys(t *testing.T) {
|
func TestClient_SSHRoots(t *testing.T) {
|
||||||
key, err := ssh.NewPublicKey(mustKey().Public())
|
key, err := ssh.NewPublicKey(mustKey().Public())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := &api.SSHKeysResponse{
|
ok := &api.SSHRootsResponse{
|
||||||
HostKey: &api.SSHPublicKey{PublicKey: key},
|
HostKeys: []api.SSHPublicKey{{PublicKey: key}},
|
||||||
UserKey: &api.SSHPublicKey{PublicKey: key},
|
UserKeys: []api.SSHPublicKey{{PublicKey: key}},
|
||||||
}
|
}
|
||||||
notFound := api.NotFound(fmt.Errorf("Not Found"))
|
notFound := api.NotFound(fmt.Errorf("Not Found"))
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ func TestClient_SSHKeys(t *testing.T) {
|
||||||
api.JSONStatus(w, tt.response, tt.responseCode)
|
api.JSONStatus(w, tt.response, tt.responseCode)
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := c.SSHKeys()
|
got, err := c.SSHRoots()
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
fmt.Printf("%+v", err)
|
fmt.Printf("%+v", err)
|
||||||
t.Errorf("Client.SSHKeys() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("Client.SSHKeys() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
|
Loading…
Reference in a new issue