Skip to content
Merged
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
28 changes: 28 additions & 0 deletions api_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3739,6 +3739,34 @@ paths:
500:
description: "Internal Server Error"

"/apps/{app_id}/restart":
post:
description: "restarts app by pulling the latest image"
tags:
- apps
consumes:
- application/json
parameters:
- in: header
name: Authorization
required: true
description: "Bearer [token]"
type: string
- in: path
name: app_id
required: true
type: string

responses:
201:
description: "Success"
404:
description: "App not found"
400:
description: "Bad request"
500:
description: "Internal Server Error"

"/apps/{app_id}/{user_id}/docker/{tag}/webhook":
post:
description: "redeploys apps by getting webhook notifiations from docker"
Expand Down
66 changes: 66 additions & 0 deletions app/controllers/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,72 @@ def get(self, app_id):
return dict(status='fail', message=str(exc)), 500


class AppRestartView(Resource):
@jwt_required
def post(self, app_id):
"""
restart app, to pull the latest images
"""
try:
current_user_id = get_jwt_identity()
current_user_roles = get_jwt_claims()['roles']
app = App.get_by_id(app_id)

if not app:
return dict(status='fail', message=f'App {app_id} not found'), 404

project = app.project

if not is_owner_or_admin(project, current_user_id, current_user_roles):
if not is_authorised_project_user(project, current_user_id, 'admin'):
return dict(status='fail', message='Unauthorised'), 403

cluster = project.cluster
namespace = project.alias
if not cluster or not namespace:
return dict(status='fail', message='Internal server error'), 500

kube_host = cluster.host
kube_token = cluster.token
kube_client = create_kube_clients(kube_host, kube_token)

dep_name = f'{app.alias}-deployment'

# Create restart annotation
now = datetime.datetime.utcnow().isoformat()

patch_body = {
"spec": {
"template": {
"metadata": {
"annotations": {
"kubectl.kubernetes.io/restartedAt": now
}
}
}
}
}
# Patch the deployment
kube_client.appsv1_api.patch_namespaced_deployment(
name=dep_name,
namespace=namespace,
body=patch_body,
_preload_content=False
)

log_activity('App', status='Success',
operation='Restart',
description='App restarted successfully',
a_project=project,
a_cluster_id=project.cluster_id,
a_app=app)
return dict(status='success', message='App restarted successfully'), 200
except client.rest.ApiException as exc:
return dict(status='fail', message=exc.reason), check_kube_error_code(exc.status)
except Exception as exc:
return dict(status='fail', message=str(exc)), 500


class AppRevertView(Resource):
@jwt_required
def patch(self, app_id):
Expand Down
10 changes: 6 additions & 4 deletions app/routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
BillingInvoiceView, BillingInvoiceNotificationView, SystemSummaryView, CreditDetailView, ProjectUsersView, ProjectUsersTransferView, AppReviseView,
ProjectUsersHandleInviteView, ClusterProjectsView, ProjectDisableView, ProjectEnableView, AppRedeployView, AppDisableView, AppEnableView,
TagsView, TagsDetailView, TagFollowingView, GenericSearchView, MLProjectAppsView, ProjectMigrationView,
UserDisableView, UserEnableView, AppDockerWebhookListenerView, UserFollowersView, UserFollowView, ProjectFollowingView, ActivityFeedView, SendInactiveUserMailReminder,GoogleOAuthView,TagProjectsView)
from app.controllers.app import AppRevisionsView
UserDisableView, UserEnableView, AppDockerWebhookListenerView, UserFollowersView, UserFollowView, ProjectFollowingView, ActivityFeedView, SendInactiveUserMailReminder, GoogleOAuthView, TagProjectsView)
from app.controllers.app import AppRestartView, AppRevisionsView
from app.controllers.app_domain import AppDomainView, AppDomainDetailView
from app.controllers.billing_invoice import BillingInvoiceDetailView
from app.controllers.receipts import BillingReceiptsDetailView, BillingReceiptsView
Expand Down Expand Up @@ -172,6 +172,7 @@
api.add_resource(AppDetailView, '/apps/<string:app_id>')
api.add_resource(AppRevertView, '/apps/<string:app_id>/revert_url')
api.add_resource(AppRevisionsView, '/apps/<string:app_id>/revisions')
api.add_resource(AppRestartView, '/apps/<string:app_id>/restart')
api.add_resource(
AppReviseView, '/apps/<string:app_id>/revise/<string:revision_id>')
api.add_resource(
Expand All @@ -189,7 +190,8 @@

# App Domain routes
api.add_resource(AppDomainView, '/apps/<string:app_id>/domains')
api.add_resource(AppDomainDetailView, '/apps/<string:app_id>/domains/<string:domain_id>')
api.add_resource(AppDomainDetailView,
'/apps/<string:app_id>/domains/<string:domain_id>')


# Registry routes
Expand All @@ -211,4 +213,4 @@
api.add_resource(SendInactiveUserMailReminder, '/users/inactive_user_reminder',
endpoint='inactive_user_reminder')

api.add_resource(SocialView, '/socials', endpoint='socials')
api.add_resource(SocialView, '/socials', endpoint='socials')
Loading