Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v16] Workload ID: Introduce basic rule condition operators (#50940) #50979

Merged
merged 2 commits into from
Jan 13, 2025
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
556 changes: 457 additions & 99 deletions api/gen/proto/go/teleport/workloadidentity/v1/resource.pb.go

Large diffs are not rendered by default.

38 changes: 36 additions & 2 deletions api/proto/teleport/workloadidentity/v1/resource.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,46 @@ message WorkloadIdentity {
WorkloadIdentitySpec spec = 5;
}

// The attribute casted to a string must be equal to the value.
message WorkloadIdentityConditionEq {
// The value to compare the attribute against.
string value = 1;
}

// The attribute casted to a string must not be equal to the value.
message WorkloadIdentityConditionNotEq {
// The value to compare the attribute against.
string value = 1;
}

// The attribute casted to a string must be in the list of values.
message WorkloadIdentityConditionIn {
// The list of values to compare the attribute against.
repeated string values = 1;
}

// The attribute casted to a string must not be in the list of values.
message WorkloadIdentityConditionNotIn {
// The list of values to compare the attribute against.
repeated string values = 1;
}

// The individual conditions that make up a rule.
message WorkloadIdentityCondition {
reserved 2;
reserved "equals";
// The name of the attribute to evaluate the condition against.
string attribute = 1;
// An exact string that the attribute must match.
string equals = 2;
oneof operator {
// The attribute casted to a string must be equal to the value.
WorkloadIdentityConditionEq eq = 3;
// The attribute casted to a string must not be equal to the value.
WorkloadIdentityConditionNotEq not_eq = 4;
// The attribute casted to a string must be in the list of values.
WorkloadIdentityConditionIn in = 5;
// The attribute casted to a string must not be in the list of values.
WorkloadIdentityConditionNotIn not_in = 6;
}
}

// An individual rule that is evaluated during the issuance of a WorkloadIdentity.
Expand Down
39 changes: 39 additions & 0 deletions api/types/resource_153.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"encoding/json"
"time"

"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"

headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
Expand Down Expand Up @@ -119,6 +121,10 @@ func (r *legacyToResource153Adapter) GetVersion() string {
// Resource153ToLegacy transforms an RFD 153 style resource into a legacy
// [Resource] type.
//
// Resources153 implemented by proto-generated structs should use ProtoResource153ToLegacy
// instead as it will ensure the protobuf message is properly marshaled to JSON
// with protojson.
//
// Note that CheckAndSetDefaults is a noop for the returned resource and
// SetSubKind is not implemented and panics on use.
func Resource153ToLegacy(r Resource153) Resource {
Expand Down Expand Up @@ -293,3 +299,36 @@ func (r *resource153ToResourceWithLabelsAdapter) MatchSearch(searchValues []stri
fieldVals := append(utils.MapToStrings(r.GetAllLabels()), r.GetName())
return MatchSearch(fieldVals, searchValues, nil)
}

// ProtoResource153 is a Resource153 implemented by a protobuf-generated struct.
type ProtoResource153 interface {
Resource153
proto.Message
}

type protoResource153ToLegacyAdapter struct {
inner ProtoResource153
resource153ToLegacyAdapter
}

// MarshalJSON adds support for marshaling the wrapped resource (instead of
// marshaling the adapter itself).
func (r *protoResource153ToLegacyAdapter) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
UseProtoNames: true,
}.Marshal(r.inner)
}

// ProtoResource153ToLegacy transforms an RFD 153 style resource implemented by
// a proto-generated struct into a legacy [Resource] type. Implements
// [ResourceWithLabels] and CloneResource (where the wrapped resource supports
// cloning).
//
// Note that CheckAndSetDefaults is a noop for the returned resource and
// SetSubKind is not implemented and panics on use.
func ProtoResource153ToLegacy(r ProtoResource153) Resource {
return &protoResource153ToLegacyAdapter{
r,
resource153ToLegacyAdapter{r},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,38 @@ Optional:
Optional:

- `attribute` (String) The name of the attribute to evaluate the condition against.
- `equals` (String) An exact string that the attribute must match.
- `eq` (Attributes) The attribute casted to a string must be equal to the value. (see [below for nested schema](#nested-schema-for-specrulesallowconditionseq))
- `in` (Attributes) The attribute casted to a string must be in the list of values. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsin))
- `not_eq` (Attributes) The attribute casted to a string must not be equal to the value. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsnot_eq))
- `not_in` (Attributes) The attribute casted to a string must not be in the list of values. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsnot_in))

### Nested Schema for `spec.rules.allow.conditions.eq`

Optional:

- `value` (String) The value to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.in`

Optional:

- `values` (List of String) The list of values to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.not_eq`

Optional:

- `value` (String) The value to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.not_in`

Optional:

- `values` (List of String) The list of values to compare the attribute against.




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ resource "teleport_workload_identity" "example" {
{
conditions = [{
attribute = "user.name"
equals = "noah"
eq = {
value = "my-user"
}
}]
}
]
Expand Down Expand Up @@ -80,7 +82,38 @@ Optional:
Optional:

- `attribute` (String) The name of the attribute to evaluate the condition against.
- `equals` (String) An exact string that the attribute must match.
- `eq` (Attributes) The attribute casted to a string must be equal to the value. (see [below for nested schema](#nested-schema-for-specrulesallowconditionseq))
- `in` (Attributes) The attribute casted to a string must be in the list of values. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsin))
- `not_eq` (Attributes) The attribute casted to a string must not be equal to the value. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsnot_eq))
- `not_in` (Attributes) The attribute casted to a string must not be in the list of values. (see [below for nested schema](#nested-schema-for-specrulesallowconditionsnot_in))

### Nested Schema for `spec.rules.allow.conditions.eq`

Optional:

- `value` (String) The value to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.in`

Optional:

- `values` (List of String) The list of values to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.not_eq`

Optional:

- `value` (String) The value to compare the attribute against.


### Nested Schema for `spec.rules.allow.conditions.not_in`

Optional:

- `values` (List of String) The list of values to compare the attribute against.




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ resource "teleport_workload_identity" "example" {
{
conditions = [{
attribute = "user.name"
equals = "noah"
eq = {
value = "my-user"
}
}]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ resource "teleport_workload_identity" "test" {
{
conditions = [{
attribute = "user.name"
equals = "foo"
eq = {
value = "foo"
}
}]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ resource "teleport_workload_identity" "test" {
{
conditions = [{
attribute = "user.name"
equals = "foo"
eq = {
value = "foo"
}
}]
}
]
Expand Down
12 changes: 8 additions & 4 deletions integrations/terraform/testlib/workload_identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (s *TerraformSuiteOSS) TestWorkloadIdentity() {
resource.TestCheckResourceAttr(name, "kind", "workload_identity"),
resource.TestCheckResourceAttr(name, "spec.spiffe.id", "/test"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.attribute", "user.name"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.equals", "foo"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.eq.value", "foo"),
),
},
{
Expand All @@ -68,7 +68,7 @@ func (s *TerraformSuiteOSS) TestWorkloadIdentity() {
resource.TestCheckResourceAttr(name, "kind", "workload_identity"),
resource.TestCheckResourceAttr(name, "spec.spiffe.id", "/test/updated"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.attribute", "user.name"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.equals", "foo"),
resource.TestCheckResourceAttr(name, "spec.rules.allow.0.conditions.0.eq.value", "foo"),
),
},
{
Expand Down Expand Up @@ -101,7 +101,11 @@ func (s *TerraformSuiteOSS) TestImportWorkloadIdentity() {
Conditions: []*workloadidentityv1pb.WorkloadIdentityCondition{
{
Attribute: "user.name",
Equals: "foo",
Operator: &workloadidentityv1pb.WorkloadIdentityCondition_Eq{
Eq: &workloadidentityv1pb.WorkloadIdentityConditionEq{
Value: "foo",
},
},
},
},
},
Expand Down Expand Up @@ -133,7 +137,7 @@ func (s *TerraformSuiteOSS) TestImportWorkloadIdentity() {
require.Equal(t, types.KindWorkloadIdentity, state[0].Attributes["kind"])
require.Equal(t, "/test", state[0].Attributes["spec.spiffe.id"])
require.Equal(t, "user.name", state[0].Attributes["spec.rules.allow.0.conditions.0.attribute"])
require.Equal(t, "foo", state[0].Attributes["spec.rules.allow.0.conditions.0.equals"])
require.Equal(t, "foo", state[0].Attributes["spec.rules.allow.0.conditions.0.eq.value"])

return nil
},
Expand Down
Loading
Loading