CA Provider Plugins (#4751)
This adds the `agent/connect/ca/plugin` library for consuming/serving Connect CA providers as [go-plugin](https://github.com/hashicorp/go-plugin) plugins. This **does not** wire this up in any way to Consul itself, so this will not enable using these plugins yet.
## Why?
We want to enable CA providers to be pluggable without modifying Consul so that any CA or PKI system can potentially back the Connect certificates. This CA system may also be used in the future for easier bootstrapping and internal cluster security.
### go-plugin
The benefit of `go-plugin` is that for the plugin consumer, the fact that the interface implementation is communicating over multi-process RPC is invisible. Internals of Consul will continue to just use `ca.Provider` interface implementations as if they're local. For plugin _authors_, they simply have to implement the interface. The network/transport/process management issues are handled by go-plugin itself.
The CA provider plugins support both `net/rpc` and gRPC transports. This enables easy authoring in any language. go-plugin handles the actual protocol handshake and connection. This is just a feature of go-plugin.
`go-plugin` is already in production use for years by Packer, Terraform, Nomad, Vault, and Sentinel. We've shown stability for both desktop and server-side software. It is very mature.
## Implementation Details
### `map[string]interface{}`
The `Configure` method passes a `map[string]interface{}`. This map contains only Go primitives and containers of primitives (no funcs, chans, etc.). For `net/rpc` we encode as-is using Gob. For gRPC we marshal to JSON and transmit as a `bytes` type. This is the same approach we take with Vault and other software.
Note that this is just the transport protocol, the end software views it fully decoded.
### `x509.Certificate` and `CertificateRequest`
We transmit the raw ASN.1 bytes and decode on the other side. Unit tests are verifying we get the same cert/csrs across the wire.
### Testing
`go-plugin` exposes test helpers that enable testing the full plugin RPC over real loopback network connections. We test all endpoints for success and error for both `net/rpc` and gRPC.
### Vendoring
This PR doesn't introduce vendoring for two reasons:
1. @banks's `f-envoy` branch introduces a lot of these and I didn't want conflict.
2. The library isn't actually used yet so it doesn't introduce compile-time errors (it does introduce test errors).
## Next Steps
With this in place, we need to figure out the proper way to actually hook these up to Consul, load them, etc. This discussion can happen elsewhere, since regardless of approach this plugin library implementation is the exact same.
2019-01-07 17:48:44 +00:00
|
|
|
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
|
|
|
|
|
|
|
package ca
|
|
|
|
|
|
|
|
import mock "github.com/stretchr/testify/mock"
|
|
|
|
import x509 "crypto/x509"
|
|
|
|
|
|
|
|
// MockProvider is an autogenerated mock type for the Provider type
|
|
|
|
type MockProvider struct {
|
|
|
|
mock.Mock
|
|
|
|
}
|
|
|
|
|
|
|
|
// ActiveIntermediate provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) ActiveIntermediate() (string, error) {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func() string); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func() error); ok {
|
|
|
|
r1 = rf()
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// ActiveRoot provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) ActiveRoot() (string, error) {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func() string); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func() error); ok {
|
|
|
|
r1 = rf()
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cleanup provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) Cleanup() error {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 error
|
|
|
|
if rf, ok := ret.Get(0).(func() error); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Error(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0
|
|
|
|
}
|
|
|
|
|
2019-08-27 21:09:01 +00:00
|
|
|
// Configure provides a mock function with given fields: clusterID, datacenterName, dnsDomain, isRoot, rawConfig
|
|
|
|
func (_m *MockProvider) Configure(clusterId string, datacenterName string, dnsDomain string, isRoot bool, rawConfig map[string]interface{}) error {
|
|
|
|
ret := _m.Called(clusterId, datacenterName, dnsDomain, isRoot, rawConfig)
|
CA Provider Plugins (#4751)
This adds the `agent/connect/ca/plugin` library for consuming/serving Connect CA providers as [go-plugin](https://github.com/hashicorp/go-plugin) plugins. This **does not** wire this up in any way to Consul itself, so this will not enable using these plugins yet.
## Why?
We want to enable CA providers to be pluggable without modifying Consul so that any CA or PKI system can potentially back the Connect certificates. This CA system may also be used in the future for easier bootstrapping and internal cluster security.
### go-plugin
The benefit of `go-plugin` is that for the plugin consumer, the fact that the interface implementation is communicating over multi-process RPC is invisible. Internals of Consul will continue to just use `ca.Provider` interface implementations as if they're local. For plugin _authors_, they simply have to implement the interface. The network/transport/process management issues are handled by go-plugin itself.
The CA provider plugins support both `net/rpc` and gRPC transports. This enables easy authoring in any language. go-plugin handles the actual protocol handshake and connection. This is just a feature of go-plugin.
`go-plugin` is already in production use for years by Packer, Terraform, Nomad, Vault, and Sentinel. We've shown stability for both desktop and server-side software. It is very mature.
## Implementation Details
### `map[string]interface{}`
The `Configure` method passes a `map[string]interface{}`. This map contains only Go primitives and containers of primitives (no funcs, chans, etc.). For `net/rpc` we encode as-is using Gob. For gRPC we marshal to JSON and transmit as a `bytes` type. This is the same approach we take with Vault and other software.
Note that this is just the transport protocol, the end software views it fully decoded.
### `x509.Certificate` and `CertificateRequest`
We transmit the raw ASN.1 bytes and decode on the other side. Unit tests are verifying we get the same cert/csrs across the wire.
### Testing
`go-plugin` exposes test helpers that enable testing the full plugin RPC over real loopback network connections. We test all endpoints for success and error for both `net/rpc` and gRPC.
### Vendoring
This PR doesn't introduce vendoring for two reasons:
1. @banks's `f-envoy` branch introduces a lot of these and I didn't want conflict.
2. The library isn't actually used yet so it doesn't introduce compile-time errors (it does introduce test errors).
## Next Steps
With this in place, we need to figure out the proper way to actually hook these up to Consul, load them, etc. This discussion can happen elsewhere, since regardless of approach this plugin library implementation is the exact same.
2019-01-07 17:48:44 +00:00
|
|
|
|
|
|
|
var r0 error
|
2019-08-27 21:09:01 +00:00
|
|
|
if rf, ok := ret.Get(0).(func(string, string, string, bool, map[string]interface{}) error); ok {
|
|
|
|
r0 = rf(clusterId, datacenterName, dnsDomain, isRoot, rawConfig)
|
CA Provider Plugins (#4751)
This adds the `agent/connect/ca/plugin` library for consuming/serving Connect CA providers as [go-plugin](https://github.com/hashicorp/go-plugin) plugins. This **does not** wire this up in any way to Consul itself, so this will not enable using these plugins yet.
## Why?
We want to enable CA providers to be pluggable without modifying Consul so that any CA or PKI system can potentially back the Connect certificates. This CA system may also be used in the future for easier bootstrapping and internal cluster security.
### go-plugin
The benefit of `go-plugin` is that for the plugin consumer, the fact that the interface implementation is communicating over multi-process RPC is invisible. Internals of Consul will continue to just use `ca.Provider` interface implementations as if they're local. For plugin _authors_, they simply have to implement the interface. The network/transport/process management issues are handled by go-plugin itself.
The CA provider plugins support both `net/rpc` and gRPC transports. This enables easy authoring in any language. go-plugin handles the actual protocol handshake and connection. This is just a feature of go-plugin.
`go-plugin` is already in production use for years by Packer, Terraform, Nomad, Vault, and Sentinel. We've shown stability for both desktop and server-side software. It is very mature.
## Implementation Details
### `map[string]interface{}`
The `Configure` method passes a `map[string]interface{}`. This map contains only Go primitives and containers of primitives (no funcs, chans, etc.). For `net/rpc` we encode as-is using Gob. For gRPC we marshal to JSON and transmit as a `bytes` type. This is the same approach we take with Vault and other software.
Note that this is just the transport protocol, the end software views it fully decoded.
### `x509.Certificate` and `CertificateRequest`
We transmit the raw ASN.1 bytes and decode on the other side. Unit tests are verifying we get the same cert/csrs across the wire.
### Testing
`go-plugin` exposes test helpers that enable testing the full plugin RPC over real loopback network connections. We test all endpoints for success and error for both `net/rpc` and gRPC.
### Vendoring
This PR doesn't introduce vendoring for two reasons:
1. @banks's `f-envoy` branch introduces a lot of these and I didn't want conflict.
2. The library isn't actually used yet so it doesn't introduce compile-time errors (it does introduce test errors).
## Next Steps
With this in place, we need to figure out the proper way to actually hook these up to Consul, load them, etc. This discussion can happen elsewhere, since regardless of approach this plugin library implementation is the exact same.
2019-01-07 17:48:44 +00:00
|
|
|
} else {
|
|
|
|
r0 = ret.Error(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0
|
|
|
|
}
|
|
|
|
|
|
|
|
// CrossSignCA provides a mock function with given fields: _a0
|
|
|
|
func (_m *MockProvider) CrossSignCA(_a0 *x509.Certificate) (string, error) {
|
|
|
|
ret := _m.Called(_a0)
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func(*x509.Certificate) string); ok {
|
|
|
|
r0 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func(*x509.Certificate) error); ok {
|
|
|
|
r1 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// GenerateIntermediate provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) GenerateIntermediate() (string, error) {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func() string); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func() error); ok {
|
|
|
|
r1 = rf()
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// GenerateIntermediateCSR provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) GenerateIntermediateCSR() (string, error) {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func() string); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func() error); ok {
|
|
|
|
r1 = rf()
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// GenerateRoot provides a mock function with given fields:
|
|
|
|
func (_m *MockProvider) GenerateRoot() error {
|
|
|
|
ret := _m.Called()
|
|
|
|
|
|
|
|
var r0 error
|
|
|
|
if rf, ok := ret.Get(0).(func() error); ok {
|
|
|
|
r0 = rf()
|
|
|
|
} else {
|
|
|
|
r0 = ret.Error(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetIntermediate provides a mock function with given fields: intermediatePEM, rootPEM
|
|
|
|
func (_m *MockProvider) SetIntermediate(intermediatePEM string, rootPEM string) error {
|
|
|
|
ret := _m.Called(intermediatePEM, rootPEM)
|
|
|
|
|
|
|
|
var r0 error
|
|
|
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
|
|
|
r0 = rf(intermediatePEM, rootPEM)
|
|
|
|
} else {
|
|
|
|
r0 = ret.Error(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sign provides a mock function with given fields: _a0
|
|
|
|
func (_m *MockProvider) Sign(_a0 *x509.CertificateRequest) (string, error) {
|
|
|
|
ret := _m.Called(_a0)
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func(*x509.CertificateRequest) string); ok {
|
|
|
|
r0 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func(*x509.CertificateRequest) error); ok {
|
|
|
|
r1 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|
|
|
|
|
|
|
|
// SignIntermediate provides a mock function with given fields: _a0
|
|
|
|
func (_m *MockProvider) SignIntermediate(_a0 *x509.CertificateRequest) (string, error) {
|
|
|
|
ret := _m.Called(_a0)
|
|
|
|
|
|
|
|
var r0 string
|
|
|
|
if rf, ok := ret.Get(0).(func(*x509.CertificateRequest) string); ok {
|
|
|
|
r0 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r0 = ret.Get(0).(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var r1 error
|
|
|
|
if rf, ok := ret.Get(1).(func(*x509.CertificateRequest) error); ok {
|
|
|
|
r1 = rf(_a0)
|
|
|
|
} else {
|
|
|
|
r1 = ret.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r0, r1
|
|
|
|
}
|