diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a99a1748..fe685da5a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: go-version-file: go.mod - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 - name: Ensure Generate Succeeds and Does Not Make Changes run: | diff --git a/go.mod b/go.mod index b50f5ef96..8b3a2155b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/pivotal-cf/kiln -go 1.21 +go 1.22.6 require ( github.com/Masterminds/semver/v3 v3.2.1 diff --git a/internal/acceptance/workflows/baking_a_tile.feature b/internal/acceptance/workflows/baking_a_tile.feature index b88b55b30..77cd16587 100644 --- a/internal/acceptance/workflows/baking_a_tile.feature +++ b/internal/acceptance/workflows/baking_a_tile.feature @@ -13,11 +13,11 @@ Feature: As a developer, I want to bake a tile | releases/bpm-1.2.12.tgz | | releases/hello-release-0.2.3.tgz | And "bake_records/0.2.0-dev.json" contains substring: "version": "0.2.0-dev" - And "bake_records/0.2.0-dev.json" contains substring: "source_revision": "bc3ac24e192ba06a2eca19381ad785ec7069e0d0" + And "bake_records/0.2.0-dev.json" contains substring: "source_revision": "6d5069f9dfb954ff77bb16c5aee670b9909f154a" And "bake_records/0.2.0-dev.json" contains substring: "tile_directory": "." And "bake_records/0.2.0-dev.json" contains substring: "kiln_version": "0.0.0+acceptance-tests" - And "bake_records/0.2.0-dev.json" contains substring: "file_checksum": "5f8abc7a3272a70fa716cdf120f6976f6b78e16a01a4b3e085ced7f51d6c7691" - And "tile-0.2.0-dev.pivotal" has sha256 sum "5f8abc7a3272a70fa716cdf120f6976f6b78e16a01a4b3e085ced7f51d6c7691" + And "bake_records/0.2.0-dev.json" contains substring: "file_checksum": "c94e5749bf676f03ff10539956e9445d309647c5299b16dfe71cb522e9258f0d" + And "tile-0.2.0-dev.pivotal" has sha256 sum "c94e5749bf676f03ff10539956e9445d309647c5299b16dfe71cb522e9258f0d" Scenario: it reads directory configuration from Kilnfile Given I have a tile source directory "testdata/tiles/non-standard-paths" diff --git a/internal/acceptance/workflows/testdata/tiles/v2/go.mod b/internal/acceptance/workflows/testdata/tiles/v2/go.mod index 946935e86..0c94a5798 100644 --- a/internal/acceptance/workflows/testdata/tiles/v2/go.mod +++ b/internal/acceptance/workflows/testdata/tiles/v2/go.mod @@ -1,6 +1,6 @@ module github.com/crhntr/hello-tile -go 1.20 +go 1.22.6 require ( github.com/cppforlife/go-patch v0.2.0 // indirect diff --git a/internal/commands/find_stemcell_version.go b/internal/commands/find_stemcell_version.go index c19606687..decc616fb 100644 --- a/internal/commands/find_stemcell_version.go +++ b/internal/commands/find_stemcell_version.go @@ -2,6 +2,7 @@ package commands import ( "encoding/json" + "errors" "fmt" "log" @@ -57,7 +58,7 @@ func (cmd FindStemcellVersion) Execute(args []string) error { } if kilnfile.Stemcell.Version == "" { - return fmt.Errorf(ErrStemcellMajorVersionMustBeValid) + return errors.New(ErrStemcellMajorVersionMustBeValid) } // Get stemcell version from pivnet diff --git a/internal/commands/update_release.go b/internal/commands/update_release.go index 003890f1a..d17a8445e 100644 --- a/internal/commands/update_release.go +++ b/internal/commands/update_release.go @@ -78,7 +78,6 @@ func (u UpdateRelease) Execute(args []string) error { StemcellOS: kilnfileLock.Stemcell.OS, GitHubRepository: releaseSpec.GitHubRepository, }, false) - if err != nil { if component.IsErrNotFound(err) { return fmt.Errorf("error finding the release: %w", err) @@ -99,7 +98,6 @@ func (u UpdateRelease) Execute(args []string) error { StemcellVersion: kilnfileLock.Stemcell.Version, GitHubRepository: releaseSpec.GitHubRepository, }) - if err != nil { if component.IsErrNotFound(err) { return fmt.Errorf("error finding the release: %w", err) diff --git a/internal/commands/update_stemcell.go b/internal/commands/update_stemcell.go index 128ec23f1..36992c79f 100644 --- a/internal/commands/update_stemcell.go +++ b/internal/commands/update_stemcell.go @@ -48,7 +48,6 @@ func (update UpdateStemcell) Execute(args []string) error { kilnStemcellVersion := kilnfile.Stemcell.Version releaseVersionConstraint, err = semver.NewConstraint(kilnStemcellVersion) - if err != nil { return fmt.Errorf("invalid stemcell constraint in kilnfile: %w", err) } diff --git a/internal/commands/validate.go b/internal/commands/validate.go index f364fe226..448ac3141 100644 --- a/internal/commands/validate.go +++ b/internal/commands/validate.go @@ -14,6 +14,7 @@ import ( type Validate struct { Options struct { flags.Standard + ReleaseSourceTypeAllowList []string `long:"allow-release-source-type"` } FS billy.Filesystem @@ -38,7 +39,7 @@ func (v Validate) Execute(args []string) error { return fmt.Errorf("failed to load kilnfiles: %w", err) } - errs := cargo.Validate(kf, lock) + errs := cargo.Validate(kf, lock, cargo.ValidateResourceTypeAllowList(v.Options.ReleaseSourceTypeAllowList...)) if len(errs) > 0 { return errorList(errs) } diff --git a/internal/commands/validate_test.go b/internal/commands/validate_test.go new file mode 100644 index 000000000..45561d7be --- /dev/null +++ b/internal/commands/validate_test.go @@ -0,0 +1,72 @@ +package commands_test + +import ( + "io" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/memfs" + + "github.com/pivotal-cf/kiln/internal/commands" +) + +var _ = Describe("validate", func() { + var ( + validate commands.Validate + directory billy.Filesystem + ) + + BeforeEach(func() { + directory = memfs.New() + }) + + JustBeforeEach(func() { + validate = commands.NewValidate(directory) + }) + + When("the kilnfile has two release_sources", func() { + BeforeEach(func() { + f, err := directory.Create("Kilnfile") + Expect(err).NotTo(HaveOccurred()) + // language=yaml + _, _ = io.WriteString(f, `--- +release_sources: + - type: "bosh.io" + - type: "github" +`) + _ = f.Close() + }) + + BeforeEach(func() { + f, err := directory.Create("Kilnfile.lock") + Expect(err).NotTo(HaveOccurred()) + _ = f.Close() + }) + + When("both types are in the allow list", func() { + It("it does fail", func() { + err := validate.Execute([]string{ + "--allow-release-source-type=bosh.io", + "--allow-release-source-type=github", + }) + Expect(err).NotTo(HaveOccurred()) + }) + }) + When("both one of the types is not in the allow list", func() { + It("it does fail", func() { + err := validate.Execute([]string{ + "--allow-release-source-type=bosh.io", + }) + Expect(err).To(MatchError(ContainSubstring("release source type not allowed: github"))) + }) + }) + When("the allow list is empty", func() { + It("it does not fail", func() { + err := validate.Execute([]string{}) + Expect(err).NotTo(HaveOccurred()) + }) + }) + }) +}) diff --git a/internal/component/artifactory.go b/internal/component/artifactory.go index f34c5b5e7..6ed9fc119 100644 --- a/internal/component/artifactory.go +++ b/internal/component/artifactory.go @@ -311,7 +311,7 @@ func (ars *ArtifactoryReleaseSource) UploadRelease(spec cargo.BOSHReleaseTarball switch response.StatusCode { case http.StatusCreated: default: - return cargo.BOSHReleaseTarballLock{}, fmt.Errorf(response.Status) + return cargo.BOSHReleaseTarballLock{}, fmt.Errorf("response contained errror status code: %d %s", response.StatusCode, response.Status) } return cargo.BOSHReleaseTarballLock{ diff --git a/internal/test/testdata/happy-tile/go.mod b/internal/test/testdata/happy-tile/go.mod index 425264502..5ac61cb88 100644 --- a/internal/test/testdata/happy-tile/go.mod +++ b/internal/test/testdata/happy-tile/go.mod @@ -1,6 +1,6 @@ module github.com/pivotal-cf/kiln/internal/commands/testdata/tas_fake/tas -go 1.20 +go 1.22.6 require ( github.com/onsi/ginkgo v1.16.4 diff --git a/pkg/cargo/validate.go b/pkg/cargo/validate.go index c3f036e03..e35067819 100644 --- a/pkg/cargo/validate.go +++ b/pkg/cargo/validate.go @@ -3,13 +3,51 @@ package cargo import ( "fmt" "slices" + "text/template/parse" "github.com/Masterminds/semver/v3" ) -func Validate(spec Kilnfile, lock KilnfileLock) []error { +type ValidationOptions struct { + resourceTypeAllowList []string +} + +func NewValidateOptions() ValidationOptions { + return ValidationOptions{} +} + +// ValidateResourceTypeAllowList calls ValidationOptions.SetValidateResourceTypeAllowList on the result of NewValidateOptions +func ValidateResourceTypeAllowList(allowList ...string) ValidationOptions { + return NewValidateOptions().SetValidateResourceTypeAllowList(allowList) +} + +func (o ValidationOptions) SetValidateResourceTypeAllowList(allowList []string) ValidationOptions { + o.resourceTypeAllowList = allowList + return o +} + +func mergeOptions(options []ValidationOptions) ValidationOptions { + var opt ValidationOptions + for _, o := range options { + if o.resourceTypeAllowList != nil { + opt.resourceTypeAllowList = o.resourceTypeAllowList + } + } + return opt +} + +func Validate(spec Kilnfile, lock KilnfileLock, options ...ValidationOptions) []error { + opt := mergeOptions(options) var result []error + if len(opt.resourceTypeAllowList) > 0 { + for _, s := range spec.ReleaseSources { + if !slices.Contains(opt.resourceTypeAllowList, s.Type) { + result = append(result, fmt.Errorf("release source type not allowed: %s", s.Type)) + } + } + } + for index, componentSpec := range spec.Releases { if componentSpec.Name == "" { result = append(result, fmt.Errorf("release at index %d missing name in spec", index)) @@ -43,6 +81,7 @@ func Validate(spec Kilnfile, lock KilnfileLock) []error { } result = append(result, ensureRemoteSourceExistsForEachReleaseLock(spec, lock)...) + result = append(result, ensureReleaseSourceConfiguration(spec.ReleaseSources)...) if len(result) > 0 { return result @@ -51,6 +90,64 @@ func Validate(spec Kilnfile, lock KilnfileLock) []error { return nil } +func ensureReleaseSourceConfiguration(sources []ReleaseSourceConfig) []error { + var errs []error + for _, source := range sources { + switch source.Type { + case BOSHReleaseTarballSourceTypeArtifactory: + if source.ArtifactoryHost == "" { + errs = append(errs, fmt.Errorf("missing required field artifactory_host")) + } + if source.Username == "" { + errs = append(errs, fmt.Errorf("missing required field username")) + } + if source.Password == "" { + errs = append(errs, fmt.Errorf("missing required field password")) + } + if source.Repo == "" { + errs = append(errs, fmt.Errorf("missing required field repo")) + } + if source.PathTemplate == "" { + errs = append(errs, fmt.Errorf("missing required field path_template")) + } else { + p := parse.New("path_template") + p.Mode |= parse.SkipFuncCheck + if _, err := p.Parse(source.PathTemplate, "", "", make(map[string]*parse.Tree)); err != nil { + errs = append(errs, fmt.Errorf("failed to parse path_template: %w", err)) + } + } + if source.Bucket != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field bucket")) + } + if source.Region != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field region")) + } + if source.AccessKeyId != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field access_key_id")) + } + if source.SecretAccessKey != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field secret_access_key")) + } + if source.RoleARN != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field role_arn")) + } + if source.Endpoint != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field endpoint")) + } + if source.Org != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field org")) + } + if source.GithubToken != "" { + errs = append(errs, fmt.Errorf("artifactory has unexpected field github_token")) + } + case BOSHReleaseTarballSourceTypeBOSHIO: + case BOSHReleaseTarballSourceTypeS3: + case BOSHReleaseTarballSourceTypeGithub: + } + } + return errs +} + func ensureRemoteSourceExistsForEachReleaseLock(spec Kilnfile, lock KilnfileLock) []error { var result []error for _, release := range lock.Releases { diff --git a/pkg/cargo/validate_test.go b/pkg/cargo/validate_test.go index bb3521367..53a2ee1d8 100644 --- a/pkg/cargo/validate_test.go +++ b/pkg/cargo/validate_test.go @@ -3,7 +3,11 @@ package cargo import ( "testing" + "github.com/stretchr/testify/require" + . "github.com/onsi/gomega" + + "github.com/stretchr/testify/assert" ) const ( @@ -296,3 +300,317 @@ func TestValidate_checkComponentVersionsAndConstraint(t *testing.T) { )) }) } + +func TestValidateWithOptions(t *testing.T) { + t.Run("resource type allow list", func(t *testing.T) { + t.Run("when the types are permitted", func(t *testing.T) { + kf := Kilnfile{ + ReleaseSources: []ReleaseSourceConfig{ + {Type: "farm"}, + {Type: "orchard"}, + }, + } + kl := KilnfileLock{} + errs := Validate(kf, kl, ValidateResourceTypeAllowList("orchard", "farm")) + assert.Zero(t, errs) + }) + t.Run("when one of the types is not in the allow list", func(t *testing.T) { + kf := Kilnfile{ + ReleaseSources: []ReleaseSourceConfig{ + {Type: "farm"}, + {Type: "orchard"}, + }, + } + kl := KilnfileLock{} + errs := Validate(kf, kl, ValidateResourceTypeAllowList("orchard")) + if assert.Len(t, errs, 1) { + assert.ErrorContains(t, errs[0], "release source type not allowed: farm") + } + }) + }) + + t.Run("when a release_source is not configured properly", func(t *testing.T) { + for _, tt := range []struct { + Name string + Sources []ReleaseSourceConfig + Error func(t *testing.T, errs []error) + }{ + { + Name: "artifactory host is empty", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + // ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "some-path", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "missing required field artifactory_host") + }, + }, + { + Name: "artifactory password is empty", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + // Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "some-path", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "missing required field password") + }, + }, + { + Name: "artifactory username is empty", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + // Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "some-path", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "missing required field username") + }, + }, + { + Name: "artifactory repo is empty", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + // Repo: "secret-stash", + PathTemplate: "some-path", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "missing required field repo") + }, + }, + { + Name: "artifactory path_template is empty", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + // PathTemplate: "some-path", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "missing required field path_template") + }, + }, + { + Name: "artifactory path_template is malformed", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "{{ loosing power", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "failed to parse path_template:") + }, + }, + { + Name: "artifactory has unexpected field bucket", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + Bucket: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field bucket") + }, + }, + { + Name: "artifactory has unexpected field region", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + Region: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field region") + }, + }, + { + Name: "artifactory has unexpected field access_key_id", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + AccessKeyId: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field access_key_id") + }, + }, + { + Name: "artifactory has unexpected field secret_access_key", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + SecretAccessKey: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field secret_access_key") + }, + }, + { + Name: "artifactory has unexpected field role_arn", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + RoleARN: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field role_arn") + }, + }, + { + Name: "artifactory has unexpected field endpoint", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + Endpoint: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field endpoint") + }, + }, + { + Name: "artifactory has unexpected field org", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + Org: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field org") + }, + }, + { + Name: "artifactory has unexpected field github_token", + Sources: []ReleaseSourceConfig{ + { + Type: BOSHReleaseTarballSourceTypeArtifactory, + ID: "", + ArtifactoryHost: "http://example.com", + Username: "bot", + Password: "beep boop", + Repo: "secret-stash", + PathTemplate: "ok", + + GithubToken: "UNEXPECTED", + }, + }, + Error: func(t *testing.T, errs []error) { + require.Len(t, errs, 1) + assert.ErrorContains(t, errs[0], "unexpected field github_token") + }, + }, + } { + t.Run(tt.Name, func(t *testing.T) { + k := Kilnfile{ + ReleaseSources: tt.Sources, + } + errs := Validate(k, KilnfileLock{}) + tt.Error(t, errs) + }) + } + }) +} diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index e06175f00..d591ed204 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -102,7 +102,7 @@ type IssuesQuery struct { } type TrainstatQuery struct { - TrainstatURL string `long:"trainstat-url" short:"tu" description:"trainstat url to fetch the release notes for component bumps" default:"https://trainstat.sc2-04-pcf1-apps.oc.vmware.com"` + TrainstatURL string `long:"trainstat-url" short:"tu" description:"trainstat url to fetch the release notes for component bumps" default:"https://tas-trainstat.eng.tanzu.broadcom.com"` } func TrainstatURL() string { diff --git a/pkg/notes/testdata/runtime-rn.html.md.erb b/pkg/notes/testdata/runtime-rn.html.md.erb index 55656385b..574269160 100644 --- a/pkg/notes/testdata/runtime-rn.html.md.erb +++ b/pkg/notes/testdata/runtime-rn.html.md.erb @@ -4187,7 +4187,7 @@ Overview tab in Apps Manager results in an `Unexpected error occurence` message. In <%= vars.app_runtime_abbr %> v2.7.17 and earlier, the `/v2/app_usage_events/destructively_purge_all_and_reseed_started_apps` endpoint may generate app events without valid GUIDs. These invalid GUIDs can cause errors with components that consume them when parsing and correlating events. This issue affects Cloud Controller and App Usage Service. -For more information about the API endpoint, see [Purge and reseed App Usage Events](https://apidocs.cloudfoundry.org/13.6.0/app_usage_events/purge_and_reseed_app_usage_events.html) in the _App Usage Events API_ documentation. For more information about the issue, see [App Usage Service startup errors and data inconsistency](https://community.pivotal.io/s/article/App-Usage-Service-startup-errors-and-data-inconsistency) in the knowledge base. +For more information about the API endpoint, see [Purge and reseed App Usage Events](https://v2-apidocs.cloudfoundry.org/app_usage_events/purge_and_reseed_app_usage_events.html) in the _App Usage Events API_ documentation. For more information about the issue, see [App Usage Service startup errors and data inconsistency](https://community.pivotal.io/s/article/App-Usage-Service-startup-errors-and-data-inconsistency) in the knowledge base. This issue is resolved in <%= vars.app_runtime_abbr %> v2.7.18. diff --git a/pkg/planitest/internal/config.go b/pkg/planitest/internal/config.go index 7e5b40463..4c3bb5cd6 100644 --- a/pkg/planitest/internal/config.go +++ b/pkg/planitest/internal/config.go @@ -43,7 +43,6 @@ func MergeAdditionalProductProperties(configFile io.Reader, additionalProperties var inputConfig ProductConfiguration err = yaml.Unmarshal(yamlInput, &inputConfig) - if err != nil { return nil, fmt.Errorf("could not parse config file: %s", err) } diff --git a/pkg/planitest/internal/om_runner.go b/pkg/planitest/internal/om_runner.go index 40fc80249..906bcb8be 100644 --- a/pkg/planitest/internal/om_runner.go +++ b/pkg/planitest/internal/om_runner.go @@ -89,7 +89,6 @@ func (o OMRunner) ResetAndConfigure(productName string, productVersion string, c "--product-name", productName, "--product-version", productVersion, ) - if err != nil { return fmt.Errorf("Unable to stage product %q, version %q: %s: %s", productName, productVersion, err, errOutput) @@ -114,7 +113,6 @@ func (o OMRunner) ResetAndConfigure(productName string, productVersion string, c "configure-product", "--config", configFile.Name(), ) - if err != nil { return fmt.Errorf("Unable to configure product %q: %s: %s", productName, err, errOutput) }