Skip to content

Commit d7f4369

Browse files
authored
Clone manifests not to modify original manifests (#5306)
Signed-off-by: t-kikuc <[email protected]>
1 parent 883383b commit d7f4369

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

pkg/app/piped/driftdetector/ecs/detector.go

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,11 @@ func (d *detector) checkApplication(ctx context.Context, app *model.Application,
209209
d.logger.Info(fmt.Sprintf("application %s has live ecs definition files", app.Id))
210210

211211
// Ignore some fields whech are not necessary or unable to detect diff.
212-
ignoreParameters(liveManifests, headManifests)
212+
live, head := ignoreParameters(liveManifests, headManifests)
213213

214214
result, err := provider.Diff(
215-
liveManifests,
216-
headManifests,
215+
live,
216+
head,
217217
diff.WithEquateEmpty(),
218218
diff.WithIgnoreAddingMapKeys(),
219219
diff.WithCompareNumberAndNumericString(),
@@ -237,8 +237,8 @@ func (d *detector) checkApplication(ctx context.Context, app *model.Application,
237237
// TODO: Maybe we should check diff of following fields when not set in the head manifests in some way. Currently they are ignored:
238238
// - service.PlatformVersion
239239
// - service.RoleArn
240-
func ignoreParameters(liveManifests provider.ECSManifests, headManifests provider.ECSManifests) {
241-
liveService := liveManifests.ServiceDefinition
240+
func ignoreParameters(liveManifests provider.ECSManifests, headManifests provider.ECSManifests) (live, head provider.ECSManifests) {
241+
liveService := *liveManifests.ServiceDefinition
242242
liveService.CreatedAt = nil
243243
liveService.CreatedBy = nil
244244
liveService.Events = nil
@@ -251,9 +251,10 @@ func ignoreParameters(liveManifests provider.ECSManifests, headManifests provide
251251
liveService.TaskDefinition = nil // TODO: Find a way to compare the task definition if possible.
252252
liveService.TaskSets = nil
253253

254-
liveTask := liveManifests.TaskDefinition
255-
// When liveTask does not exist, e.g. right after the service is created.
256-
if liveTask != nil {
254+
var liveTask types.TaskDefinition
255+
if liveManifests.TaskDefinition != nil {
256+
// When liveTask does not exist, e.g. right after the service is created.
257+
liveTask = *liveManifests.TaskDefinition
257258
liveTask.RegisteredAt = nil
258259
liveTask.RegisteredBy = nil
259260
liveTask.RequiresAttributes = nil
@@ -267,7 +268,7 @@ func ignoreParameters(liveManifests provider.ECSManifests, headManifests provide
267268
}
268269
}
269270

270-
headService := headManifests.ServiceDefinition
271+
headService := *headManifests.ServiceDefinition
271272
if headService.PlatformVersion == nil {
272273
// The LATEST platform version is used by default if PlatformVersion is not specified.
273274
// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html#ECS-CreateService-request-platformVersion.
@@ -279,37 +280,43 @@ func ignoreParameters(liveManifests provider.ECSManifests, headManifests provide
279280
headService.RoleArn = liveService.RoleArn
280281
}
281282
if headService.NetworkConfiguration != nil && headService.NetworkConfiguration.AwsvpcConfiguration != nil {
282-
awsvpcCfg := headService.NetworkConfiguration.AwsvpcConfiguration
283+
awsvpcCfg := *headService.NetworkConfiguration.AwsvpcConfiguration
284+
awsvpcCfg.Subnets = slices.Clone(awsvpcCfg.Subnets)
283285
slices.Sort(awsvpcCfg.Subnets)
284286
if len(awsvpcCfg.AssignPublicIp) == 0 {
285287
// AssignPublicIp is DISABLED by default.
286288
// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AwsVpcConfiguration.html#ECS-Type-AwsVpcConfiguration-assignPublicIp.
287289
awsvpcCfg.AssignPublicIp = types.AssignPublicIpDisabled
288290
}
291+
headService.NetworkConfiguration = &types.NetworkConfiguration{AwsvpcConfiguration: &awsvpcCfg}
289292
}
290293

291294
// Sort the subnets of the live service as well
292295
if liveService.NetworkConfiguration != nil && liveService.NetworkConfiguration.AwsvpcConfiguration != nil {
293-
awsvpcCfg := liveService.NetworkConfiguration.AwsvpcConfiguration
296+
awsvpcCfg := *liveService.NetworkConfiguration.AwsvpcConfiguration
297+
awsvpcCfg.Subnets = slices.Clone(awsvpcCfg.Subnets)
294298
slices.Sort(awsvpcCfg.Subnets)
299+
liveService.NetworkConfiguration = &types.NetworkConfiguration{AwsvpcConfiguration: &awsvpcCfg}
295300
}
296301

297302
// TODO: In order to check diff of the tags, we need to add pipecd-managed tags and sort.
298303
liveService.Tags = nil
299304
headService.Tags = nil
300305

301-
headTask := headManifests.TaskDefinition
306+
headTask := *headManifests.TaskDefinition
302307
headTask.Status = types.TaskDefinitionStatusActive // If livestate's status is not ACTIVE, we should re-deploy a new task definition.
303-
if liveTask != nil {
308+
if liveManifests.TaskDefinition != nil {
304309
headTask.Compatibilities = liveTask.Compatibilities // Users can specify Compatibilities in a task definition file, but it is not used when registering a task definition.
305310
}
306311

312+
headTask.ContainerDefinitions = slices.Clone(headManifests.TaskDefinition.ContainerDefinitions)
307313
for i := range headTask.ContainerDefinitions {
308314
cd := &headTask.ContainerDefinitions[i]
309315
if cd.Essential == nil {
310316
// Essential is true by default. See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html#ECS-Type-ContainerDefinition-es.
311317
cd.Essential = aws.Bool(true)
312318
}
319+
cd.PortMappings = slices.Clone(cd.PortMappings)
313320
for j := range cd.PortMappings {
314321
pm := &cd.PortMappings[j]
315322
if len(pm.Protocol) == 0 {
@@ -319,6 +326,10 @@ func ignoreParameters(liveManifests provider.ECSManifests, headManifests provide
319326
pm.HostPort = nil // We ignore diff of HostPort because it has several default values.
320327
}
321328
}
329+
330+
live = provider.ECSManifests{ServiceDefinition: &liveService, TaskDefinition: &liveTask}
331+
head = provider.ECSManifests{ServiceDefinition: &headService, TaskDefinition: &headTask}
332+
return live, head
322333
}
323334

324335
func (d *detector) loadConfigs(app *model.Application, repo git.Repo, headCommit git.Commit) (provider.ECSManifests, error) {

pkg/app/piped/driftdetector/ecs/detector_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,25 @@ func TestIgnoreParameters(t *testing.T) {
162162
},
163163
}
164164

165-
ignoreParameters(livestate, headManifest)
165+
ignoredLive, ignoredHead := ignoreParameters(livestate, headManifest)
166+
166167
result, err := provider.Diff(
167-
livestate,
168-
headManifest,
168+
ignoredLive,
169+
ignoredHead,
169170
diff.WithEquateEmpty(),
170171
diff.WithIgnoreAddingMapKeys(),
171172
diff.WithCompareNumberAndNumericString(),
172173
)
173174

174175
assert.NoError(t, err)
175176
assert.Equal(t, false, result.Diff.HasDiff())
177+
178+
// Check if the original manifests are not modified.
179+
assert.Equal(t, []string{"1_test-subnet", "0_test-subnet"}, headManifest.ServiceDefinition.NetworkConfiguration.AwsvpcConfiguration.Subnets)
180+
assert.Equal(t, []string{"1_test-sg", "0_test-sg"}, livestate.ServiceDefinition.NetworkConfiguration.AwsvpcConfiguration.SecurityGroups)
181+
assert.Equal(t, 0, len(headManifest.TaskDefinition.Status))
182+
assert.Nil(t, headManifest.TaskDefinition.ContainerDefinitions[1].Essential)
183+
assert.Equal(t, 0, len(headManifest.TaskDefinition.ContainerDefinitions[0].PortMappings[0].Protocol))
176184
}
177185

178186
func TestIgnoreAutoScalingDiff(t *testing.T) {

0 commit comments

Comments
 (0)