@@ -131,7 +131,7 @@ func RemoveConsumerPlugins(targetContentPlugins []file.FPlugin) []file.FPlugin {
131131}
132132
133133func syncMain (ctx context.Context , filenames []string , dry bool , parallelism ,
134- delay int , workspace string , enableJSONOutput bool ,
134+ delay int , workspace string , enableJSONOutput bool , noDeletes bool ,
135135) error {
136136 // read target file
137137 if enableJSONOutput {
@@ -157,6 +157,13 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
157157 }
158158
159159 cmd := "sync"
160+
161+ isPartialApply := false
162+ if noDeletes {
163+ cmd = "apply"
164+ isPartialApply = true
165+ }
166+
160167 if dry {
161168 cmd = "diff"
162169 }
@@ -202,14 +209,31 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
202209 // load Kong version after workspace
203210 var kongVersion string
204211 var parsedKongVersion semver.Version
212+ isLicensedKongEnterprise := false
205213 if mode == modeKonnect {
206214 kongVersion = fetchKonnectKongVersion ()
215+ isLicensedKongEnterprise = true
207216 } else {
208217 kongVersion , err = fetchKongVersion (ctx , wsConfig )
209218 if err != nil {
210219 return fmt .Errorf ("reading Kong version: %w" , err )
211220 }
221+
222+ // Are we running enterprise?
223+ v , err := kong .ParseSemanticVersion (kongVersion )
224+ if err != nil {
225+ return fmt .Errorf ("parsing Kong version: %w" , err )
226+ }
227+
228+ // Check if there's an active license for Consumer Group checks
229+ if v .IsKongGatewayEnterprise () {
230+ isLicensedKongEnterprise , err = isLicensed (ctx , wsConfig )
231+ if err != nil {
232+ return fmt .Errorf ("checking if Kong is licensed: %w" , err )
233+ }
234+ }
212235 }
236+
213237 parsedKongVersion , err = reconcilerUtils .ParseKongVersion (kongVersion )
214238 if err != nil {
215239 return fmt .Errorf ("parsing Kong version: %w" , err )
@@ -248,21 +272,24 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
248272 return err
249273 }
250274
251- dumpConfig .LookUpSelectorTagsConsumerGroups , err = determineLookUpSelectorTagsConsumerGroups (* targetContent )
252- if err != nil {
253- return fmt .Errorf ("error determining lookup selector tags for consumer groups: %w" , err )
254- }
255-
256- if dumpConfig .LookUpSelectorTagsConsumerGroups != nil {
257- consumerGroupsGlobal , err := dump .GetAllConsumerGroups (ctx , kongClient , dumpConfig .LookUpSelectorTagsConsumerGroups )
275+ // Consumer groups are an enterprise 3.4+ feature
276+ if parsedKongVersion .GTE (reconcilerUtils .Kong340Version ) && isLicensedKongEnterprise {
277+ dumpConfig .LookUpSelectorTagsConsumerGroups , err = determineLookUpSelectorTagsConsumerGroups (* targetContent )
258278 if err != nil {
259- return fmt .Errorf ("error retrieving global consumer groups via lookup selector tags: %w" , err )
279+ return fmt .Errorf ("error determining lookup selector tags for consumer groups : %w" , err )
260280 }
261- for _ , c := range consumerGroupsGlobal {
262- targetContent . ConsumerGroups = append ( targetContent . ConsumerGroups ,
263- file. FConsumerGroupObject { ConsumerGroup : * c . ConsumerGroup } )
281+
282+ if dumpConfig . LookUpSelectorTagsConsumerGroups != nil || isPartialApply {
283+ consumerGroupsGlobal , err := dump . GetAllConsumerGroups ( ctx , kongClient , dumpConfig . LookUpSelectorTagsConsumerGroups )
264284 if err != nil {
265- return fmt .Errorf ("error adding global consumer group %v: %w" , * c .ConsumerGroup .Name , err )
285+ return fmt .Errorf ("error retrieving global consumer groups via lookup selector tags: %w" , err )
286+ }
287+ for _ , c := range consumerGroupsGlobal {
288+ targetContent .ConsumerGroups = append (targetContent .ConsumerGroups ,
289+ file.FConsumerGroupObject {ConsumerGroup : * c .ConsumerGroup })
290+ if err != nil {
291+ return fmt .Errorf ("error adding global consumer group %v: %w" , * c .ConsumerGroup .Name , err )
292+ }
266293 }
267294 }
268295 }
@@ -272,7 +299,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
272299 return fmt .Errorf ("error determining lookup selector tags for consumers: %w" , err )
273300 }
274301
275- if dumpConfig .LookUpSelectorTagsConsumers != nil {
302+ if dumpConfig .LookUpSelectorTagsConsumers != nil || isPartialApply {
276303 consumersGlobal , err := dump .GetAllConsumers (ctx , kongClient , dumpConfig .LookUpSelectorTagsConsumers )
277304 if err != nil {
278305 return fmt .Errorf ("error retrieving global consumers via lookup selector tags: %w" , err )
@@ -290,7 +317,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
290317 return fmt .Errorf ("error determining lookup selector tags for routes: %w" , err )
291318 }
292319
293- if dumpConfig .LookUpSelectorTagsRoutes != nil {
320+ if dumpConfig .LookUpSelectorTagsRoutes != nil || isPartialApply {
294321 routesGlobal , err := dump .GetAllRoutes (ctx , kongClient , dumpConfig .LookUpSelectorTagsRoutes )
295322 if err != nil {
296323 return fmt .Errorf ("error retrieving global routes via lookup selector tags: %w" , err )
@@ -308,7 +335,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
308335 return fmt .Errorf ("error determining lookup selector tags for services: %w" , err )
309336 }
310337
311- if dumpConfig .LookUpSelectorTagsServices != nil {
338+ if dumpConfig .LookUpSelectorTagsServices != nil || isPartialApply {
312339 servicesGlobal , err := dump .GetAllServices (ctx , kongClient , dumpConfig .LookUpSelectorTagsServices )
313340 if err != nil {
314341 return fmt .Errorf ("error retrieving global services via lookup selector tags: %w" , err )
@@ -373,7 +400,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
373400 }
374401
375402 totalOps , err := performDiff (
376- ctx , currentState , targetState , dry , parallelism , delay , kongClient , mode == modeKonnect , enableJSONOutput )
403+ ctx , currentState , targetState , dry , parallelism , delay , kongClient , mode == modeKonnect , enableJSONOutput , noDeletes )
377404 if err != nil {
378405 if enableJSONOutput {
379406 var errs reconcilerUtils.ErrArray
@@ -502,7 +529,7 @@ func fetchCurrentState(ctx context.Context, client *kong.Client, dumpConfig dump
502529
503530func performDiff (ctx context.Context , currentState , targetState * state.KongState ,
504531 dry bool , parallelism int , delay int , client * kong.Client , isKonnect bool ,
505- enableJSONOutput bool ,
532+ enableJSONOutput bool , noDeletes bool ,
506533) (int , error ) {
507534 s , err := diff .NewSyncer (diff.SyncerOpts {
508535 CurrentState : currentState ,
@@ -511,6 +538,7 @@ func performDiff(ctx context.Context, currentState, targetState *state.KongState
511538 StageDelaySec : delay ,
512539 NoMaskValues : noMaskValues ,
513540 IsKonnect : isKonnect ,
541+ NoDeletes : noDeletes ,
514542 })
515543 if err != nil {
516544 return 0 , err
@@ -542,6 +570,31 @@ func performDiff(ctx context.Context, currentState, targetState *state.KongState
542570 return int (totalOps ), nil
543571}
544572
573+ func isLicensed (ctx context.Context , config reconcilerUtils.KongClientConfig ) (bool , error ) {
574+ client , err := reconcilerUtils .GetKongClient (config )
575+ if err != nil {
576+ return false , err
577+ }
578+
579+ req , err := http .NewRequest ("GET" ,
580+ reconcilerUtils .CleanAddress (config .Address )+ "/" ,
581+ nil )
582+ if err != nil {
583+ return false , err
584+ }
585+ var resp map [string ]interface {}
586+ _ , err = client .Do (ctx , req , & resp )
587+ if err != nil {
588+ return false , err
589+ }
590+ _ , ok := resp ["license" ]
591+ if ! ok {
592+ return false , nil
593+ }
594+
595+ return true , nil
596+ }
597+
545598func fetchKongVersion (ctx context.Context , config reconcilerUtils.KongClientConfig ) (string , error ) {
546599 var version string
547600
0 commit comments