Skip to content

Commit

Permalink
Implement job for app deletions
Browse files Browse the repository at this point in the history
Issue: cloudfoundry#2606

Co-authored-by: Giuseppe Capizzi <[email protected]>
  • Loading branch information
georgethebeatle and gcapizzi committed Jul 12, 2023
1 parent 720a2f0 commit 3a29482
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 26 deletions.
2 changes: 1 addition & 1 deletion api/handlers/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (h *Job) get(r *http.Request) (*routing.Response, error) {
switch job.Type {
case syncSpaceJobType:
jobResponse = presenter.ForManifestApplyJob(job, h.serverURL)
case AppDeleteJobType, RouteDeleteJobType, DomainDeleteJobType, RoleDeleteJobType:
case RouteDeleteJobType, DomainDeleteJobType, RoleDeleteJobType:
jobResponse = presenter.ForJob(job, []presenter.JobResponseError{}, presenter.StateComplete, h.serverURL)
default:
repository, ok := h.repositories[job.Type]
Expand Down
1 change: 0 additions & 1 deletion api/handlers/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ var _ = Describe("Job", func() {

Expect(rr).To(HaveHTTPBody(SatisfyAll(bodyMatchers...)))
},
Entry("app delete", "app.delete", "cf-app-guid"),
Entry("route delete", "route.delete", "cf-route-guid"),
Entry("domain delete", "domain.delete", "cf-domain-guid"),
Entry("role delete", "role.delete", "cf-role-guid"),
Expand Down
1 change: 1 addition & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ func main() {
map[string]handlers.DeletionRepository{
handlers.OrgDeleteJobType: orgRepo,
handlers.SpaceDeleteJobType: spaceRepo,
handlers.AppDeleteJobType: appRepo,
},
500*time.Millisecond,
),
Expand Down
10 changes: 10 additions & 0 deletions api/repositories/app_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type AppRecord struct {
Lifecycle Lifecycle
CreatedAt time.Time
UpdatedAt *time.Time
DeletedAt *time.Time
IsStaged bool
envSecretName string
vcapServiceSecretName string
Expand Down Expand Up @@ -515,6 +516,14 @@ func (f *AppRepo) GetAppEnv(ctx context.Context, authInfo authorization.Info, ap
return appEnvRecord, nil
}

func (f *AppRepo) GetDeletedAt(ctx context.Context, authInfo authorization.Info, appGUID string) (*time.Time, error) {
app, err := f.GetApp(ctx, authInfo, appGUID)
if err != nil {
return nil, err
}
return app.DeletedAt, nil
}

func getSystemEnv(ctx context.Context, userClient client.Client, app AppRecord) (map[string]any, error) {
systemEnvMap := map[string]any{}
if app.vcapServiceSecretName != "" {
Expand Down Expand Up @@ -638,6 +647,7 @@ func cfAppToAppRecord(cfApp korifiv1alpha1.CFApp) AppRecord {
},
CreatedAt: cfApp.CreationTimestamp.Time,
UpdatedAt: getLastUpdatedTime(&cfApp),
DeletedAt: golangTime(cfApp.DeletionTimestamp),
IsStaged: meta.IsStatusConditionTrue(cfApp.Status.Conditions, shared.StatusConditionReady),
envSecretName: cfApp.Spec.EnvSecretName,
vcapServiceSecretName: cfApp.Status.VCAPServicesSecretName,
Expand Down
47 changes: 47 additions & 0 deletions api/repositories/app_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ var _ = Describe("AppRepository", func() {
},
}))
Expect(app.IsStaged).To(BeFalse())
Expect(app.DeletedAt).To(BeNil())
})

When("the app has staged condition true", func() {
Expand Down Expand Up @@ -1450,6 +1451,52 @@ var _ = Describe("AppRepository", func() {
})
})
})

Describe("GetDeletedAt", func() {
var (
deletionTime *time.Time
getErr error
)

BeforeEach(func() {
createRoleBinding(testCtx, userName, orgUserRole.Name, cfOrg.Name)
createRoleBinding(testCtx, userName, spaceDeveloperRole.Name, cfSpace.Name)
})

JustBeforeEach(func() {
deletionTime, getErr = appRepo.GetDeletedAt(ctx, authInfo, cfApp.Name)
})

It("returns nil", func() {
Expect(getErr).NotTo(HaveOccurred())
Expect(deletionTime).To(BeNil())
})

When("the app is being deleted", func() {
BeforeEach(func() {
Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() {
cfApp.Finalizers = append(cfApp.Finalizers, "foo")
})).To(Succeed())

Expect(k8sClient.Delete(ctx, cfApp)).To(Succeed())
})

It("returns the deletion time", func() {
Expect(getErr).NotTo(HaveOccurred())
Expect(deletionTime).To(PointTo(BeTemporally("~", time.Now(), time.Minute)))
})
})

When("the app isn't found", func() {
BeforeEach(func() {
Expect(k8sClient.Delete(ctx, cfApp)).To(Succeed())
})

It("errors", func() {
Expect(getErr).To(matchers.WrapErrorAssignableToTypeOf(apierrors.NotFoundError{}))
})
})
})
})

func createApp(space string) *korifiv1alpha1.CFApp {
Expand Down
38 changes: 14 additions & 24 deletions tests/e2e/apps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,35 +248,25 @@ var _ = Describe("Apps", func() {
Eventually(func(g Gomega) {
resp, err = certClient.R().Get(jobURL)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(string(resp.Body())).To(ContainSubstring("COMPLETE"))
jobRespBody := string(resp.Body())
g.Expect(jobRespBody).To(ContainSubstring("COMPLETE"))
}).Should(Succeed())
})

It("successfully deletes the app and associated child resources", func() {
var result resource
Eventually(func(g Gomega) {
resp, err = certClient.R().SetResult(&result).Get("/v3/apps/" + appGUID)
g.Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))
g.Expect(err).NotTo(HaveOccurred())
}).Should(Succeed())
resp, err = certClient.R().Get("/v3/apps/" + appGUID)
Expect(err).NotTo(HaveOccurred())
Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))

Eventually(func(g Gomega) {
resp, err = certClient.R().SetResult(&result).Get("/v3/packages/" + pkgGUID)
g.Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))
g.Expect(err).NotTo(HaveOccurred())
}).Should(Succeed())
resp, err = certClient.R().Get("/v3/packages/" + pkgGUID)
Expect(err).NotTo(HaveOccurred())
Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))

Eventually(func(g Gomega) {
resp, err = certClient.R().SetResult(&result).Get("/v3/builds/" + buildGUID)
g.Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))
g.Expect(err).NotTo(HaveOccurred())
}).Should(Succeed())
resp, err = certClient.R().Get("/v3/builds/" + buildGUID)
Expect(err).NotTo(HaveOccurred())
Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))

Eventually(func(g Gomega) {
resp, err = certClient.R().SetResult(&result).Get("/v3/apps/" + appGUID + "/processes/" + processType)
g.Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))
g.Expect(err).NotTo(HaveOccurred())
}).Should(Succeed())
resp, err = certClient.R().Get("/v3/apps/" + appGUID + "/processes/" + processType)
Expect(err).NotTo(HaveOccurred())
Expect(resp).To(HaveRestyStatusCode(http.StatusNotFound))
})
})

Expand Down

0 comments on commit 3a29482

Please sign in to comment.