diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cab21ecb..928cfd89 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,8 @@ "mounts": [ "source=${localWorkspaceFolder}/../pipe-fittings,target=/workspaces/pipe-fittings,type=bind,consistency=cached", - "source=${localWorkspaceFolder}/../flowpipe-sdk-go,target=/workspaces/flowpipe-sdk-go,type=bind,consistency=cached" + "source=${localWorkspaceFolder}/../flowpipe-sdk-go,target=/workspaces/flowpipe-sdk-go,type=bind,consistency=cached", + "source=go-build-cache,target=/root/.cache/go-build,type=volume" ], "features": { @@ -33,6 +34,6 @@ "HashiCorp.HCL"] } }, - + "postStartCommand": ".devcontainer/scripts/post-start-command.sh" } diff --git a/.gitattributes b/.gitattributes index 5e314d5c..7b0e6afc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ **/*.fp linguist-language=HCL +**/*.fpc linguist-language=HCL diff --git a/.github/workflows/devcontainer-release.yaml b/.github/workflows/devcontainer-release.yaml index a1fb88ac..adf9ff77 100644 --- a/.github/workflows/devcontainer-release.yaml +++ b/.github/workflows/devcontainer-release.yaml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Flowpipe repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: flowpipe diff --git a/.github/workflows/flowpipe-container.yaml b/.github/workflows/flowpipe-container.yaml index c36f832c..dec769cc 100644 --- a/.github/workflows/flowpipe-container.yaml +++ b/.github/workflows/flowpipe-container.yaml @@ -21,7 +21,7 @@ jobs: # Checks out the Flowpipe repository code. - name: Checkout Flowpipe repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: flowpipe # Directory path under $GITHUB_WORKSPACE to place the repository. diff --git a/.github/workflows/flowpipe-release.yaml b/.github/workflows/flowpipe-release.yaml index fbe21821..532dcc3c 100644 --- a/.github/workflows/flowpipe-release.yaml +++ b/.github/workflows/flowpipe-release.yaml @@ -78,13 +78,13 @@ jobs: fi - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: flowpipe ref: ${{ github.event.ref }} - name: Checkout Pipe Fittings Components repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.PIPE_FITTINGS_DEPLOY_PRIVATE_KEY }} repository: turbot/pipe-fittings @@ -92,7 +92,7 @@ jobs: ref: main - name: Checkout Flowpipe SDK Go repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.FLOWPIPE_GO_SDK_DEPLOY_PRIVATE_KEY }} repository: turbot/flowpipe-sdk-go diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index e808c447..e65acb88 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -41,10 +41,10 @@ jobs: MARIADB_DATABASE: flowpipe-test ports: - 3306:3306 - options: >- - --health-cmd="healthcheck.sh --connect --innodb_initialized" - --health-interval=10s - --health-timeout=5s + options: >- + --health-cmd="healthcheck.sh --connect --innodb_initialized" + --health-interval=10s + --health-timeout=5s --health-retries=3 # Install MailHog for SMTP mail testing @@ -56,12 +56,12 @@ jobs: steps: - name: Checkout Flowpipe repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: flowpipe - name: Checkout Pipe Fittings Components repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.PIPE_FITTINGS_DEPLOY_PRIVATE_KEY }} repository: turbot/pipe-fittings @@ -69,7 +69,7 @@ jobs: ref: main - name: Checkout Flowpipe SDK Go repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.FLOWPIPE_GO_SDK_DEPLOY_PRIVATE_KEY }} repository: turbot/flowpipe-sdk-go diff --git a/.github/workflows/test-lint-test.yaml b/.github/workflows/test-lint-test.yaml index b59c1506..3d05a83d 100644 --- a/.github/workflows/test-lint-test.yaml +++ b/.github/workflows/test-lint-test.yaml @@ -40,10 +40,10 @@ jobs: MARIADB_DATABASE: flowpipe-test ports: - 3306:3306 - options: >- - --health-cmd="healthcheck.sh --connect --innodb_initialized" - --health-interval=10s - --health-timeout=5s + options: >- + --health-cmd="healthcheck.sh --connect --innodb_initialized" + --health-interval=10s + --health-timeout=5s --health-retries=3 # Install MailHog for SMTP mail testing @@ -55,12 +55,12 @@ jobs: steps: - name: Checkout Flowpipe repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: flowpipe - name: Checkout Pipe Fittings Components repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.PIPE_FITTINGS_DEPLOY_PRIVATE_KEY }} repository: turbot/pipe-fittings @@ -68,7 +68,7 @@ jobs: ref: main - name: Checkout Flowpipe SDK Go repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.FLOWPIPE_GO_SDK_DEPLOY_PRIVATE_KEY }} repository: turbot/flowpipe-sdk-go diff --git a/internal/es/estest/test_suite_mod/integrations.fpc b/internal/es/estest/test_suite_mod/integrations.fpc index 9d0724dd..4fe2d6d7 100644 --- a/internal/es/estest/test_suite_mod/integrations.fpc +++ b/internal/es/estest/test_suite_mod/integrations.fpc @@ -5,17 +5,23 @@ integration "slack" "my_slack_app" { signing_secret = "Q#$$#@#$$#W" } +integration "email" "email_integration_1" { + +} + notifier "my_notifier" { description = "my notifier with 2 notifies" notify { integration = integration.webform.default channel = "fake one" + subject = "bar" } notify { integration = integration.webform.default - to = ["just some things here"] + to = ["a", "b", "c"] + channel = "foo" } } @@ -24,4 +30,21 @@ integration "slack" "my_other_slack_app" { # optional - if you want to verify the source signing_secret = "Q#$$#@#$$#W" -} \ No newline at end of file +} + +notifier "slack_notify" { + description = "slack notifer with some notifies" + + notify { + integration = integration.slack.my_other_slack_app + channel = "fake one" + subject = "bar" + } + + notify { + integration = integration.email.email_integration_1 + to = ["billie", "bob", "joe"] + cc = ["angus", "brian", "charlie", "dave"] + bcc = ["eddie", "frank", "george", "harry"] + } +} diff --git a/internal/types/integration.go b/internal/types/integration.go index 48b45dad..7afc5fd8 100644 --- a/internal/types/integration.go +++ b/internal/types/integration.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "github.com/turbot/go-kit/helpers" "github.com/logrusorgru/aurora" flowpipeapiclient "github.com/turbot/flowpipe-sdk-go" @@ -20,16 +19,14 @@ type ListIntegrationResponse struct { } type FpIntegration struct { - Name string `json:"name"` - Type string `json:"type"` - Description *string `json:"description,omitempty"` - Title *string `json:"title,omitempty"` - Documentation *string `json:"documentation,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - FileName string `json:"file_name,omitempty"` - StartLineNumber int `json:"start_line_number,omitempty"` - EndLineNumber int `json:"end_line_number,omitempty"` - Url *string `json:"url,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + Description *string `json:"description,omitempty"` + Title *string `json:"title,omitempty"` + FileName string `json:"file_name,omitempty"` + StartLineNumber int `json:"start_line_number,omitempty"` + EndLineNumber int `json:"end_line_number,omitempty"` + Url *string `json:"url,omitempty"` } func (f FpIntegration) String(_ *sanitize.Sanitizer, opts sanitize.RenderOptions) string { @@ -39,7 +36,7 @@ func (f FpIntegration) String(_ *sanitize.Sanitizer, opts sanitize.RenderOptions // left := au.BrightBlack("[") // right := au.BrightBlack("]") keyWidth := 10 - if f.Description != nil { + if f.Description != nil || f.Url != nil { keyWidth = 13 } @@ -52,13 +49,7 @@ func (f FpIntegration) String(_ *sanitize.Sanitizer, opts sanitize.RenderOptions output += fmt.Sprintf("%-*s%s\n", keyWidth, au.Blue("Description:"), *f.Description) } if f.Url != nil { - output += fmt.Sprintf("%-*s%s\n", keyWidth, au.Blue("URL:"), *f.Url) - } - if len(f.Tags) > 0 { - output += fmt.Sprintf("%s\n", au.Blue("Tags:")) - for k, v := range f.Tags { - output += fmt.Sprintf(" %s %s\n", au.Cyan(k+":"), v) - } + output += fmt.Sprintf("%-*s%s\n", keyWidth, au.Blue("Request URL:"), *f.Url) } return output @@ -81,16 +72,10 @@ func ListIntegrationResponseFromAPI(apiResp *flowpipeapiclient.ListIntegrationRe func FpIntegrationFromAPI(apiIntegration flowpipeapiclient.FpIntegration) FpIntegration { res := FpIntegration{ - Name: typehelpers.SafeString(apiIntegration.Name), - Type: typehelpers.SafeString(apiIntegration.Type), - Description: apiIntegration.Description, - Title: apiIntegration.Title, - Documentation: apiIntegration.Documentation, - } - if !helpers.IsNil(apiIntegration.Tags) { - res.Tags = *apiIntegration.Tags - } else { - res.Tags = make(map[string]string) + Name: typehelpers.SafeString(apiIntegration.Name), + Type: typehelpers.SafeString(apiIntegration.Type), + Description: apiIntegration.Description, + Title: apiIntegration.Title, } return res } @@ -101,7 +86,6 @@ func FpIntegrationFromModIntegration(integration modconfig.Integration) (*FpInte Type: integration.GetIntegrationType(), Url: integration.GetIntegrationImpl().Url, Description: integration.GetHclResourceImpl().Description, - Tags: integration.GetTags(), } resp.FileName = integration.GetIntegrationImpl().FileName @@ -156,5 +140,5 @@ func (p PrintableIntegration) GetTable() (*printers.Table, error) { } func (PrintableIntegration) getColumns() (columns []string) { - return []string{"NAME", "TYPE", "DESCRIPTION", "URL"} + return []string{"NAME", "TYPE", "DESCRIPTION", "REQUEST URL"} } diff --git a/internal/types/notifier.go b/internal/types/notifier.go index 379b95f9..bc1f6dae 100644 --- a/internal/types/notifier.go +++ b/internal/types/notifier.go @@ -2,11 +2,9 @@ package types import ( "fmt" - "strconv" "github.com/logrusorgru/aurora" flowpipeapiclient "github.com/turbot/flowpipe-sdk-go" - "github.com/turbot/flowpipe/internal/util" "github.com/turbot/go-kit/helpers" "github.com/turbot/pipe-fittings/modconfig" "github.com/turbot/pipe-fittings/printers" @@ -19,15 +17,13 @@ type ListNotifierResponse struct { } type FpNotifier struct { - Name string `json:"name"` - Description *string `json:"description,omitempty"` - Title *string `json:"title,omitempty"` - Documentation *string `json:"documentation,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - Notifies []FpNotify `json:"notifies,omitempty"` - FileName string `json:"file_name,omitempty"` - StartLineNumber int `json:"start_line_number,omitempty"` - EndLineNumber int `json:"end_line_number,omitempty"` + Name string `json:"name"` + Description *string `json:"description,omitempty"` + Title *string `json:"title,omitempty"` + Notifies []FpNotify `json:"notifies,omitempty"` + FileName string `json:"file_name,omitempty"` + StartLineNumber int `json:"start_line_number,omitempty"` + EndLineNumber int `json:"end_line_number,omitempty"` } type FpNotify struct { @@ -61,42 +57,35 @@ func (p FpNotifier) String(_ *sanitize.Sanitizer, opts sanitize.RenderOptions) s output += fmt.Sprintf("%-*s%s\n", keyWidth, au.Blue("Description:"), *p.Description) } - if len(p.Tags) > 0 { - output += fmt.Sprintf("%s\n", au.Blue("Tags:")) - for k, v := range p.Tags { - output += fmt.Sprintf(" %s %s\n", au.Cyan(k+":"), v) - } - } - if len(p.Notifies) > 0 { output += fmt.Sprintf("%s\n", au.Blue("Notifies:")) - for i, n := range p.Notifies { - output += fmt.Sprintf(" %s %s\n", au.Blue("Notify"), strconv.Itoa(i+1)) - - if n.Integration != nil && util.SafeDeref(n.Integration) != "" { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Integration:"), *n.Integration) - } + for _, n := range p.Notifies { + // Integration can't be null, it's mandatory field in the schema + output += fmt.Sprintf("%4s- %s %s\n", "", au.Cyan("Integration:"), *n.Integration) if n.Title != nil { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Title:"), *n.Title) + output += fmt.Sprintf("%6s%s %s\n", "", au.Cyan("Title:"), *n.Title) } if n.Description != nil { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Description:"), *n.Description) + output += fmt.Sprintf("%6s%s %s\n", "", au.Cyan("Description:"), *n.Description) } if n.Subject != nil { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Subject:"), *n.Subject) + output += fmt.Sprintf("%6s%s %s\n", "", au.Cyan("Subject:"), *n.Subject) } if len(n.To) > 0 { - output += fmt.Sprintf(" %s %s\n", au.Cyan("To:"), n.To) + output += fmt.Sprintf("%6s%s\n", "", au.Cyan("To:")) + output = printItems(output, n.To, 8) } if len(n.Cc) > 0 { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Cc:"), n.Cc) + output += fmt.Sprintf("%6s%s\n", "", au.Cyan("Cc:")) + output = printItems(output, n.Cc, 8) } if len(n.Bcc) > 0 { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Bcc:"), n.Bcc) + output += fmt.Sprintf("%6s%s\n", "", au.Cyan("Bcc:")) + output = printItems(output, n.Bcc, 8) } if n.Channel != nil { - output += fmt.Sprintf(" %s %s\n", au.Cyan("Channel:"), *n.Channel) + output += fmt.Sprintf("%6s%s %s\n", "", au.Cyan("Channel:"), *n.Channel) } } } @@ -104,11 +93,18 @@ func (p FpNotifier) String(_ *sanitize.Sanitizer, opts sanitize.RenderOptions) s return output } +func printItems(output string, items []string, baseLeftPad int) string { + for _, item := range items { + output += fmt.Sprintf("%*s- %s\n", baseLeftPad, "", item) + } + + return output +} + func FpNotifierFromModNotifier(notifier modconfig.Notifier) (*FpNotifier, error) { resp := &FpNotifier{ Name: notifier.Name(), Description: notifier.GetHclResourceImpl().Description, - Tags: notifier.GetTags(), } resp.FileName = notifier.GetNotifierImpl().FileName @@ -127,6 +123,9 @@ func FpNotifierFromModNotifier(notifier modconfig.Notifier) (*FpNotifier, error) } if !helpers.IsNil(notify.Integration) { fpNotify.Integration = ¬ify.Integration.GetHclResourceImpl().FullName + } else { + defaultIntegration := "webform.default" + fpNotify.Integration = &defaultIntegration } resp.Notifies = append(resp.Notifies, fpNotify) @@ -141,12 +140,6 @@ func FpNotifierFromAPI(apiResp flowpipeapiclient.FpNotifier) FpNotifier { Description: apiResp.Description, } - if !helpers.IsNil(apiResp.Tags) { - res.Tags = *apiResp.Tags - } else { - res.Tags = make(map[string]string) - } - for _, n := range apiResp.Notifies { var notify = FpNotify{ Cc: n.Cc,