Skip to content

Commit

Permalink
fix(clickhousegrant): remote and local states comparison
Browse files Browse the repository at this point in the history
Unable to compare remote and local states because of unsorted list values.
  • Loading branch information
byashimov committed Jul 10, 2024
1 parent aa12ace commit 956bcdf
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Ignore `http.StatusBadRequest` on `ClickhouseGrant` deletion
- Retry conflict error when k8s object saved to the storage
- Fix `ClickhouseGrant` invalid remote and local privileges comparison

## v0.22.0 - 2024-07-02

Expand Down
44 changes: 32 additions & 12 deletions controllers/clickhousegrant_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ package controllers

import (
"context"
"encoding/json"
"fmt"
"net/http"
"slices"
"strconv"
"strings"

"github.com/aiven/aiven-go-client/v2"
avngen "github.com/aiven/go-client-codegen"
Expand Down Expand Up @@ -158,44 +159,63 @@ func diffClickhouseGrantSpecToApi(specPrivilegeGrants []v1alpha1.PrivilegeGrant,
var roleGrantsToRevoke, roleGrantsToAdd []v1alpha1.RoleGrant

for _, apiGrant := range apiPrivilegeGrants {
if !containsPrivilegeGrant(specPrivilegeGrants, apiGrant) {
if !containsGrant(specPrivilegeGrants, apiGrant) {
privilegeGrantsToRevoke = append(privilegeGrantsToRevoke, apiGrant)
}
}

for _, specGrant := range specPrivilegeGrants {
if !containsPrivilegeGrant(apiPrivilegeGrants, specGrant) {
if !containsGrant(apiPrivilegeGrants, specGrant) {
privilegeGrantsToAdd = append(privilegeGrantsToAdd, specGrant)
}
}

for _, apiGrant := range apiRoleGrants {
if !containsRoleGrant(specRoleGrants, apiGrant) {
if !containsGrant(specRoleGrants, apiGrant) {
roleGrantsToRevoke = append(roleGrantsToRevoke, apiGrant)
}
}

for _, specGrant := range specRoleGrants {
if !containsRoleGrant(apiRoleGrants, specGrant) {
if !containsGrant(apiRoleGrants, specGrant) {
roleGrantsToAdd = append(roleGrantsToAdd, specGrant)
}
}

return privilegeGrantsToRevoke, privilegeGrantsToAdd, roleGrantsToRevoke, roleGrantsToAdd
}

func containsPrivilegeGrant(grants []v1alpha1.PrivilegeGrant, grant chUtils.Grant) bool {
for _, g := range grants {
if cmp.Equal(g, grant) {
return true
// normalizeGrant v1alpha1.PrivilegeGrant and []v1alpha1.RoleGrant
// have array fields with scalars and objects.
// To compare two grants list fields must be sorted
func normalizeGrant(grant any) (result map[string]any) {
b, _ := json.Marshal(grant)
_ = json.Unmarshal(b, &result)
return sortValues(result)
}

func sortValues[T map[string]any](m T) T {
for k, v := range m {
switch val := v.(type) {
case T:
m[k] = sortValues(val)
case []any:
sorted := make([]string, len(val))
for i, s := range val {
sorted[i] = fmt.Sprintf("%v", s)
}

slices.Sort(sorted)
m[k] = sorted
}
}
return false
return m
}

func containsRoleGrant(grants []v1alpha1.RoleGrant, grant v1alpha1.RoleGrant) bool {
func containsGrant[T any](grants []T, grant T) bool {
s := normalizeGrant(grant)
for _, g := range grants {
if cmp.Equal(g, grant) {
if cmp.Equal(s, normalizeGrant(g)) {
return true
}
}
Expand Down

0 comments on commit 956bcdf

Please sign in to comment.