diff --git a/api/oapigen/server.go b/api/oapigen/server.go index 51ba2c9df..676579eb2 100644 --- a/api/oapigen/server.go +++ b/api/oapigen/server.go @@ -294,59 +294,59 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "naGfNgAA", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/oapigen/types.go b/api/oapigen/types.go index 535c06a1e..27b31b5ab 100644 --- a/api/oapigen/types.go +++ b/api/oapigen/types.go @@ -77,10 +77,26 @@ type HealthCheckResponse struct { Error *Error `json:"error,omitempty"` } +// IntentionsModuleInput defines model for IntentionsModuleInput. +type IntentionsModuleInput struct { + CtsUserDefinedMeta *IntentionsModuleInput_CtsUserDefinedMeta `json:"cts_user_defined_meta,omitempty"` + Datacenter *string `json:"datacenter,omitempty"` + Filter *string `json:"filter,omitempty"` + Names *[]string `json:"names,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Regexp *string `json:"regexp,omitempty"` +} + +// IntentionsModuleInput_CtsUserDefinedMeta defines model for IntentionsModuleInput.CtsUserDefinedMeta. +type IntentionsModuleInput_CtsUserDefinedMeta struct { + AdditionalProperties map[string]string `json:"-"` +} + // The additional module input(s) that the tasks provides to the Terraform module on execution. If the task has the deprecated services field configured as a module input, it is represented here as module_input.services. type ModuleInput struct { - ConsulKv *ConsulKVModuleInput `json:"consul_kv,omitempty"` - Services *ServicesModuleInput `json:"services,omitempty"` + ConsulKv *ConsulKVModuleInput `json:"consul_kv,omitempty"` + Intentions *IntentionsModuleInput `json:"intentions,omitempty"` + Services *ServicesModuleInput `json:"services,omitempty"` } // RequestID defines model for RequestID. @@ -286,6 +302,59 @@ func (a CatalogServicesCondition_NodeMeta) MarshalJSON() ([]byte, error) { return json.Marshal(object) } +// Getter for additional properties for IntentionsModuleInput_CtsUserDefinedMeta. Returns the specified +// element and whether it was found +func (a IntentionsModuleInput_CtsUserDefinedMeta) Get(fieldName string) (value string, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for IntentionsModuleInput_CtsUserDefinedMeta +func (a *IntentionsModuleInput_CtsUserDefinedMeta) Set(fieldName string, value string) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]string) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for IntentionsModuleInput_CtsUserDefinedMeta to handle AdditionalProperties +func (a *IntentionsModuleInput_CtsUserDefinedMeta) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]string) + for fieldName, fieldBuf := range object { + var fieldVal string + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for IntentionsModuleInput_CtsUserDefinedMeta to handle AdditionalProperties +func (a IntentionsModuleInput_CtsUserDefinedMeta) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + // Getter for additional properties for ServicesCondition_CtsUserDefinedMeta. Returns the specified // element and whether it was found func (a ServicesCondition_CtsUserDefinedMeta) Get(fieldName string) (value string, found bool) { diff --git a/api/openapi.yaml b/api/openapi.yaml index 73abdfb29..5ca3c28c1 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -450,7 +450,7 @@ components: cts_user_defined_meta: type: object additionalProperties: - type: string + type: string ConsulKVModuleInput: type: object additionalProperties: false diff --git a/templates/tftmpl/template_intentions.go b/templates/tftmpl/template_intentions.go new file mode 100644 index 000000000..93cfd9221 --- /dev/null +++ b/templates/tftmpl/template_intentions.go @@ -0,0 +1,120 @@ +package tftmpl + +import ( + "fmt" + "io" + + //"sort" + "strings" + + //"github.com/hashicorp/consul-terraform-sync/logging" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclwrite" +) + +var ( + _ Template = (*IntentionsTemplate)(nil) +) + +type intentionServices struct { + Regexp string + Names []string +} + +type IntentionsTemplate struct { + Datacenter string + Namespace string + SourceServices *intentionServices + DestinationServices *intentionServices +} + +// IsServicesVar returns false because the template returns an intentions +// variable, not a services variable +func (t IntentionsTemplate) IsServicesVar() bool { + return false +} + +func (t IntentionsTemplate) RendersVar() bool { + return false +} + +func (t IntentionsTemplate) appendModuleAttribute(body *hclwrite.Body) { + body.SetAttributeTraversal("intentions", hcl.Traversal{ + hcl.TraverseRoot{Name: "var"}, + hcl.TraverseAttr{Name: "intentions"}, + }) +} + +func (t IntentionsTemplate) appendTemplate(w io.Writer) error { + q := t.hcatQuery() + + if _, err := fmt.Fprintf(w, catalogServicesEmptyTmpl, q); err != nil { + err = fmt.Errorf("unable to write intentions empty template, error %v", err) + return err + } + return nil +} + +func (t IntentionsTemplate) appendVariable(w io.Writer) error { + return nil +} + +// NEED TO DO 1 +// sortIntentionsTemplates sorts the services by precedence and then alphabetically +// func (t ServicesTemplate) sortIntentionsTemplates() (string, error) { +// } + +// NEED TO DO 2 +func (t IntentionsTemplate) hcatQuery() string { + var opts []string + + if t.Datacenter != "" { + opts = append(opts, fmt.Sprintf("dc=%s", t.Datacenter)) + } + + if t.Namespace != "" { + opts = append(opts, fmt.Sprintf("ns=%s", t.Namespace)) + } + + if t.SourceServices != nil { + if len(t.SourceServices.Names) > 0 { + ds := strings.Join(t.SourceServices.Names, " ") + opts = append(opts, fmt.Sprintf("source services names=%s", ds)) + } else { + opts = append(opts, fmt.Sprintf("source services regexp=%s", t.SourceServices.Regexp)) + } + } + + if t.DestinationServices != nil { + if len(t.DestinationServices.Names) > 0 { + ds := strings.Join(t.DestinationServices.Names, " ") + opts = append(opts, fmt.Sprintf("destination services names=%s", ds)) + } else { + opts = append(opts, fmt.Sprintf("destination services regexp=%s", t.DestinationServices.Regexp)) + } + } + + if len(opts) > 0 { + return `"` + strings.Join(opts, `" "`) + `"` // add space at end ?? + } + return "" +} + +var intentionsSetVarTmpl = fmt.Sprintf(` +intentions = {%s} +`, intentionsBaseTmpl) + +// NEED TO DO 3 +const intentionsBaseTmpl = ` +{{- with $intentions := intentions %s}} + {{- range $cs := $intentions }} + "{{ $cs.Name }}" = {{ HCLServiceTags $cs.Tags }} +{{- end}}{{- end}} +` + +const intentionsEmptyTmpl = ` +{{- with $intentions := intentions %s}} + {{- range $cs := $intentions }} + {{- /* Empty template. Detects changes in Intentions */ -}} +{{- end}}{{- end}} +` diff --git a/templates/tftmpl/template_intentions_test.go b/templates/tftmpl/template_intentions_test.go new file mode 100644 index 000000000..6f9bb40be --- /dev/null +++ b/templates/tftmpl/template_intentions_test.go @@ -0,0 +1,108 @@ +package tftmpl + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIntentionsTemplate_appendTemplate(t *testing.T) { + testcases := []struct { + name string + c *IntentionsTemplate + exp string + }{ + { + "fully configured & no var", + &IntentionsTemplate{ + Datacenter: "dc1", + Namespace: "test-ns", + SourceServices: &intentionServices{ + Names: []string{"api", "^web.*"}, + }, + DestinationServices: &intentionServices{ + Names: []string{"api2", "^web2.*"}, + }, + }, + ` +{{- with $srv := servicesRegex "regexp=.*" "dc=dc1" "ns=ns1" "filter" }} + {{- range $s := $srv}} + {{- /* Empty template. Detects changes in Services */ -}} + {{- end}} +{{- end}} +`, + }, + { + "source and destination only", + &IntentionsTemplate{ + SourceServices: &intentionServices{ + Regexp: "^web.*", + }, + DestinationServices: &intentionServices{ + Regexp: "^api.*", + }, + }, + ` +{{- with $srv := servicesRegex "regexp=" }} + {{- range $s := $srv}} + {{- /* Empty template. Detects changes in Services */ -}} + {{- end}} +{{- end}} +`, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + w := new(strings.Builder) + err := tc.c.appendTemplate(w) + require.NoError(t, err) + assert.Equal(t, tc.exp, w.String()) + }) + } +} + +func TestIntentionsVTemplate_hcatQuery(t *testing.T) { + testcase := []struct { + name string + c *IntentionsTemplate + exp string + }{ + { + "all parameters", + &IntentionsTemplate{ + Datacenter: "dc1", + Namespace: "test-ns", + SourceServices: &intentionServices{ + Regexp: "^web.*", + }, + DestinationServices: &intentionServices{ + Regexp: "^api.*", + }, + }, + `"dc=dc1" "ns=test-ns source"`, + }, + { + "source and destination only", + &IntentionsTemplate{ + SourceServices: &intentionServices{ + Regexp: "^web.*", + }, + DestinationServices: &intentionServices{ + Regexp: "^api.*", + }, + }, + `"regexp=.*"`, + }, + } + + for _, tc := range testcase { + t.Run(tc.name, func(t *testing.T) { + actual := tc.c.hcatQuery() + assert.Equal(t, tc.exp, actual) + }) + } + +} diff --git a/templates/tftmpl/tmplfunc/intentions.go b/templates/tftmpl/tmplfunc/intentions.go new file mode 100644 index 000000000..abda3ee25 --- /dev/null +++ b/templates/tftmpl/tmplfunc/intentions.go @@ -0,0 +1,201 @@ +package tmplfunc + +import ( + "fmt" + "strings" + + "github.com/hashicorp/hcat" + "github.com/hashicorp/hcat/dep" + "github.com/pkg/errors" +) + +var ( + _ hcatQuery = (*intentionsQuery)(nil) +) + +// returns info on registered consul services +// reference from catalog_services_registration +func intentionsFunc(recall hcat.Recaller) interface{} { + return func(opts ...string) ([]*dep.Intention, error) { + result := []*dep.Intention{} + + d, err := newIntentionsQuery(opts) + if err != nil { + return nil, err + } + + if value, ok := recall(d); ok { + return value.([]*dep.Intention), nil + } + + return result, nil + } +} + +type ServiceTags []string + +// intentionsQuery is the representation of a requested +// intention query from inside a template. +type intentionsQuery struct { + isConsul + stopCh chan struct{} + + id string + name string + address string + //port int + kind string + //tags ServiceTags + namespace string + status string + nodeMeta map[string]string + opts hcat.QueryOptions +} + +// newIntentionsQuery processes options +func newIntentionsQuery(opts []string) (*intentionsQuery, error) { + query := intentionsQuery{ + stopCh: make(chan struct{}, 1), + } + + for _, opt := range opts { + if strings.TrimSpace(opt) == "" { + continue + } + + param, value, err := stringsSplit2(opt, "=") + if err != nil { + return nil, fmt.Errorf("intentions.services: invalid "+ + "query parameter format: %q", opt) + } + switch param { + case "id": + query.id = value + case "name": + query.name = value + case "address": + query.address = value + // case "port": + // query.port = value + case "kind": + query.kind = value + // case "tags": + // query.tags = value + case "namespace": + query.namespace = value + case "status": + query.kind = value + case "node-meta": + if query.nodeMeta == nil { + query.nodeMeta = make(map[string]string) + } + k, v, err := stringsSplit2(value, ":") + if err != nil { + return nil, fmt.Errorf( + "intention.services: invalid format for query "+ + "parameter %q: %s", param, value) + } + query.nodeMeta[k] = v + default: + return nil, fmt.Errorf( + "intentions.services: invalid query parameter: %q", opt) + } + } + + return &query, nil + +} + +// // IntentionSnippet is an Intention entry in Consul. +// type IntentionSnippet struct { +// SourceName string +// DestinationName string +// Permissions []*IntentionPermission +// Precedence int +// } + +func (d *intentionsQuery) Fetch(clients dep.Clients) (interface{}, *dep.ResponseMetadata, error) { + select { + case <-d.stopCh: + return nil, nil, dep.ErrStopped + default: + } + + hcatOpts := d.opts.Merge(&hcat.QueryOptions{ + // ID: d.id, + // Name: d.name, + // Address: d.address, + //port int + // Kind: d.kind, + //tags ServiceTags + Namespace: d.namespace, + // Status: d.status, + }) + opts := hcatOpts.ToConsulOpts() + if len(d.nodeMeta) != 0 { + opts.NodeMeta = d.nodeMeta + } + + entries, qm, err := clients.Consul().Connect().Intentions(opts) + if err != nil { + return nil, nil, errors.Wrap(err, d.String()) + } + + var intentionSnippets []*dep.IntentionSnippet + for sourceName, destinationName := range entries { + intentionSnippets = append(intentionSnippets, &dep.IntentionSnippet{ + // SourceName: sourceName, + // DestinationName: destinationName, + }) + } + // //return nil, nil, dep.ErrStopped + + // sort.Stable(ByName(intentionSnippets, reverse(less))) + + // rm := &dep.ResponseMetadata{ + // LastIndex: qm.LastIndex, + // LastContact: qm.LastContact, + // } + + return nil, nil, dep.ErrStopped + // return intentionSnippets, rm, nil +} + +func (d *intentionsQuery) SetOptions(opts hcat.QueryOptions) { + d.opts = opts +} + +func (d *intentionsQuery) ID() string { + var opts []string + if d.regexp != nil { + opts = append(opts, fmt.Sprintf("regexp=%s", d.regexp.String())) + } + if d.dc != "" { + opts = append(opts, fmt.Sprintf("dc=%s", d.dc)) + } + if d.ns != "" { + opts = append(opts, fmt.Sprintf("ns=%s", d.ns)) + } + for k, v := range d.nodeMeta { + opts = append(opts, fmt.Sprintf("node-meta=%s:%s", k, v)) + } + if len(opts) > 0 { + return fmt.Sprintf("intentions.services(%s)", + strings.Join(opts, "&")) + } + // return "" + return "intentions.services" +} + +func (d *intentionsQuery) String() string { + return d.ID() +} +func (d *intentionsQuery) Stop() { + close(d.stopCh) +} + +func reverse(less func(i, j int) bool) func(i, j int) bool { + return func(i, j int) bool { + return !less(i, j) + } +} diff --git a/templates/tftmpl/tmplfunc/intentions_test.go b/templates/tftmpl/tmplfunc/intentions_test.go new file mode 100644 index 000000000..b0795944c --- /dev/null +++ b/templates/tftmpl/tmplfunc/intentions_test.go @@ -0,0 +1,159 @@ +package tmplfunc + +import ( + //"regexp" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIntentionsQuery(t *testing.T) { + //t.parrallel() + + cases := []struct { + name string + opts []string + exp *intentionsQuery + err bool + }{ + { + "no opts", + []string{}, + &intentionsQuery{}, + false, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + act, err := newIntentionsQuery(tc.opts) + if tc.err { + assert.Error(t, err) + return + } + + if act != nil { + act.stopCh = nil + } + + assert.NoError(t, err, err) + assert.Equal(t, tc.exp, act) + }) + } +} + +func TestIntentionsQuery_String(t *testing.T) { + //t.parrallel() + + cases := []struct { + name string + i []string + exp string + }{ + { + "empty", + []string{}, + "intentions.services", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + d, err := newIntentionsQuery(tc.i) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, tc.exp, d.String()) + }) + } +} + +func TestNewIntentionsQuery(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + opts []string + exp *intentionsQuery + err bool + }{ + { + "no opts", + []string{}, + &intentionsQuery{}, + false, + }, + // { + // "regexp", + // []string{"regexp=.*"}, + // &intentionsQuery{ + // regexp: regexp.MustCompile(".*"), + // }, + // false, + // }, + // { + // "dc", + // []string{"dc=dc1"}, + // &intentionsQuery{ + // dc: "dc1", + // }, + // false, + // }, + // { + // "ns", + // []string{"ns=namespace"}, + // &intentionsQuery{ + // ns: "namespace", + // }, + // false, + // }, + { + "node-meta", + []string{"node-meta=k:v", "node-meta=foo:bar"}, + &intentionsQuery{ + nodeMeta: map[string]string{"k": "v", "foo": "bar"}, + }, + false, + }, + // { + // "multiple", + // []string{"node-meta=k:v", "ns=namespace", "dc=dc1", "regexp=.*"}, + // &intentionsQuery{ + // regexp: regexp.MustCompile(".*"), + // dc: "dc1", + // ns: "namespace", + // nodeMeta: map[string]string{"k": "v"}, + // }, + // false, + // }, + { + "invalid query", + []string{"invalid=true"}, + nil, + true, + }, + { + "invalid query format", + []string{"dc1"}, + nil, + true, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + act, err := newIntentionsQuery(tc.opts) + if tc.err { + assert.Error(t, err) + return + } + + if act != nil { + act.stopCh = nil + } + + assert.NoError(t, err, err) + assert.Equal(t, tc.exp, act) + }) + } +} diff --git a/templates/tftmpl/tmplfunc/tmpl_func.go b/templates/tftmpl/tmplfunc/tmpl_func.go index d20f4496c..99fa30512 100644 --- a/templates/tftmpl/tmplfunc/tmpl_func.go +++ b/templates/tftmpl/tmplfunc/tmpl_func.go @@ -16,6 +16,7 @@ func HCLMap(meta *ServicesMeta) template.FuncMap { tmplFuncs := tfunc.FuncMapConsulV1() tmplFuncs["catalogServicesRegistration"] = catalogServicesRegistrationFunc tmplFuncs["servicesRegex"] = servicesRegexFunc + tmplFuncs["intentions"] = intentionsFunc tmplFuncs["indent"] = tfunc.Helpers()["indent"] tmplFuncs["subtract"] = tfunc.Math()["subtract"] tmplFuncs["joinStrings"] = joinStringsFunc