Skip to content

Commit

Permalink
Revert "WOR-659 Remove v1 billing and workspaces code - Part 1 (#2492)…
Browse files Browse the repository at this point in the history
…" (#2504)

This reverts commit 107b957.
  • Loading branch information
blakery authored Aug 24, 2023
1 parent 9dbad07 commit 986159f
Show file tree
Hide file tree
Showing 17 changed files with 1,333 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)

// remove "student" from billing project
Rawls.billingV2.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)

Expand Down Expand Up @@ -120,7 +120,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)

// remove "student" from billing project
Rawls.billingV2.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)
Expand All @@ -146,7 +146,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)
Expand Down Expand Up @@ -175,13 +175,13 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)

// remove "student" from billing project
Rawls.billingV2.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)
Expand All @@ -206,7 +206,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)

Expand Down Expand Up @@ -238,7 +238,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)

Expand All @@ -248,7 +248,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)

// remove "student" from billing project
Rawls.billingV2.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)
Expand Down Expand Up @@ -276,7 +276,7 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
Sam.user.addUserToPolicy(groupName, GroupRole.Member.toString, student.email)(projectOwnerToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)

Expand Down Expand Up @@ -309,14 +309,14 @@ class AuthDomainGroupRoleSpec extends AnyFreeSpec with WorkspaceFixtures with Gr
Sam.user.addUserToPolicy(groupName, GroupRole.Member.toString, student.email)(projectOwnerToken)

// add "student" to billing project with owner role
Rawls.billingV2.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.addUserToBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)

AuthDomainMatcher.checkVisibleAndAccessible(projectName, workspaceName, List(groupName))(studentToken)

// remove "student" from billing project
Rawls.billingV2.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
Rawls.billing.removeUserFromBillingProject(projectName, student.email, BillingProjectRole.Owner)(
projectOwnerToken
)
AuthDomainMatcher.checkNotVisibleNotAccessible(projectName, workspaceName)(studentToken)
Expand Down
186 changes: 186 additions & 0 deletions core/src/main/resources/swagger/api-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ servers:
- url: /
tags:
- name: admin
- name: billing
- name: billing_v2
- name: entities
- name: methodconfigs
Expand Down Expand Up @@ -72,6 +73,102 @@ paths:
'application/json':
schema:
$ref: '#/components/schemas/ExecutionEngineVersion'
/api/billing/{projectId}/members:
get:
tags:
- billing
summary: list members of billing project
description: List members of billing project. Owners can view all members, users will only be able to view owners. Deprecated, use v2 version.
deprecated: true
operationId: listBillingProjectMembers
parameters:
- $ref: '#/components/parameters/billingProjectIdPathParam'
responses:
200:
description: Success
content:
'application/json':
schema:
type: array
items:
$ref: '#/components/schemas/RawlsBillingProjectMember'
403:
description: You must be a project member to view the members of a project
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
500:
$ref: '#/components/responses/RawlsInternalError'
/api/billing/{projectId}/{workbenchRole}/{email}:
put:
tags:
- billing
summary: add user or group to billing project the caller owns
description: Add user or group to billing project the caller owns. Deprecated, use v2 version.
deprecated: true
operationId: addUserToBillingProject
parameters:
- $ref: '#/components/parameters/billingProjectIdPathParam'
- $ref: '#/components/parameters/workbenchRolePathParam'
- name: email
in: path
description: email of user or group to add
required: true
schema:
type: string
responses:
200:
description: Successfully Added User/Group To Billing Project
content: {}
403:
description: You must be a project owner to add a user to a billing project
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
404:
description: User not found
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
500:
$ref: '#/components/responses/RawlsInternalError'
delete:
tags:
- billing
summary: remove user or group from billing project the caller owns
description: Remove user or group from billing project the caller owns. Deprecated, use v2 version.
deprecated: true
operationId: removeUserFromBillingProject
parameters:
- $ref: '#/components/parameters/billingProjectIdPathParam'
- $ref: '#/components/parameters/workbenchRolePathParam'
- name: email
in: path
description: email of user or group to remove
required: true
schema:
type: string
responses:
200:
description: Successfully Removed User From Billing Project
content: {}
403:
description: You must be a project owner to add a user to a billing project
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
404:
description: User not found
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
500:
$ref: '#/components/responses/RawlsInternalError'
/api/billing/v2:
get:
tags:
Expand Down Expand Up @@ -3557,9 +3654,98 @@ paths:
content: {}
500:
$ref: '#/components/responses/RawlsInternalError'
/api/user/billing:
get:
tags:
- billing
- users
summary: list billing projects for a user
description: List billing projects for a user. Deprecated, use v2 version.
deprecated: true
operationId: listUserBillingProjects
responses:
200:
description: Successful Request
content:
'application/json':
schema:
type: array
description: list of billing projects for this user
items:
$ref: '#/components/schemas/RawlsBillingProjectMembership'
404:
description: User not found
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
500:
$ref: '#/components/responses/RawlsInternalError'
/api/user/billing/{projectName}:
get:
tags:
- billing
- users
summary: billing project status
description: Billing project status. Deprecated, use v2 API.
deprecated: true
operationId: billingProjectStatus
parameters:
- name: projectName
in: path
description: Name of the billing project
required: true
schema:
type: string
responses:
200:
description: OK
content:
'application/json':
schema:
$ref: '#/components/schemas/RawlsBillingProjectStatus'
404:
description: Project Not Found
content: {}
500:
description: Internal Server Error
content: {}
delete:
tags:
- billing
- users
summary: delete billing project
description: Delete billing project. Deprecated, use v2 version.
deprecated: true
operationId: deleteBillingProject
parameters:
- name: projectName
in: path
description: Name of the billing project
required: true
schema:
type: string
responses:
204:
description: Successfully delete billing project
400:
description: Project cannot be deleted because it contains workspaces.
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
403:
description: You must be a project owner to delete billing project
content:
'application/json':
schema:
$ref: '#/components/schemas/ErrorReport'
500:
$ref: '#/components/responses/RawlsInternalError'
/api/user/billingAccounts:
get:
tags:
- billing
- users
summary: list billing accounts for a user
description: list billing accounts for a user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import org.broadinstitute.dsde.rawls.model.{
RawlsRequestContext
}
import org.broadinstitute.dsde.rawls.serviceperimeter.ServicePerimeterService
import org.broadinstitute.dsde.rawls.user.UserService.syncBillingProjectOwnerPolicyToGoogleAndGetEmail
import org.broadinstitute.dsde.rawls.user.UserService.{
deleteGoogleProjectIfChild,
syncBillingProjectOwnerPolicyToGoogleAndGetEmail
}

import java.util.UUID
import scala.concurrent.{ExecutionContext, Future}
Expand Down Expand Up @@ -64,7 +67,12 @@ class GoogleBillingProjectLifecycle(

override def initiateDelete(projectName: RawlsBillingProjectName, ctx: RawlsRequestContext)(implicit
executionContext: ExecutionContext
): Future[Option[UUID]] = Future.successful(None)
): Future[Option[UUID]] =
// Note: GoogleBillingProjectLifecycleSpec does not test that this method is called because the method
// lives in a companion object (which makes straight mocking impossible), and the method will be removed
// once workspace migration is complete. Note also that the more "integration" level test BillingApiServiceV2Spec
// does verify that code in this method is executed when a Google-based project is deleted.
deleteGoogleProjectIfChild(projectName, ctx.userInfo, gcsDAO, samDAO, ctx).map(_ => None)

override def finalizeDelete(projectName: RawlsBillingProjectName, ctx: RawlsRequestContext)(implicit
executionContext: ExecutionContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ abstract class GoogleServicesDAO(groupsPrefix: String) extends ErrorReportable {

def pollOperation(operationId: OperationId): Future[OperationStatus]

def deleteV1Project(googleProject: GoogleProjectId): Future[Unit]

def updateGoogleProject(googleProjectId: GoogleProjectId, googleProjectWithUpdates: Project): Future[Project]

def deleteGoogleProject(googleProject: GoogleProjectId): Future[Unit]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,36 @@ class HttpGoogleServicesDAO(val clientSecrets: GoogleClientSecrets,
} yield updated
}

// TODO - once workspace migration is complete and there are no more v1 workspaces or v1 billing projects, we can remove this https://broadworkbench.atlassian.net/browse/CA-1118
// V2 workspace projects are managed by rawls SA but the v1 billing google projects are managed by the billing SA.
override def deleteV1Project(googleProject: GoogleProjectId): Future[Unit] = {
implicit val service = GoogleInstrumentedService.Billing
val billingServiceAccountCredential = getBillingServiceAccountCredential

val resMgr = getCloudResourceManagerWithBillingServiceAccountCredential
val billingManager = getCloudBillingManager(billingServiceAccountCredential)

for {
_ <- retryWhen500orGoogleError { () =>
executeGoogleRequest(
billingManager
.projects()
.updateBillingInfo(s"projects/${googleProject.value}", new ProjectBillingInfo().setBillingEnabled(false))
)
}
_ <- retryWithRecoverWhen500orGoogleError { () =>
executeGoogleRequest(resMgr.projects().delete(googleProject.value))
} {
case e: GoogleJsonResponseException
if e.getDetails.getCode == 403 && "Cannot delete an inactive project.".equals(e.getDetails.getMessage) =>
new Empty()
// stop trying to delete an already deleted project
}
} yield {
// nothing
}
}

/**
* Updates the project specified by the googleProjectId with any values in googleProjectWithUpdates.
* @param googleProjectId project to update
Expand Down
Loading

0 comments on commit 986159f

Please sign in to comment.