Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions pkg/operator/resources/batchapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,19 @@ func UpdateAPI(apiConfig *userconfig.API, projectID string) (*spec.API, string,

err = applyK8sResources(api, prevVirtualService)
if err != nil {
return nil, "", err
rollBackErr := rollBack(prevVirtualService)
if rollBackErr != nil {
return nil, "", err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be good to return both errors, and say something along the lines of “update failed” with the error, and “During rollback, another error occurred” with that error

}
return nil, "update failed; rollbacked to previous deployment", nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might still be good to return the error, in case the user can do anything about it

}

if err := operator.UpdateAPIGatewayK8s(prevVirtualService, api, true); err != nil {
return nil, "", err
rollBackErr := rollBack(prevVirtualService)
if rollBackErr != nil {
return nil, "", err
}
return nil, "update failed; rollbacked to previous deployment", nil
}

return api, fmt.Sprintf("updated %s", api.Resource.UserString()), nil
Expand All @@ -90,6 +98,26 @@ func UpdateAPI(apiConfig *userconfig.API, projectID string) (*spec.API, string,
return api, fmt.Sprintf("%s is up to date", api.Resource.UserString()), nil
}

func rollBack(prevVirtualService *istioclientnetworking.VirtualService) error {
prevAPIID := prevVirtualService.Labels["apiID"]
prevAPIName := prevVirtualService.Labels["apiName"]

prevAPI, err := operator.DownloadAPISpec(prevAPIName, prevAPIID)
if err != nil {
return err
}

if err := applyK8sResources(prevAPI, prevVirtualService); err != nil {
return err
}

if err := operator.UpdateAPIGatewayK8s(prevVirtualService, prevAPI, false); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the third arg be “true”?

return err
}

return nil
}

func DeleteAPI(apiName string, keepCache bool) error {
// best effort deletion, so don't handle error yet
virtualService, vsErr := config.K8s.GetVirtualService(operator.K8sName(apiName))
Expand Down
34 changes: 31 additions & 3 deletions pkg/operator/resources/realtimeapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func UpdateAPI(apiConfig *userconfig.API, projectID string, force bool) (*spec.A
}

if err := applyK8sResources(api, prevDeployment, prevService, prevVirtualService); err != nil {
go deleteK8sResources(api.Name)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we still delete what may have been created?

return nil, "", err
}
err = operator.AddAPIToAPIGateway(*api.Networking.Endpoint, api.Networking.APIGateway, false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove from api gateway if this fails, like we do for batch APIs?

Expand Down Expand Up @@ -98,10 +98,18 @@ func UpdateAPI(apiConfig *userconfig.API, projectID string, force bool) (*spec.A
}

if err := applyK8sResources(api, prevDeployment, prevService, prevVirtualService); err != nil {
return nil, "", err
rollBackErr := rollBack(prevDeployment, prevService, prevVirtualService)
if rollBackErr != nil {
return nil, "", err
}
return nil, "update failed; rollbacked to previous deployment", nil
}
if err := operator.UpdateAPIGatewayK8s(prevVirtualService, api, false); err != nil {
return nil, "", err
rollBackErr := rollBack(prevDeployment, prevService, prevVirtualService)
if rollBackErr != nil {
return nil, "", err
}
return nil, "update failed; rollbacked to previous deployment", nil
}
return api, fmt.Sprintf("updating %s", api.Resource.UserString()), nil
}
Expand All @@ -117,6 +125,26 @@ func UpdateAPI(apiConfig *userconfig.API, projectID string, force bool) (*spec.A
return api, fmt.Sprintf("%s is up to date", api.Resource.UserString()), nil
}

func rollBack(prevDeployment *kapps.Deployment, prevService *kcore.Service, prevVirtualService *istioclientnetworking.VirtualService) error {
prevAPIID := prevVirtualService.Labels["apiID"]
prevAPIName := prevVirtualService.Labels["apiName"]

prevAPI, err := operator.DownloadAPISpec(prevAPIName, prevAPIID)
if err != nil {
return err
}

if err := applyK8sResources(prevAPI, prevDeployment, prevService, prevVirtualService); err != nil {
return err
}

if err := operator.UpdateAPIGatewayK8s(prevVirtualService, prevAPI, false); err != nil {
return err
}

return nil
}

func RefreshAPI(apiName string, force bool) (string, error) {
prevDeployment, err := config.K8s.GetDeployment(operator.K8sName(apiName))
if err != nil {
Expand Down
32 changes: 30 additions & 2 deletions pkg/operator/resources/trafficsplitter/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,45 @@ func UpdateAPI(apiConfig *userconfig.API, force bool) (*spec.API, string, error)
return nil, "", errors.Wrap(err, "upload api spec")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(above) Should we remove from API Gateway if adding it failed, like we do in batch?

}
if err := applyK8sVirtualService(api, prevVirtualService); err != nil {
return nil, "", err
rollBackErr := rollBack(prevVirtualService)
if rollBackErr != nil {
return nil, "", err
}
return nil, "update failed; rollbacked to previous deployment", nil
}
if err := operator.UpdateAPIGatewayK8s(prevVirtualService, api, false); err != nil {
return nil, "", err
rollBackErr := rollBack(prevVirtualService)
if rollBackErr != nil {
return nil, "", err
}
return nil, "update failed; rollbacked to previous deployment", nil
}
return api, fmt.Sprintf("updated %s", api.Resource.UserString()), nil
}

return api, fmt.Sprintf("%s is up to date", api.Resource.UserString()), nil
}

func rollBack(prevVirtualService *istioclientnetworking.VirtualService) error {
prevAPIID := prevVirtualService.Labels["apiID"]
prevAPIName := prevVirtualService.Labels["apiName"]

prevAPI, err := operator.DownloadAPISpec(prevAPIName, prevAPIID)
if err != nil {
return err
}

if err := applyK8sVirtualService(prevAPI, prevVirtualService); err != nil {
return err
}

if err := operator.UpdateAPIGatewayK8s(prevVirtualService, prevAPI, false); err != nil {
return err
}

return nil
}

func DeleteAPI(apiName string, keepCache bool) error {
// best effort deletion, so don't handle error yet
virtualService, vsErr := config.K8s.GetVirtualService(operator.K8sName(apiName))
Expand Down