Add version endpoint.

This commit is contained in:
Mariano Cano 2019-11-20 17:01:31 -08:00 committed by max furman
parent db3b795eea
commit c60641701b
3 changed files with 49 additions and 2 deletions

View file

@ -42,6 +42,7 @@ type Authority interface {
GetEncryptedKey(kid string) (string, error) GetEncryptedKey(kid string) (string, error)
GetRoots() (federation []*x509.Certificate, err error) GetRoots() (federation []*x509.Certificate, err error)
GetFederation() ([]*x509.Certificate, error) GetFederation() ([]*x509.Certificate, error)
Version() authority.Version
} }
// TimeDuration is an alias of provisioner.TimeDuration // TimeDuration is an alias of provisioner.TimeDuration
@ -71,6 +72,13 @@ func NewCertificate(cr *x509.Certificate) Certificate {
} }
} }
// reset sets the inner x509.CertificateRequest to nil
func (c *Certificate) reset() {
if c != nil {
c.Certificate = nil
}
}
// MarshalJSON implements the json.Marshaler interface. The certificate is // MarshalJSON implements the json.Marshaler interface. The certificate is
// quoted string using the PEM encoding. // quoted string using the PEM encoding.
func (c Certificate) MarshalJSON() ([]byte, error) { func (c Certificate) MarshalJSON() ([]byte, error) {
@ -91,6 +99,13 @@ func (c *Certificate) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &s); err != nil { if err := json.Unmarshal(data, &s); err != nil {
return errors.Wrap(err, "error decoding certificate") return errors.Wrap(err, "error decoding certificate")
} }
// Make sure the inner x509.Certificate is nil
if s == "null" || s == "" {
c.reset()
return nil
}
block, _ := pem.Decode([]byte(s)) block, _ := pem.Decode([]byte(s))
if block == nil { if block == nil {
return errors.New("error decoding certificate") return errors.New("error decoding certificate")
@ -117,6 +132,13 @@ func NewCertificateRequest(cr *x509.CertificateRequest) CertificateRequest {
} }
} }
// reset sets the inner x509.CertificateRequest to nil
func (c *CertificateRequest) reset() {
if c != nil {
c.CertificateRequest = nil
}
}
// MarshalJSON implements the json.Marshaler interface. The certificate request // MarshalJSON implements the json.Marshaler interface. The certificate request
// is a quoted string using the PEM encoding. // is a quoted string using the PEM encoding.
func (c CertificateRequest) MarshalJSON() ([]byte, error) { func (c CertificateRequest) MarshalJSON() ([]byte, error) {
@ -137,6 +159,13 @@ func (c *CertificateRequest) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &s); err != nil { if err := json.Unmarshal(data, &s); err != nil {
return errors.Wrap(err, "error decoding csr") return errors.Wrap(err, "error decoding csr")
} }
// Make sure the inner x509.CertificateRequest is nil
if s == "null" || s == "" {
c.reset()
return nil
}
block, _ := pem.Decode([]byte(s)) block, _ := pem.Decode([]byte(s))
if block == nil { if block == nil {
return errors.New("error decoding csr") return errors.New("error decoding csr")
@ -162,6 +191,13 @@ type RouterHandler interface {
Route(r Router) Route(r Router)
} }
// VersionResponse is the response object that returns the version of the
// server.
type VersionResponse struct {
Version string `json:"version"`
RequireClientAuthentication bool `json:"requireClientAuthentication,omitempty"`
}
// HealthResponse is the response object that returns the health of the server. // HealthResponse is the response object that returns the health of the server.
type HealthResponse struct { type HealthResponse struct {
Status string `json:"status"` Status string `json:"status"`
@ -241,6 +277,7 @@ func New(authority Authority) RouterHandler {
} }
func (h *caHandler) Route(r Router) { func (h *caHandler) Route(r Router) {
r.MethodFunc("GET", "/version", h.Version)
r.MethodFunc("GET", "/health", h.Health) r.MethodFunc("GET", "/health", h.Health)
r.MethodFunc("GET", "/root/{sha}", h.Root) r.MethodFunc("GET", "/root/{sha}", h.Root)
r.MethodFunc("POST", "/sign", h.Sign) r.MethodFunc("POST", "/sign", h.Sign)
@ -268,6 +305,15 @@ func (h *caHandler) Route(r Router) {
r.MethodFunc("POST", "/sign-ssh", h.SSHSign) r.MethodFunc("POST", "/sign-ssh", h.SSHSign)
} }
// Version is an HTTP handler that returns the version of the server.
func (h *caHandler) Version(w http.ResponseWriter, r *http.Request) {
v := h.Authority.Version()
JSON(w, VersionResponse{
Version: v.Version,
RequireClientAuthentication: v.RequireClientAuthentication,
})
}
// Health is an HTTP handler that returns the status of the server. // Health is an HTTP handler that returns the status of the server.
func (h *caHandler) Health(w http.ResponseWriter, r *http.Request) { func (h *caHandler) Health(w http.ResponseWriter, r *http.Request) {
JSON(w, HealthResponse{Status: "ok"}) JSON(w, HealthResponse{Status: "ok"})

View file

@ -8,11 +8,10 @@ import (
"sync" "sync"
"time" "time"
"github.com/smallstep/certificates/templates"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/authority/provisioner" "github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/db" "github.com/smallstep/certificates/db"
"github.com/smallstep/certificates/templates"
"github.com/smallstep/cli/crypto/pemutil" "github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/crypto/x509util" "github.com/smallstep/cli/crypto/x509util"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"

View file

@ -13,6 +13,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/commands" "github.com/smallstep/certificates/commands"
"github.com/smallstep/cli/command" "github.com/smallstep/cli/command"
"github.com/smallstep/cli/command/version" "github.com/smallstep/cli/command/version"
@ -29,6 +30,7 @@ var (
func init() { func init() {
config.Set("Smallstep CA", Version, BuildTime) config.Set("Smallstep CA", Version, BuildTime)
authority.GlobalVersion.Version = Version
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
} }