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

NIFI-375: Added operation policy #2990

Closed
wants to merge 12 commits into from

Conversation

ijokarumawak
Copy link
Member

@ijokarumawak ijokarumawak commented Sep 5, 2018

The operation policy allows that a user to operate components even if they does not have direct READ/WRITE permission of the component.

Following operations are controlled by the new operate policy:

  • Start/stop/enable/disable Processors, ControllerServices,
    ReportingTasks, Input/OuputPorts
  • Enable/disable transmission of RemoteInput/OutputPorts and
    RemoteProcessGroups
  • Terminate Processor threads

ControllerServices table view

image

  1. If the user doesn't have READ permission for the CS, 'Name' shows its uuid, and 'Type' and 'Bundle' are hidden.
  2. If the user has either WRITE or OPERATE permission, the enable/disable icon is shown to open the enable/disable dialog.
  3. If the user has READ, but no WRITE permission, they can only 'View Configuration'
  4. Only users having both READ and WRITE permissions can 'Configure' the CS

Enabling/Disabling ControllerService

This PR supports following spec based on the ControllerService and its referencing components permissions:

No CS READ CS WRITE or OPS Ref READ Ref WRITE or OPS Can Disable? Can Enable? Detail
1 F F - - No No No action button is shown.
2 T F - - No No Enable/Disable buttons are hidden.
3 F T Uncertain - No Service Only UI can't if there's any referencing components to disable. But directly sending a PUT request to controller-services/{id}/run-status can be successful, and can be used from operational scripts. NOTE Technically we can update the UI to do the same thing, but currently this PR doesn't allow this from UI.
4 T T No Ref - Yes Yes Since there's no referencing component, all actions are supported.
5 T T F F No Service Only Currently, UI doesn't look at referencing components run status if the user doesn't have READ permission.
6 T T T F No Service Only UI requires all referencing components can be operated. NOTE UI doesn't check if the referencing component is stopped or running. If all referencing components are stopped, it would be fine to allow disabling the CS. Directly calling API may be successful if all referencing components are stopped.
7 T T F T No Service Only UI can't traverse all referencing components. Directly calling API may be successful if all referencing components are stopped.
8 T T T T Yes Yes All actions are supported.

ReportingTasks view

image

  1. If the user doesn't have READ permission for the CS, 'Name' shows its uuid, and 'Type' and 'Bundle' are hidden.
  2. If the user has READ permission, they can see configuration and usage
  3. Start/stop icons can be seen by users having WRITE or OPERATE permission
  4. Only users having both READ and WRITE permissions can edit the ReportingTask. Delete icon is shown if the user has WRITE permission to controller.

Thank you for submitting a contribution to Apache NiFi.

In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:

For all changes:

  • Is there a JIRA ticket associated with this PR? Is it referenced
    in the commit message?

  • Does your PR title start with NIFI-XXXX where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.

  • Has your PR been rebased against the latest commit within the target branch (typically master)?

  • Is your initial contribution a single, squashed commit?

For code changes:

  • Have you ensured that the full suite of tests is executed via mvn -Pcontrib-check clean install at the root nifi folder?
  • Have you written or updated unit tests to verify your changes?
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE file, including the main LICENSE file under nifi-assembly?
  • If applicable, have you updated the NOTICE file, including the main NOTICE file found under nifi-assembly?
  • If adding new Properties, have you added .displayName in addition to .name (programmatic access) for each of the new properties?

For documentation related changes:

  • Have you ensured that format looks appropriate for the output in which it is rendered?

Note:

Please ensure that once the PR is submitted, you check travis-ci for build issues and submit an update to your PR as soon as possible.

@mcgilman
Copy link
Contributor

mcgilman commented Sep 5, 2018

Will review...

@ijokarumawak
Copy link
Member Author

@mcgilman Updated how API exposes required data to operate components. Although I need to do the similar refactoring with RGPs, the most complex ControllerService implementation is done. I updated the PR description, too, to illustrate how ControllerService enable/disable operations are authorized. It'd be great if you can review this while I'm working on the remaining RPG stuffs. Thanks!

@ijokarumawak
Copy link
Member Author

@mcgilman I hope this PR is now fully ready for review. Thanks.

@mcgilman
Copy link
Contributor

@ijokarumawak Thanks for the additional commits! Will review...

@mcgilman
Copy link
Contributor

@ijokarumawak Thanks for the update. I'm still in the process of reviewing but one thing that concerns me is where we've identified Service Only in the scenarios above. Currently (before the PR) the Enable case we allow the user to specify if they want to enable just this service or this service and all components that reference it (including other services and their referencing components). During the Disable case, we require that the user disables this service and all referencing components. This is because the referencing components require this service's availability to continue running.

The issue that we're hitting now is that a user with permissions outlined above with Service Only will be able to Enable this service but will be unable to subsequently disable it. Because of this, I'm wondering if we need to be even more strict to prevent this cases via the UI. I don't think its too restrictive as this is more of a corner case. The more common use case here will be granting operators permissions to the read policies and operation policies for these components.

Thoughts?

@@ -68,10 +75,13 @@ default void merge(final EntityType clientEntity, final Map<NodeIdentifier, Enti
if (clientEntity.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) {
clientEntity.setBulletins(clientEntity.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT));
}
} else {
clientEntity.setBulletins(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to continue to set the component to null when canRead is false. It may have been changed to accommodate an earlier iteration of this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. Thanks for caching this!

The operation policy allows that a user to operate components even if they does not have direct READ/WRITE
permission of the component.

Following operations are controlled by the new operate policy:
- Start/stop/enable/disable Processors, ControllerServices,
ReportingTasks, Input/OuputPorts
- Enable/disable transmission of RemoteInput/OutputPorts and
RemoteProcessGroups
- Terminate Processor threads
The previous commit let API exposes few fields in DTO. But we should
avoid returning partial DTO as it complicates authorization logic.

Instead, this commit adds StatusDTO for ReportingTaskEntity and
ControllerServiceEntity, so that it can be returned regardless of having
READ permission. Component DTO can only be returned with a READ
permission.
- Cleaned up merger classes
- Recreate DTO instance at each function during two phase commmit
@ijokarumawak
Copy link
Member Author

@mcgilman Rebased with the latest master and incorporated the feedback.

About the concern:

The issue that we're hitting now is that a user with permissions outlined above with Service Only will be able to Enable this service but will be unable to subsequently disable it.

I added another commit to address this, but I'm going to remove that commit. Because...

I confirmed that even before this PR, NiFi UI works like this if the user has READ/WRITE permissions for a CS, but only has READ to its referencing components. Such user can enable the CS if 'Service Only', but can not disable the CS because the referencing component can not be written.

@mcgilman
Copy link
Contributor

@ijokarumawak I see. You're correct that the existing codebase also exhibits this behavior. However, I think that its an issue we should consider fixing separately from this. Generally speaking, I think the UI should not allow the user to change something that they cannot change back (assuming the same permissions).

Let's proceed here and we can address this concern in a future effort. Thanks... I'll continue reviewing!

- Renamed confusing static method names and its parameters
- Removed unnecessary permission checks from UI condition
@mcgilman
Copy link
Contributor

@ijokarumawak This is looking really good! Just seeing a couple minor things aside from the NPE I commented in the code.

It looks like the operatePermissions were added to the ComponentEntity. This is good since this applied to the majority of components. However, I noticed that the operatePermissions was also added to the each of the concrete implementations (ProcessorEntity, PortEntity, etc). I do not believe we need the field and getter/setter methods within each concrete implementation. Is there a reason they are there?

Also, I think we need to apply the new Operation policy checks in FlowResource#activeControllerServices. This is essentially like the corresponding FlowResource#scheduleComponents but for ControllerServices. This endpoint is not called directly by the NiFi UI but I think it should probably utilize the new policy.

Thanks again!

@ijokarumawak
Copy link
Member Author

@mcgilman Incorporated the last review comments.

The original intent of having operatePermissions at each concrete entity implementation is to clarify which entity is OperationPermissible. I thought adding that to ComponentEntity is to vague as ComponentEntity is the super class of various entities, including those do not have running status such as AccessPolicySummaryEntity, TemplateEntity or UserGroupEntity.

I wasn't consistent enough while I was refactoring the code at some point and added it to ComponentEntity. But I still think the operatePermissions should exist with only component those can be operated. So, I removed operatePermissions from ComponentEntity.

I hope this we have polished this PR enough to get merged. Thanks for your comprehensive review comments!

@mcgilman
Copy link
Contributor

@ijokarumawak Thanks this looks good. I'm going to squash and merged to master. I've created two new JIRAs that are related to this effort but separate from the initial concern. Thanks again for working through all the review comments!

https://issues.apache.org/jira/browse/NIFI-5610
https://issues.apache.org/jira/browse/NIFI-5611

@asfgit asfgit closed this in f570cb9 Sep 19, 2018
bdesert pushed a commit to bdesert/nifi that referenced this pull request Oct 15, 2018
The operation policy allows that a user to operate components even if they does not have direct READ/WRITE
permission of the component.

Following operations are controlled by the new operate policy:
- Start/stop/enable/disable Processors, ControllerServices,
ReportingTasks, Input/OuputPorts
- Enable/disable transmission of RemoteInput/OutputPorts and
RemoteProcessGroups
- Terminate Processor threads

Refactored what API exposes

The previous commit let API exposes few fields in DTO. But we should
avoid returning partial DTO as it complicates authorization logic.

Instead, this commit adds StatusDTO for ReportingTaskEntity and
ControllerServiceEntity, so that it can be returned regardless of having
READ permission. Component DTO can only be returned with a READ
permission.

Refactor RPG same as ControllerService.

WIP incorporating review comments.

Incorporated review comments

- Cleaned up merger classes
- Recreate DTO instance at each function during two phase commmit

Restrict enabling ControllerService without read permission

Revert the last commit.

Fix review comments.

- Renamed confusing static method names and its parameters
- Removed unnecessary permission checks from UI condition

Fixed delete action display condition.

Fixed NPE at Summary.

Apply operation policy to activateControllerServices.

Removed OperationPermissible from ComponentEntity.

This closes apache#2990
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants