Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
cmd = "diff"
}

dumpConfig.SkipHashForBasicAuth = determineSkipHashForBasicAuth(*targetContent, dumpConfig)

var kongClient *kong.Client
mode := getMode(targetContent)
if mode == modeKonnect {
Expand Down Expand Up @@ -210,6 +212,10 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
dumpConfig.KonnectControlPlane = konnectControlPlane
}

if dumpConfig.SkipHashForBasicAuth && mode != modeKonnect {
return errors.New("skip-hash-for-basic-auth functionality can be used with Konnect only")
}

rootClient, err := reconcilerUtils.GetKongClient(rootConfig)
if err != nil {
return err
Expand Down Expand Up @@ -513,6 +519,18 @@ func determinePolicyOverride(targetContent file.Content, config dump.Config) boo
return false
}

func determineSkipHashForBasicAuth(targetContent file.Content, config dump.Config) bool {
if config.SkipHashForBasicAuth {
return true
}

if targetContent.Info != nil && targetContent.Info.SkipHashForBasicAuth {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this block necessary? 🤔

return targetContent.Info.SkipHashForBasicAuth
}

return false
}

func determineLookUpSelectorTagsConsumerGroups(targetContent file.Content) ([]string, error) {
if targetContent.Info != nil &&
targetContent.Info.LookUpSelectorTags != nil &&
Expand Down
3 changes: 3 additions & 0 deletions cmd/gateway_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func newApplyCmd() *cobra.Command {
0, "artificial delay (in seconds) that is injected between insert operations \n"+
"for related entities (usually for Cassandra deployments).\n"+
"See `db_update_propagation` in kong.conf.")
applyCmd.Flags().BoolVar(&dumpConfig.SkipHashForBasicAuth, "skip-hash-for-basic-auth",
false, "do not sync hash for basic auth credentials.\n"+
"This flag is only valid with Konnect.")
applyCmd.Flags().BoolVar(&syncJSONOutput, "json-output",
false, "generate command execution report in a JSON format")
addSilenceEventsFlag(applyCmd.Flags())
Expand Down
3 changes: 3 additions & 0 deletions cmd/gateway_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ to get Kong's state in sync with the input state.`,
"thus gaining some performance with large configs.\n"+
"Usage of this flag without apt select-tags and default-lookup-tags can be problematic.\n"+
"This flag is not valid with Konnect.")
syncCmd.Flags().BoolVar(&dumpConfig.SkipHashForBasicAuth, "skip-hash-for-basic-auth",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want this flag for gateway apply?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will add

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in cases where the basic auth has been synced before without the flag, using this flag leads to no diff and so no action - that is expected, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. That is expected.
The GET /basic-auth endpoint doesn't have any skip-hash param. So, there's no way of knowing if the returned password is a hash or not. Earlier too we didn't compare for passwords while syncing/diffing. So, I am retaining the same behaviour.

false, "do not sync hash for basic auth credentials.\n"+
"This flag is only valid with Konnect.")
syncCmd.Flags().BoolVar(&syncCmdAssumeYes, "yes",
false, "assume `yes` to prompts and run non-interactively.")
syncCmd.Flags().BoolVar(&syncJSONOutput, "json-output",
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ require (
github.com/fatih/color v1.18.0
github.com/google/go-cmp v0.7.0
github.com/kong/go-apiops v0.2.0
github.com/kong/go-database-reconciler v1.27.1
github.com/kong/go-kong v0.68.0
github.com/kong/go-database-reconciler v1.27.2-0.20250929075510-119315653725
github.com/kong/go-kong v0.69.0
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,12 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kong/go-apiops v0.2.0 h1:QzHmEvl12vr3lxayTuY40dFuQpPECHTvopsILpwuLdE=
github.com/kong/go-apiops v0.2.0/go.mod h1:yPwbl3P2eQinVGAEA0d3legaYmzPJ+WtJf9fSeGF4b8=
github.com/kong/go-database-reconciler v1.27.1 h1:a5EyqQsY5BF2p964J2PQW9BMIMvTz30A2FInIAf1TcA=
github.com/kong/go-database-reconciler v1.27.1/go.mod h1:6EnCqJqkYWwf9UjkiIKXCv29kapPFUBQ2+FVjR9ZslE=
github.com/kong/go-kong v0.68.0 h1:rQrLYRKXD6/xf41GBXj9Ns+woAH9p6a4VvcXNMiPZPI=
github.com/kong/go-kong v0.68.0/go.mod h1:J0vGB3wsZ2i99zly1zTRe3v7rOKpkhQZRwbcTFP76qM=
github.com/kong/go-database-reconciler v1.27.2-0.20250929075001-0b5d637b1d8a h1:Uu3zegR48fHb4gE6OGcfyTb/F1f61Y9VL1Bb3094s1g=
github.com/kong/go-database-reconciler v1.27.2-0.20250929075001-0b5d637b1d8a/go.mod h1:DnqxRK/TH8HugJca1cw2n1NCApaNgpzEZhXUzITU0Ro=
github.com/kong/go-database-reconciler v1.27.2-0.20250929075510-119315653725 h1:/fiWY6JOM6ZXyMvlRCdZ0s9RviCI/5z9dPzk3jT9R84=
github.com/kong/go-database-reconciler v1.27.2-0.20250929075510-119315653725/go.mod h1:DnqxRK/TH8HugJca1cw2n1NCApaNgpzEZhXUzITU0Ro=
github.com/kong/go-kong v0.69.0 h1:1LHU3y+i23X+RxxXT/bKml5bsxeUfKTfWFa3RK85cSU=
github.com/kong/go-kong v0.69.0/go.mod h1:J0vGB3wsZ2i99zly1zTRe3v7rOKpkhQZRwbcTFP76qM=
github.com/kong/go-slugify v1.0.0 h1:vCFAyf2sdoSlBtLcrmDWUFn0ohlpKiKvQfXZkO5vSKY=
github.com/kong/go-slugify v1.0.0/go.mod h1:dbR2h3J2QKXQ1k0aww6cN7o4cIcwlWflr6RKRdcoaiw=
github.com/kong/kubernetes-configuration v1.4.2 h1:/OafLbl2NucvgQV7Xf/uneIgjxmPPUeE92BrssfVAQY=
Expand Down
140 changes: 140 additions & 0 deletions tests/integration/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/kong/go-database-reconciler/pkg/utils"
"github.com/kong/go-kong/kong"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -377,3 +379,141 @@ func Test_Apply_NestedEntities_Konnect(t *testing.T) {
})
}
}

// test scope:
//
// - konnect
func Test_Apply_BasicAuth_SkipHash_Konnect(t *testing.T) {
setDefaultKonnectControlPlane(t)
runWhenKonnect(t)
setup(t)

client, err := getTestClient()
require.NoError(t, err)
ctx := context.Background()

tests := []struct {
name string
kongFile string
updateFile string
cmdArgs []string
expectedState utils.KongRawState
}{
{
name: "skip basic auth hash - via flag",
kongFile: "testdata/sync/047-basic-auth-skip-hash/kong.yaml",
cmdArgs: []string{"--skip-hash-for-basic-auth"},
expectedState: utils.KongRawState{
Consumers: []*kong.Consumer{
{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
Username: kong.String("foo"),
},
},
BasicAuths: []*kong.BasicAuthOptions{
{
BasicAuth: kong.BasicAuth{
Username: kong.String("user1"),
Password: kong.String("76789880fe1b54caf0875cf1f1fbcfd89202468d"),
Consumer: &kong.Consumer{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
},
},
},
},
},
},
{
name: "skip basic auth hash - via info in config",
kongFile: "testdata/sync/047-basic-auth-skip-hash/kong-with-info.yaml",
expectedState: utils.KongRawState{
Consumers: []*kong.Consumer{
{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
Username: kong.String("foo"),
},
},
BasicAuths: []*kong.BasicAuthOptions{
{
BasicAuth: kong.BasicAuth{
Username: kong.String("user1"),
Password: kong.String("76789880fe1b54caf0875cf1f1fbcfd89202468d"),
Consumer: &kong.Consumer{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
},
},
},
},
},
},
{
name: "update basic auth with skip hash flag",
kongFile: "testdata/sync/047-basic-auth-skip-hash/kong.yaml",
updateFile: "testdata/sync/047-basic-auth-skip-hash/kong-update.yaml",
cmdArgs: []string{"--skip-hash-for-basic-auth"},
expectedState: utils.KongRawState{
Consumers: []*kong.Consumer{
{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
Username: kong.String("foo"),
},
},
BasicAuths: []*kong.BasicAuthOptions{
{
BasicAuth: kong.BasicAuth{
Username: kong.String("user1"),
Password: kong.String("76789880fe1b54caf0875cf1f1fbcfd89202468d"),
Consumer: &kong.Consumer{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
},
Tags: kong.StringSlice("tag1", "tag2"),
},
},
},
},
},
{
name: "update basic auth with skip hash in info config",
kongFile: "testdata/sync/047-basic-auth-skip-hash/kong-with-info.yaml",
updateFile: "testdata/sync/047-basic-auth-skip-hash/kong-with-info-update.yaml",
cmdArgs: []string{"--skip-hash-for-basic-auth"},
expectedState: utils.KongRawState{
Consumers: []*kong.Consumer{
{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
Username: kong.String("foo"),
},
},
BasicAuths: []*kong.BasicAuthOptions{
{
BasicAuth: kong.BasicAuth{
Username: kong.String("user1"),
Password: kong.String("76789880fe1b54caf0875cf1f1fbcfd89202468d"),
Consumer: &kong.Consumer{
ID: kong.String("9efa87d1-0f29-4b8b-bf71-b947ddccf100"),
},
Tags: kong.StringSlice("tag1", "tag2"),
},
},
},
},
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
reset(t)

require.NoError(t, apply(ctx, tc.kongFile, tc.cmdArgs...))

if tc.updateFile != "" {
require.NoError(t, apply(ctx, tc.updateFile, tc.cmdArgs...))
}

ignoreFields := []cmp.Option{
cmpopts.IgnoreFields(kong.BasicAuthOptions{}, "ID", "CreatedAt"),
}
testKongState(t, client, true, false, tc.expectedState, ignoreFields)
})
}
}
19 changes: 19 additions & 0 deletions tests/integration/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,22 @@ func Test_Dump_Sanitize_Special_Entities(t *testing.T) {
})
}
}

// test scope:
//
// - konnect
func Test_Dump_BasicAuth_SkipHash(t *testing.T) {
setDefaultKonnectControlPlane(t)
runWhenKonnect(t)
setup(t)

ctx := context.Background()
require.NoError(t, sync(ctx, "testdata/sync/047-basic-auth-skip-hash/kong.yaml", "--skip-hash-for-basic-auth"))

output, err := dump("-o", "-")
require.NoError(t, err)

expected, err := readFile("testdata/sync/047-basic-auth-skip-hash/expected-dump.yaml")
require.NoError(t, err)
assert.Equal(t, expected, output)
}
Loading
Loading