Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion internal/cac/storage/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"path/filepath"

"github.com/cloudentity/cac/internal/cac/templates"
"github.com/cloudentity/cac/internal/cac/utils"
ccyaml "github.com/goccy/go-yaml"

Check failure on line 9 in internal/cac/storage/reader.go

View workflow job for this annotation

GitHub Actions / test

"github.com/goccy/go-yaml" imported as ccyaml and not used

Check failure on line 9 in internal/cac/storage/reader.go

View workflow job for this annotation

GitHub Actions / golangci

"github.com/goccy/go-yaml" imported as ccyaml and not used) (typecheck)

Check failure on line 9 in internal/cac/storage/reader.go

View workflow job for this annotation

GitHub Actions / golangci

"github.com/goccy/go-yaml" imported as ccyaml and not used) (typecheck)

Check failure on line 9 in internal/cac/storage/reader.go

View workflow job for this annotation

GitHub Actions / golangci

"github.com/goccy/go-yaml" imported as ccyaml and not used) (typecheck)

Check failure on line 9 in internal/cac/storage/reader.go

View workflow job for this annotation

GitHub Actions / golangci

"github.com/goccy/go-yaml" imported as ccyaml and not used (typecheck)
"github.com/pkg/errors"
"golang.org/x/exp/slog"
)
Expand Down Expand Up @@ -44,7 +45,7 @@
slog.Debug("read template", "path", path, "data", bts)


if err = ccyaml.Unmarshal(bts, &out); err != nil {
if out, err = utils.FromYaml(bts); err != nil {
return out, errors.Wrapf(err, "failed to unmarshal template %s", path)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/cac/storage/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func createMultilineIncludeTemplate(str string, indent int) string {

var multilineTemplateRegexp = regexp.MustCompile(`⌘⌘(\d+) ([^⌘]+)⌘⌘`)

func postProcessMultilineTemplates(bts []byte) []byte {
func postProcessMultilineTemplates(bts []byte) []byte {
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Extra whitespace between 'func' and function name. This appears to be unintended formatting noise. The tab character should be removed to maintain consistent code formatting.

Suggested change
func postProcessMultilineTemplates(bts []byte) []byte {
func postProcessMultilineTemplates(bts []byte) []byte {

Copilot uses AI. Check for mistakes.
bts = multilineTemplateRegexp.ReplaceAll(bts, []byte("{{ $2 | nindent $1 }}"))

return bts
Expand Down
2 changes: 1 addition & 1 deletion internal/cac/utils/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Decoder(result any) (*mapstructure.Decoder, error) {

func ConfigureDecoder(config *mapstructure.DecoderConfig) {
config.TagName = "json"
config.WeaklyTypedInput = true
config.WeaklyTypedInput = false
config.DecodeHook = mapstructure.ComposeDecodeHookFunc(urlDecoder(), timeDecoder(), stringToSlice())
}

Expand Down
41 changes: 41 additions & 0 deletions internal/cac/utils/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,44 @@ func TestFilterPatch(t *testing.T) {
})
}
}

func TestMappingNumbersToModel(t *testing.T) {
patch := models.Rfc7396PatchOperation{
"policies": map[string]any{
"p1": map[string]any{
"validators": []any{
map[string]any{
"conf": map[string]any{
"max_x": 3,
},
},
},
},
},
}

result, err := utils.FromPatchToModel[models.TreeServer](patch)

require.NoError(t, err)
require.Equal(t, float64(3), result.Policies["p1"].Validators[0].Conf["max_x"])
}

func TestMappingNumbersToYaml(t *testing.T) {
model := models.TreeServer{
Policies: models.TreePolicies{
"p1": models.TreePolicy{
Validators: []*models.ValidatorConfig{
{
Conf: map[string]any{
"max_x": 3,
},
},
},
},
},
}
patch, err := utils.FromModelToPatch(&model)

require.NoError(t, err)
require.Equal(t, float64(3), patch["policies"].(map[string]any)["p1"].(map[string]any)["validators"].([]any)[0].(map[string]any)["conf"].(map[string]any)["max_x"])
}
15 changes: 15 additions & 0 deletions internal/cac/utils/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
ccyaml "github.com/goccy/go-yaml"
"github.com/pkg/errors"
)

func ToYaml(it any) ([]byte, error) {
Expand All @@ -18,6 +19,7 @@ func ToYaml(it any) ([]byte, error) {
enc := jsontext.NewEncoder(buffer,
json.FormatNilMapAsNull(true),
json.FormatNilSliceAsNull(true),
json.StringifyNumbers(true),
)

if err = json.MarshalEncode(enc, it); err != nil {
Expand All @@ -32,3 +34,16 @@ func ToYaml(it any) ([]byte, error) {

return bts, nil
}

func FromYaml(bts []byte) (map[string]any, error) {
var (
out map[string]any
err error
)

if err = ccyaml.Unmarshal(bts, &out); err != nil {
return out, errors.Wrapf(err, "failed to unmarshal template %s", string(bts))
}

return out, nil
}
32 changes: 32 additions & 0 deletions internal/cac/utils/yaml_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package utils_test

import (
"testing"

"github.com/cloudentity/cac/internal/cac/utils"
"github.com/stretchr/testify/require"
)

func TestDecodingNumbers(t *testing.T) {
patchWithNumbers := []byte(`something:
else: 3`)

yml, err := utils.FromYaml(patchWithNumbers)

require.NoError(t, err)
something, ok := yml["something"].(map[string]any)
require.True(t, ok)
require.Equal(t, uint64(3), something["else"])
}

func TestEncodingNumbers(t *testing.T) {
yml, err := utils.ToYaml(map[string]any{
"something": map[string]any{
"else": 3,
},
})

require.NoError(t, err)
require.YAMLEq(t, `something:
else: 3`, string(yml))
}
Loading