diff --git a/apis/glue/generator-config.yaml b/apis/glue/generator-config.yaml index 4d2307d74b..86a91febc2 100644 --- a/apis/glue/generator-config.yaml +++ b/apis/glue/generator-config.yaml @@ -8,7 +8,6 @@ ignore: - Schema - Script - Table - - Trigger - UserDefinedFunction - Workflow - Partition @@ -34,6 +33,9 @@ ignore: - CreateClassifierInput.JsonClassifier - CreateClassifierInput.GrokClassifier - CreateConnectionInput.ConnectionInput + - CreateTriggerInput.Name + - DeleteTriggerInput.Name + - GetTriggerInput.Name - Mapping.Children resources: Job: @@ -176,3 +178,24 @@ resources: from: operation: GetClassifier path: Classifier.CsvClassifier.Version + Trigger: + renames: + operations: + CreateTrigger: + input_fields: + Type: TriggerType + exceptions: + errors: + 404: + code: EntityNotFoundException + fields: + ID: + is_read_only: true + from: + operation: GetTrigger + path: Trigger.Id + State: + is_read_only: true + from: + operation: GetTrigger + path: Trigger.State diff --git a/apis/glue/v1alpha1/custom_types.go b/apis/glue/v1alpha1/custom_types.go index 939c5f9588..9fab4a324c 100644 --- a/apis/glue/v1alpha1/custom_types.go +++ b/apis/glue/v1alpha1/custom_types.go @@ -632,3 +632,5 @@ type CustomCreateCSVClassifierRequest struct { // +optional QuoteSymbol *string `json:"quoteSymbol,omitempty"` } + +type CustomTriggerParameters struct{} diff --git a/apis/glue/v1alpha1/zz_generated.deepcopy.go b/apis/glue/v1alpha1/zz_generated.deepcopy.go index e429d12d69..d399003b4c 100644 --- a/apis/glue/v1alpha1/zz_generated.deepcopy.go +++ b/apis/glue/v1alpha1/zz_generated.deepcopy.go @@ -587,6 +587,11 @@ func (in *BatchStopJobRunError) DeepCopyInto(out *BatchStopJobRunError) { *out = new(string) **out = **in } + if in.JobRunID != nil { + in, out := &in.JobRunID, &out.JobRunID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BatchStopJobRunError. @@ -607,6 +612,11 @@ func (in *BatchStopJobRunSuccessfulSubmission) DeepCopyInto(out *BatchStopJobRun *out = new(string) **out = **in } + if in.JobRunID != nil { + in, out := &in.JobRunID, &out.JobRunID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BatchStopJobRunSuccessfulSubmission. @@ -657,6 +667,26 @@ func (in *Blueprint) DeepCopy() *Blueprint { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BlueprintDetails) DeepCopyInto(out *BlueprintDetails) { + *out = *in + if in.RunID != nil { + in, out := &in.RunID, &out.RunID + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlueprintDetails. +func (in *BlueprintDetails) DeepCopy() *BlueprintDetails { + if in == nil { + return nil + } + out := new(BlueprintDetails) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BlueprintRun) DeepCopyInto(out *BlueprintRun) { *out = *in @@ -664,6 +694,11 @@ func (in *BlueprintRun) DeepCopyInto(out *BlueprintRun) { in, out := &in.CompletedOn, &out.CompletedOn *out = (*in).DeepCopy() } + if in.RunID != nil { + in, out := &in.RunID, &out.RunID + *out = new(string) + **out = **in + } if in.StartedOn != nil { in, out := &in.StartedOn, &out.StartedOn *out = (*in).DeepCopy() @@ -1759,6 +1794,11 @@ func (in *ColumnStatistics) DeepCopy() *ColumnStatistics { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Condition) DeepCopyInto(out *Condition) { *out = *in + if in.CrawlState != nil { + in, out := &in.CrawlState, &out.CrawlState + *out = new(string) + **out = **in + } if in.CrawlerName != nil { in, out := &in.CrawlerName, &out.CrawlerName *out = new(string) @@ -1769,6 +1809,16 @@ func (in *Condition) DeepCopyInto(out *Condition) { *out = new(string) **out = **in } + if in.LogicalOperator != nil { + in, out := &in.LogicalOperator, &out.LogicalOperator + *out = new(string) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. @@ -2153,6 +2203,11 @@ func (in *Crawl) DeepCopyInto(out *Crawl) { in, out := &in.StartedOn, &out.StartedOn *out = (*in).DeepCopy() } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Crawl. @@ -3944,6 +3999,21 @@ func (in *CustomSecurityConfigurationParameters) DeepCopy() *CustomSecurityConfi return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomTriggerParameters) DeepCopyInto(out *CustomTriggerParameters) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomTriggerParameters. +func (in *CustomTriggerParameters) DeepCopy() *CustomTriggerParameters { + if in == nil { + return nil + } + out := new(CustomTriggerParameters) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DQResultsPublishingOptions) DeepCopyInto(out *DQResultsPublishingOptions) { *out = *in @@ -5582,6 +5652,31 @@ func (in *EvaluateDataQualityMultiFrame) DeepCopy() *EvaluateDataQualityMultiFra return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventBatchingCondition) DeepCopyInto(out *EventBatchingCondition) { + *out = *in + if in.BatchSize != nil { + in, out := &in.BatchSize, &out.BatchSize + *out = new(int64) + **out = **in + } + if in.BatchWindow != nil { + in, out := &in.BatchWindow, &out.BatchWindow + *out = new(int64) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventBatchingCondition. +func (in *EventBatchingCondition) DeepCopy() *EventBatchingCondition { + if in == nil { + return nil + } + out := new(EventBatchingCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExecutionProperty) DeepCopyInto(out *ExecutionProperty) { *out = *in @@ -6908,11 +7003,21 @@ func (in *JobRun) DeepCopyInto(out *JobRun) { *out = new(string) **out = **in } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } if in.JobName != nil { in, out := &in.JobName, &out.JobName *out = new(string) **out = **in } + if in.JobRunState != nil { + in, out := &in.JobRunState, &out.JobRunState + *out = new(string) + **out = **in + } if in.LastModifiedOn != nil { in, out := &in.LastModifiedOn, &out.LastModifiedOn *out = (*in).DeepCopy() @@ -6937,6 +7042,11 @@ func (in *JobRun) DeepCopyInto(out *JobRun) { *out = new(int64) **out = **in } + if in.PreviousRunID != nil { + in, out := &in.PreviousRunID, &out.PreviousRunID + *out = new(string) + **out = **in + } if in.SecurityConfiguration != nil { in, out := &in.SecurityConfiguration, &out.SecurityConfiguration *out = new(string) @@ -8695,6 +8805,11 @@ func (in *Predecessor) DeepCopyInto(out *Predecessor) { *out = new(string) **out = **in } + if in.RunID != nil { + in, out := &in.RunID, &out.RunID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Predecessor. @@ -8707,6 +8822,37 @@ func (in *Predecessor) DeepCopy() *Predecessor { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Predicate) DeepCopyInto(out *Predicate) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]*Condition, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Condition) + (*in).DeepCopyInto(*out) + } + } + } + if in.Logical != nil { + in, out := &in.Logical, &out.Logical + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Predicate. +func (in *Predicate) DeepCopy() *Predicate { + if in == nil { + return nil + } + out := new(Predicate) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PrincipalPermissions) DeepCopyInto(out *PrincipalPermissions) { *out = *in @@ -11998,8 +12144,87 @@ func (in *TransformFilterCriteria) DeepCopy() *TransformFilterCriteria { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Trigger) DeepCopyInto(out *Trigger) { *out = *in - if in.Description != nil { - in, out := &in.Description, &out.Description + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger. +func (in *Trigger) DeepCopy() *Trigger { + if in == nil { + return nil + } + out := new(Trigger) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Trigger) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerList) DeepCopyInto(out *TriggerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Trigger, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerList. +func (in *TriggerList) DeepCopy() *TriggerList { + if in == nil { + return nil + } + out := new(TriggerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TriggerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerNodeDetails) DeepCopyInto(out *TriggerNodeDetails) { + *out = *in + if in.Trigger != nil { + in, out := &in.Trigger, &out.Trigger + *out = new(Trigger_SDK) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerNodeDetails. +func (in *TriggerNodeDetails) DeepCopy() *TriggerNodeDetails { + if in == nil { + return nil + } + out := new(TriggerNodeDetails) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerObservation) DeepCopyInto(out *TriggerObservation) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID *out = new(string) **out = **in } @@ -12008,24 +12233,131 @@ func (in *Trigger) DeepCopyInto(out *Trigger) { *out = new(string) **out = **in } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerObservation. +func (in *TriggerObservation) DeepCopy() *TriggerObservation { + if in == nil { + return nil + } + out := new(TriggerObservation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerParameters) DeepCopyInto(out *TriggerParameters) { + *out = *in + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]*Action, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Action) + (*in).DeepCopyInto(*out) + } + } + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.EventBatchingCondition != nil { + in, out := &in.EventBatchingCondition, &out.EventBatchingCondition + *out = new(EventBatchingCondition) + (*in).DeepCopyInto(*out) + } + if in.Predicate != nil { + in, out := &in.Predicate, &out.Predicate + *out = new(Predicate) + (*in).DeepCopyInto(*out) + } if in.Schedule != nil { in, out := &in.Schedule, &out.Schedule *out = new(string) **out = **in } + if in.StartOnCreation != nil { + in, out := &in.StartOnCreation, &out.StartOnCreation + *out = new(bool) + **out = **in + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make(map[string]*string, len(*in)) + for key, val := range *in { + var outVal *string + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(string) + **out = **in + } + (*out)[key] = outVal + } + } + if in.TriggerType != nil { + in, out := &in.TriggerType, &out.TriggerType + *out = new(string) + **out = **in + } if in.WorkflowName != nil { in, out := &in.WorkflowName, &out.WorkflowName *out = new(string) **out = **in } + out.CustomTriggerParameters = in.CustomTriggerParameters } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger. -func (in *Trigger) DeepCopy() *Trigger { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerParameters. +func (in *TriggerParameters) DeepCopy() *TriggerParameters { if in == nil { return nil } - out := new(Trigger) + out := new(TriggerParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerSpec) DeepCopyInto(out *TriggerSpec) { + *out = *in + in.ResourceSpec.DeepCopyInto(&out.ResourceSpec) + in.ForProvider.DeepCopyInto(&out.ForProvider) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerSpec. +func (in *TriggerSpec) DeepCopy() *TriggerSpec { + if in == nil { + return nil + } + out := new(TriggerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerStatus) DeepCopyInto(out *TriggerStatus) { + *out = *in + in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) + in.AtProvider.DeepCopyInto(&out.AtProvider) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerStatus. +func (in *TriggerStatus) DeepCopy() *TriggerStatus { + if in == nil { + return nil + } + out := new(TriggerStatus) in.DeepCopyInto(out) return out } @@ -12033,16 +12365,37 @@ func (in *Trigger) DeepCopy() *Trigger { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TriggerUpdate) DeepCopyInto(out *TriggerUpdate) { *out = *in + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]*Action, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Action) + (*in).DeepCopyInto(*out) + } + } + } if in.Description != nil { in, out := &in.Description, &out.Description *out = new(string) **out = **in } + if in.EventBatchingCondition != nil { + in, out := &in.EventBatchingCondition, &out.EventBatchingCondition + *out = new(EventBatchingCondition) + (*in).DeepCopyInto(*out) + } if in.Name != nil { in, out := &in.Name, &out.Name *out = new(string) **out = **in } + if in.Predicate != nil { + in, out := &in.Predicate, &out.Predicate + *out = new(Predicate) + (*in).DeepCopyInto(*out) + } if in.Schedule != nil { in, out := &in.Schedule, &out.Schedule *out = new(string) @@ -12060,6 +12413,77 @@ func (in *TriggerUpdate) DeepCopy() *TriggerUpdate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Trigger_SDK) DeepCopyInto(out *Trigger_SDK) { + *out = *in + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]*Action, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Action) + (*in).DeepCopyInto(*out) + } + } + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.EventBatchingCondition != nil { + in, out := &in.EventBatchingCondition, &out.EventBatchingCondition + *out = new(EventBatchingCondition) + (*in).DeepCopyInto(*out) + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.Predicate != nil { + in, out := &in.Predicate, &out.Predicate + *out = new(Predicate) + (*in).DeepCopyInto(*out) + } + if in.Schedule != nil { + in, out := &in.Schedule, &out.Schedule + *out = new(string) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(string) + **out = **in + } + if in.WorkflowName != nil { + in, out := &in.WorkflowName, &out.WorkflowName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger_SDK. +func (in *Trigger_SDK) DeepCopy() *Trigger_SDK { + if in == nil { + return nil + } + out := new(Trigger_SDK) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UnfilteredPartition) DeepCopyInto(out *UnfilteredPartition) { *out = *in @@ -12443,10 +12867,20 @@ func (in *WorkflowRun) DeepCopyInto(out *WorkflowRun) { *out = new(string) **out = **in } + if in.PreviousRunID != nil { + in, out := &in.PreviousRunID, &out.PreviousRunID + *out = new(string) + **out = **in + } if in.StartedOn != nil { in, out := &in.StartedOn, &out.StartedOn *out = (*in).DeepCopy() } + if in.WorkflowRunID != nil { + in, out := &in.WorkflowRunID, &out.WorkflowRunID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowRun. diff --git a/apis/glue/v1alpha1/zz_generated.managed.go b/apis/glue/v1alpha1/zz_generated.managed.go index 9a1c4e3fe1..d5ce2ff991 100644 --- a/apis/glue/v1alpha1/zz_generated.managed.go +++ b/apis/glue/v1alpha1/zz_generated.managed.go @@ -379,3 +379,63 @@ func (mg *SecurityConfiguration) SetPublishConnectionDetailsTo(r *xpv1.PublishCo func (mg *SecurityConfiguration) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { mg.Spec.WriteConnectionSecretToReference = r } + +// GetCondition of this Trigger. +func (mg *Trigger) GetCondition(ct xpv1.ConditionType) xpv1.Condition { + return mg.Status.GetCondition(ct) +} + +// GetDeletionPolicy of this Trigger. +func (mg *Trigger) GetDeletionPolicy() xpv1.DeletionPolicy { + return mg.Spec.DeletionPolicy +} + +// GetManagementPolicies of this Trigger. +func (mg *Trigger) GetManagementPolicies() xpv1.ManagementPolicies { + return mg.Spec.ManagementPolicies +} + +// GetProviderConfigReference of this Trigger. +func (mg *Trigger) GetProviderConfigReference() *xpv1.Reference { + return mg.Spec.ProviderConfigReference +} + +// GetPublishConnectionDetailsTo of this Trigger. +func (mg *Trigger) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo { + return mg.Spec.PublishConnectionDetailsTo +} + +// GetWriteConnectionSecretToReference of this Trigger. +func (mg *Trigger) GetWriteConnectionSecretToReference() *xpv1.SecretReference { + return mg.Spec.WriteConnectionSecretToReference +} + +// SetConditions of this Trigger. +func (mg *Trigger) SetConditions(c ...xpv1.Condition) { + mg.Status.SetConditions(c...) +} + +// SetDeletionPolicy of this Trigger. +func (mg *Trigger) SetDeletionPolicy(r xpv1.DeletionPolicy) { + mg.Spec.DeletionPolicy = r +} + +// SetManagementPolicies of this Trigger. +func (mg *Trigger) SetManagementPolicies(r xpv1.ManagementPolicies) { + mg.Spec.ManagementPolicies = r +} + +// SetProviderConfigReference of this Trigger. +func (mg *Trigger) SetProviderConfigReference(r *xpv1.Reference) { + mg.Spec.ProviderConfigReference = r +} + +// SetPublishConnectionDetailsTo of this Trigger. +func (mg *Trigger) SetPublishConnectionDetailsTo(r *xpv1.PublishConnectionDetailsTo) { + mg.Spec.PublishConnectionDetailsTo = r +} + +// SetWriteConnectionSecretToReference of this Trigger. +func (mg *Trigger) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { + mg.Spec.WriteConnectionSecretToReference = r +} diff --git a/apis/glue/v1alpha1/zz_generated.managedlist.go b/apis/glue/v1alpha1/zz_generated.managedlist.go index e91ccaaf4e..de8e742420 100644 --- a/apis/glue/v1alpha1/zz_generated.managedlist.go +++ b/apis/glue/v1alpha1/zz_generated.managedlist.go @@ -73,3 +73,12 @@ func (l *SecurityConfigurationList) GetItems() []resource.Managed { } return items } + +// GetItems of this TriggerList. +func (l *TriggerList) GetItems() []resource.Managed { + items := make([]resource.Managed, len(l.Items)) + for i := range l.Items { + items[i] = &l.Items[i] + } + return items +} diff --git a/apis/glue/v1alpha1/zz_trigger.go b/apis/glue/v1alpha1/zz_trigger.go new file mode 100644 index 0000000000..39410099aa --- /dev/null +++ b/apis/glue/v1alpha1/zz_trigger.go @@ -0,0 +1,125 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by ack-generate. DO NOT EDIT. + +package v1alpha1 + +import ( + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// TriggerParameters defines the desired state of Trigger +type TriggerParameters struct { + // Region is which region the Trigger will be created. + // +kubebuilder:validation:Required + Region string `json:"region"` + // The actions initiated by this trigger when it fires. + // +kubebuilder:validation:Required + Actions []*Action `json:"actions"` + // A description of the new trigger. + Description *string `json:"description,omitempty"` + // Batch condition that must be met (specified number of events received or + // batch time window expired) before EventBridge event trigger fires. + EventBatchingCondition *EventBatchingCondition `json:"eventBatchingCondition,omitempty"` + // A predicate to specify when the new trigger should fire. + // + // This field is required when the trigger type is CONDITIONAL. + Predicate *Predicate `json:"predicate,omitempty"` + // A cron expression used to specify the schedule (see Time-Based Schedules + // for Jobs and Crawlers (https://docs.aws.amazon.com/glue/latest/dg/monitor-data-warehouse-schedule.html). + // For example, to run something every day at 12:15 UTC, you would specify: + // cron(15 12 * * ? *). + // + // This field is required when the trigger type is SCHEDULED. + Schedule *string `json:"schedule,omitempty"` + // Set to true to start SCHEDULED and CONDITIONAL triggers when created. True + // is not supported for ON_DEMAND triggers. + StartOnCreation *bool `json:"startOnCreation,omitempty"` + // The tags to use with this trigger. You may use tags to limit access to the + // trigger. For more information about tags in Glue, see Amazon Web Services + // Tags in Glue (https://docs.aws.amazon.com/glue/latest/dg/monitor-tags.html) + // in the developer guide. + Tags map[string]*string `json:"tags,omitempty"` + // The type of the new trigger. + // +kubebuilder:validation:Required + TriggerType *string `json:"triggerType"` + // The name of the workflow associated with the trigger. + WorkflowName *string `json:"workflowName,omitempty"` + CustomTriggerParameters `json:",inline"` +} + +// TriggerSpec defines the desired state of Trigger +type TriggerSpec struct { + xpv1.ResourceSpec `json:",inline"` + ForProvider TriggerParameters `json:"forProvider"` +} + +// TriggerObservation defines the observed state of Trigger +type TriggerObservation struct { + // Reserved for future use. + ID *string `json:"id,omitempty"` + // The name of the trigger. + Name *string `json:"name,omitempty"` + // The current state of the trigger. + State *string `json:"state,omitempty"` +} + +// TriggerStatus defines the observed state of Trigger. +type TriggerStatus struct { + xpv1.ResourceStatus `json:",inline"` + AtProvider TriggerObservation `json:"atProvider,omitempty"` +} + +// +kubebuilder:object:root=true + +// Trigger is the Schema for the Triggers API +// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status" +// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status" +// +kubebuilder:printcolumn:name="EXTERNAL-NAME",type="string",JSONPath=".metadata.annotations.crossplane\\.io/external-name" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:scope=Cluster,categories={crossplane,managed,aws} +type Trigger struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec TriggerSpec `json:"spec"` + Status TriggerStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// TriggerList contains a list of Triggers +type TriggerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Trigger `json:"items"` +} + +// Repository type metadata. +var ( + TriggerKind = "Trigger" + TriggerGroupKind = schema.GroupKind{Group: CRDGroup, Kind: TriggerKind}.String() + TriggerKindAPIVersion = TriggerKind + "." + GroupVersion.String() + TriggerGroupVersionKind = GroupVersion.WithKind(TriggerKind) +) + +func init() { + SchemeBuilder.Register(&Trigger{}, &TriggerList{}) +} diff --git a/apis/glue/v1alpha1/zz_types.go b/apis/glue/v1alpha1/zz_types.go index 7c659fc045..2e83ea012c 100644 --- a/apis/glue/v1alpha1/zz_types.go +++ b/apis/glue/v1alpha1/zz_types.go @@ -185,11 +185,15 @@ type BasicCatalogTarget struct { // +kubebuilder:skipversion type BatchStopJobRunError struct { JobName *string `json:"jobName,omitempty"` + + JobRunID *string `json:"jobRunID,omitempty"` } // +kubebuilder:skipversion type BatchStopJobRunSuccessfulSubmission struct { JobName *string `json:"jobName,omitempty"` + + JobRunID *string `json:"jobRunID,omitempty"` } // +kubebuilder:skipversion @@ -205,10 +209,17 @@ type Blueprint struct { LastModifiedOn *metav1.Time `json:"lastModifiedOn,omitempty"` } +// +kubebuilder:skipversion +type BlueprintDetails struct { + RunID *string `json:"runID,omitempty"` +} + // +kubebuilder:skipversion type BlueprintRun struct { CompletedOn *metav1.Time `json:"completedOn,omitempty"` + RunID *string `json:"runID,omitempty"` + StartedOn *metav1.Time `json:"startedOn,omitempty"` WorkflowName *string `json:"workflowName,omitempty"` @@ -547,9 +558,15 @@ type ColumnStatistics struct { // +kubebuilder:skipversion type Condition struct { + CrawlState *string `json:"crawlState,omitempty"` + CrawlerName *string `json:"crawlerName,omitempty"` JobName *string `json:"jobName,omitempty"` + + LogicalOperator *string `json:"logicalOperator,omitempty"` + + State *string `json:"state,omitempty"` } // +kubebuilder:skipversion @@ -611,6 +628,8 @@ type Crawl struct { LogStream *string `json:"logStream,omitempty"` StartedOn *metav1.Time `json:"startedOn,omitempty"` + + State *string `json:"state,omitempty"` } // +kubebuilder:skipversion @@ -1241,6 +1260,13 @@ type EvaluateDataQualityMultiFrame struct { StopJobOnFailureOptions *DQStopJobOnFailureOptions `json:"stopJobOnFailureOptions,omitempty"` } +// +kubebuilder:skipversion +type EventBatchingCondition struct { + BatchSize *int64 `json:"batchSize,omitempty"` + + BatchWindow *int64 `json:"batchWindow,omitempty"` +} + // +kubebuilder:skipversion type ExecutionProperty struct { MaxConcurrentRuns *int64 `json:"maxConcurrentRuns,omitempty"` @@ -1537,8 +1563,12 @@ type JobRun struct { GlueVersion *string `json:"glueVersion,omitempty"` + ID *string `json:"id,omitempty"` + JobName *string `json:"jobName,omitempty"` + JobRunState *string `json:"jobRunState,omitempty"` + LastModifiedOn *metav1.Time `json:"lastModifiedOn,omitempty"` LogGroupName *string `json:"logGroupName,omitempty"` @@ -1549,6 +1579,8 @@ type JobRun struct { NumberOfWorkers *int64 `json:"numberOfWorkers,omitempty"` + PreviousRunID *string `json:"previousRunID,omitempty"` + SecurityConfiguration *string `json:"securityConfiguration,omitempty"` StartedOn *metav1.Time `json:"startedOn,omitempty"` @@ -2061,6 +2093,15 @@ type PostgreSQLCatalogTarget struct { // +kubebuilder:skipversion type Predecessor struct { JobName *string `json:"jobName,omitempty"` + + RunID *string `json:"runID,omitempty"` +} + +// +kubebuilder:skipversion +type Predicate struct { + Conditions []*Condition `json:"conditions,omitempty"` + + Logical *string `json:"logical,omitempty"` } // +kubebuilder:skipversion @@ -2918,23 +2959,49 @@ type TransformFilterCriteria struct { } // +kubebuilder:skipversion -type Trigger struct { +type TriggerNodeDetails struct { + // Information about a specific trigger. + Trigger *Trigger_SDK `json:"trigger,omitempty"` +} + +// +kubebuilder:skipversion +type TriggerUpdate struct { + Actions []*Action `json:"actions,omitempty"` + Description *string `json:"description,omitempty"` + // Batch condition that must be met (specified number of events received or + // batch time window expired) before EventBridge event trigger fires. + EventBatchingCondition *EventBatchingCondition `json:"eventBatchingCondition,omitempty"` Name *string `json:"name,omitempty"` + // Defines the predicate of the trigger, which determines when it fires. + Predicate *Predicate `json:"predicate,omitempty"` Schedule *string `json:"schedule,omitempty"` - - WorkflowName *string `json:"workflowName,omitempty"` } // +kubebuilder:skipversion -type TriggerUpdate struct { +type Trigger_SDK struct { + Actions []*Action `json:"actions,omitempty"` + Description *string `json:"description,omitempty"` + // Batch condition that must be met (specified number of events received or + // batch time window expired) before EventBridge event trigger fires. + EventBatchingCondition *EventBatchingCondition `json:"eventBatchingCondition,omitempty"` + + ID *string `json:"id,omitempty"` Name *string `json:"name,omitempty"` + // Defines the predicate of the trigger, which determines when it fires. + Predicate *Predicate `json:"predicate,omitempty"` Schedule *string `json:"schedule,omitempty"` + + State *string `json:"state,omitempty"` + + Type *string `json:"type_,omitempty"` + + WorkflowName *string `json:"workflowName,omitempty"` } // +kubebuilder:skipversion @@ -3053,7 +3120,11 @@ type WorkflowRun struct { Name *string `json:"name,omitempty"` + PreviousRunID *string `json:"previousRunID,omitempty"` + StartedOn *metav1.Time `json:"startedOn,omitempty"` + + WorkflowRunID *string `json:"workflowRunID,omitempty"` } // +kubebuilder:skipversion diff --git a/examples/glue/trigger.yaml b/examples/glue/trigger.yaml new file mode 100644 index 0000000000..b5290d6bbd --- /dev/null +++ b/examples/glue/trigger.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: glue.aws.crossplane.io/v1alpha1 +kind: Trigger +metadata: + name: glue-trigger +spec: + forProvider: + region: eu-central-1 + actions: + - jobName: "job-name" + timeout: 1 + description: "Trigger for Glue" + triggerType: SCHEDULED + schedule: "cron(*/5 * * * ? *)" + startOnCreation: false + tags: + created-by: crossplane + providerConfigRef: + name: example diff --git a/package/crds/glue.aws.crossplane.io_triggers.yaml b/package/crds/glue.aws.crossplane.io_triggers.yaml new file mode 100644 index 0000000000..fcb56905fa --- /dev/null +++ b/package/crds/glue.aws.crossplane.io_triggers.yaml @@ -0,0 +1,423 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: triggers.glue.aws.crossplane.io +spec: + group: glue.aws.crossplane.io + names: + categories: + - crossplane + - managed + - aws + kind: Trigger + listKind: TriggerList + plural: triggers + singular: trigger + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=='Ready')].status + name: READY + type: string + - jsonPath: .status.conditions[?(@.type=='Synced')].status + name: SYNCED + type: string + - jsonPath: .metadata.annotations.crossplane\.io/external-name + name: EXTERNAL-NAME + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Trigger is the Schema for the Triggers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: TriggerSpec defines the desired state of Trigger + properties: + deletionPolicy: + default: Delete + description: |- + DeletionPolicy specifies what will happen to the underlying external + when this managed resource is deleted - either "Delete" or "Orphan" the + external resource. + This field is planned to be deprecated in favor of the ManagementPolicies + field in a future release. Currently, both could be set independently and + non-default values would be honored if the feature flag is enabled. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + enum: + - Orphan + - Delete + type: string + forProvider: + description: TriggerParameters defines the desired state of Trigger + properties: + actions: + description: The actions initiated by this trigger when it fires. + items: + properties: + arguments: + additionalProperties: + type: string + type: object + crawlerName: + type: string + jobName: + type: string + notificationProperty: + description: Specifies configuration properties of a notification. + properties: + notifyDelayAfter: + format: int64 + type: integer + type: object + securityConfiguration: + type: string + timeout: + format: int64 + type: integer + type: object + type: array + description: + description: A description of the new trigger. + type: string + eventBatchingCondition: + description: |- + Batch condition that must be met (specified number of events received or + batch time window expired) before EventBridge event trigger fires. + properties: + batchSize: + format: int64 + type: integer + batchWindow: + format: int64 + type: integer + type: object + predicate: + description: |- + A predicate to specify when the new trigger should fire. + + + This field is required when the trigger type is CONDITIONAL. + properties: + conditions: + items: + properties: + crawlState: + type: string + crawlerName: + type: string + jobName: + type: string + logicalOperator: + type: string + state: + type: string + type: object + type: array + logical: + type: string + type: object + region: + description: Region is which region the Trigger will be created. + type: string + schedule: + description: |- + A cron expression used to specify the schedule (see Time-Based Schedules + for Jobs and Crawlers (https://docs.aws.amazon.com/glue/latest/dg/monitor-data-warehouse-schedule.html). + For example, to run something every day at 12:15 UTC, you would specify: + cron(15 12 * * ? *). + + + This field is required when the trigger type is SCHEDULED. + type: string + startOnCreation: + description: |- + Set to true to start SCHEDULED and CONDITIONAL triggers when created. True + is not supported for ON_DEMAND triggers. + type: boolean + tags: + additionalProperties: + type: string + description: |- + The tags to use with this trigger. You may use tags to limit access to the + trigger. For more information about tags in Glue, see Amazon Web Services + Tags in Glue (https://docs.aws.amazon.com/glue/latest/dg/monitor-tags.html) + in the developer guide. + type: object + triggerType: + description: The type of the new trigger. + type: string + workflowName: + description: The name of the workflow associated with the trigger. + type: string + required: + - actions + - region + - triggerType + type: object + managementPolicies: + default: + - '*' + description: |- + THIS IS A BETA FIELD. It is on by default but can be opted out + through a Crossplane feature flag. + ManagementPolicies specify the array of actions Crossplane is allowed to + take on the managed and external resources. + This field is planned to replace the DeletionPolicy field in a future + release. Currently, both could be set independently and non-default + values would be honored if the feature flag is enabled. If both are + custom, the DeletionPolicy field will be ignored. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md + items: + description: |- + A ManagementAction represents an action that the Crossplane controllers + can take on an external resource. + enum: + - Observe + - Create + - Update + - Delete + - LateInitialize + - '*' + type: string + type: array + providerConfigRef: + default: + name: default + description: |- + ProviderConfigReference specifies how the provider that will be used to + create, observe, update, and delete this managed resource should be + configured. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: |- + Resolution specifies whether resolution of this reference is required. + The default is 'Required', which means the reconcile will fail if the + reference cannot be resolved. 'Optional' means this reference will be + a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: |- + Resolve specifies when this reference should be resolved. The default + is 'IfNotPresent', which will attempt to resolve the reference only when + the corresponding field is not present. Use 'Always' to resolve the + reference on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + publishConnectionDetailsTo: + description: |- + PublishConnectionDetailsTo specifies the connection secret config which + contains a name, metadata and a reference to secret store config to + which any connection details for this managed resource should be written. + Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + properties: + configRef: + default: + name: default + description: |- + SecretStoreConfigRef specifies which secret store config should be used + for this ConnectionSecret. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: |- + Resolution specifies whether resolution of this reference is required. + The default is 'Required', which means the reconcile will fail if the + reference cannot be resolved. 'Optional' means this reference will be + a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: |- + Resolve specifies when this reference should be resolved. The default + is 'IfNotPresent', which will attempt to resolve the reference only when + the corresponding field is not present. Use 'Always' to resolve the + reference on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + metadata: + description: Metadata is the metadata for connection secret. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations are the annotations to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.annotations". + - It is up to Secret Store implementation for others store types. + type: object + labels: + additionalProperties: + type: string + description: |- + Labels are the labels/tags to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.labels". + - It is up to Secret Store implementation for others store types. + type: object + type: + description: |- + Type is the SecretType for the connection secret. + - Only valid for Kubernetes Secret Stores. + type: string + type: object + name: + description: Name is the name of the connection secret. + type: string + required: + - name + type: object + writeConnectionSecretToRef: + description: |- + WriteConnectionSecretToReference specifies the namespace and name of a + Secret to which any connection details for this managed resource should + be written. Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + This field is planned to be replaced in a future release in favor of + PublishConnectionDetailsTo. Currently, both could be set independently + and connection details would be published to both without affecting + each other. + properties: + name: + description: Name of the secret. + type: string + namespace: + description: Namespace of the secret. + type: string + required: + - name + - namespace + type: object + required: + - forProvider + type: object + status: + description: TriggerStatus defines the observed state of Trigger. + properties: + atProvider: + description: TriggerObservation defines the observed state of Trigger + properties: + id: + description: Reserved for future use. + type: string + name: + description: The name of the trigger. + type: string + state: + description: The current state of the trigger. + type: string + type: object + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the last time this condition transitioned from one + status to another. + format: date-time + type: string + message: + description: |- + A Message containing details about this condition's last transition from + one status to another, if any. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + type: integer + reason: + description: A Reason for this condition's last transition from + one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: |- + Type of this condition. At most one of each condition type may apply to + a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the latest metadata.generation + which resulted in either a ready state, or stalled due to error + it can not recover from without human intervention. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/pkg/controller/glue/setup.go b/pkg/controller/glue/setup.go index 0279bd592c..546cd61f23 100644 --- a/pkg/controller/glue/setup.go +++ b/pkg/controller/glue/setup.go @@ -26,6 +26,7 @@ import ( "github.com/crossplane-contrib/provider-aws/pkg/controller/glue/database" "github.com/crossplane-contrib/provider-aws/pkg/controller/glue/job" "github.com/crossplane-contrib/provider-aws/pkg/controller/glue/securityconfiguration" + "github.com/crossplane-contrib/provider-aws/pkg/controller/glue/trigger" "github.com/crossplane-contrib/provider-aws/pkg/utils/setup" ) @@ -39,5 +40,6 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { database.SetupDatabase, job.SetupJob, securityconfiguration.SetupSecurityConfiguration, + trigger.SetupTrigger, ) } diff --git a/pkg/controller/glue/trigger/setup.go b/pkg/controller/glue/trigger/setup.go new file mode 100644 index 0000000000..1ed93b3570 --- /dev/null +++ b/pkg/controller/glue/trigger/setup.go @@ -0,0 +1,334 @@ +/* +Copyright 2024 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package trigger + +import ( + "context" + "encoding/json" + + svcsdk "github.com/aws/aws-sdk-go/service/glue" + svcsdkapi "github.com/aws/aws-sdk-go/service/glue/glueiface" + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + "github.com/crossplane/crossplane-runtime/pkg/connection" + "github.com/crossplane/crossplane-runtime/pkg/controller" + "github.com/crossplane/crossplane-runtime/pkg/event" + "github.com/crossplane/crossplane-runtime/pkg/meta" + "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" + "github.com/crossplane/crossplane-runtime/pkg/resource" + cpresource "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/glue/v1alpha1" + "github.com/crossplane-contrib/provider-aws/apis/v1alpha1" + "github.com/crossplane-contrib/provider-aws/pkg/features" + connectaws "github.com/crossplane-contrib/provider-aws/pkg/utils/connect/aws" + errorutils "github.com/crossplane-contrib/provider-aws/pkg/utils/errors" + "github.com/crossplane-contrib/provider-aws/pkg/utils/jsonpatch" + "github.com/crossplane-contrib/provider-aws/pkg/utils/pointer" +) + +type customConnector struct { + kube client.Client +} + +// customExternal is external connector with overridden Update method due to ACK doesn't correctly generate it. +type customExternal struct { + external +} + +func (c *customConnector) Connect(ctx context.Context, mg cpresource.Managed) (managed.ExternalClient, error) { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return nil, errors.New(errUnexpectedObject) + } + sess, err := connectaws.GetConfigV1(ctx, c.kube, mg, cr.Spec.ForProvider.Region) + if err != nil { + return nil, errors.Wrap(err, errCreateSession) + } + return newCustomExternal(c.kube, svcsdk.New(sess)), nil +} + +func newCustomExternal(kube client.Client, client svcsdkapi.GlueAPI) *customExternal { + return &customExternal{ + external{ + kube: kube, + client: client, + preObserve: preObserve, + postObserve: postObserve, + isUpToDate: isUpToDate, + preCreate: preCreate, + preDelete: preDelete, + preUpdate: preUpdate, + lateInitialize: nopLateInitialize, + postCreate: nopPostCreate, + postDelete: nopPostDelete, + postUpdate: nopPostUpdate, + }, + } +} + +func (e *customExternal) Update(ctx context.Context, mg cpresource.Managed) (managed.ExternalUpdate, error) { //nolint:gocyclo + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return managed.ExternalUpdate{}, errors.New(errUnexpectedObject) + } + triggerUpdate := &svcsdk.TriggerUpdate{} + + if cr.Spec.ForProvider.Predicate != nil { + if cr.Spec.ForProvider.Predicate.Conditions != nil { + triggerUpdate.Predicate.Conditions = make([]*svcsdk.Condition, 0, len(cr.Spec.ForProvider.Predicate.Conditions)) + + for _, crCondition := range cr.Spec.ForProvider.Predicate.Conditions { + inputCondition := &svcsdk.Condition{} + if crCondition.CrawlState != nil { + inputCondition.CrawlState = crCondition.CrawlState + } + if crCondition.CrawlerName != nil { + inputCondition.CrawlerName = crCondition.CrawlerName + } + if crCondition.JobName != nil { + inputCondition.JobName = crCondition.JobName + } + if crCondition.LogicalOperator != nil { + inputCondition.LogicalOperator = crCondition.LogicalOperator + } + if crCondition.State != nil { + inputCondition.State = crCondition.State + } + triggerUpdate.Predicate.Conditions = append(triggerUpdate.Predicate.Conditions, inputCondition) + } + } + if cr.Spec.ForProvider.Predicate.Logical != nil { + triggerUpdate.Predicate.Logical = cr.Spec.ForProvider.Predicate.Logical + } + } + if cr.Spec.ForProvider.EventBatchingCondition != nil { + if cr.Spec.ForProvider.EventBatchingCondition.BatchSize != nil { + triggerUpdate.EventBatchingCondition.BatchSize = cr.Spec.ForProvider.EventBatchingCondition.BatchSize + } + if cr.Spec.ForProvider.EventBatchingCondition.BatchWindow != nil { + triggerUpdate.EventBatchingCondition.BatchWindow = cr.Spec.ForProvider.EventBatchingCondition.BatchWindow + } + } + + if cr.Spec.ForProvider.Actions != nil { + triggerUpdate.Actions = make([]*svcsdk.Action, 0, len(cr.Spec.ForProvider.Actions)) + for _, crAction := range cr.Spec.ForProvider.Actions { + inputAction := &svcsdk.Action{} + if crAction.NotificationProperty != nil && crAction.NotificationProperty.NotifyDelayAfter != nil { + inputAction.NotificationProperty = &svcsdk.NotificationProperty{NotifyDelayAfter: crAction.NotificationProperty.NotifyDelayAfter} + } + if crAction.Arguments != nil { + inputAction.Arguments = crAction.Arguments + } + if crAction.CrawlerName != nil { + inputAction.CrawlerName = crAction.CrawlerName + } + if crAction.JobName != nil { + inputAction.JobName = crAction.JobName + } + if crAction.SecurityConfiguration != nil { + inputAction.SecurityConfiguration = crAction.SecurityConfiguration + } + if crAction.Timeout != nil { + inputAction.Timeout = crAction.Timeout + } + triggerUpdate.Actions = append(triggerUpdate.Actions, inputAction) + } + } + + if cr.Spec.ForProvider.Schedule != nil { + triggerUpdate.Schedule = cr.Spec.ForProvider.Schedule + } + + if cr.Spec.ForProvider.Description != nil { + triggerUpdate.Description = cr.Spec.ForProvider.Description + } + input := &svcsdk.UpdateTriggerInput{TriggerUpdate: triggerUpdate} + if err := preUpdate(ctx, cr, input); err != nil { + return managed.ExternalUpdate{}, errors.Wrap(err, "pre-update failed") + } + resp, err := e.client.UpdateTriggerWithContext(ctx, input) + return nopPostUpdate(ctx, cr, resp, managed.ExternalUpdate{}, errorutils.Wrap(err, errUpdate)) +} + +// SetupTrigger adds a controller that reconciles Trigger. +func SetupTrigger(mgr ctrl.Manager, o controller.Options) error { + name := managed.ControllerName(svcapitypes.TriggerGroupKind) + + cps := []managed.ConnectionPublisher{managed.NewAPISecretPublisher(mgr.GetClient(), mgr.GetScheme())} + if o.Features.Enabled(features.EnableAlphaExternalSecretStores) { + cps = append(cps, connection.NewDetailsManager(mgr.GetClient(), v1alpha1.StoreConfigGroupVersionKind)) + } + + return ctrl.NewControllerManagedBy(mgr). + Named(name). + WithOptions(o.ForControllerRuntime()). + WithEventFilter(resource.DesiredStateChanged()). + For(&svcapitypes.Trigger{}). + Complete(managed.NewReconciler(mgr, + resource.ManagedKind(svcapitypes.TriggerGroupVersionKind), + managed.WithExternalConnecter(&customConnector{kube: mgr.GetClient()}), + managed.WithPollInterval(o.PollInterval), + managed.WithLogger(o.Logger.WithValues("controller", name)), + managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), + managed.WithConnectionPublishers(cps...))) +} + +func preCreate(_ context.Context, cr *svcapitypes.Trigger, input *svcsdk.CreateTriggerInput) error { + input.Name = pointer.ToOrNilIfZeroValue(meta.GetExternalName(cr)) + return nil +} + +func preDelete(_ context.Context, cr *svcapitypes.Trigger, input *svcsdk.DeleteTriggerInput) (bool, error) { + input.Name = pointer.ToOrNilIfZeroValue(meta.GetExternalName(cr)) + state := ptr.Deref(cr.Status.AtProvider.State, "") + if state == svcsdk.TriggerStateActivating || state == svcsdk.TriggerStateDeactivating || + state == svcsdk.TriggerStateCreating || state == svcsdk.TriggerStateDeleting { + return false, nil + } + return false, nil +} + +func preObserve(_ context.Context, cr *svcapitypes.Trigger, input *svcsdk.GetTriggerInput) error { + input.Name = pointer.ToOrNilIfZeroValue(meta.GetExternalName(cr)) + return nil +} + +func isUpToDate(_ context.Context, cr *svcapitypes.Trigger, resp *svcsdk.GetTriggerOutput) (upToDate bool, diff string, err error) { + state := ptr.Deref(cr.Status.AtProvider.State, "") + if state == svcsdk.TriggerStateActivating || state == svcsdk.TriggerStateDeactivating || + state == svcsdk.TriggerStateCreating || state == svcsdk.TriggerStateDeleting { + return true, "", nil + } + patch, err := createPatch(&cr.Spec.ForProvider, resp) + if err != nil { + return false, "", err + } + diff = cmp.Diff(&svcapitypes.TriggerParameters{}, patch, cmpopts.EquateEmpty(), + cmpopts.IgnoreFields(svcapitypes.TriggerParameters{}, "Region"), + cmpopts.IgnoreFields(svcapitypes.TriggerParameters{}, "Tags"), + cmpopts.IgnoreFields(svcapitypes.TriggerParameters{}, "StartOnCreation"), + cmpopts.IgnoreFields(svcapitypes.TriggerParameters{}, "TriggerType"), // TriggerType is immutable + ) + if diff != "" { + return false, "Found observed difference in glue trigger " + diff, nil + } + return true, "", nil +} + +func postObserve(_ context.Context, cr *svcapitypes.Trigger, resp *svcsdk.GetTriggerOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) { + if err != nil { + return managed.ExternalObservation{}, err + } + cr.Status.AtProvider.ID = resp.Trigger.Id + cr.Status.AtProvider.State = resp.Trigger.State + cr.SetConditions(xpv1.Available()) + return obs, nil +} + +func preUpdate(_ context.Context, cr *svcapitypes.Trigger, input *svcsdk.UpdateTriggerInput) error { + input.Name = pointer.ToOrNilIfZeroValue(meta.GetExternalName(cr)) + return nil +} + +func createPatch(currentParams *svcapitypes.TriggerParameters, resp *svcsdk.GetTriggerOutput) (*svcapitypes.TriggerParameters, error) { //nolint:gocyclo + targetConfig := currentParams.DeepCopy() + externalConfig := &svcapitypes.TriggerParameters{} + externalConfig.Schedule = resp.Trigger.Schedule + if resp.Trigger.Predicate != nil { + externalConfig.Predicate = &svcapitypes.Predicate{} + if resp.Trigger.Predicate.Conditions != nil { + externalConfig.Predicate = &svcapitypes.Predicate{Conditions: make([]*svcapitypes.Condition, 0, len(resp.Trigger.Predicate.Conditions))} + for _, respCondition := range resp.Trigger.Predicate.Conditions { + curCondition := &svcapitypes.Condition{} + if respCondition.CrawlState != nil { + curCondition.CrawlState = respCondition.CrawlState + } + if respCondition.CrawlerName != nil { + curCondition.CrawlerName = respCondition.CrawlerName + } + if respCondition.JobName != nil { + curCondition.JobName = respCondition.JobName + } + if respCondition.LogicalOperator != nil { + curCondition.LogicalOperator = respCondition.LogicalOperator + } + if respCondition.State != nil { + curCondition.State = respCondition.State + } + externalConfig.Predicate.Conditions = append(externalConfig.Predicate.Conditions, curCondition) + } + } + if resp.Trigger.Predicate != nil && resp.Trigger.Predicate.Logical != nil { + externalConfig.Predicate = &svcapitypes.Predicate{Logical: resp.Trigger.Predicate.Logical} + } + } + if resp.Trigger.Actions != nil { + externalConfig.Actions = make([]*svcapitypes.Action, 0, len(resp.Trigger.Actions)) + for _, respAction := range resp.Trigger.Actions { + crAction := &svcapitypes.Action{} + if respAction.NotificationProperty != nil && respAction.NotificationProperty.NotifyDelayAfter != nil { + crAction.NotificationProperty = &svcapitypes.NotificationProperty{NotifyDelayAfter: respAction.NotificationProperty.NotifyDelayAfter} + } + if respAction.Arguments != nil { + crAction.Arguments = respAction.Arguments + } + if respAction.CrawlerName != nil { + crAction.CrawlerName = respAction.CrawlerName + } + if respAction.JobName != nil { + crAction.JobName = respAction.JobName + } + if respAction.SecurityConfiguration != nil { + crAction.SecurityConfiguration = respAction.SecurityConfiguration + } + if respAction.Timeout != nil { + crAction.Timeout = respAction.Timeout + } + externalConfig.Actions = append(externalConfig.Actions, crAction) + } + } + externalConfig.Description = resp.Trigger.Description + eventBatchingCondition := &svcapitypes.EventBatchingCondition{} + if resp.Trigger.EventBatchingCondition != nil { + eventBatchingCondition.BatchSize = resp.Trigger.EventBatchingCondition.BatchSize + eventBatchingCondition.BatchWindow = resp.Trigger.EventBatchingCondition.BatchWindow + } + externalConfig.EventBatchingCondition = eventBatchingCondition + if resp.Trigger.Type != nil { + externalConfig.TriggerType = resp.Trigger.Type + } + if resp.Trigger.WorkflowName != nil { + externalConfig.WorkflowName = resp.Trigger.WorkflowName + } + + jsonPatch, err := jsonpatch.CreateJSONPatch(externalConfig, targetConfig) + if err != nil { + return nil, err + } + patch := &svcapitypes.TriggerParameters{} + if err := json.Unmarshal(jsonPatch, patch); err != nil { + return nil, err + } + return patch, nil +} diff --git a/pkg/controller/glue/trigger/setup_test.go b/pkg/controller/glue/trigger/setup_test.go new file mode 100644 index 0000000000..d36ec4a708 --- /dev/null +++ b/pkg/controller/glue/trigger/setup_test.go @@ -0,0 +1,724 @@ +/* +Copyright 2024 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package trigger + +import ( + "context" + "testing" + + svcsdk "github.com/aws/aws-sdk-go/service/glue" + "github.com/crossplane/crossplane-runtime/pkg/meta" + "github.com/google/go-cmp/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + svcapitypes "github.com/crossplane-contrib/provider-aws/apis/glue/v1alpha1" +) + +type args struct { + trigger *svcapitypes.Trigger + getTriggerOutput *svcsdk.GetTriggerOutput +} + +func TestIsUpToDate(t *testing.T) { + region := "eu-central-2" + + triggerName := "TriggerName" + + actionsJobName1 := "JobName1" + actionsJobName2 := "jobName2" + + actionArgumentValue1 := "argumentValue" + + eventBatchingConditionBatchSize := int64(3) + newEventBatchingConditionBatchSize := int64(4) + + eventBatchingConditionBatchWindow := int64(15) + newEventBatchingConditionBatchWindow := int64(20) + + actionJobTimeout := int64(1) + newActionJobTimeout := int64(2) + + description := "Trigger for Glue" + newDescription := "New Description" + + triggerType := "SCHEDULED" + newTriggerType := "ON_DEMAND" + + schedule := "cron(*/5 * * * ? *)" + newSchedule := "cron(*/3 * * * ? *)" + + startOnCreation := true + newStartOnCreation := false + + notificationPropertyNotifyDelayAfter := int64(1) + newNotificationPropertyNotifyDelayAfter := int64(2) + + predicateConditionCrawlerStateReady := "READY" + predicateConditionCrawlerStateRunning := "RUNNING" + + predicateConditionCrawlerName := "CrawlerName" + newPredicateConditionCrawlerName := "NewCrawlerName" + + predicateConditionJobName := "JobName" + newPredicateConditionJobName := "NewJobName" + + predicateConditionLogicalOperator := "EQUALS" + + predicateConditionStateSucceeded := "SUCCEEDED" + predicateConditionStateStopped := "STOPPED" + + predicateLogical := "AND" + newPredicateLogical := "ANY" + + workflowName := "WorkflowName" + newWorkflowName := "NewWorkflowName" + + type want struct { + result bool + err error + } + cases := map[string]struct { + args + want + }{ + "NothingChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Region: region, + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + }, + Description: &description, + Schedule: &schedule, + StartOnCreation: &startOnCreation, + TriggerType: &triggerType, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + }, + Description: &description, + Schedule: &schedule, + Type: &triggerType, + }, + }, + }, + want: want{ + result: true, + err: nil, + }, + }, + "ScheduleChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Schedule: &newSchedule, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Schedule: &schedule, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "DescriptionChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Description: &newDescription, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Description: &description, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ActionTimeoutChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName1, + Timeout: &newActionJobTimeout, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ActionArgumentsChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName1, + Arguments: map[string]*string{ + "--foo": &actionArgumentValue1, + "--bar": &actionArgumentValue1, + }, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + Arguments: map[string]*string{ + "--foo": &actionArgumentValue1, + }, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ActionNotificationPropertyNotifyDelayAfterChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName1, + NotificationProperty: &svcapitypes.NotificationProperty{ + NotifyDelayAfter: ¬ificationPropertyNotifyDelayAfter, + }, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + NotificationProperty: &svcsdk.NotificationProperty{ + NotifyDelayAfter: &newNotificationPropertyNotifyDelayAfter, + }, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ActionAdded": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + { + JobName: &actionsJobName2, + Timeout: &newActionJobTimeout, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ActionRemoved": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Actions: []*svcapitypes.Action{ + { + JobName: &actionsJobName2, + Timeout: &newActionJobTimeout, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Actions: []*svcsdk.Action{ + { + JobName: &actionsJobName1, + Timeout: &actionJobTimeout, + }, + { + JobName: &actionsJobName2, + Timeout: &newActionJobTimeout, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "EventBatchingConditionBatchSizeChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + EventBatchingCondition: &svcapitypes.EventBatchingCondition{ + BatchWindow: &eventBatchingConditionBatchWindow, + BatchSize: &newEventBatchingConditionBatchSize, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + EventBatchingCondition: &svcsdk.EventBatchingCondition{ + BatchWindow: &eventBatchingConditionBatchWindow, + BatchSize: &eventBatchingConditionBatchSize, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "EventBatchingConditionBatchWindowChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + EventBatchingCondition: &svcapitypes.EventBatchingCondition{ + BatchWindow: &newEventBatchingConditionBatchWindow, + BatchSize: &eventBatchingConditionBatchSize, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + EventBatchingCondition: &svcsdk.EventBatchingCondition{ + BatchWindow: &eventBatchingConditionBatchWindow, + BatchSize: &eventBatchingConditionBatchSize, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "PredicateConditionCrawlerStateChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Conditions: []*svcapitypes.Condition{ + {CrawlState: &predicateConditionCrawlerStateRunning}, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Conditions: []*svcsdk.Condition{ + {CrawlState: &predicateConditionCrawlerStateReady}, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "PredicateConditionJobNameChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Conditions: []*svcapitypes.Condition{ + {JobName: &newPredicateConditionJobName}, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Conditions: []*svcsdk.Condition{ + {JobName: &predicateConditionJobName}, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "PredicateConditionCrawlerNameChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Conditions: []*svcapitypes.Condition{ + {CrawlerName: &newPredicateConditionCrawlerName}, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Conditions: []*svcsdk.Condition{ + {CrawlerName: &predicateConditionCrawlerName}, + }, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "PredicateConditionLogicalOperatorAdded": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Conditions: []*svcapitypes.Condition{ + {LogicalOperator: &predicateConditionLogicalOperator}, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Conditions: []*svcsdk.Condition{}, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "PredicateConditionStateChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Conditions: []*svcapitypes.Condition{ + {State: &predicateConditionStateSucceeded}, + }, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Conditions: []*svcsdk.Condition{ + {State: &predicateConditionStateStopped}, + }, + }, + }, + }, + }, + }, + "PredicateLogicalChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + Predicate: &svcapitypes.Predicate{ + Logical: &newPredicateLogical, + }, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Predicate: &svcsdk.Predicate{ + Logical: &predicateLogical, + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "WorkflowNameChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + WorkflowName: &newWorkflowName, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + WorkflowName: &workflowName, + }, + }, + }, + }, + "ImmutableParamsChanged": { + args: args{ + trigger: &svcapitypes.Trigger{ + ObjectMeta: metav1.ObjectMeta{ + Name: triggerName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: triggerName, + }, + }, + Spec: svcapitypes.TriggerSpec{ + ForProvider: svcapitypes.TriggerParameters{ + StartOnCreation: &newStartOnCreation, + TriggerType: &newTriggerType, + }, + }, + }, + getTriggerOutput: &svcsdk.GetTriggerOutput{ + Trigger: &svcsdk.Trigger{ + Name: &triggerName, + Type: &triggerType, + }, + }, + }, + want: want{ + result: true, + err: nil, + }, + }, + } + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + result, _, _ := isUpToDate(context.TODO(), tc.args.trigger, tc.args.getTriggerOutput) + if diff := cmp.Diff(tc.want.result, result); diff != "" { + t.Errorf("r: -want, +got:\n%s", diff) + } + }) + } +} diff --git a/pkg/controller/glue/trigger/zz_controller.go b/pkg/controller/glue/trigger/zz_controller.go new file mode 100644 index 0000000000..5ba1732fbb --- /dev/null +++ b/pkg/controller/glue/trigger/zz_controller.go @@ -0,0 +1,231 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by ack-generate. DO NOT EDIT. + +package trigger + +import ( + "context" + + svcapi "github.com/aws/aws-sdk-go/service/glue" + svcsdk "github.com/aws/aws-sdk-go/service/glue" + svcsdkapi "github.com/aws/aws-sdk-go/service/glue/glueiface" + "github.com/google/go-cmp/cmp" + "github.com/pkg/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + "github.com/crossplane/crossplane-runtime/pkg/meta" + "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" + cpresource "github.com/crossplane/crossplane-runtime/pkg/resource" + + svcapitypes "github.com/crossplane-contrib/provider-aws/apis/glue/v1alpha1" + connectaws "github.com/crossplane-contrib/provider-aws/pkg/utils/connect/aws" + errorutils "github.com/crossplane-contrib/provider-aws/pkg/utils/errors" +) + +const ( + errUnexpectedObject = "managed resource is not an Trigger resource" + + errCreateSession = "cannot create a new session" + errCreate = "cannot create Trigger in AWS" + errUpdate = "cannot update Trigger in AWS" + errDescribe = "failed to describe Trigger" + errDelete = "failed to delete Trigger" +) + +type connector struct { + kube client.Client + opts []option +} + +func (c *connector) Connect(ctx context.Context, mg cpresource.Managed) (managed.ExternalClient, error) { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return nil, errors.New(errUnexpectedObject) + } + sess, err := connectaws.GetConfigV1(ctx, c.kube, mg, cr.Spec.ForProvider.Region) + if err != nil { + return nil, errors.Wrap(err, errCreateSession) + } + return newExternal(c.kube, svcapi.New(sess), c.opts), nil +} + +func (e *external) Observe(ctx context.Context, mg cpresource.Managed) (managed.ExternalObservation, error) { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return managed.ExternalObservation{}, errors.New(errUnexpectedObject) + } + if meta.GetExternalName(cr) == "" { + return managed.ExternalObservation{ + ResourceExists: false, + }, nil + } + input := GenerateGetTriggerInput(cr) + if err := e.preObserve(ctx, cr, input); err != nil { + return managed.ExternalObservation{}, errors.Wrap(err, "pre-observe failed") + } + resp, err := e.client.GetTriggerWithContext(ctx, input) + if err != nil { + return managed.ExternalObservation{ResourceExists: false}, errorutils.Wrap(cpresource.Ignore(IsNotFound, err), errDescribe) + } + currentSpec := cr.Spec.ForProvider.DeepCopy() + if err := e.lateInitialize(&cr.Spec.ForProvider, resp); err != nil { + return managed.ExternalObservation{}, errors.Wrap(err, "late-init failed") + } + GenerateTrigger(resp).Status.AtProvider.DeepCopyInto(&cr.Status.AtProvider) + upToDate := true + diff := "" + if !meta.WasDeleted(cr) { // There is no need to run isUpToDate if the resource is deleted + upToDate, diff, err = e.isUpToDate(ctx, cr, resp) + if err != nil { + return managed.ExternalObservation{}, errors.Wrap(err, "isUpToDate check failed") + } + } + return e.postObserve(ctx, cr, resp, managed.ExternalObservation{ + ResourceExists: true, + ResourceUpToDate: upToDate, + Diff: diff, + ResourceLateInitialized: !cmp.Equal(&cr.Spec.ForProvider, currentSpec), + }, nil) +} + +func (e *external) Create(ctx context.Context, mg cpresource.Managed) (managed.ExternalCreation, error) { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return managed.ExternalCreation{}, errors.New(errUnexpectedObject) + } + cr.Status.SetConditions(xpv1.Creating()) + input := GenerateCreateTriggerInput(cr) + if err := e.preCreate(ctx, cr, input); err != nil { + return managed.ExternalCreation{}, errors.Wrap(err, "pre-create failed") + } + resp, err := e.client.CreateTriggerWithContext(ctx, input) + if err != nil { + return managed.ExternalCreation{}, errorutils.Wrap(err, errCreate) + } + + if resp.Name != nil { + cr.Status.AtProvider.Name = resp.Name + } else { + cr.Status.AtProvider.Name = nil + } + + return e.postCreate(ctx, cr, resp, managed.ExternalCreation{}, err) +} + +func (e *external) Update(ctx context.Context, mg cpresource.Managed) (managed.ExternalUpdate, error) { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return managed.ExternalUpdate{}, errors.New(errUnexpectedObject) + } + input := GenerateUpdateTriggerInput(cr) + if err := e.preUpdate(ctx, cr, input); err != nil { + return managed.ExternalUpdate{}, errors.Wrap(err, "pre-update failed") + } + resp, err := e.client.UpdateTriggerWithContext(ctx, input) + return e.postUpdate(ctx, cr, resp, managed.ExternalUpdate{}, errorutils.Wrap(err, errUpdate)) +} + +func (e *external) Delete(ctx context.Context, mg cpresource.Managed) error { + cr, ok := mg.(*svcapitypes.Trigger) + if !ok { + return errors.New(errUnexpectedObject) + } + cr.Status.SetConditions(xpv1.Deleting()) + input := GenerateDeleteTriggerInput(cr) + ignore, err := e.preDelete(ctx, cr, input) + if err != nil { + return errors.Wrap(err, "pre-delete failed") + } + if ignore { + return nil + } + resp, err := e.client.DeleteTriggerWithContext(ctx, input) + return e.postDelete(ctx, cr, resp, errorutils.Wrap(cpresource.Ignore(IsNotFound, err), errDelete)) +} + +type option func(*external) + +func newExternal(kube client.Client, client svcsdkapi.GlueAPI, opts []option) *external { + e := &external{ + kube: kube, + client: client, + preObserve: nopPreObserve, + postObserve: nopPostObserve, + lateInitialize: nopLateInitialize, + isUpToDate: alwaysUpToDate, + preCreate: nopPreCreate, + postCreate: nopPostCreate, + preDelete: nopPreDelete, + postDelete: nopPostDelete, + preUpdate: nopPreUpdate, + postUpdate: nopPostUpdate, + } + for _, f := range opts { + f(e) + } + return e +} + +type external struct { + kube client.Client + client svcsdkapi.GlueAPI + preObserve func(context.Context, *svcapitypes.Trigger, *svcsdk.GetTriggerInput) error + postObserve func(context.Context, *svcapitypes.Trigger, *svcsdk.GetTriggerOutput, managed.ExternalObservation, error) (managed.ExternalObservation, error) + lateInitialize func(*svcapitypes.TriggerParameters, *svcsdk.GetTriggerOutput) error + isUpToDate func(context.Context, *svcapitypes.Trigger, *svcsdk.GetTriggerOutput) (bool, string, error) + preCreate func(context.Context, *svcapitypes.Trigger, *svcsdk.CreateTriggerInput) error + postCreate func(context.Context, *svcapitypes.Trigger, *svcsdk.CreateTriggerOutput, managed.ExternalCreation, error) (managed.ExternalCreation, error) + preDelete func(context.Context, *svcapitypes.Trigger, *svcsdk.DeleteTriggerInput) (bool, error) + postDelete func(context.Context, *svcapitypes.Trigger, *svcsdk.DeleteTriggerOutput, error) error + preUpdate func(context.Context, *svcapitypes.Trigger, *svcsdk.UpdateTriggerInput) error + postUpdate func(context.Context, *svcapitypes.Trigger, *svcsdk.UpdateTriggerOutput, managed.ExternalUpdate, error) (managed.ExternalUpdate, error) +} + +func nopPreObserve(context.Context, *svcapitypes.Trigger, *svcsdk.GetTriggerInput) error { + return nil +} + +func nopPostObserve(_ context.Context, _ *svcapitypes.Trigger, _ *svcsdk.GetTriggerOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) { + return obs, err +} +func nopLateInitialize(*svcapitypes.TriggerParameters, *svcsdk.GetTriggerOutput) error { + return nil +} +func alwaysUpToDate(context.Context, *svcapitypes.Trigger, *svcsdk.GetTriggerOutput) (bool, string, error) { + return true, "", nil +} + +func nopPreCreate(context.Context, *svcapitypes.Trigger, *svcsdk.CreateTriggerInput) error { + return nil +} +func nopPostCreate(_ context.Context, _ *svcapitypes.Trigger, _ *svcsdk.CreateTriggerOutput, cre managed.ExternalCreation, err error) (managed.ExternalCreation, error) { + return cre, err +} +func nopPreDelete(context.Context, *svcapitypes.Trigger, *svcsdk.DeleteTriggerInput) (bool, error) { + return false, nil +} +func nopPostDelete(_ context.Context, _ *svcapitypes.Trigger, _ *svcsdk.DeleteTriggerOutput, err error) error { + return err +} +func nopPreUpdate(context.Context, *svcapitypes.Trigger, *svcsdk.UpdateTriggerInput) error { + return nil +} +func nopPostUpdate(_ context.Context, _ *svcapitypes.Trigger, _ *svcsdk.UpdateTriggerOutput, upd managed.ExternalUpdate, err error) (managed.ExternalUpdate, error) { + return upd, err +} diff --git a/pkg/controller/glue/trigger/zz_conversions.go b/pkg/controller/glue/trigger/zz_conversions.go new file mode 100644 index 0000000000..f5f07532cf --- /dev/null +++ b/pkg/controller/glue/trigger/zz_conversions.go @@ -0,0 +1,284 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by ack-generate. DO NOT EDIT. + +package trigger + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" + svcsdk "github.com/aws/aws-sdk-go/service/glue" + + svcapitypes "github.com/crossplane-contrib/provider-aws/apis/glue/v1alpha1" +) + +// NOTE(muvaf): We return pointers in case the function needs to start with an +// empty object, hence need to return a new pointer. + +// GenerateGetTriggerInput returns input for read +// operation. +func GenerateGetTriggerInput(cr *svcapitypes.Trigger) *svcsdk.GetTriggerInput { + res := &svcsdk.GetTriggerInput{} + + return res +} + +// GenerateTrigger returns the current state in the form of *svcapitypes.Trigger. +func GenerateTrigger(resp *svcsdk.GetTriggerOutput) *svcapitypes.Trigger { + cr := &svcapitypes.Trigger{} + + if resp.Trigger.Actions != nil { + f0 := []*svcapitypes.Action{} + for _, f0iter := range resp.Trigger.Actions { + f0elem := &svcapitypes.Action{} + if f0iter.Arguments != nil { + f0elemf0 := map[string]*string{} + for f0elemf0key, f0elemf0valiter := range f0iter.Arguments { + var f0elemf0val string + f0elemf0val = *f0elemf0valiter + f0elemf0[f0elemf0key] = &f0elemf0val + } + f0elem.Arguments = f0elemf0 + } + if f0iter.CrawlerName != nil { + f0elem.CrawlerName = f0iter.CrawlerName + } + if f0iter.JobName != nil { + f0elem.JobName = f0iter.JobName + } + if f0iter.NotificationProperty != nil { + f0elemf3 := &svcapitypes.NotificationProperty{} + if f0iter.NotificationProperty.NotifyDelayAfter != nil { + f0elemf3.NotifyDelayAfter = f0iter.NotificationProperty.NotifyDelayAfter + } + f0elem.NotificationProperty = f0elemf3 + } + if f0iter.SecurityConfiguration != nil { + f0elem.SecurityConfiguration = f0iter.SecurityConfiguration + } + if f0iter.Timeout != nil { + f0elem.Timeout = f0iter.Timeout + } + f0 = append(f0, f0elem) + } + cr.Spec.ForProvider.Actions = f0 + } else { + cr.Spec.ForProvider.Actions = nil + } + if resp.Trigger.Description != nil { + cr.Spec.ForProvider.Description = resp.Trigger.Description + } else { + cr.Spec.ForProvider.Description = nil + } + if resp.Trigger.EventBatchingCondition != nil { + f2 := &svcapitypes.EventBatchingCondition{} + if resp.Trigger.EventBatchingCondition.BatchSize != nil { + f2.BatchSize = resp.Trigger.EventBatchingCondition.BatchSize + } + if resp.Trigger.EventBatchingCondition.BatchWindow != nil { + f2.BatchWindow = resp.Trigger.EventBatchingCondition.BatchWindow + } + cr.Spec.ForProvider.EventBatchingCondition = f2 + } else { + cr.Spec.ForProvider.EventBatchingCondition = nil + } + if resp.Trigger.Name != nil { + cr.Status.AtProvider.Name = resp.Trigger.Name + } else { + cr.Status.AtProvider.Name = nil + } + if resp.Trigger.Predicate != nil { + f5 := &svcapitypes.Predicate{} + if resp.Trigger.Predicate.Conditions != nil { + f5f0 := []*svcapitypes.Condition{} + for _, f5f0iter := range resp.Trigger.Predicate.Conditions { + f5f0elem := &svcapitypes.Condition{} + if f5f0iter.CrawlState != nil { + f5f0elem.CrawlState = f5f0iter.CrawlState + } + if f5f0iter.CrawlerName != nil { + f5f0elem.CrawlerName = f5f0iter.CrawlerName + } + if f5f0iter.JobName != nil { + f5f0elem.JobName = f5f0iter.JobName + } + if f5f0iter.LogicalOperator != nil { + f5f0elem.LogicalOperator = f5f0iter.LogicalOperator + } + if f5f0iter.State != nil { + f5f0elem.State = f5f0iter.State + } + f5f0 = append(f5f0, f5f0elem) + } + f5.Conditions = f5f0 + } + if resp.Trigger.Predicate.Logical != nil { + f5.Logical = resp.Trigger.Predicate.Logical + } + cr.Spec.ForProvider.Predicate = f5 + } else { + cr.Spec.ForProvider.Predicate = nil + } + if resp.Trigger.Schedule != nil { + cr.Spec.ForProvider.Schedule = resp.Trigger.Schedule + } else { + cr.Spec.ForProvider.Schedule = nil + } + if resp.Trigger.State != nil { + cr.Status.AtProvider.State = resp.Trigger.State + } else { + cr.Status.AtProvider.State = nil + } + if resp.Trigger.WorkflowName != nil { + cr.Spec.ForProvider.WorkflowName = resp.Trigger.WorkflowName + } else { + cr.Spec.ForProvider.WorkflowName = nil + } + + return cr +} + +// GenerateCreateTriggerInput returns a create input. +func GenerateCreateTriggerInput(cr *svcapitypes.Trigger) *svcsdk.CreateTriggerInput { + res := &svcsdk.CreateTriggerInput{} + + if cr.Spec.ForProvider.Actions != nil { + f0 := []*svcsdk.Action{} + for _, f0iter := range cr.Spec.ForProvider.Actions { + f0elem := &svcsdk.Action{} + if f0iter.Arguments != nil { + f0elemf0 := map[string]*string{} + for f0elemf0key, f0elemf0valiter := range f0iter.Arguments { + var f0elemf0val string + f0elemf0val = *f0elemf0valiter + f0elemf0[f0elemf0key] = &f0elemf0val + } + f0elem.SetArguments(f0elemf0) + } + if f0iter.CrawlerName != nil { + f0elem.SetCrawlerName(*f0iter.CrawlerName) + } + if f0iter.JobName != nil { + f0elem.SetJobName(*f0iter.JobName) + } + if f0iter.NotificationProperty != nil { + f0elemf3 := &svcsdk.NotificationProperty{} + if f0iter.NotificationProperty.NotifyDelayAfter != nil { + f0elemf3.SetNotifyDelayAfter(*f0iter.NotificationProperty.NotifyDelayAfter) + } + f0elem.SetNotificationProperty(f0elemf3) + } + if f0iter.SecurityConfiguration != nil { + f0elem.SetSecurityConfiguration(*f0iter.SecurityConfiguration) + } + if f0iter.Timeout != nil { + f0elem.SetTimeout(*f0iter.Timeout) + } + f0 = append(f0, f0elem) + } + res.SetActions(f0) + } + if cr.Spec.ForProvider.Description != nil { + res.SetDescription(*cr.Spec.ForProvider.Description) + } + if cr.Spec.ForProvider.EventBatchingCondition != nil { + f2 := &svcsdk.EventBatchingCondition{} + if cr.Spec.ForProvider.EventBatchingCondition.BatchSize != nil { + f2.SetBatchSize(*cr.Spec.ForProvider.EventBatchingCondition.BatchSize) + } + if cr.Spec.ForProvider.EventBatchingCondition.BatchWindow != nil { + f2.SetBatchWindow(*cr.Spec.ForProvider.EventBatchingCondition.BatchWindow) + } + res.SetEventBatchingCondition(f2) + } + if cr.Spec.ForProvider.Predicate != nil { + f3 := &svcsdk.Predicate{} + if cr.Spec.ForProvider.Predicate.Conditions != nil { + f3f0 := []*svcsdk.Condition{} + for _, f3f0iter := range cr.Spec.ForProvider.Predicate.Conditions { + f3f0elem := &svcsdk.Condition{} + if f3f0iter.CrawlState != nil { + f3f0elem.SetCrawlState(*f3f0iter.CrawlState) + } + if f3f0iter.CrawlerName != nil { + f3f0elem.SetCrawlerName(*f3f0iter.CrawlerName) + } + if f3f0iter.JobName != nil { + f3f0elem.SetJobName(*f3f0iter.JobName) + } + if f3f0iter.LogicalOperator != nil { + f3f0elem.SetLogicalOperator(*f3f0iter.LogicalOperator) + } + if f3f0iter.State != nil { + f3f0elem.SetState(*f3f0iter.State) + } + f3f0 = append(f3f0, f3f0elem) + } + f3.SetConditions(f3f0) + } + if cr.Spec.ForProvider.Predicate.Logical != nil { + f3.SetLogical(*cr.Spec.ForProvider.Predicate.Logical) + } + res.SetPredicate(f3) + } + if cr.Spec.ForProvider.Schedule != nil { + res.SetSchedule(*cr.Spec.ForProvider.Schedule) + } + if cr.Spec.ForProvider.StartOnCreation != nil { + res.SetStartOnCreation(*cr.Spec.ForProvider.StartOnCreation) + } + if cr.Spec.ForProvider.Tags != nil { + f6 := map[string]*string{} + for f6key, f6valiter := range cr.Spec.ForProvider.Tags { + var f6val string + f6val = *f6valiter + f6[f6key] = &f6val + } + res.SetTags(f6) + } + if cr.Spec.ForProvider.TriggerType != nil { + res.SetType(*cr.Spec.ForProvider.TriggerType) + } + if cr.Spec.ForProvider.WorkflowName != nil { + res.SetWorkflowName(*cr.Spec.ForProvider.WorkflowName) + } + + return res +} + +// GenerateUpdateTriggerInput returns an update input. +func GenerateUpdateTriggerInput(cr *svcapitypes.Trigger) *svcsdk.UpdateTriggerInput { + res := &svcsdk.UpdateTriggerInput{} + + if cr.Status.AtProvider.Name != nil { + res.SetName(*cr.Status.AtProvider.Name) + } + + return res +} + +// GenerateDeleteTriggerInput returns a deletion input. +func GenerateDeleteTriggerInput(cr *svcapitypes.Trigger) *svcsdk.DeleteTriggerInput { + res := &svcsdk.DeleteTriggerInput{} + + return res +} + +// IsNotFound returns whether the given error is of type NotFound or not. +func IsNotFound(err error) bool { + awsErr, ok := err.(awserr.Error) + return ok && awsErr.Code() == "EntityNotFoundException" +}