Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added transport layer classes for getting and deleting the workflow #835

Conversation

stevanbz
Copy link
Contributor

@stevanbz stevanbz commented Mar 23, 2023

Issue #, if available:
#834
Description of changes:
Added classes for getting and deleting the workflows.

CheckList:
[ ] Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@stevanbz stevanbz requested a review from a team March 23, 2023 18:21

val searchRequest = SearchRequest()
.indices(ScheduledJob.SCHEDULED_JOBS_INDEX)
.source(SearchSourceBuilder().query(queryBuilder).fetchSource(true))
Copy link
Member

Choose a reason for hiding this comment

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

do we need fetch source as true?

.indices(ScheduledJob.SCHEDULED_JOBS_INDEX)
.source(SearchSourceBuilder().query(queryBuilder).fetchSource(true))

val searchResponse: SearchResponse = client.suspendUntil { search(searchRequest, it) }
Copy link
Member

Choose a reason for hiding this comment

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

plz add a try catch for search response failure. Log error that validation failed and re-throw the error as required

if (searchResponse.hits.totalHits?.value == 0L) {
return true
}
return false
Copy link
Member

Choose a reason for hiding this comment

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

add validation failure reason as info or error log

Copy link
Member

Choose a reason for hiding this comment

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

how are we returning this infromation to user in delete failed response?

Copy link
Member

Choose a reason for hiding this comment

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

it can't tailgate on 403 security error

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can see here - if the canDelete is false, user is getting the message that the monitor can't be deleted. The question is should we be more descriptive or it's enough to say that user is not allowed to do deleting.
Now I just saw Ashish comment - where he said that we should tell to end user that the monitor can't be deleted because it is a part of the workflow

Copy link
Member

@eirsep eirsep left a comment

Choose a reason for hiding this comment

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

added minor comments

if (searchResponse.hits.totalHits?.value == 0L) {
return true
}
return false
Copy link
Member

Choose a reason for hiding this comment

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

how are we returning this infromation to user in delete failed response?

if (searchResponse.hits.totalHits?.value == 0L) {
return true
}
return false
Copy link
Member

Choose a reason for hiding this comment

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

it can't tailgate on 403 security error

return client.suspendUntil { delete(deleteRequest, it) }
}

private suspend fun deleteMetadata(workflow: Workflow) {
Copy link
Member

Choose a reason for hiding this comment

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

plz add debug logs like "deleting metadata",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok this part is copy pasted - even we don't have workflow metada. will comment out the call and add TODO - since we are going to introduce the metadata with workflow execution. Tnx!


private suspend fun deleteMetadata(workflow: Workflow) {
val deleteRequest = DeleteRequest(ScheduledJob.SCHEDULED_JOBS_INDEX, "${workflow.id}-metadata")
val deleteResponse: DeleteResponse = client.suspendUntil { delete(deleteRequest, it) }
Copy link
Member

Choose a reason for hiding this comment

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

add try catch for failure in deletion and log error and re-throw wrapped exception

getRequest,
object : ActionListener<GetResponse> {
override fun onResponse(response: GetResponse) {
if (!response.isExists) {
Copy link
Member

Choose a reason for hiding this comment

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

error log

}

override fun onFailure(t: Exception) {
if (t is IndexNotFoundException) {
Copy link
Member

Choose a reason for hiding this comment

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

error log

val canDelete = user == null ||
!doFilterForUser(user) ||
checkUserPermissionsWithResource(user, monitor.user, actionListener, "monitor", monitorId)
val canDelete = monitorIsNotInWorkflows(monitor.id) && (
Copy link
Member

Choose a reason for hiding this comment

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

If the monitor cannot be deleted if it is part of a workflow, we need to mention it is part of a workflow and that is why it cannot be deleted.

.indices(ScheduledJob.SCHEDULED_JOBS_INDEX)
.source(SearchSourceBuilder().query(queryBuilder).fetchSource(true))

val searchResponse: SearchResponse = client.suspendUntil { search(searchRequest, it) }
Copy link
Member

Choose a reason for hiding this comment

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

We need to stash the context since the user would not have permissions to search the alerting config index directly.
reference: https://github.com/opensearch-project/alerting/blob/main/alerting/src/main/kotlin/org/opensearch/alerting/transport/TransportGetMonitorAction.kt#L66-L72

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it good point!

*/
private suspend fun getDeletableDelegates(workflowIdToBeDeleted: String, monitorIds: List<String>): List<String> {
// Retrieve monitors belonging to another workflows
val queryBuilder = QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery("_id", workflowIdToBeDeleted)).filter(
Copy link
Member

Choose a reason for hiding this comment

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

We need to check if the user has permissions to these monitor with the backend roles too as the monitors could get modified later and the user might not have the backend roles to access those monitors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aaahh got it! Good point

// Check if user can access the monitors (since the monitors could get modified later and the user might not have the backend roles to access the monitors)
if (user != null && filterByEnabled) {
addFilter(user, searchRequest.source(), "monitor.user.backend_roles.keyword")
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we add a SecureWorkflowMonitorIT test case to test this part of code (both with & without) backend roles.


val user = readUserFromThreadContext(client)
val deleteRequest = DeleteRequest(ScheduledJob.SCHEDULED_JOBS_INDEX, transformedRequest.workflowId)
.setRefreshPolicy(RefreshPolicy.IMMEDIATE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

transformedRequest.deleteDelegateMonitors,
user,
transformedRequest.workflowId
).resolveUserAndStart()
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need make resolveUserAndStart a suspend function? is there any advantage? i see TransportIndexMonitorAction not doing it. https://github.com/opensearch-project/alerting/blob/main/alerting/src/main/kotlin/org/opensearch/alerting/transport/TransportIndexMonitorAction.kt#L247

Copy link
Contributor Author

Choose a reason for hiding this comment

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

deleteMonitors and deleteWorkflow are suspend functions - both are called by resolveUserAndStart

actionListener,
"workflow",
getWorkflowRequest.workflowId
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets add a SecureWorkflowMonitorIT test case for TransportGetWorkflowAction also.

@stevanbz stevanbz force-pushed the feature/composite-monitors-get-delete-workflow branch from e571313 to 0ab964a Compare March 31, 2023 20:08
@@ -126,10 +127,11 @@ class TransportDeleteWorkflowAction @Inject constructor(

if (canDelete) {
val deleteResponse = deleteWorkflow(workflow)
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 attempt to delete monitors first and then delete the workflow? And only delete everything if the user has permission to delete everything?

.indices(ScheduledJob.SCHEDULED_JOBS_INDEX)
.source(SearchSourceBuilder().query(queryBuilder))

// Check if user can access the monitors (since the monitors could get modified later and the user might not have the backend roles to access the monitors)
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: remove extra space ( ) between Check and if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Member

Choose a reason for hiding this comment

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

remove this

Copy link
Member

Choose a reason for hiding this comment

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

remove this

Copy link
Member

Choose a reason for hiding this comment

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

remove this

stevanbz added 3 commits April 3, 2023 23:31
…specified when deleting the workflow

Signed-off-by: Stevan Buzejic <[email protected]>
Signed-off-by: Stevan Buzejic <[email protected]>
) {
actionListener.onFailure(
AlertingException(
"Not allowed to delete ${delegateMonitorIds.joinToString()} monitors",
Copy link
Member

Choose a reason for hiding this comment

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

Lets remove the monitors from this list that can be deleted from monitorIdsToBeDeleted

@lezzago lezzago merged commit 9f4a61f into opensearch-project:feature/composite-monitors Apr 4, 2023
eirsep pushed a commit that referenced this pull request May 24, 2023
…835)

* Added transport layer classes for getting and deleting the workflow

Signed-off-by: Stevan Buzejic <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants