diff --git a/apis/iam/v1beta1/role_types.go b/apis/iam/v1beta1/role_types.go index e9097dcf0d..686fe4aa2b 100644 --- a/apis/iam/v1beta1/role_types.go +++ b/apis/iam/v1beta1/role_types.go @@ -44,6 +44,29 @@ type Tag struct { Value string `json:"value,omitempty"` } +// Contains information about the last time that an IAM role was used. This +// includes the date and time and the Region in which the role was last used. +// Activity is only reported for the trailing 400 days. This period can be shorter +// if your Region began supporting these features within the last year. The role +// might have been used more than 400 days ago. For more information, see Regions +// where data is tracked +// (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period) +// in the IAM User Guide. This data type is returned as a response element in the +// GetRole and GetAccountAuthorizationDetails operations. +type RoleLastUsed struct { + + // The date and time, in ISO 8601 date-time format (http://www.iso.org/iso/iso8601) + // that the role was last used. This field is null if the role has not been used + // within the IAM tracking period. For more information about the tracking period, + // see Regions where data is tracked + // (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period) + // in the IAM User Guide. + LastUsedDate *metav1.Time `json:"lastUsedDate,omitempty"` + + // The name of the Amazon Web Services Region in which the role was last used. + Region *string `json:"region,omitempty"` +} + // RoleParameters define the desired state of an AWS IAM Role. type RoleParameters struct { @@ -98,6 +121,20 @@ type RoleExternalStatus struct { // IDs, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) // in the Using IAM guide. RoleID string `json:"roleID"` + + // The date and time, in ISO 8601 date-time format + // (http://www.iso.org/iso/iso8601), when the role was created. + CreateDate *metav1.Time `json:"createDate,omitempty"` + + // Contains information about the last time that an IAM role was used. This + // includes the date and time and the Region in which the role was last used. + // Activity is only reported for the trailing 400 days. This period can be shorter + // if your Region began supporting these features within the last year. The role + // might have been used more than 400 days ago. For more information, see Regions + // where data is tracked + // (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period) + // in the IAM User Guide. + RoleLastUsed *RoleLastUsed `json:"roleLastUsed,omitempty"` } // A RoleStatus represents the observed state of a Role. diff --git a/apis/iam/v1beta1/zz_generated.deepcopy.go b/apis/iam/v1beta1/zz_generated.deepcopy.go index c3edf5d84f..1091f5bfb7 100644 --- a/apis/iam/v1beta1/zz_generated.deepcopy.go +++ b/apis/iam/v1beta1/zz_generated.deepcopy.go @@ -866,6 +866,15 @@ func (in *Role) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RoleExternalStatus) DeepCopyInto(out *RoleExternalStatus) { *out = *in + if in.CreateDate != nil { + in, out := &in.CreateDate, &out.CreateDate + *out = (*in).DeepCopy() + } + if in.RoleLastUsed != nil { + in, out := &in.RoleLastUsed, &out.RoleLastUsed + *out = new(RoleLastUsed) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleExternalStatus. @@ -878,6 +887,30 @@ func (in *RoleExternalStatus) DeepCopy() *RoleExternalStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoleLastUsed) DeepCopyInto(out *RoleLastUsed) { + *out = *in + if in.LastUsedDate != nil { + in, out := &in.LastUsedDate, &out.LastUsedDate + *out = (*in).DeepCopy() + } + if in.Region != nil { + in, out := &in.Region, &out.Region + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleLastUsed. +func (in *RoleLastUsed) DeepCopy() *RoleLastUsed { + if in == nil { + return nil + } + out := new(RoleLastUsed) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RoleList) DeepCopyInto(out *RoleList) { *out = *in @@ -1114,7 +1147,7 @@ func (in *RoleSpec) DeepCopy() *RoleSpec { func (in *RoleStatus) DeepCopyInto(out *RoleStatus) { *out = *in in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) - out.AtProvider = in.AtProvider + in.AtProvider.DeepCopyInto(&out.AtProvider) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleStatus. diff --git a/package/crds/iam.aws.crossplane.io_roles.yaml b/package/crds/iam.aws.crossplane.io_roles.yaml index 2ea4234f32..88aadf87b4 100644 --- a/package/crds/iam.aws.crossplane.io_roles.yaml +++ b/package/crds/iam.aws.crossplane.io_roles.yaml @@ -299,12 +299,41 @@ spec: in policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) in the IAM User Guide guide. type: string + createDate: + description: The date and time, in ISO 8601 date-time format (http://www.iso.org/iso/iso8601), + when the role was created. + format: date-time + type: string roleID: description: RoleID is the stable and unique string identifying the role. For more information about IDs, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) in the Using IAM guide. type: string + roleLastUsed: + description: Contains information about the last time that an + IAM role was used. This includes the date and time and the Region + in which the role was last used. Activity is only reported for + the trailing 400 days. This period can be shorter if your Region + began supporting these features within the last year. The role + might have been used more than 400 days ago. For more information, + see Regions where data is tracked (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period) + in the IAM User Guide. + properties: + lastUsedDate: + description: The date and time, in ISO 8601 date-time format + (http://www.iso.org/iso/iso8601) that the role was last + used. This field is null if the role has not been used within + the IAM tracking period. For more information about the + tracking period, see Regions where data is tracked (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period) + in the IAM User Guide. + format: date-time + type: string + region: + description: The name of the Amazon Web Services Region in + which the role was last used. + type: string + type: object required: - arn - roleID diff --git a/pkg/clients/iam/role.go b/pkg/clients/iam/role.go index bcefc2e32f..5c6f7e2296 100644 --- a/pkg/clients/iam/role.go +++ b/pkg/clients/iam/role.go @@ -71,10 +71,20 @@ func GenerateCreateRoleInput(name string, p *v1beta1.RoleParameters) *iam.Create // GenerateRoleObservation is used to produce RoleExternalStatus from iamtypes.Role func GenerateRoleObservation(role iamtypes.Role) v1beta1.RoleExternalStatus { - return v1beta1.RoleExternalStatus{ - ARN: aws.ToString(role.Arn), - RoleID: aws.ToString(role.RoleId), + o := v1beta1.RoleExternalStatus{ + ARN: pointer.StringValue(role.Arn), + CreateDate: pointer.TimeToMetaTime(role.CreateDate), + RoleID: pointer.StringValue(role.RoleId), } + + if role.RoleLastUsed != nil { + o.RoleLastUsed = &v1beta1.RoleLastUsed{ + LastUsedDate: pointer.TimeToMetaTime(role.RoleLastUsed.LastUsedDate), + Region: role.RoleLastUsed.Region, + } + } + + return o } // GenerateRole assigns the in RoleParamters to role. @@ -180,7 +190,7 @@ func IsRoleUpToDate(in v1beta1.RoleParameters, observed iamtypes.Role) (bool, st diff := cmp.Diff(desired, &observed, cmpopts.IgnoreInterfaces(struct{ resource.AttributeReferencer }{}), - cmpopts.IgnoreFields(observed, "AssumeRolePolicyDocument", "CreateDate", "PermissionsBoundary.PermissionsBoundaryType"), + cmpopts.IgnoreFields(observed, "AssumeRolePolicyDocument", "CreateDate", "PermissionsBoundary.PermissionsBoundaryType", "RoleLastUsed"), cmpopts.IgnoreTypes(document.NoSerde{}), cmpopts.SortSlices(lessTag)) if diff == "" && policyUpToDate { return true, diff, nil diff --git a/pkg/clients/iam/role_test.go b/pkg/clients/iam/role_test.go index 8b118f5986..bca91c926a 100644 --- a/pkg/clients/iam/role_test.go +++ b/pkg/clients/iam/role_test.go @@ -52,6 +52,7 @@ var ( tagValue = "value" permissionBoundary = "arn:aws:iam::111111111111:policy/permission-boundary" createDate = time.Now() + region = "us-east-1" ) func roleParams(m ...func(*v1beta1.RoleParameters)) *v1beta1.RoleParameters { @@ -93,12 +94,22 @@ func role(m ...func(*iamtypes.Role)) *iamtypes.Role { func addRoleOutputFields(r *iamtypes.Role) { r.Arn = pointer.ToOrNilIfZeroValue(roleARN) r.RoleId = pointer.ToOrNilIfZeroValue(roleID) + r.CreateDate = &createDate + r.RoleLastUsed = &iamtypes.RoleLastUsed{ + LastUsedDate: &createDate, + Region: ®ion, + } } func roleObservation(m ...func(*v1beta1.RoleExternalStatus)) *v1beta1.RoleExternalStatus { o := &v1beta1.RoleExternalStatus{ - ARN: roleARN, - RoleID: roleID, + ARN: roleARN, + RoleID: roleID, + CreateDate: pointer.TimeToMetaTime(&createDate), + RoleLastUsed: &v1beta1.RoleLastUsed{ + LastUsedDate: pointer.TimeToMetaTime(&createDate), + Region: ®ion, + }, } for _, f := range m { @@ -285,6 +296,10 @@ func TestIsRoleUpToDate(t *testing.T) { PermissionsBoundaryArn: &permissionBoundary, PermissionsBoundaryType: "Policy", }, + RoleLastUsed: &iamtypes.RoleLastUsed{ + LastUsedDate: &createDate, + Region: pointer.ToOrNilIfZeroValue("us-east-1"), + }, Tags: []iamtypes.Tag{{ Key: pointer.ToOrNilIfZeroValue("key1"), Value: pointer.ToOrNilIfZeroValue("value1"),