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 Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
# SPDX-FileCopyrightText: (C) 2026 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

SUBPROJECTS := apiv2 tenant-controller exporters-inventory inventory
Expand Down
2 changes: 1 addition & 1 deletion inventory/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.35.1
2.35.2-dev
29 changes: 19 additions & 10 deletions inventory/internal/store/util.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: (C) 2025 Intel Corporation
// SPDX-FileCopyrightText: (C) 2026 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

package store
Expand Down Expand Up @@ -51,12 +52,22 @@ const (
PutString = "PUT"
)

const (
MetadataKeyNameMaxLength = 63
MetadataKeyPrefixMaxLength = 253

// MetadataValueMaxLength was previously set to 63, but it was increased to 4096 to allow for
// additional use cases such as kubeconfig data in the value of the metadata.
MetadataValueMaxLength = 4096
)

// MetadataPatternKey representing the metadata pattern for key.
var MetadataPatternKey = regexp.MustCompile(
"^$|^[a-z.]+/$|^[a-z.]+/[a-z0-9][a-z0-9-_.]*[a-z0-9]$|^[a-z.]+/[a-z0-9]$|^[a-z]$|^[a-z0-9][a-z0-9-_.]*[a-z0-9]$")

// MetadataPatternValue representing the metadata pattern for value.
var MetadataPatternValue = regexp.MustCompile("^$|^[a-z0-9]$|^[a-z0-9][a-z0-9+._-]*[a-z0-9]$")
// Relaxed pattern to allow for base64 strings, which can be used for encoding kubeconfigs in metadata values.
var MetadataPatternValue = regexp.MustCompile("^$|^[a-z0-9]$|^[a-z0-9][a-z0-9+._-]*[a-z0-9]$|^[A-Za-z0-9+/]*={0,2}$")

// Metadata struct representing the JSON metadata.
type Metadata struct {
Expand Down Expand Up @@ -109,10 +120,8 @@ func ParseMetadata(metadata string) (map[string]string, error) {
return metaMap, nil
}

//nolint:cyclop // calculated cyclomatic complexity for func is 11, max is 10
//nolint:cyclop,nolintlint // calculated cyclomatic complexity for func is 11, max is 10
func validateKeyValue(meta []Metadata) error {
maxMetaKeyNameLen, maxMetaValueLen, maxMetaKeyPrefixLen := 63, 63, 253

for _, rmetadata := range meta {
if rmetadata.Key != "" {
if !MetadataPatternKey.MatchString(rmetadata.Key) {
Expand All @@ -122,17 +131,17 @@ func validateKeyValue(meta []Metadata) error {
// max prefix len: 253 max name len:63
if strings.Contains(rmetadata.Key, `/`) {
prefixname := strings.Split(rmetadata.Key, "/")
if len(prefixname[0]) > maxMetaKeyPrefixLen ||
len(prefixname[1]) > maxMetaKeyNameLen {
if len(prefixname[0]) > MetadataKeyPrefixMaxLength ||
len(prefixname[1]) > MetadataKeyNameMaxLength {
return errors.Errorfc(codes.InvalidArgument, "Invalid length of metadata key")
}
} else if len(rmetadata.Key) > maxMetaKeyNameLen { // meta data key pattern with name
} else if len(rmetadata.Key) > MetadataKeyNameMaxLength { // meta data key pattern with name
return errors.Errorfc(codes.InvalidArgument, "Invalid length of metadata key")
}
}
if rmetadata.Value != "" {
if len(rmetadata.Value) > maxMetaValueLen {
return errors.Errorfc(codes.InvalidArgument, "Invalid length of metadata value")
if len(rmetadata.Value) > MetadataValueMaxLength {
return errors.Errorfc(codes.InvalidArgument, "Label value too long")
}
if !MetadataPatternValue.MatchString(rmetadata.Value) {
return errors.Errorfc(codes.InvalidArgument, "Invalid metadata value")
Expand Down
50 changes: 23 additions & 27 deletions inventory/internal/store/util_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// SPDX-FileCopyrightText: (C) 2025 Intel Corporation
// SPDX-FileCopyrightText: (C) 2026 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

package store_test

import (
"strings"
"testing"

"github.com/goccy/go-json"
Expand All @@ -14,14 +16,9 @@ import (
telemetry_v1 "github.com/open-edge-platform/infra-core/inventory/v2/pkg/api/telemetry/v1"
)

type Metadata struct {
Key string `json:"key"`
Value string `json:"value"`
}

var (
// valid metadata key and value.
Metadata1 = []Metadata{
Metadata1 = []store.Metadata{
{
Key: "cluster.orchestration.io/cluster-id",
Value: "clusterid-1234",
Expand Down Expand Up @@ -75,50 +72,50 @@ var (
`"example.com/2-test_9":"123test-other.symbol_123","example.com/8":"12","example.com/a":"v",` +
`"example.com/a9_9":"12","k":"v","test.com/test-123_name.test":"123test-other.symbol_123"}`
// invalid metadata key with upper case char.
Metadata2 = []Metadata{
Metadata2 = []store.Metadata{
{
Key: "Cluster-id",
Value: "clusterid-1234",
},
}
// invalid metadata key no prefix.
Metadata3 = []Metadata{
Metadata3 = []store.Metadata{
{
Key: "/cluster-id",
Value: "clusterid-1234",
},
}
// invalid metadata key with upper case char at end.
Metadata4 = []Metadata{
Metadata4 = []store.Metadata{
{
Key: "cluster-ID",
Value: "clusterid-1234",
},
}
// invalid metadata value with upper case char at begin.
Metadata5 = []Metadata{
Metadata5 = []store.Metadata{
{
Key: "cluster-id",
Value: "Clusterid-test",
},
}

// invalid meatadata value length > 63.
Metadata6 = []Metadata{
// invalid meatadata value length.
Metadata6 = []store.Metadata{
{
Key: "cluster-id",
Value: "invalidvaluelengthinvalidvaluelengthinvalidvaluelengthinvalidval",
Value: strings.Repeat("a", store.MetadataValueMaxLength+1),
},
}
// invalid metadata key( name )length > 63.
Metadata7 = []Metadata{
Metadata7 = []store.Metadata{
{
Key: "cluster.com/invalidkeylengthinvalidkeylengthinvalidkeylengthinvalidkeylength",
Value: "clusterid-1234",
},
}
// invalid prefix length > 253.
Metadata8 = []Metadata{
Metadata8 = []store.Metadata{
{
Key: `invalidprefixlengthinvalidprefixlengthinvalidprefixlengthinvalidprefix
lengthinvalidprefixlengthinvalidprefixlengthinvalidprefixlengthinvalidprefix
Expand All @@ -128,41 +125,42 @@ var (
},
}
// invalid metadata key with prefix upper case char.
Metadata9 = []Metadata{
Metadata9 = []store.Metadata{
{
Key: "Test.com/id",
Value: "test",
},
}
// invalid metadata key with other symbol at last.
Metadata10 = []Metadata{
Metadata10 = []store.Metadata{
{
Key: "test1234-",
Value: "test",
},
}
// invalid metadata key with other symbol at begin.
Metadata11 = []Metadata{
Metadata11 = []store.Metadata{
{
Key: "_test1234",
Value: "test",
},
}
// invalid metadata key name with other symbol at begin.
Metadata12 = []Metadata{
Metadata12 = []store.Metadata{
{
Key: "test.com/-",
Value: "test",
},
}
// invalid metadata key name othersymbol at last.
Metadata13 = []Metadata{
Metadata13 = []store.Metadata{
{
Key: "test.com/1a_",
Value: "0123456789",
},
} // invalid metadata key name upper case.
Metadata14 = []Metadata{
}
// invalid metadata key name upper case.
Metadata14 = []store.Metadata{
{
Key: "test.com/A",
Value: "0123456789",
Expand All @@ -172,7 +170,7 @@ var (

func Test_ValidateMetadata(t *testing.T) {
testcases := map[string]struct {
in []Metadata
in []store.Metadata
valid bool
}{
"ValidMetadatakeyAndValue": {in: Metadata1, valid: true},
Expand Down Expand Up @@ -225,8 +223,6 @@ func Test_ValidateOSMetadata(t *testing.T) {
"InValidMetadatakeyWithUppercaseChar": {in: helperMetadataToJSONPlain(t, Metadata2), valid: false},
"InValidMetadatakeyNameNoPrefix": {in: helperMetadataToJSONPlain(t, Metadata3), valid: false},
"InValidMetadatakeyWithUppercaseLastChar": {in: helperMetadataToJSONPlain(t, Metadata4), valid: false},
"InValidMetadataValueWithUppercaseChar": {in: helperMetadataToJSONPlain(t, Metadata5), valid: false},
"InValidMetadataValueLength": {in: helperMetadataToJSONPlain(t, Metadata6), valid: false},
"InValidMetadataKeyNameLength": {in: helperMetadataToJSONPlain(t, Metadata7), valid: false},
"InValidMetadataKeyPrefixLength": {in: helperMetadataToJSONPlain(t, Metadata8), valid: false},
"InValidMetadataKeyPrefixUppercaseChar": {in: helperMetadataToJSONPlain(t, Metadata9), valid: false},
Expand Down Expand Up @@ -259,7 +255,7 @@ func Test_ValidateOSMetadata(t *testing.T) {
}
}

func helperMetadataToJSONPlain(t *testing.T, metadata []Metadata) string {
func helperMetadataToJSONPlain(t *testing.T, metadata []store.Metadata) string {
t.Helper()

result := make(map[string]string)
Expand Down
Loading