diff --git a/.golangci.yml b/.golangci.yml index b805551..f0e2d02 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -4,7 +4,6 @@ linters: - dogsled - durationcheck - exhaustive - - exportloopref - gci - goconst - gofmt @@ -29,6 +28,7 @@ linters: - unparam - wastedassign - errorlint + - copyloopvar issues: max-same-issues: 0 exclude-rules: diff --git a/pkg/diff/diff.go b/pkg/diff/diff.go index 56ca0bb..2435bd9 100644 --- a/pkg/diff/diff.go +++ b/pkg/diff/diff.go @@ -149,6 +149,9 @@ type Syncer struct { // enableEntityActions enables entity actions and disables direct output prints. If set to true, clients must // consume the Syncer.resultChan channel or Syncer.Solve() will block. enableEntityActions bool + + // Prevents the Syncer from performing any Delete operations. Default is false (will delete). + noDeletes bool } type SyncerOpts struct { @@ -173,6 +176,9 @@ type SyncerOpts struct { // EnableEntityActions instructs the Syncer to send EntityActions to its resultChan. If enabled, clients must // consume the Syncer.resultChan channel or Syncer.Solve() will block. EnableEntityActions bool + + // Prevents the Syncer from performing any Delete operations. Default is false (will delete). + NoDeletes bool } // NewSyncer constructs a Syncer. @@ -196,6 +202,7 @@ func NewSyncer(opts SyncerOpts) (*Syncer, error) { isKonnect: opts.IsKonnect, enableEntityActions: opts.EnableEntityActions, + noDeletes: opts.NoDeletes, } if opts.IsKonnect { @@ -278,11 +285,20 @@ func (sc *Syncer) init() error { } func (sc *Syncer) diff() error { - for _, operation := range []func() error{ - sc.deleteDuplicates, - sc.createUpdate, - sc.delete, - } { + var operations []func() error + + // If the syncer is configured to skip deletes, then don't add those functions at all to the list of diff operations. + if !sc.noDeletes { + operations = append(operations, sc.deleteDuplicates) + } + + operations = append(operations, sc.createUpdate) + + if !sc.noDeletes { + operations = append(operations, sc.delete) + } + + for _, operation := range operations { err := operation() if err != nil { return err diff --git a/pkg/file/builder.go b/pkg/file/builder.go index 35f6780..1c4ca3c 100644 --- a/pkg/file/builder.go +++ b/pkg/file/builder.go @@ -167,7 +167,6 @@ func (b *stateBuilder) consumerGroups() { } for _, cg := range b.targetContent.ConsumerGroups { - cg := cg current, err := b.currentState.ConsumerGroups.Get(*cg.Name) if utils.Empty(cg.ID) { if errors.Is(err, state.ErrNotFound) { @@ -290,7 +289,6 @@ func (b *stateBuilder) certificates() { func (b *stateBuilder) ingestSNIs(snis []kong.SNI) error { for _, sni := range snis { - sni := sni currentSNI, err := b.currentState.SNIs.Get(*sni.Name) if utils.Empty(sni.ID) { if errors.Is(err, state.ErrNotFound) { @@ -316,7 +314,6 @@ func (b *stateBuilder) caCertificates() { } for _, c := range b.targetContent.CACertificates { - c := c cert, err := b.currentState.CACertificates.Get(*c.Cert) if utils.Empty(c.ID) { if errors.Is(err, state.ErrNotFound) { @@ -412,8 +409,6 @@ func (b *stateBuilder) consumers() { } for _, c := range b.targetContent.Consumers { - c := c - var ( consumer *state.Consumer err error @@ -602,7 +597,6 @@ func (b *stateBuilder) ingestIntoConsumerGroup(consumer FConsumer) error { func (b *stateBuilder) ingestKeyAuths(creds []kong.KeyAuth) error { for _, cred := range creds { - cred := cred existingCred, err := b.currentState.KeyAuths.Get(*cred.Key) if utils.Empty(cred.ID) { if errors.Is(err, state.ErrNotFound) { @@ -626,7 +620,6 @@ func (b *stateBuilder) ingestKeyAuths(creds []kong.KeyAuth) error { func (b *stateBuilder) ingestBasicAuths(creds []kong.BasicAuth) error { for _, cred := range creds { - cred := cred existingCred, err := b.currentState.BasicAuths.Get(*cred.Username) if utils.Empty(cred.ID) { if errors.Is(err, state.ErrNotFound) { @@ -650,7 +643,6 @@ func (b *stateBuilder) ingestBasicAuths(creds []kong.BasicAuth) error { func (b *stateBuilder) ingestHMACAuths(creds []kong.HMACAuth) error { for _, cred := range creds { - cred := cred existingCred, err := b.currentState.HMACAuths.Get(*cred.Username) if utils.Empty(cred.ID) { if errors.Is(err, state.ErrNotFound) { @@ -674,7 +666,6 @@ func (b *stateBuilder) ingestHMACAuths(creds []kong.HMACAuth) error { func (b *stateBuilder) ingestJWTAuths(creds []kong.JWTAuth) error { for _, cred := range creds { - cred := cred existingCred, err := b.currentState.JWTAuths.Get(*cred.Key) if utils.Empty(cred.ID) { if errors.Is(err, state.ErrNotFound) { @@ -698,7 +689,6 @@ func (b *stateBuilder) ingestJWTAuths(creds []kong.JWTAuth) error { func (b *stateBuilder) ingestOauth2Creds(creds []kong.Oauth2Credential) error { for _, cred := range creds { - cred := cred existingCred, err := b.currentState.Oauth2Creds.Get(*cred.ClientID) if utils.Empty(cred.ID) { if errors.Is(err, state.ErrNotFound) { @@ -722,7 +712,6 @@ func (b *stateBuilder) ingestOauth2Creds(creds []kong.Oauth2Credential) error { func (b *stateBuilder) ingestACLGroups(creds []kong.ACLGroup) error { for _, cred := range creds { - cred := cred if utils.Empty(cred.ID) { existingCred, err := b.currentState.ACLGroups.Get( *cred.Consumer.ID, @@ -746,7 +735,6 @@ func (b *stateBuilder) ingestACLGroups(creds []kong.ACLGroup) error { func (b *stateBuilder) ingestMTLSAuths(creds []kong.MTLSAuth) { kong230Version := semver.MustParse("2.3.0") for _, cred := range creds { - cred := cred // normally, we'd want to look up existing resources in this case // however, this is impossible here: mtls-auth simply has no unique fields other than ID, // so we don't--schema validation requires the ID @@ -876,7 +864,6 @@ func (b *stateBuilder) services() { } for _, s := range b.targetContent.Services { - s := s err := b.ingestService(&s) if err != nil { b.err = err @@ -950,7 +937,6 @@ func (b *stateBuilder) ingestService(s *FService) error { // routes for the service for _, r := range s.Routes { - r := r r.Service = utils.GetServiceReference(s.Service) if err := b.ingestRoute(*r); err != nil { return err @@ -965,7 +951,6 @@ func (b *stateBuilder) routes() { } for _, r := range b.targetContent.Routes { - r := r if err := b.ingestRoute(r); err != nil { b.err = err return @@ -1007,7 +992,6 @@ func (b *stateBuilder) vaults() { } for _, v := range b.targetContent.Vaults { - v := v vault, err := b.currentState.Vaults.Get(*v.Prefix) if utils.Empty(v.ID) { if errors.Is(err, state.ErrNotFound) { @@ -1034,7 +1018,6 @@ func (b *stateBuilder) licenses() { } for _, l := range b.targetContent.Licenses { - l := l // Fill with a random ID if the ID is not given. // If ID is not given in the file to sync from, a NEW license will be created. if utils.Empty(l.ID) { @@ -1051,7 +1034,6 @@ func (b *stateBuilder) rbacRoles() { } for _, r := range b.targetContent.RBACRoles { - r := r role, err := b.currentState.RBACRoles.Get(*r.Name) if utils.Empty(r.ID) { if errors.Is(err, state.ErrNotFound) { @@ -1069,7 +1051,6 @@ func (b *stateBuilder) rbacRoles() { b.rawState.RBACRoles = append(b.rawState.RBACRoles, &r.RBACRole) // rbac endpoint permissions for the role for _, ep := range r.EndpointPermissions { - ep := ep ep.Role = &kong.RBACRole{ID: kong.String(*r.ID)} b.rawState.RBACEndpointPermissions = append(b.rawState.RBACEndpointPermissions, &ep.RBACEndpointPermission) } @@ -1146,7 +1127,6 @@ func (b *stateBuilder) upstreams() { } for _, u := range b.targetContent.Upstreams { - u := u ups, err := b.currentState.Upstreams.Get(*u.Name) if utils.Empty(u.ID) { if errors.Is(err, state.ErrNotFound) { @@ -1181,8 +1161,6 @@ func (b *stateBuilder) upstreams() { func (b *stateBuilder) ingestTargets(targets []kong.Target) error { for _, t := range targets { - t := t - if t.Target != nil && hasIPv6Format(*t.Target) { normalizedTarget, err := normalizeIPv6(*t.Target) if err != nil { @@ -1215,7 +1193,6 @@ func (b *stateBuilder) plugins() { var plugins []FPlugin for _, p := range b.targetContent.Plugins { - p := p if p.Consumer != nil && !utils.Empty(p.Consumer.ID) { c, err := b.intermediate.Consumers.GetByIDOrUsername(*p.Consumer.ID) if errors.Is(err, state.ErrNotFound) { @@ -1287,7 +1264,6 @@ func (b *stateBuilder) filterChains() { var filterChains []FFilterChain for _, f := range b.targetContent.FilterChains { - f := f if f.Service != nil && !utils.Empty(f.Service.ID) { s, err := b.intermediate.Services.Get(*f.Service.ID) if errors.Is(err, state.ErrNotFound) { @@ -1476,7 +1452,6 @@ func (b *stateBuilder) ingestRoute(r FRoute) error { func (b *stateBuilder) ingestPlugins(plugins []FPlugin) error { for _, p := range plugins { - p := p cID, rID, sID, cgID := pluginRelations(&p.Plugin) plugin, err := b.currentState.Plugins.GetByProp(*p.Name, sID, rID, cID, cgID) @@ -1543,7 +1518,6 @@ func pluginRelations(plugin *kong.Plugin) (cID, rID, sID, cgID string) { func (b *stateBuilder) ingestFilterChains(filterChains []FFilterChain) error { for _, f := range filterChains { - f := f rID, sID := filterChainRelations(&f.FilterChain) filterChain, err := b.currentState.FilterChains.GetByProp(sID, rID) if utils.Empty(f.ID) { diff --git a/pkg/file/writer.go b/pkg/file/writer.go index a205140..a092ce2 100644 --- a/pkg/file/writer.go +++ b/pkg/file/writer.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "sort" @@ -356,7 +355,6 @@ func fetchService(id string, kongState *state.KongState, config WriteConfig) (*F return nil, err } for _, p := range plugins { - p := p if p.Route != nil || p.Consumer != nil || p.ConsumerGroup != nil { continue } @@ -370,7 +368,6 @@ func fetchService(id string, kongState *state.KongState, config WriteConfig) (*F return compareOrder(s.Plugins[i], s.Plugins[j]) }) for _, r := range routes { - r := r r.Service = nil route, err := getFRouteFromRoute(r, kongState, config) if err != nil { @@ -405,7 +402,6 @@ func populateServicelessRoutes(kongState *state.KongState, file *Content, return err } for _, r := range routes { - r := r if r.Service != nil { continue } @@ -429,7 +425,6 @@ func populatePlugins(kongState *state.KongState, file *Content, return err } for _, p := range plugins { - p := p associations := 0 if p.Consumer != nil { associations++ @@ -551,7 +546,6 @@ func populateUpstreams(kongState *state.KongState, file *Content, return err } for _, t := range targets { - t := t t.Upstream = nil utils.ZeroOutID(t, t.Target.Target, config.WithID) utils.ZeroOutTimestamps(t) @@ -611,7 +605,6 @@ func populateCertificates(kongState *state.KongState, file *Content, return err } for _, s := range snis { - s := s s.Certificate = nil utils.ZeroOutID(s, s.Name, config.WithID) utils.ZeroOutTimestamps(s) @@ -668,7 +661,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, p := range plugins { - p := p if p.Service != nil || p.Route != nil || p.ConsumerGroup != nil { continue } @@ -687,7 +679,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range keyAuths { - k := k utils.ZeroOutID(k, k.Key, config.WithID) utils.ZeroOutTimestamps(k) utils.MustRemoveTags(k, config.SelectTags) @@ -699,7 +690,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range hmacAuth { - k := k k.Consumer = nil utils.ZeroOutID(k, k.Username, config.WithID) utils.ZeroOutTimestamps(k) @@ -711,7 +701,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range jwtSecrets { - k := k k.Consumer = nil utils.ZeroOutID(k, k.Key, config.WithID) utils.ZeroOutTimestamps(k) @@ -723,7 +712,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range basicAuths { - k := k k.Consumer = nil utils.ZeroOutID(k, k.Username, config.WithID) utils.ZeroOutTimestamps(k) @@ -735,7 +723,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range oauth2Creds { - k := k k.Consumer = nil utils.ZeroOutID(k, k.ClientID, config.WithID) utils.ZeroOutTimestamps(k) @@ -747,7 +734,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range aclGroups { - k := k k.Consumer = nil utils.ZeroOutID(k, k.Group, config.WithID) utils.ZeroOutTimestamps(k) @@ -759,7 +745,6 @@ func populateConsumers(kongState *state.KongState, file *Content, return err } for _, k := range mtlsAuths { - k := k utils.ZeroOutTimestamps(k) utils.MustRemoveTags(k, config.SelectTags) k.Consumer = nil @@ -916,7 +901,7 @@ func WriteContentToFile(content *Content, filename string, format Format) error } else { filename = utils.AddExtToFilename(filename, strings.ToLower(string(format))) prefix, _ := filepath.Split(filename) - if err := ioutil.WriteFile(filename, c, 0o600); err != nil { + if err := os.WriteFile(filename, c, 0o600); err != nil { return fmt.Errorf("writing file: %w", err) } for _, sp := range content.ServicePackages { diff --git a/pkg/state/document_test.go b/pkg/state/document_test.go index 5bd7ff2..c264d7b 100644 --- a/pkg/state/document_test.go +++ b/pkg/state/document_test.go @@ -122,7 +122,6 @@ func TestDocumentCollection_Add(t *testing.T) { } k.Add(d1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.document); (err != nil) != tt.wantErr { diff --git a/pkg/state/filter_chain_test.go b/pkg/state/filter_chain_test.go index 05dabc5..e0d3bc5 100644 --- a/pkg/state/filter_chain_test.go +++ b/pkg/state/filter_chain_test.go @@ -247,7 +247,6 @@ func TestFilterChainsCollection_Add(t *testing.T) { } for _, tt := range commonCases { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -259,7 +258,6 @@ func TestFilterChainsCollection_Add(t *testing.T) { } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -371,7 +369,6 @@ func TestFilterChainsCollection_Update(t *testing.T) { }) for _, tt := range commonCases { - tt := tt if utils.Empty(tt.filterChain.ID) { continue } @@ -406,7 +403,6 @@ func TestFilterChainsCollection_Update(t *testing.T) { } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() diff --git a/pkg/state/license_test.go b/pkg/state/license_test.go index 7042d88..2b7019d 100644 --- a/pkg/state/license_test.go +++ b/pkg/state/license_test.go @@ -49,7 +49,6 @@ func TestLicenseCollection_Add(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { initialState := state() c := initialState.Licenses @@ -91,7 +90,6 @@ func TestLicenseCollection_Get(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { initialState := state() c := initialState.Licenses @@ -143,7 +141,6 @@ func TestLicenseCollection_Update(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { initialState := state() c := initialState.Licenses @@ -186,7 +183,6 @@ func TestLicenseCollection_Delete(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { initialState := state() c := initialState.Licenses diff --git a/pkg/state/plugin_test.go b/pkg/state/plugin_test.go index f808806..59e0bc0 100644 --- a/pkg/state/plugin_test.go +++ b/pkg/state/plugin_test.go @@ -144,7 +144,6 @@ func TestPluginsCollection_Add(t *testing.T) { k.Add(plugin2) k.Add(plugin3) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.plugin); (err != nil) != tt.wantErr { @@ -291,7 +290,6 @@ func TestPluginsCollection_Update(t *testing.T) { k.Add(plugin3) k.Add(plugin4) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Update(tt.args.plugin); (err != nil) != tt.wantErr { diff --git a/pkg/state/rbac_endpoint_permission_test.go b/pkg/state/rbac_endpoint_permission_test.go index 05e6931..90d2a91 100644 --- a/pkg/state/rbac_endpoint_permission_test.go +++ b/pkg/state/rbac_endpoint_permission_test.go @@ -60,7 +60,6 @@ func TestRBACEndpointPermissionsCollection_Add(t *testing.T) { } k.Add(rbacEndpointPermission1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.rbacEndpointPermission); (err != nil) != tt.wantErr { diff --git a/pkg/state/rbac_role_test.go b/pkg/state/rbac_role_test.go index 8e8f945..dc4e774 100644 --- a/pkg/state/rbac_role_test.go +++ b/pkg/state/rbac_role_test.go @@ -89,7 +89,6 @@ func TestRBACRolesCollection_Add(t *testing.T) { } k.Add(rbacRole1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.rbacRole); (err != nil) != tt.wantErr { diff --git a/pkg/state/route_test.go b/pkg/state/route_test.go index f85a672..06fce69 100644 --- a/pkg/state/route_test.go +++ b/pkg/state/route_test.go @@ -95,7 +95,6 @@ func TestRoutesCollection_Add(t *testing.T) { } k.Add(route1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.route); (err != nil) != tt.wantErr { diff --git a/pkg/state/service_package_test.go b/pkg/state/service_package_test.go index e89c771..a81fa3d 100644 --- a/pkg/state/service_package_test.go +++ b/pkg/state/service_package_test.go @@ -90,7 +90,6 @@ func TestServicePackagesCollection_Add(t *testing.T) { } k.Add(svc1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.servicePackage); (err != nil) != tt.wantErr { diff --git a/pkg/state/service_test.go b/pkg/state/service_test.go index 6624683..fb05aa7 100644 --- a/pkg/state/service_test.go +++ b/pkg/state/service_test.go @@ -95,7 +95,6 @@ func TestServicesCollection_Add(t *testing.T) { } k.Add(svc1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.service); (err != nil) != tt.wantErr { diff --git a/pkg/state/service_version_test.go b/pkg/state/service_version_test.go index cfc939a..979b318 100644 --- a/pkg/state/service_version_test.go +++ b/pkg/state/service_version_test.go @@ -114,7 +114,6 @@ func TestServiceVersionCollection_Add(t *testing.T) { } k.Add(sv1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.serviceVersion); (err != nil) != tt.wantErr { diff --git a/pkg/state/sni_test.go b/pkg/state/sni_test.go index 0ec3803..70c04ba 100644 --- a/pkg/state/sni_test.go +++ b/pkg/state/sni_test.go @@ -122,7 +122,6 @@ func TestSNIsCollection_Add(t *testing.T) { } k.Add(sni1) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() if err := k.Add(tt.args.sni); (err != nil) != tt.wantErr {