diff --git a/apis/ecs/generator-config.yaml b/apis/ecs/generator-config.yaml index 5d86b39587..6d627255c0 100644 --- a/apis/ecs/generator-config.yaml +++ b/apis/ecs/generator-config.yaml @@ -18,6 +18,14 @@ ignore: resource_names: - CapacityProvider - TaskSet +resources: + Service: + fields: + TaskArns: + is_read_only: true + from: + operation: ListTasks + path: TaskArns operations: DeregisterTaskDefinition: operation_type: diff --git a/apis/ecs/v1alpha1/zz_generated.deepcopy.go b/apis/ecs/v1alpha1/zz_generated.deepcopy.go index d8363d9149..289b53c154 100644 --- a/apis/ecs/v1alpha1/zz_generated.deepcopy.go +++ b/apis/ecs/v1alpha1/zz_generated.deepcopy.go @@ -3592,6 +3592,17 @@ func (in *ServiceObservation) DeepCopyInto(out *ServiceObservation) { *out = new(string) **out = **in } + if in.TaskARNs != nil { + in, out := &in.TaskARNs, &out.TaskARNs + *out = make([]*string, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(string) + **out = **in + } + } + } if in.TaskDefinition != nil { in, out := &in.TaskDefinition, &out.TaskDefinition *out = new(string) diff --git a/apis/ecs/v1alpha1/zz_service.go b/apis/ecs/v1alpha1/zz_service.go index aa13c36b42..440bd8cb8b 100644 --- a/apis/ecs/v1alpha1/zz_service.go +++ b/apis/ecs/v1alpha1/zz_service.go @@ -263,6 +263,8 @@ type ServiceObservation struct { ServiceName *string `json:"serviceName,omitempty"` // The status of the service. The valid values are ACTIVE, DRAINING, or INACTIVE. Status *string `json:"status,omitempty"` + // The list of task ARN entries for the ListTasks request. + TaskARNs []*string `json:"taskARNs,omitempty"` // The task definition to use for tasks in the service. This value is specified // when the service is created with CreateService, and it can be modified with // UpdateService. diff --git a/package/crds/ecs.aws.crossplane.io_services.yaml b/package/crds/ecs.aws.crossplane.io_services.yaml index fce0c29c7b..56d340c036 100644 --- a/package/crds/ecs.aws.crossplane.io_services.yaml +++ b/package/crds/ecs.aws.crossplane.io_services.yaml @@ -1586,6 +1586,11 @@ spec: description: The status of the service. The valid values are ACTIVE, DRAINING, or INACTIVE. type: string + taskARNs: + description: The list of task ARN entries for the ListTasks request. + items: + type: string + type: array taskDefinition: description: |- The task definition to use for tasks in the service. This value is specified diff --git a/pkg/controller/ecs/service/setup.go b/pkg/controller/ecs/service/setup.go index b8f0524bf4..9a687de6ae 100644 --- a/pkg/controller/ecs/service/setup.go +++ b/pkg/controller/ecs/service/setup.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" svcsdk "github.com/aws/aws-sdk-go/service/ecs" + svcsdkapi "github.com/aws/aws-sdk-go/service/ecs/ecsiface" xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" "github.com/crossplane/crossplane-runtime/pkg/connection" "github.com/crossplane/crossplane-runtime/pkg/controller" @@ -14,8 +15,10 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/resource" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/pkg/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" svcapitypes "github.com/crossplane-contrib/provider-aws/apis/ecs/v1alpha1" "github.com/crossplane-contrib/provider-aws/apis/v1alpha1" @@ -23,13 +26,19 @@ import ( custommanaged "github.com/crossplane-contrib/provider-aws/pkg/utils/reconciler/managed" ) +type custom struct { + kube client.Client + client svcsdkapi.ECSAPI +} + // SetupService adds a controller that reconciles Service. func SetupService(mgr ctrl.Manager, o controller.Options) error { name := managed.ControllerName(svcapitypes.ServiceGroupKind) opts := []option{ func(e *external) { + c := &custom{client: e.client, kube: e.kube} e.preObserve = preObserve - e.postObserve = postObserve + e.postObserve = c.postObserve e.preCreate = preCreate e.preUpdate = preUpdate e.preDelete = preDelete @@ -170,7 +179,7 @@ func preObserve(_ context.Context, cr *svcapitypes.Service, obj *svcsdk.Describe return nil } -func postObserve(_ context.Context, cr *svcapitypes.Service, resp *svcsdk.DescribeServicesOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) { +func (e *custom) postObserve(_ context.Context, cr *svcapitypes.Service, resp *svcsdk.DescribeServicesOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) { if err != nil { return obs, err } @@ -179,6 +188,15 @@ func postObserve(_ context.Context, cr *svcapitypes.Service, resp *svcsdk.Descri return obs, err } + listTasksOutput, err := e.client.ListTasks(&svcsdk.ListTasksInput{ + Cluster: cr.Spec.ForProvider.Cluster, + ServiceName: aws.String(meta.GetExternalName(cr)), + }) + if err != nil { + return managed.ExternalObservation{}, errors.Wrap(err, "ListTasks failed") + } + cr.Status.AtProvider.TaskARNs = listTasksOutput.TaskArns + switch aws.StringValue(resp.Services[0].Status) { case "ACTIVE": if resp.Services[0].DesiredCount == nil || resp.Services[0].RunningCount == nil || *resp.Services[0].DesiredCount != *resp.Services[0].RunningCount {