Merge pull request #19110 from hashicorp/jbardin/provider-config

PrepareProviderConfig
This commit is contained in:
James Bardin 2018-10-18 10:53:06 -04:00 committed by GitHub
commit e377b8878d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 596 additions and 506 deletions

View File

@ -77,8 +77,8 @@ func (s *GRPCProviderServer) getDatasourceSchemaBlock(name string) *configschema
return dat.CoreConfigSchema() return dat.CoreConfigSchema()
} }
func (s *GRPCProviderServer) ValidateProviderConfig(_ context.Context, req *proto.ValidateProviderConfig_Request) (*proto.ValidateProviderConfig_Response, error) { func (s *GRPCProviderServer) PrepareProviderConfig(_ context.Context, req *proto.PrepareProviderConfig_Request) (*proto.PrepareProviderConfig_Response, error) {
resp := &proto.ValidateProviderConfig_Response{} resp := &proto.PrepareProviderConfig_Response{}
block := s.getProviderSchemaBlock() block := s.getProviderSchemaBlock()
@ -93,6 +93,9 @@ func (s *GRPCProviderServer) ValidateProviderConfig(_ context.Context, req *prot
warns, errs := s.provider.Validate(config) warns, errs := s.provider.Validate(config)
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, convert.WarnsAndErrsToProto(warns, errs)) resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, convert.WarnsAndErrsToProto(warns, errs))
// TODO: set defaults
resp.PreparedConfig = req.Config
return resp, nil return resp, nil
} }

View File

@ -147,26 +147,38 @@ func (p *GRPCProvider) GetSchema() (resp providers.GetSchemaResponse) {
return resp return resp
} }
func (p *GRPCProvider) ValidateProviderConfig(r providers.ValidateProviderConfigRequest) (resp providers.ValidateProviderConfigResponse) { func (p *GRPCProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRequest) (resp providers.PrepareProviderConfigResponse) {
log.Printf("[TRACE] GRPCProvider: ValidateProviderConfig") log.Printf("[TRACE] GRPCProvider: PrepareProviderConfig")
schema := p.getSchema() schema := p.getSchema()
mp, err := msgpack.Marshal(r.Config, schema.Provider.Block.ImpliedType()) ty := schema.Provider.Block.ImpliedType()
mp, err := msgpack.Marshal(r.Config, ty)
if err != nil { if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err) resp.Diagnostics = resp.Diagnostics.Append(err)
return resp return resp
} }
protoReq := &proto.ValidateProviderConfig_Request{ protoReq := &proto.PrepareProviderConfig_Request{
Config: &proto.DynamicValue{Msgpack: mp}, Config: &proto.DynamicValue{Msgpack: mp},
} }
protoResp, err := p.client.ValidateProviderConfig(p.ctx, protoReq) protoResp, err := p.client.PrepareProviderConfig(p.ctx, protoReq)
if err != nil { if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err) resp.Diagnostics = resp.Diagnostics.Append(err)
return resp return resp
} }
config := cty.NullVal(ty)
if protoResp.PreparedConfig != nil {
config, err = msgpack.Unmarshal(protoResp.PreparedConfig.Msgpack, ty)
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err)
return resp
}
}
resp.PreparedConfig = config
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
return resp return resp
} }

View File

@ -91,19 +91,19 @@ func TestGRPCProvider_GetSchema(t *testing.T) {
checkDiags(t, resp.Diagnostics) checkDiags(t, resp.Diagnostics)
} }
func TestGRPCProvider_ValidateProviderConfig(t *testing.T) { func TestGRPCProvider_PrepareProviderConfig(t *testing.T) {
client := mockProviderClient(t) client := mockProviderClient(t)
p := &GRPCProvider{ p := &GRPCProvider{
client: client, client: client,
} }
client.EXPECT().ValidateProviderConfig( client.EXPECT().PrepareProviderConfig(
gomock.Any(), gomock.Any(),
gomock.Any(), gomock.Any(),
).Return(&proto.ValidateProviderConfig_Response{}, nil) ).Return(&proto.PrepareProviderConfig_Response{}, nil)
cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"}) cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
resp := p.ValidateProviderConfig(providers.ValidateProviderConfigRequest{Config: cfg}) resp := p.PrepareProviderConfig(providers.PrepareProviderConfigRequest{Config: cfg})
checkDiags(t, resp.Diagnostics) checkDiags(t, resp.Diagnostics)
} }

View File

@ -5,9 +5,9 @@
package mock_proto package mock_proto
import ( import (
context "context"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
proto "github.com/hashicorp/terraform/plugin/proto" proto "github.com/hashicorp/terraform/plugin/proto"
context "golang.org/x/net/context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
metadata "google.golang.org/grpc/metadata" metadata "google.golang.org/grpc/metadata"
reflect "reflect" reflect "reflect"
@ -126,6 +126,24 @@ func (mr *MockProviderClientMockRecorder) PlanResourceChange(arg0, arg1 interfac
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PlanResourceChange", reflect.TypeOf((*MockProviderClient)(nil).PlanResourceChange), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PlanResourceChange", reflect.TypeOf((*MockProviderClient)(nil).PlanResourceChange), varargs...)
} }
// PrepareProviderConfig mocks base method
func (m *MockProviderClient) PrepareProviderConfig(arg0 context.Context, arg1 *proto.PrepareProviderConfig_Request, arg2 ...grpc.CallOption) (*proto.PrepareProviderConfig_Response, error) {
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "PrepareProviderConfig", varargs...)
ret0, _ := ret[0].(*proto.PrepareProviderConfig_Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// PrepareProviderConfig indicates an expected call of PrepareProviderConfig
func (mr *MockProviderClientMockRecorder) PrepareProviderConfig(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareProviderConfig", reflect.TypeOf((*MockProviderClient)(nil).PrepareProviderConfig), varargs...)
}
// ReadDataSource mocks base method // ReadDataSource mocks base method
func (m *MockProviderClient) ReadDataSource(arg0 context.Context, arg1 *proto.ReadDataSource_Request, arg2 ...grpc.CallOption) (*proto.ReadDataSource_Response, error) { func (m *MockProviderClient) ReadDataSource(arg0 context.Context, arg1 *proto.ReadDataSource_Request, arg2 ...grpc.CallOption) (*proto.ReadDataSource_Response, error) {
varargs := []interface{}{arg0, arg1} varargs := []interface{}{arg0, arg1}
@ -216,24 +234,6 @@ func (mr *MockProviderClientMockRecorder) ValidateDataSourceConfig(arg0, arg1 in
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateDataSourceConfig", reflect.TypeOf((*MockProviderClient)(nil).ValidateDataSourceConfig), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateDataSourceConfig", reflect.TypeOf((*MockProviderClient)(nil).ValidateDataSourceConfig), varargs...)
} }
// ValidateProviderConfig mocks base method
func (m *MockProviderClient) ValidateProviderConfig(arg0 context.Context, arg1 *proto.ValidateProviderConfig_Request, arg2 ...grpc.CallOption) (*proto.ValidateProviderConfig_Response, error) {
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ValidateProviderConfig", varargs...)
ret0, _ := ret[0].(*proto.ValidateProviderConfig_Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ValidateProviderConfig indicates an expected call of ValidateProviderConfig
func (mr *MockProviderClientMockRecorder) ValidateProviderConfig(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateProviderConfig", reflect.TypeOf((*MockProviderClient)(nil).ValidateProviderConfig), varargs...)
}
// ValidateResourceTypeConfig mocks base method // ValidateResourceTypeConfig mocks base method
func (m *MockProviderClient) ValidateResourceTypeConfig(arg0 context.Context, arg1 *proto.ValidateResourceTypeConfig_Request, arg2 ...grpc.CallOption) (*proto.ValidateResourceTypeConfig_Response, error) { func (m *MockProviderClient) ValidateResourceTypeConfig(arg0 context.Context, arg1 *proto.ValidateResourceTypeConfig_Request, arg2 ...grpc.CallOption) (*proto.ValidateResourceTypeConfig_Response, error) {
varargs := []interface{}{arg0, arg1} varargs := []interface{}{arg0, arg1}

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,7 @@ message Schema {
service Provider { service Provider {
//////// Information about what a provider supports/expects //////// Information about what a provider supports/expects
rpc GetSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response); rpc GetSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response);
rpc ValidateProviderConfig(ValidateProviderConfig.Request) returns (ValidateProviderConfig.Response); rpc PrepareProviderConfig(PrepareProviderConfig.Request) returns (PrepareProviderConfig.Response);
rpc ValidateResourceTypeConfig(ValidateResourceTypeConfig.Request) returns (ValidateResourceTypeConfig.Response); rpc ValidateResourceTypeConfig(ValidateResourceTypeConfig.Request) returns (ValidateResourceTypeConfig.Response);
rpc ValidateDataSourceConfig(ValidateDataSourceConfig.Request) returns (ValidateDataSourceConfig.Response); rpc ValidateDataSourceConfig(ValidateDataSourceConfig.Request) returns (ValidateDataSourceConfig.Response);
rpc UpgradeResourceState(UpgradeResourceState.Request) returns (UpgradeResourceState.Response); rpc UpgradeResourceState(UpgradeResourceState.Request) returns (UpgradeResourceState.Response);
@ -129,12 +129,13 @@ message GetProviderSchema {
} }
} }
message ValidateProviderConfig { message PrepareProviderConfig {
message Request { message Request {
DynamicValue config = 1; DynamicValue config = 1;
} }
message Response { message Response {
repeated Diagnostic diagnostics = 1; DynamicValue prepared_config = 1;
repeated Diagnostic diagnostics = 2;
} }
} }

View File

@ -14,9 +14,9 @@ type Interface interface {
// GetSchema returns the complete schema for the provider. // GetSchema returns the complete schema for the provider.
GetSchema() GetSchemaResponse GetSchema() GetSchemaResponse
// ValidateProviderConfig allows the provider to validate the configuration // PrepareProviderConfig allows the provider to validate the configuration
// values. // values, and set or override any values with defaults.
ValidateProviderConfig(ValidateProviderConfigRequest) ValidateProviderConfigResponse PrepareProviderConfig(PrepareProviderConfigRequest) PrepareProviderConfigResponse
// ValidateResourceTypeConfig allows the provider to validate the resource // ValidateResourceTypeConfig allows the provider to validate the resource
// configuration values. // configuration values.
@ -90,12 +90,14 @@ type Schema struct {
Block *configschema.Block Block *configschema.Block
} }
type ValidateProviderConfigRequest struct { type PrepareProviderConfigRequest struct {
// Config is the complete configuration value for the provider. // Config is the raw configuration value for the provider.
Config cty.Value Config cty.Value
} }
type ValidateProviderConfigResponse struct { type PrepareProviderConfigResponse struct {
// PreparedConfig is the configuration as prepared by the provider.
PreparedConfig cty.Value
// Diagnostics contains any warnings or errors from the method call. // Diagnostics contains any warnings or errors from the method call.
Diagnostics tfdiags.Diagnostics Diagnostics tfdiags.Diagnostics
} }

View File

@ -603,7 +603,7 @@ func TestContext2Validate_providerConfig_bad(t *testing.T) {
), ),
}) })
p.ValidateProviderConfigResponse = providers.ValidateProviderConfigResponse{ p.PrepareProviderConfigResponse = providers.PrepareProviderConfigResponse{
Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")), Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")),
} }
@ -641,7 +641,7 @@ func TestContext2Validate_providerConfig_badEmpty(t *testing.T) {
), ),
}) })
p.ValidateProviderConfigResponse = providers.ValidateProviderConfigResponse{ p.PrepareProviderConfigResponse = providers.PrepareProviderConfigResponse{
Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")), Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")),
} }
@ -709,7 +709,7 @@ func TestContext2Validate_provisionerConfig_bad(t *testing.T) {
}, },
}) })
p.ValidateProviderConfigResponse = providers.ValidateProviderConfigResponse{ p.PrepareProviderConfigResponse = providers.PrepareProviderConfigResponse{
Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")), Diagnostics: tfdiags.Diagnostics{}.Append(fmt.Errorf("bad")),
} }

View File

@ -98,11 +98,11 @@ func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
return nil, diags.NonFatalErr() return nil, diags.NonFatalErr()
} }
req := providers.ValidateProviderConfigRequest{ req := providers.PrepareProviderConfigRequest{
Config: configVal, Config: configVal,
} }
validateResp := provider.ValidateProviderConfig(req) validateResp := provider.PrepareProviderConfig(req)
diags = diags.Append(validateResp.Diagnostics) diags = diags.Append(validateResp.Diagnostics)
return nil, diags.NonFatalErr() return nil, diags.NonFatalErr()

View File

@ -26,10 +26,10 @@ type MockProvider struct {
GetSchemaCalled bool GetSchemaCalled bool
GetSchemaReturn *ProviderSchema // This is using ProviderSchema directly rather than providers.GetSchemaResponse for compatibility with old tests GetSchemaReturn *ProviderSchema // This is using ProviderSchema directly rather than providers.GetSchemaResponse for compatibility with old tests
ValidateProviderConfigCalled bool PrepareProviderConfigCalled bool
ValidateProviderConfigResponse providers.ValidateProviderConfigResponse PrepareProviderConfigResponse providers.PrepareProviderConfigResponse
ValidateProviderConfigRequest providers.ValidateProviderConfigRequest PrepareProviderConfigRequest providers.PrepareProviderConfigRequest
ValidateProviderConfigFn func(providers.ValidateProviderConfigRequest) providers.ValidateProviderConfigResponse PrepareProviderConfigFn func(providers.PrepareProviderConfigRequest) providers.PrepareProviderConfigResponse
ValidateResourceTypeConfigCalled bool ValidateResourceTypeConfigCalled bool
ValidateResourceTypeConfigTypeName string ValidateResourceTypeConfigTypeName string
@ -133,16 +133,16 @@ func (p *MockProvider) getSchema() providers.GetSchemaResponse {
return ret return ret
} }
func (p *MockProvider) ValidateProviderConfig(r providers.ValidateProviderConfigRequest) providers.ValidateProviderConfigResponse { func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRequest) providers.PrepareProviderConfigResponse {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
p.ValidateProviderConfigCalled = true p.PrepareProviderConfigCalled = true
p.ValidateProviderConfigRequest = r p.PrepareProviderConfigRequest = r
if p.ValidateProviderConfigFn != nil { if p.PrepareProviderConfigFn != nil {
return p.ValidateProviderConfigFn(r) return p.PrepareProviderConfigFn(r)
} }
return p.ValidateProviderConfigResponse return p.PrepareProviderConfigResponse
} }
func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) providers.ValidateResourceTypeConfigResponse { func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) providers.ValidateResourceTypeConfigResponse {