diff --git a/.changes/unreleased/Changed-20240103-091510.yaml b/.changes/unreleased/Changed-20240103-091510.yaml new file mode 100644 index 0000000..e8d0b42 --- /dev/null +++ b/.changes/unreleased/Changed-20240103-091510.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: Upgraded to sdk v2 and implemented honeycombio_marker resource +time: 2024-01-03T09:15:10.825897649+01:00 diff --git a/go.mod b/go.mod index e1c6106..04ece17 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/mach-composer/mach-composer-plugin-helpers v0.0.4 - github.com/mach-composer/mach-composer-plugin-sdk v1.0.0 + github.com/mach-composer/mach-composer-plugin-sdk/v2 v2.0.0 github.com/mitchellh/mapstructure v1.5.0 ) diff --git a/go.sum b/go.sum index 5487a82..1044c76 100644 --- a/go.sum +++ b/go.sum @@ -31,7 +31,7 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -39,8 +39,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/mach-composer/mach-composer-plugin-helpers v0.0.4 h1:n5jVGw4hE6ydXsfAZp0Cvi6qKK5CcASvtOn8mb3VEM8= github.com/mach-composer/mach-composer-plugin-helpers v0.0.4/go.mod h1:Ir2OV7RNUZgss0iVPPH0P4j7t2NaNzjtvFOd4bhKvLI= -github.com/mach-composer/mach-composer-plugin-sdk v1.0.0 h1:JC2CexXB03VxxyfNUdlBPdT5zEnB6o0hnR7Q69wOYPA= -github.com/mach-composer/mach-composer-plugin-sdk v1.0.0/go.mod h1:qfmnfIOp8k4RYlOEbV0UVOQZ8g3mJPKsUopZCOW2qDU= +github.com/mach-composer/mach-composer-plugin-sdk/v2 v2.0.0 h1:rz5PgtCAEtbCIiiQF9VbsggSvjXvmz2orKvgpWtcIuc= +github.com/mach-composer/mach-composer-plugin-sdk/v2 v2.0.0/go.mod h1:xzxcSqyvZpOa3j5MbSOQFfeBt5Anv9zsXI/pHcfSQx0= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -62,11 +62,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/internal/config.go b/internal/config.go index 0b2cd30..c7130b6 100644 --- a/internal/config.go +++ b/internal/config.go @@ -1,5 +1,76 @@ package internal -type HoneycombConfig struct { - ApiKey string `mapstructure:"api_key"` +// BaseConfig is the base honeycomb config. +type BaseConfig struct { + ApiKey string `mapstructure:"api_key"` + DataSet string `mapstructure:"dataset"` + Type string `mapstructure:"type"` + Url string `mapstructure:"url"` + TrackDeployments bool `mapstructure:"track_deployments"` +} + +type GlobalConfig struct { + BaseConfig `mapstructure:",squash"` +} + +type SiteConfig struct { + BaseConfig `mapstructure:",squash"` + SiteComponents map[string]*SiteComponentConfig `mapstructure:"-"` +} + +func (c *SiteConfig) extendGlobalConfig(g *GlobalConfig) *SiteConfig { + cfg := &SiteConfig{ + BaseConfig: g.BaseConfig, + SiteComponents: c.SiteComponents, + } + + if c.ApiKey != "" { + cfg.ApiKey = c.ApiKey + } + if c.DataSet != "" { + cfg.DataSet = c.DataSet + } + if c.Type != "" { + cfg.Type = c.Type + } + if c.Url != "" { + cfg.Url = c.Url + } + + if c.TrackDeployments != false { + cfg.TrackDeployments = c.TrackDeployments + } + + return cfg +} + +// SiteComponentConfig is for component specific sentry DSN settings +type SiteComponentConfig struct { + BaseConfig `mapstructure:",squash"` +} + +func (c *SiteComponentConfig) extendSiteConfig(s *SiteConfig) *SiteComponentConfig { + cfg := &SiteComponentConfig{ + BaseConfig: s.BaseConfig, + } + + if c.DataSet != "" { + cfg.DataSet = c.DataSet + } + if c.Type != "" { + cfg.Type = c.Type + } + if c.Url != "" { + cfg.Url = c.Url + } + + if c.TrackDeployments != false { + cfg.TrackDeployments = c.TrackDeployments + } + + return cfg +} + +type ComponentConfig struct { + Version string `mapstructure:"-"` } diff --git a/internal/plugin.go b/internal/plugin.go index b7a954b..0ed6190 100644 --- a/internal/plugin.go +++ b/internal/plugin.go @@ -1,35 +1,41 @@ package internal import ( + "embed" "fmt" "github.com/mach-composer/mach-composer-plugin-helpers/helpers" - "github.com/mach-composer/mach-composer-plugin-sdk/plugin" - "github.com/mach-composer/mach-composer-plugin-sdk/schema" + "github.com/mach-composer/mach-composer-plugin-sdk/v2/plugin" + "github.com/mach-composer/mach-composer-plugin-sdk/v2/schema" "github.com/mitchellh/mapstructure" ) +//go:embed templates/* +var templates embed.FS + type HoneycombPlugin struct { - provider string - environment string - globalConfig *HoneycombConfig - siteConfigs map[string]*HoneycombConfig - enabled bool + provider string + environment string + globalConfig *GlobalConfig + siteConfigs map[string]*SiteConfig + componentConfigs map[string]*ComponentConfig } func NewHoneycombPlugin() schema.MachComposerPlugin { state := &HoneycombPlugin{ - provider: "0.18.1", // Provider version of `honeycombio/honeycombio` - siteConfigs: map[string]*HoneycombConfig{}, + provider: "0.18.1", // Provider version of `honeycombio/honeycombio` + siteConfigs: map[string]*SiteConfig{}, + componentConfigs: map[string]*ComponentConfig{}, } return plugin.NewPlugin(&schema.PluginSchema{ Identifier: "honeycomb", Configure: state.Configure, - IsEnabled: func() bool { return state.enabled }, GetValidationSchema: state.GetValidationSchema, - SetGlobalConfig: state.SetGlobalConfig, - SetSiteConfig: state.SetSiteConfig, + SetGlobalConfig: state.SetGlobalConfig, + SetSiteConfig: state.SetSiteConfig, + SetComponentConfig: state.SetComponentConfig, + SetSiteComponentConfig: state.SetSiteComponentConfig, // Renders RenderTerraformProviders: state.RenderTerraformProviders, @@ -38,6 +44,36 @@ func NewHoneycombPlugin() schema.MachComposerPlugin { }) } +func (p *HoneycombPlugin) getSiteConfig(site string) *SiteConfig { + cfg, ok := p.siteConfigs[site] + if !ok { + cfg = &SiteConfig{} + } + return cfg.extendGlobalConfig(p.globalConfig) +} + +func (p *HoneycombPlugin) getSiteComponentConfig(site, name string) *SiteComponentConfig { + siteCfg := p.getSiteConfig(site) + if siteCfg == nil { + return nil + } + + cfg, ok := siteCfg.SiteComponents[name] + if !ok { + cfg = &SiteComponentConfig{} + } + + return cfg.extendSiteConfig(siteCfg) +} + +func (p *HoneycombPlugin) getComponentConfig(component string) *ComponentConfig { + cfg, ok := p.componentConfigs[component] + if !ok { + cfg = &ComponentConfig{} + } + return cfg +} + func (p *HoneycombPlugin) Configure(environment string, provider string) error { p.environment = environment if provider != "" { @@ -52,45 +88,56 @@ func (p *HoneycombPlugin) GetValidationSchema() (*schema.ValidationSchema, error } func (p *HoneycombPlugin) SetGlobalConfig(data map[string]any) error { - cfg := HoneycombConfig{} + cfg := GlobalConfig{} if err := mapstructure.Decode(data, &cfg); err != nil { return err } p.globalConfig = &cfg - p.enabled = true return nil } func (p *HoneycombPlugin) SetSiteConfig(site string, data map[string]any) error { - cfg := HoneycombConfig{} + cfg := SiteConfig{ + SiteComponents: map[string]*SiteComponentConfig{}, + } if err := mapstructure.Decode(data, &cfg); err != nil { return err } p.siteConfigs[site] = &cfg - p.enabled = true return nil } -func (p *HoneycombPlugin) getSiteConfig(site string) *HoneycombConfig { - result := &HoneycombConfig{} - if p.globalConfig != nil { - result.ApiKey = p.globalConfig.ApiKey +func (p *HoneycombPlugin) SetSiteComponentConfig(site string, component string, data map[string]any) error { + cfg := SiteComponentConfig{} + if err := mapstructure.Decode(data, &cfg); err != nil { + return err } - cfg, ok := p.siteConfigs[site] - if ok { - if cfg.ApiKey != "" { - result.ApiKey = cfg.ApiKey + siteCfg, ok := p.siteConfigs[site] + if !ok { + siteCfg = &SiteConfig{ + SiteComponents: map[string]*SiteComponentConfig{}, } + p.siteConfigs[site] = siteCfg } + siteCfg.SiteComponents[component] = &cfg - return result + return nil } -func (p *HoneycombPlugin) RenderTerraformStateBackend(_ string) (string, error) { - return "", nil +func (p *HoneycombPlugin) SetComponentConfig(component, version string, data map[string]any) error { + cfg := ComponentConfig{ + Version: version, + } + if err := mapstructure.Decode(data, &cfg); err != nil { + return err + } + + p.componentConfigs[component] = &cfg + + return nil } func (p *HoneycombPlugin) RenderTerraformProviders(site string) (string, error) { @@ -125,12 +172,33 @@ func (p *HoneycombPlugin) RenderTerraformResources(site string) (string, error) return helpers.RenderGoTemplate(template, cfg) } -func (p *HoneycombPlugin) RenderTerraformComponent(site string, _ string) (*schema.ComponentSchema, error) { - cfg := p.getSiteConfig(site) +func (p *HoneycombPlugin) RenderTerraformComponent(site string, component string) (*schema.ComponentSchema, error) { + cfg := p.getSiteComponentConfig(site, component) if cfg == nil { return nil, nil } + componentConfig := p.getComponentConfig(component) + + vars, err := terraformRenderVariables(cfg) + if err != nil { + return nil, err + } + + resources, err := terraformRenderComponentResources(component, componentConfig.Version, cfg) + if err != nil { + return nil, err + } + + result := &schema.ComponentSchema{ + Variables: vars, + Resources: resources, + } + + return result, nil +} + +func terraformRenderVariables(cfg *SiteComponentConfig) (string, error) { template := ` honeycomb = { {{ renderProperty "api_key" .ApiKey }} @@ -139,12 +207,27 @@ func (p *HoneycombPlugin) RenderTerraformComponent(site string, _ string) (*sche vars, err := helpers.RenderGoTemplate(template, cfg) if err != nil { - return nil, err + return "", err } - result := &schema.ComponentSchema{ - Variables: vars, + return vars, nil +} + +func terraformRenderComponentResources(component, version string, cfg *SiteComponentConfig) (string, error) { + templateContext := struct { + ComponentName string + Version string + Config *SiteComponentConfig + }{ + ComponentName: component, + Version: version, + Config: cfg, } - return result, nil + tpl, err := templates.ReadFile("templates/resources.tmpl") + if err != nil { + return "", err + } + + return helpers.RenderGoTemplate(string(tpl), templateContext) } diff --git a/internal/schema.go b/internal/schema.go index 10bea4d..1d42bf9 100644 --- a/internal/schema.go +++ b/internal/schema.go @@ -4,7 +4,7 @@ import ( "embed" "encoding/json" - "github.com/mach-composer/mach-composer-plugin-sdk/schema" + "github.com/mach-composer/mach-composer-plugin-sdk/v2/schema" ) //go:embed schemas/* @@ -14,6 +14,7 @@ func getSchema() *schema.ValidationSchema { s := schema.ValidationSchema{} loadSchemaNode("schemas/global-config.json", &s.GlobalConfigSchema) loadSchemaNode("schemas/site-config.json", &s.SiteConfigSchema) + loadSchemaNode("schemas/site-component-config.json", &s.SiteComponentConfigSchema) return &s } diff --git a/internal/schemas/global-config.json b/internal/schemas/global-config.json index 5f2d3ae..7a55251 100644 --- a/internal/schemas/global-config.json +++ b/internal/schemas/global-config.json @@ -1,9 +1,23 @@ { - "type": "object", - "description": "Global Honeycomb configuration.", - "properties": { - "api_key": { - "type": "string" - } + "type": "object", + "description": "Global Honeycomb configuration.", + "properties": { + "api_key": { + "type": "string" + }, + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "track_deployments": { + "type": "boolean", + "description": "Whether to track release deployments in Honeycomb.", + "default": false } + } } diff --git a/internal/schemas/site-component-config.json b/internal/schemas/site-component-config.json new file mode 100644 index 0000000..8f02e81 --- /dev/null +++ b/internal/schemas/site-component-config.json @@ -0,0 +1,23 @@ +{ + "type": "object", + "description": "Site Component Honeycomb configuration.", + "properties": { + "api_key": { + "type": "string" + }, + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "track_deployments": { + "type": "boolean", + "description": "Whether to track release deployments in Honeycomb.", + "default": false + } + } +} diff --git a/internal/schemas/site-config.json b/internal/schemas/site-config.json index 3f62be7..9a96250 100644 --- a/internal/schemas/site-config.json +++ b/internal/schemas/site-config.json @@ -1,9 +1,20 @@ { - "type": "object", - "description": "Site Honeycomb configuration.", - "properties": { - "api_key": { - "type": "string" - } + "type": "object", + "description": "Site Honeycomb configuration.", + "properties": { + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "track_deployments": { + "type": "boolean", + "description": "Whether to track release deployments in Honeycomb.", + "default": false } + } } diff --git a/internal/templates/resources.tmpl b/internal/templates/resources.tmpl new file mode 100644 index 0000000..88baaa6 --- /dev/null +++ b/internal/templates/resources.tmpl @@ -0,0 +1,14 @@ +{{ if .Config.TrackDeployments }} + resource "honeycombio_marker" "{{ .ComponentName }}" { + dataset = "{{ .Config.DataSet }}" + message = "{{ .Version }}" + {{ if .Config.Type }} + type = "{{ .Config.Type }}" + {{ end }} + {{ if .Config.Url }} + url = "{{ .Config.Url }}" + {{ end }} + + depends_on = [module.{{ .ComponentName }}] + } +{{ end}} diff --git a/main.go b/main.go index d43638a..1ff3da5 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "github.com/mach-composer/mach-composer-plugin-honeycomb/internal" - "github.com/mach-composer/mach-composer-plugin-sdk/plugin" + "github.com/mach-composer/mach-composer-plugin-sdk/v2/plugin" ) func main() { diff --git a/plugin/main.go b/plugin/main.go deleted file mode 100644 index 9e4e130..0000000 --- a/plugin/main.go +++ /dev/null @@ -1,13 +0,0 @@ -package plugin - -import ( - "github.com/mach-composer/mach-composer-plugin-sdk/plugin" - - "github.com/mach-composer/mach-composer-plugin-honeycomb/internal" -) - -// Serve serves the plugin -func Serve() { - p := internal.NewHoneycombPlugin() - plugin.ServePlugin(p) -}