Manila/design/access groups

Current approach
Today we use "manila allow-access" and "manila deny-access" cli command, to allow and deny, "one" ip address/user/cert the access, to a particular share. In situation, when we want a "share" to be accessible by we have to execute, allow-access for each combination of (IP address, share) one by one!! That is, If we want to allow, a same set of 'n' ip addresses, for each of 'n' shares, then it requires "n iterations for each of n shares", that's n^2 operations from user side. That's cumbersome hence access-groups were proposed
 * a subnet OR
 * a set of IP addresses together OR
 * a set users together

Requirement
Requirement is to have a mechanism, by which a set of 'ip addresses' can be considered as 'one entity' i.e. 'can be allowed the access to a share together.' Henceforth, the 'same set of ip addresses', can be allowed access to any 'other share', in 'one single request' from user. There comes the idea of "manila access-groups".

Manila Access Groups
A new object named 'access_group', can be created by user. Each 'access_group' contains, a bunch of homogeneous 'access_entries'. Homogeneous here means, 'entries of same access_type & access_level(in case access_type is 'user'))'. Each 'access_entry' represents, either one ip-address or one username. Bunch of access entries, associated to an "access-group", can be "allowed or denied" access, to a share in one go.

Feature requirement is, to provide a mechanism, to allow the access to a share, for "a group of ip addresses/users", in one go, instead of allowing each ip-address/user one at a time.

Challenges
So, that can interfere and allow/deny any access, without any knowledge of access-group api. This has to be understood and resolved.
 * With new proposal, a set of access-rules can be applied together using "access-group". Earlier "allow-access/deny-access" api worked on individual access rule.


 * A parallel api interface, serving same purpose, but in different granularity, causes redundancy in database and information.


 * Sending a bunch of rules together to backend, if any one rule throws an exception, status of whole access-group will be errored.

Though 'access-group' feature will allow user, to request access, to set of ip addresses, in one go, still backend will work on access-rules individually.
 * If backend driver doesn't implement 'update_access' newer version yet, then 'access-rules' will be sent to driver one by one only.

Proposed Object Relationships:-

Allow Access Group
center | 500px | Allow access group flow

Deny Access Group
center | 500px| deny access group flow

How it works in different situations
'''Ques 1. Lets say a user requests allow-access-group for (share1, AG1)''' What if the share is already mapped to another access_group/access_rule.

Ans: Nothing, set of access_rules for AG1, will be applied on share, using 'add_rule' field of 'update_access' helper function.

'''Ques 2. lets say 'share1' has an already applied access rule i.e ( user ,admin, rw).''' '''Now, 'AG1' contains (user, admin, ro). A request comes as 'allow_access_group(share1, AG1)'.''' share1 is asked to map with AG1, what should happen?

What if the already applied rules are redundant to AG1's access rules. Note:- its a redundant rule, not contradictory, as rules with 'same access_type and access_to' are considered redundant..

Ans: Its same as case, if we apply two redundant rules, even without access-groups. We will get an exception, 'access rule for (user, admin) already exists' and we will proceed to examine, rest of the rules, in access_group. We need to deny this rule first "to change its level if required.

'''Ques 3. What if AG1 is made up of n rules, only one is redundant ?'''

Ans:If any one of the access_rule, from this access_group, is already applied on share(individually)... lets say due to 'allow-access' api. Then excluding that access_rule, rest of the rules, present in 'access_group' will be applied on share.

'''Ques 4. What if AG1 is made up of 'n' rules, an error reported from backend for one of the rules?'''

Ans: If there is an error, reported from backend, then error will be registered in share_instances table. 'access_rules_status' will go in 'error' state and 'access_status_message' will contain the descriptive message.

'''Ques 5. What if access group is already mapped to other shares and this is a new mapping.'''

Ans: Simply, rules from the access-group will be applied on the requested share. '''Ques 6. Two compatible access-groups mapping request got out of order before reaching backend driver.'''

Lets say two api requests for two access_groups where two access groups's rules are compatible as below: Two api requests come in this order chronologically, req1 then req2, AG1 has (user, admin, rw), AG2 has (ip, 10.1.1.1, None) req1 = allow_access_group(share1, AG1), req2 = allow_access_group(share1, AG2) Let’s say these request reach driver layer, out of order, driver receives req2 then req1. What will happen in such case?

Ans: req1 creates a access_group_mapping in db for (share1 -> AG1) and passes “only set of rules in AG1" to driver layer.           req2  also creates a access_group_mapping in db for (share1 -> AG2) and passes that “only set of rules in AG2" to driver layer. Driver layer gets req2 first, it will apply access_rules of req2 first and then access_rules from req1 will be applied on backend.

'''Ques 7. What happens if an exception is raised for one of the access-rules in access-group in api layer itself? Do we proceed for next rule or we come out ?'''

Ans: These are such exceptions which come like 1)if share status is not AVAILABLE >> we raise exception and come out 2)If share_access entry already exists for this share ? >> we raise exception but continue to consider next access_rule 3)if access_level value requested for is not a valid value >> we raise exception and come out 4)If share_instance is invalid one >> we raise exception and come out 5)if access_rules_status is not active >> we raise exception and come out

in all such cases we raise exception before rpc request is sent to driver layer. access_status_message" field in "share_instances" table - does not show error messages for above mentioned exceptions. Note:- in last two cases(4,5), though we come out, but 'share_access_group_mapping' and 'many share_access_map' entries would have been created!!!

'''Ques 8. What is purpose of access_rules_status and access_status_message field in share_instances table?'''

Ans: access_status_message field, registers the error message, from the driver layer. if we get an error message back from driver, it gets registered in 'access_status_message' in 'share_instances' table. 'access_status_message' field in 'share_instances' table - does not register error messages for above mentioned exceptions in Ques7. '''Ques 9. Lets say an access-group that contains 4 access_rules, that is applied on a share1.''' now these 4 access_rules have got their entries created in share_access_map too. What is someone deleted/denies the access rule individually ? that is sequence is like 1) manila access-group-allow   2) manila access-deny  3) manila access-group-deny   Now some rules of this access-group are denied individually .. when we go to 'deny-access-group' '''what will happen?

Ans: For each of 4 rules, if anyone is not present in the DB, we raise exception Not-Found and continue to next access_entry.

'''Ques 10. Lets say a share share1 is mapped to an access_group AG1. Now we delete one of access_rule''' '''of AG1 or we add an entry to mapped access_group AG1. What will happen?'''

Ans: any addition or deletion of access_entry to an access_group after being mapped, will trigger 'update_access' on the backend.

2nd Alternative Approach
This approach suggests to tag/group share_access_map records by using a new field access_group_tag. Here we do not create a separate entity access_group and access_group_entries. Instead by using a string type tag with share_access_map records, we group a few entries together.

For first share that wants to allow a group of ip addresses/user the access. cli call will be like... manila access-allow %some_share% ip 1.1.1.1,2.2.2.2, 3.3.3.3  --tag %tag_name_1%

After that any share that wants similar access will do either: manila access-inherit %some_new_share% --by-share %some_source_share% Or manila access-inherit %some_new_share% --by-tag %tag%

Thinking impact of 2nd approach..

 * This approach is lighter and less amount of redundancy in database as compared to 1st approach.

its associated with. So no further means to deal with 'access-groups', independently OR after share deletion. Now 'share1' adds a rule by old 'allow-access' api. How will we tackle such situation? * Will we keep these new individual access_rule records without tag? * Will we give every record which is in 'share_access_map' table, a tag..so this individual rule will have new access_group_tag??? I think we can keep the new rule without tag. Now, the next share 'share3' that inherits with --share from 'share1', will get all rules inclusive (share1, with tag) and (share1, without tag). okay. But, if the next share 'share3' that inherits with --tag 'AG1' will get rules which is with ('share1' ,AG1)
 * Access-group, being dynamic entity in 2nd approach/a no separate entity, which has its 'existence scope', same as the share,
 * Lets say, 'share1' is applied with set of access-rules tagged as 'AG1'. if 'share2' inherits all access_rules from 'share1'.


 * If share is deleted and if its last share which was associated with a access-group, the access-group is considered deleted.

now, a old 'deny-access' request comes, to delete one of the rule with share1 from these 3 rules. Now, access-group with 'AG1' tag - has got two separate set of access-rules, defining its members. Now, If a 'share3' is asking for rules same as tag 'AG1', what rules will be applied on it? '''That needs to be decided in this approach. A group/A tag can not have a static definition (set of rules) among all these allow/deny of different sorts.'''
 * If a share 'share1' has allowed access to 3 ip addresses tagged with 'AG1', now another 'share2' inherited all 3 rules with 'AG1' tag itself.
 * one that's coming from share1(2 rules)
 * other that's coming from share2(3 rules).

this becomes hard for someone to remember, which share has what access-group tagging and what a tag composed of?
 * As access-group tag definition is not static and is not kept independently. Now, With a large deployment and after many iterations of allow/deny,


 * Lets say 'share1' has 3 rules, share2 inherits from access-rules of 'share1'. Now, If there is a change in access-rules of 'share1' for some reason, after that point 'share1' and 'share2' will have different set of access-rule mapping. We can not trigger update on child shares(share2) as we are not keeping this parent child share mapping anywhere.

3rd approach - Simplifying More
Actually, As a tag doesn't have a individual independent identity, we can think of "NOT" providing, --tag the interface, to inherit from. manila access-inherit %some_new_share% --by-tag %tag% (********* Lets NOT have it **********) manila access-inherit %some_new_share% --by-share %some_source_share% (Lets "only" have this) There should be only api to inherit access from a share.

In such a case, we will allow, for first share like this... manila access-allow %some_share% ip 1.1.1.1,2.2.2.2, 3.3.3.3,4.4.4.4,5.5.5.5,6.6.6.6 we will create multiple access-records, for the share, in share_access_map table, without any tagging. Next, a share, who wants similar access-scope, will do manila access-inherit %some_new_share% --by-share %some_source_share%


 * This solves the problem associated with tagging and trying to keep a static definition of a tag.


 * This solves the problem of redundancy, as present in 1st approach.


 * This has same problem, as in 2nd approach, of "not having an access-group after share-deletion".

will be set of rules, associated "at that very moment" with share1. Things are dynamic. At some other moment in time, some share might inherit separate set of rules, from same share, 'share1'.
 * Once a share share1, has got a set of rules, it can be inherited by another share and rules-set that's inherited,

Deny-access will be similar to  manila access-deny %some_share% ip 1.1.1.1,2.2.2.2, 3.3.3.3,4.4.4.4,5.5.5.5,6.6.6.6
 * There will be no such api deny-access-rules where we can just say, deny group of rules, which we gave access together.

Discussion
As has been discussed with bswartz the key points are as below:-


 * Need to write spec fitting in formal template, as will be formalized by community soon.

Its many to many relationship. Architecture should be designed considering that access-group should be object immunal, it can be set of ip addresses or can be set of users and so on. as per requested entry operation.
 * Access Group are envisioned to provide a grouping mechanism that can allow lets say a 100 shares an access to same host or 100 host can access a share.
 * Adding an entry or deleting an entry to an access-group that's already mapped to a share, will affect all associated shares, either by applying or denying

There should be a provision to say "allow access of this share to a nova instance uuid", wherein uuid is associated with an ip address. Now, it may so happen that uuid changes its ip address in future, how will that be tackled? Will neutron or nova inform such changes ? Or a polling required from manila side to obtain such information.. That needs to be seen. that were formed earlier. A group can include other groups.
 * Design should allow later enhancements like, access-group should be able to refer to external entities like neutron security group or lets say a set of nova instances.
 * Access group can be asked to be "a union of previously formed access groups". An access group can contain all rules of two or more access-groups