github.imxd.top/hashicorp/consul@v1.4.5/api/connect_ca.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/mitchellh/mapstructure" 8 ) 9 10 // CAConfig is the structure for the Connect CA configuration. 11 type CAConfig struct { 12 // Provider is the CA provider implementation to use. 13 Provider string 14 15 // Configuration is arbitrary configuration for the provider. This 16 // should only contain primitive values and containers (such as lists 17 // and maps). 18 Config map[string]interface{} 19 20 CreateIndex uint64 21 ModifyIndex uint64 22 } 23 24 // CommonCAProviderConfig is the common options available to all CA providers. 25 type CommonCAProviderConfig struct { 26 LeafCertTTL time.Duration 27 SkipValidate bool 28 CSRMaxPerSecond float32 29 CSRMaxConcurrent int 30 } 31 32 // ConsulCAProviderConfig is the config for the built-in Consul CA provider. 33 type ConsulCAProviderConfig struct { 34 CommonCAProviderConfig `mapstructure:",squash"` 35 36 PrivateKey string 37 RootCert string 38 RotationPeriod time.Duration 39 } 40 41 // ParseConsulCAConfig takes a raw config map and returns a parsed 42 // ConsulCAProviderConfig. 43 func ParseConsulCAConfig(raw map[string]interface{}) (*ConsulCAProviderConfig, error) { 44 var config ConsulCAProviderConfig 45 decodeConf := &mapstructure.DecoderConfig{ 46 DecodeHook: mapstructure.StringToTimeDurationHookFunc(), 47 Result: &config, 48 WeaklyTypedInput: true, 49 } 50 51 decoder, err := mapstructure.NewDecoder(decodeConf) 52 if err != nil { 53 return nil, err 54 } 55 56 if err := decoder.Decode(raw); err != nil { 57 return nil, fmt.Errorf("error decoding config: %s", err) 58 } 59 60 return &config, nil 61 } 62 63 // CARootList is the structure for the results of listing roots. 64 type CARootList struct { 65 ActiveRootID string 66 TrustDomain string 67 Roots []*CARoot 68 } 69 70 // CARoot represents a root CA certificate that is trusted. 71 type CARoot struct { 72 // ID is a globally unique ID (UUID) representing this CA root. 73 ID string 74 75 // Name is a human-friendly name for this CA root. This value is 76 // opaque to Consul and is not used for anything internally. 77 Name string 78 79 // RootCertPEM is the PEM-encoded public certificate. 80 RootCertPEM string `json:"RootCert"` 81 82 // Active is true if this is the current active CA. This must only 83 // be true for exactly one CA. For any method that modifies roots in the 84 // state store, tests should be written to verify that multiple roots 85 // cannot be active. 86 Active bool 87 88 CreateIndex uint64 89 ModifyIndex uint64 90 } 91 92 // LeafCert is a certificate that has been issued by a Connect CA. 93 type LeafCert struct { 94 // SerialNumber is the unique serial number for this certificate. 95 // This is encoded in standard hex separated by :. 96 SerialNumber string 97 98 // CertPEM and PrivateKeyPEM are the PEM-encoded certificate and private 99 // key for that cert, respectively. This should not be stored in the 100 // state store, but is present in the sign API response. 101 CertPEM string `json:",omitempty"` 102 PrivateKeyPEM string `json:",omitempty"` 103 104 // Service is the name of the service for which the cert was issued. 105 // ServiceURI is the cert URI value. 106 Service string 107 ServiceURI string 108 109 // ValidAfter and ValidBefore are the validity periods for the 110 // certificate. 111 ValidAfter time.Time 112 ValidBefore time.Time 113 114 CreateIndex uint64 115 ModifyIndex uint64 116 } 117 118 // CARoots queries the list of available roots. 119 func (h *Connect) CARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) { 120 r := h.c.newRequest("GET", "/v1/connect/ca/roots") 121 r.setQueryOptions(q) 122 rtt, resp, err := requireOK(h.c.doRequest(r)) 123 if err != nil { 124 return nil, nil, err 125 } 126 defer resp.Body.Close() 127 128 qm := &QueryMeta{} 129 parseQueryMeta(resp, qm) 130 qm.RequestTime = rtt 131 132 var out CARootList 133 if err := decodeBody(resp, &out); err != nil { 134 return nil, nil, err 135 } 136 return &out, qm, nil 137 } 138 139 // CAGetConfig returns the current CA configuration. 140 func (h *Connect) CAGetConfig(q *QueryOptions) (*CAConfig, *QueryMeta, error) { 141 r := h.c.newRequest("GET", "/v1/connect/ca/configuration") 142 r.setQueryOptions(q) 143 rtt, resp, err := requireOK(h.c.doRequest(r)) 144 if err != nil { 145 return nil, nil, err 146 } 147 defer resp.Body.Close() 148 149 qm := &QueryMeta{} 150 parseQueryMeta(resp, qm) 151 qm.RequestTime = rtt 152 153 var out CAConfig 154 if err := decodeBody(resp, &out); err != nil { 155 return nil, nil, err 156 } 157 return &out, qm, nil 158 } 159 160 // CASetConfig sets the current CA configuration. 161 func (h *Connect) CASetConfig(conf *CAConfig, q *WriteOptions) (*WriteMeta, error) { 162 r := h.c.newRequest("PUT", "/v1/connect/ca/configuration") 163 r.setWriteOptions(q) 164 r.obj = conf 165 rtt, resp, err := requireOK(h.c.doRequest(r)) 166 if err != nil { 167 return nil, err 168 } 169 defer resp.Body.Close() 170 171 wm := &WriteMeta{} 172 wm.RequestTime = rtt 173 return wm, nil 174 }