Skip to content

Commit bd4be6e

Browse files
bharatviswa504arp7
authored andcommitted
HDDS-1895. Support Key ACL operations for OM HA. (#1230)
1 parent 8a77a22 commit bd4be6e

File tree

11 files changed

+885
-76
lines changed

11 files changed

+885
-76
lines changed

hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java

Lines changed: 134 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
import java.io.IOException;
2121
import java.util.ArrayList;
22+
import java.util.BitSet;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
2526
import java.util.Objects;
2627
import java.util.stream.Collectors;
2728

29+
import com.google.protobuf.ByteString;
2830
import org.apache.hadoop.fs.FileEncryptionInfo;
2931
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
3032
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyInfo;
@@ -34,6 +36,8 @@
3436

3537
import com.google.common.base.Preconditions;
3638

39+
import static org.apache.hadoop.ozone.OzoneAcl.ZERO_BITSET;
40+
3741
/**
3842
* Args for key block. The block instance for the key requested in putKey.
3943
* This is returned from OM to client, and client use class to talk to
@@ -235,6 +239,119 @@ public List<OzoneAclInfo> getAcls() {
235239
return acls;
236240
}
237241

242+
/**
243+
* Add an ozoneAcl to list of existing Acl set.
244+
* @param ozoneAcl
245+
* @return true - if successfully added, false if not added or acl is
246+
* already existing in the acl list.
247+
*/
248+
public boolean addAcl(OzoneAclInfo ozoneAcl) {
249+
// Case 1: When we are adding more rights to existing user/group.
250+
boolean addToExistingAcl = false;
251+
for(OzoneAclInfo existingAcl: getAcls()) {
252+
if(existingAcl.getName().equals(ozoneAcl.getName()) &&
253+
existingAcl.getType().equals(ozoneAcl.getType())) {
254+
255+
// We need to do "or" before comparision because think of a case like
256+
// existing acl is 777 and newly added acl is 444, we have already
257+
// that acl set. In this case if we do direct check they will not
258+
// be equal, but if we do or and then check, we shall know it
259+
// has acl's already set or not.
260+
BitSet newAclBits = BitSet.valueOf(
261+
existingAcl.getRights().toByteArray());
262+
263+
newAclBits.or(BitSet.valueOf(ozoneAcl.getRights().toByteArray()));
264+
265+
if (newAclBits.equals(BitSet.valueOf(
266+
existingAcl.getRights().toByteArray()))) {
267+
return false;
268+
} else {
269+
OzoneAclInfo newAcl = OzoneAclInfo.newBuilder()
270+
.setType(ozoneAcl.getType())
271+
.setName(ozoneAcl.getName())
272+
.setAclScope(ozoneAcl.getAclScope())
273+
.setRights(ByteString.copyFrom(newAclBits.toByteArray()))
274+
.build();
275+
getAcls().remove(existingAcl);
276+
getAcls().add(newAcl);
277+
addToExistingAcl = true;
278+
break;
279+
}
280+
}
281+
}
282+
283+
// Case 2: When a completely new acl is added.
284+
if(!addToExistingAcl) {
285+
getAcls().add(ozoneAcl);
286+
}
287+
return true;
288+
}
289+
290+
/**
291+
* Remove acl from existing acl list.
292+
* @param ozoneAcl
293+
* @return true - if successfully removed, false if not able to remove due
294+
* to that acl is not in the existing acl list.
295+
*/
296+
public boolean removeAcl(OzoneAclInfo ozoneAcl) {
297+
boolean removed = false;
298+
299+
// When we are removing subset of rights from existing acl.
300+
for(OzoneAclInfo existingAcl: getAcls()) {
301+
if (existingAcl.getName().equals(ozoneAcl.getName()) &&
302+
existingAcl.getType().equals(ozoneAcl.getType())) {
303+
304+
BitSet bits = BitSet.valueOf(ozoneAcl.getRights().toByteArray());
305+
BitSet existingAclBits =
306+
BitSet.valueOf(existingAcl.getRights().toByteArray());
307+
bits.and(existingAclBits);
308+
309+
// This happens when the acl bitset asked to remove is not set for
310+
// matched name and type.
311+
// Like a case we have 444 permission, 333 is asked to removed.
312+
if (bits.equals(ZERO_BITSET)) {
313+
return false;
314+
}
315+
316+
// We have some matching. Remove them.
317+
bits.xor(existingAclBits);
318+
319+
// If existing acl has same bitset as passed acl bitset, remove that
320+
// acl from the list
321+
if (bits.equals(ZERO_BITSET)) {
322+
getAcls().remove(existingAcl);
323+
} else {
324+
// Remove old acl and add new acl.
325+
OzoneAclInfo newAcl = OzoneAclInfo.newBuilder()
326+
.setType(ozoneAcl.getType())
327+
.setName(ozoneAcl.getName())
328+
.setAclScope(ozoneAcl.getAclScope())
329+
.setRights(ByteString.copyFrom(bits.toByteArray()))
330+
.build();
331+
getAcls().remove(existingAcl);
332+
getAcls().add(newAcl);
333+
}
334+
removed = true;
335+
break;
336+
}
337+
}
338+
339+
return removed;
340+
}
341+
342+
/**
343+
* Reset the existing acl list.
344+
* @param ozoneAcls
345+
* @return true - if successfully able to reset.
346+
*/
347+
public boolean setAcls(List<OzoneAclInfo> ozoneAcls) {
348+
this.acls.clear();
349+
this.acls = ozoneAcls;
350+
return true;
351+
}
352+
353+
354+
238355
/**
239356
* Builder of OmKeyInfo.
240357
*/
@@ -320,7 +437,8 @@ public Builder setFileEncryptionInfo(FileEncryptionInfo feInfo) {
320437
}
321438

322439
public Builder setAcls(List<OzoneAclInfo> listOfAcls) {
323-
this.acls = listOfAcls;
440+
this.acls = new ArrayList<>();
441+
this.acls.addAll(listOfAcls);
324442
return this;
325443
}
326444

@@ -359,22 +477,22 @@ public KeyInfo getProtobuf() {
359477
}
360478

361479
public static OmKeyInfo getFromProtobuf(KeyInfo keyInfo) {
362-
return new OmKeyInfo(
363-
keyInfo.getVolumeName(),
364-
keyInfo.getBucketName(),
365-
keyInfo.getKeyName(),
366-
keyInfo.getKeyLocationListList().stream()
480+
return new OmKeyInfo.Builder()
481+
.setVolumeName(keyInfo.getVolumeName())
482+
.setBucketName(keyInfo.getBucketName())
483+
.setKeyName(keyInfo.getKeyName())
484+
.setOmKeyLocationInfos(keyInfo.getKeyLocationListList().stream()
367485
.map(OmKeyLocationInfoGroup::getFromProtobuf)
368-
.collect(Collectors.toList()),
369-
keyInfo.getDataSize(),
370-
keyInfo.getCreationTime(),
371-
keyInfo.getModificationTime(),
372-
keyInfo.getType(),
373-
keyInfo.getFactor(),
374-
KeyValueUtil.getFromProtobuf(keyInfo.getMetadataList()),
375-
keyInfo.hasFileEncryptionInfo() ? OMPBHelper.convert(keyInfo
376-
.getFileEncryptionInfo()): null,
377-
keyInfo.getAclsList());
486+
.collect(Collectors.toList()))
487+
.setDataSize(keyInfo.getDataSize())
488+
.setCreationTime(keyInfo.getCreationTime())
489+
.setModificationTime(keyInfo.getModificationTime())
490+
.setReplicationType(keyInfo.getType())
491+
.setReplicationFactor(keyInfo.getFactor())
492+
.addAllMetadata(KeyValueUtil.getFromProtobuf(keyInfo.getMetadataList()))
493+
.setFileEncryptionInfo(keyInfo.hasFileEncryptionInfo() ?
494+
OMPBHelper.convert(keyInfo.getFileEncryptionInfo()): null)
495+
.setAcls(keyInfo.getAclsList()).build();
378496
}
379497

380498
@Override

0 commit comments

Comments
 (0)