Skip to content
Merged
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
38 changes: 38 additions & 0 deletions pkg/common/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,44 @@ func NormalizePlatformName(platform string) string {
return p
}

// Canonical tokens returned by NormalizeScopeName.
const (
ScopeRegional = "regional"
ScopeZonal = "zonal"
)

// NormalizeTenancyName normalizes an EC2 tenancy for comparison. "shared" is
// the operator spelling of the API value "default"; "dedicated" and "host" stay
// distinct. Unrecognized input returns "" (unknown, a wildcard). Mirrors the
// accepted inputs of parseEC2Tenancy in providers/aws/services/ec2/client.go,
// which pkg cannot import.
func NormalizeTenancyName(tenancy string) string {
switch t := strings.ToLower(strings.TrimSpace(tenancy)); t {
case "default", "shared":
return "default"
case "dedicated", "host":
return t
default:
return ""
}
}

// NormalizeScopeName normalizes an EC2 reservation scope to ScopeRegional or
// ScopeZonal. Unrecognized input returns "" (unknown, a wildcard). Mirrors
// parseEC2Scope in providers/aws/services/ec2/client.go ("Region",
// "Availability Zone", and the hyphenated legacy spelling), which pkg cannot
// import.
func NormalizeScopeName(scope string) string {
switch strings.ToLower(strings.TrimSpace(scope)) {
case "region", "regional":
return ScopeRegional
case "availability zone", "availability-zone", "zonal":
return ScopeZonal
default:
return ""
}
}

// EngineFilterKey returns the value the --include-engines/--exclude-engines
// filters compare against, and the normalizer to apply to each filter entry.
// Databases and caches use their engine; compute (EC2) uses its platform,
Expand Down
35 changes: 35 additions & 0 deletions pkg/common/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,38 @@ func TestEngineFromDetails(t *testing.T) {
})
}
}

func TestNormalizeTenancyName(t *testing.T) {
t.Parallel()

tests := []struct{ in, want string }{
{"default", "default"},
{"Shared", "default"},
{" SHARED ", "default"},
{"Dedicated", "dedicated"},
{"host", "host"},
{"Bogus", ""},
{"", ""},
}
for _, tt := range tests {
assert.Equal(t, tt.want, NormalizeTenancyName(tt.in), "input %q", tt.in)
}
}

func TestNormalizeScopeName(t *testing.T) {
t.Parallel()

tests := []struct{ in, want string }{
{"Region", ScopeRegional},
{"regional", ScopeRegional},
{" REGIONAL ", ScopeRegional},
{"Availability Zone", ScopeZonal},
{"availability-zone", ScopeZonal},
{"Zonal", ScopeZonal},
{"", ""},
{"Bogus", ""},
}
for _, tt := range tests {
assert.Equal(t, tt.want, NormalizeScopeName(tt.in), "input %q", tt.in)
}
}
8 changes: 8 additions & 0 deletions pkg/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,14 @@ type Commitment struct {
// means StartDate is a precise timestamp; true means the real instant
// lies in [StartDate, StartDate+24h).
StartDateIsDay bool `json:"start_date_is_day,omitempty"`

// EC2 reserved-instance dimensions. Empty means unknown or a wildcard.
// Filled by the EC2 commitment listing from the reserved instance's
// product description, tenancy, scope and availability zone.
Platform string `json:"platform,omitempty"`
Tenancy string `json:"tenancy,omitempty"`
Scope string `json:"scope,omitempty"`
AvailabilityZone string `json:"availability_zone,omitempty"`
}

// OfferingDetails represents cloud provider offering details.
Expand Down
22 changes: 22 additions & 0 deletions pkg/common/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,3 +598,25 @@ func TestCommitment_StartDateIsDayJSON(t *testing.T) {
require.NoError(t, err)
assert.Contains(t, string(b), `"start_date_is_day":true`)
}

func TestCommitment_EC2DimensionsJSON(t *testing.T) {
empty, err := json.Marshal(Commitment{})
require.NoError(t, err)
for _, key := range []string{`"platform"`, `"tenancy"`, `"scope"`, `"availability_zone"`} {
assert.NotContains(t, string(empty), key)
}

in := Commitment{Platform: "Linux/UNIX", Tenancy: "default", Scope: "Availability Zone", AvailabilityZone: "us-east-1a"}
raw, err := json.Marshal(in)
require.NoError(t, err)
assert.Contains(t, string(raw), `"availability_zone":"us-east-1a"`)
var out Commitment
require.NoError(t, json.Unmarshal(raw, &out))
assert.Equal(t, in, out)

var old Commitment
require.NoError(t, json.Unmarshal([]byte(`{"provider":"aws","commitment_id":"ri-1","count":2}`), &old))
assert.Equal(t, "ri-1", old.CommitmentID)
assert.Empty(t, old.Platform)
assert.Empty(t, old.AvailabilityZone)
}
Loading