package secretsengine import ( "context" // "fmt" "reflect" "testing" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" ) var testConfigData map[string]interface{} = map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", } func TestConfig_Create(t *testing.T) { type testCase struct { createData *framework.FieldData createExpectErr bool expectedReadResp map[string]interface{} } tests := map[string]testCase{ "happy path": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: false, expectedReadResp: map[string]interface{}{ "realm": "ACME.INC", "kdc": []string{"localhost:88"}, "admin_server": []string{"localhost:749"}, "kpasswd_server": []string{"localhost:749"}, "username": "admin", }, }, "happy path with multiple servers": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": []string{"localhost:88", "other.host:88"}, "admin_server": []string{"localhost:749", "other.host:749"}, "kpasswd_server": []string{"localhost:749", "other.host:749"}, "username": "admin", "password": "hunter21", }), createExpectErr: false, expectedReadResp: map[string]interface{}{ "realm": "ACME.INC", "kdc": []string{"localhost:88", "other.host:88"}, "admin_server": []string{"localhost:749", "other.host:749"}, "kpasswd_server": []string{"localhost:749", "other.host:749"}, "username": "admin", }, }, "happy path with multiple servers, comma seperated": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88,other.host:88", "admin_server": "localhost:749,other.host:749", "kpasswd_server": "localhost:749,other.host:749", "username": "admin", "password": "hunter21", }), createExpectErr: false, expectedReadResp: map[string]interface{}{ "realm": "ACME.INC", "kdc": []string{"localhost:88", "other.host:88"}, "admin_server": []string{"localhost:749", "other.host:749"}, "kpasswd_server": []string{"localhost:749", "other.host:749"}, "username": "admin", }, }, "missing realm": { createData: fieldData(map[string]interface{}{ "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "missing username": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "password": "hunter21", }), createExpectErr: true, }, "missing password": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", }), createExpectErr: true, }, "missing kdc": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty kdc": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "", "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty kdc list": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": []string{}, "admin_server": "localhost:749", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "missing admin server": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty admin server": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "", "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty admin server list": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": []string{}, "kpasswd_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "missing kpasswd server": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty kpasswd server": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": "", "username": "admin", "password": "hunter21", }), createExpectErr: true, }, "empty kpasswd server list": { createData: fieldData(map[string]interface{}{ "realm": "ACME.INC", "kdc": "localhost:88", "admin_server": "localhost:749", "kpasswd_server": []string{}, "username": "admin", "password": "hunter21", }), createExpectErr: true, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { b, storage := getBackend() defer b.Cleanup(context.Background()) req := &logical.Request{ Storage: storage, Operation: logical.CreateOperation, } resp, err := b.pathConfigWrite(context.Background(), req, test.createData) if test.createExpectErr && err == nil { t.Fatalf("err expected, got nil") } if !test.createExpectErr && err != nil { t.Fatalf("no error expected, got: %s", err) } if resp != nil { t.Fatalf("no response expected, got: %#v", resp) } if test.createExpectErr { return } readReq := &logical.Request{ Storage: storage, } resp, err = b.pathConfigRead(context.Background(), readReq, nil) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } if !reflect.DeepEqual(resp.Data, test.expectedReadResp) { t.Fatalf("Actual: %#v\nExpected: %#v", resp.Data, test.expectedReadResp) } }) } } func TestConfig_Update(t *testing.T) { t.Run("happy path", func(t *testing.T) { b, storage := getBackend() defer b.Cleanup(context.Background()) req := &logical.Request{ Operation: logical.CreateOperation, Path: configStoragePath, Storage: storage, Data: testConfigData, } resp, err := b.HandleRequest(context.Background(), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } data := map[string]interface{}{ "realm": "NEW.ACME.INC", "kdc": "other.host:88", "admin_server": "other.host:749", "kpasswd_server": "other.host:749", "username": "admin2", "password": "hunter22", } req = &logical.Request{ Operation: logical.UpdateOperation, Path: configStoragePath, Storage: storage, Data: data, } resp, err = b.HandleRequest(context.Background(), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } req = &logical.Request{ Operation: logical.ReadOperation, Path: configStoragePath, Storage: storage, Data: nil, } resp, err = b.HandleRequest(context.Background(), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } if resp.Data["realm"] != "NEW.ACME.INC" { t.Fatalf("expected realm to be %s, got %s", "NEW.ACME.INC", resp.Data["realm"]) } }) } func TestConfig_Delete(t *testing.T) { t.Run("happy path", func(t *testing.T) { b, storage := getBackend() defer b.Cleanup(context.Background()) req := &logical.Request{ Operation: logical.CreateOperation, Path: configStoragePath, Storage: storage, Data: testConfigData, } resp, err := b.HandleRequest(context.Background(), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } req = &logical.Request{ Operation: logical.DeleteOperation, Path: configStoragePath, Storage: storage, Data: nil, } resp, err = b.HandleRequest(context.Background(), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%s resp:%#v\n", err, resp) } }) } func fieldData(raw map[string]interface{}) *framework.FieldData { return &framework.FieldData{ Raw: raw, Schema: configSchema(), } }