Repository navigation
Hbase 30402 - #8786
Closed
Apache9 wants to merge 22 commits into
Closed
Hbase 30402#8786Apache9 wants to merge 22 commits into
Apache9 wants to merge 22 commits into
Conversation
Add RefreshAclState/RefreshAclStateData/RefreshAclRemoteStateData/AclEntryUpdate to MasterProcedure.proto (import AccessControl.proto for UsersAndPermissions). Payloads carry a master assigned timestamp for RS side watermark filtering. Update the UsersAndPermissions comment: it is no longer the /hbase/acl znode content, but a per-entry permissions snapshot.
…Manager Fixed rules (evaluated before cached grants): hbase:meta READ is open to any user, other meta actions and all hbase:acl actions are superuser only. A null table name keeps its historical global scope semantics and is not subject to the rules. New APIs for the ACL de-ZK design: applyUpdates(List<EntryUpdate>) applies incremental per-entry replace/delete, applyFullSnapshot(...) swaps in a full entry->permissions snapshot (e.g. from PermissionStorage.loadAll) built aside so readers never see a partial cache.
Drop the hbase:meta READ short circuit in AccessChecker.permissionGranted; AuthManager now owns the fixed rules for hbase:meta / hbase:acl. Narrow AccessControlFilter's blanket INCLUDE from all system tables to hbase:meta only, so reads of hbase:acl and other system tables go through the regular permission checks instead of being exposed to any user that reaches the filter (e.g. with hbase.security.access.early_out=false).
…otonic timestamps Add PermissionStorage.AclWriteHook: when installed (master side), every write to the hbase:acl table is stamped with a hook assigned monotonic timestamp (so the cell timestamp carries the master assigned ts) and the resulting state of the written entry is announced after the write succeeds. Entry state is read back over the same table instance, CF m (snapshot HDFS acl markers) is ignored. All mutating entry points are covered from inside PermissionStorage so future write paths cannot forget to trigger the refresh pipeline.
…ark filtering AclRefresher owns all AuthManager cache mutations through one serial queue: - Incremental batches and master pushed full snapshots carry the master assigned timestamp of their writes; batches not newer than the last applied one are dropped, so stale deliveries (e.g. remote procedures replayed after a master failover) cannot regress the cache or resurrect deleted entries. - reloadFromTable() scans hbase:acl and swaps in the result as one queue task: updates enqueued before it are already reflected in the scan, updates arriving during the scan apply after the swap, so a reload never loses a concurrent update. AclReloadChore runs the full reload periodically (hbase.security.acl.reload.period.msec, default 5min) as the fallback for lost updates and direct table writes. Also pair PermissionStorage write hook notifications with the write timestamp, and extend loadAll with the max cell timestamp of the scan (AclSnapshot), used as the version watermark of a full reload.
RefreshAclRemoteProcedure (per-RS child task of the future RefreshAclProcedure) carries a change set over ExecuteProceduresRequest and is retried against the same server while it is alive; when the server disappears the task is dropped and the restarted server reloads from hbase:acl. RefreshAclRemoteCallable applies the change set on the RS through AclRefresher (serial queue + timestamp watermark). Registrations: ServerOperationType.REFRESH_ACL + ServerQueue lock case, EventType.M_RS_REFRESH_ACL, ExecutorType.RS_REFRESH_ACL and its RS thread pool (hbase.regionserver.executor.refresh.acl.threads, default 1). Minimal wiring: create AclRefresher next to AccessChecker in HBaseRpcServicesBase and expose it via HBaseServerBase.
…e push pipeline ACLManager assigns the monotonic timestamps of hbase:acl writes (seeded at activation from the acl table content and the wall clock, so they never move backwards across restarts or failovers), tracks the pending entry updates (latest per entry) and pushes change sets to all registered region servers through a single in-flight RefreshAclProcedure. Updates arriving while a push runs merge into the next one; the local AuthManager cache is updated as soon as the write lands in the table. RefreshAclProcedure drains the pending queue as its first step (persisted in the procedure store before dispatch, replayed at-least-once after a failover; stale replays are dropped by the RS side timestamp watermark), fans out one RefreshAclRemoteProcedure per online server and releases the single-flight gate on completion (completionCleanup). Wired into MasterServices/HMaster: constructed before the procedure executor starts so recovered procedures can consult it.
…ests until loaded Region server: after reportForDuty succeeds, load the full hbase:acl content into the local cache (retrying with backoff; a missing acl table counts as loaded with an empty cache) and only then open the gate in RSRpcServices.checkOpen: non superuser requests get a retryable PleaseHoldException until the cache is loaded, superusers pass so bootstrap and operations keep working. Authorization disabled servers open immediately. Master: ACLManager.initialize() runs at the end of active master initialization (seed timestamps, load the local cache, push one full round), and unregisters the write hook on shutdown. Both: schedule AclReloadChore (periodic full reload, the fallback for lost updates and direct table writes) when authorization is enabled.
The hbase:acl table is the authoritative store now; masters push changes to the servers (ACLManager/RefreshAclProcedure) and servers load the table at startup and periodically, so the postPut/postDelete mirroring (updateACL), the acl region postOpen full flush (initialize) and the znode deletes on table/namespace removal are gone. preGrant/preRevoke now reject table level grants on hbase:meta and hbase:acl: fixed rules govern access to those two tables and stored grants would never take effect.
The watcher is obsolete: ACL updates reach the servers through the master push pipeline and the startup/periodic loads. Remove the class, its test, the lifecycle in HBaseRpcServicesBase and getZKPermissionWatcher from MasterServices/RegionServerServices/HBaseServerBase and the test mocks.
The znode payload format is gone with ZKPermissionWatcher: drop PermissionStorage.writePermissionsAsBytes/readUserPermission/readPermissions and the old HbaseObjectWritable compatibility branch, the AuthManager *FromWritable cache refreshers and the HBASE-22503 ZK data compatibility branch (updateGlobalCache now swaps the cache atomically). The acl table cell format (action code bytes) is unaffected. Remove TestTablePermissions.testSerialization which round tripped the mirror blob.
Add hbase.security.acl.reload.period.msec (periodic full ACL reload, default 5min) to hbase-default.xml and drop the obsolete zookeeper.znode.acl.parent entry; setting the old key now logs a startup warning and is ignored.
…er cache updates applyEntry stripped the '@' prefix when applying namespace permissions but not when deleting the entry, so deletes never hit the cache. Delete paths also skipped the mtime bump, which the test synchronization relies on. Drop the now unused removeTable/removeNamespace helpers.
…alescing TestAuthManager: hbase:meta READ open to all / other actions superuser only, hbase:acl superuser only, global and namespace grants do not penetrate, table == null keeps its global scope semantics, EntryUpdate apply/delete and full snapshot swap. TestAclRefresher: timestamp watermark drops stale updates and stale full snapshots (e.g. replayed procedures after a master failover), deletes are not resurrected, newer updates apply on top of a snapshot. TestACLManager: monotonic timestamps, per entry coalescing of the pending queue, single flight push submission.
submitPushProcedure() and flush() are the hooks the unit tests use to observe push submission and to wait for queued updates.
- Run the RS startup ACL load on a background thread: blocking the run loop kept regionServerReport from being sent, and the master only assigns regions to servers that have reported once (HBASE-25032), so meta never came online and the load could not finish either. - Do not hold calls without a request user in the checkOpen gate: those are in-process internal paths (e.g. postOpenDeployTasks) and holding them aborted the RS while opening hbase:meta. Only non superuser client requests are held until the cache is loaded. - Unwrap UncheckedIOException in PermissionStorage.loadAllSnapshot so callers can recognize a missing hbase:acl table (fresh cluster) and treat it as empty content. - Run ACLManager.initialize() after the master is marked initialized: the acl table scan needs the master registry, which serves only then. TestTablePermissions now passes end to end.
RefreshAclRemoteCallable now waits until the change has been applied to the cache before reporting completion, so a finished push procedure means the change is visible on that server. SecureTestUtil.updateACLs synchronizes on the master assigned timestamps instead of cache modification times: a server that has applied timestamp T reflects every write up to T, so waiting for this call's timestamp is exact. The mtime counter cannot attribute a bump to a specific update and was tripped by concurrent pushes (table create owner grants, previous test cleanups), letting verifications run before their own grant was applied. TestAccessController passes fully (84 tests).
…mirror TestAccessController2: hbase:acl access is superuser only now, stored grants of any scope must not penetrate it (testACLTableAccess); drop testACLZNodeDeletion which asserted the removed ZooKeeper mirror. TestRpcAccessChecks.testExecProcedure runs its permission check against a user table: hbase:meta admin actions are superuser only under the fixed rules, while the test verifies the RPC level admin check.
…TableManager PermissionStorage is a stateless util, the static write hook it carried was an awkward backdoor. Replace it with AclTableManager, the master side facade over hbase:acl: - grant/revoke/getUserPermissions/hasUserPermissions move out of MasterRpcServices into AclTableManager (the RPC methods keep the protocol plumbing and coprocessor hooks and delegate); - the AccessController master hooks (table create/modify/truncate/delete, namespace delete) write through it too, so every write path announces its update: the entry state is applied to the local cache via AclRefresher and queued for broadcast via ACLManager; - PermissionStorage goes back to a pure util: writes take the timestamp to stamp explicitly (the master assigned monotonic timestamp) and have no side effects.
AuthManager mixed two concerns: maintaining the in-memory permission caches and making authorization decisions. Split them along the usage line: - AclSnapshot holds the global/namespace/table permission caches and the EntryUpdate delta type, and feeds them through applyUpdates and applyFullSnapshot; - AclView is the narrow read-only view of the snapshot; - AuthManager becomes pure decision logic over an injected AclView and never mutates anything. Also drop the dead mtime bookkeeping and the unused Configuration of AuthManager. PermissionStorage.AclSnapshot (the hbase:acl scan result) is renamed to AclTableContent to free the name.
Merge AclTableManager into ACLManager: the master now has a single ACL controller that owns the authoritative AclSnapshot of hbase:acl, performs every permission update and query on the table, assigns the write timestamps and drives the broadcast to the region servers through RefreshAclProcedure. The refresh procedure only updates the region servers; the master applies each change at write time. Serialize the whole write path (timestamp assignment, table write, entry read back, local apply, queueing for broadcast) under one lock. This makes the local apply order match the timestamp order and fixes a lost update window: previously two concurrent grants to different entries could apply out of order and the refresher watermark would drop the earlier one from the master's cache until the next periodic reload.
The region server now has one class maintaining its current ACL snapshot: AclStore, merging what AclRefresher and AclReloadChore did. - the snapshot is fed through exactly one place: the startup full load, the master pushes (RefreshAclRemoteCallable) and the periodic reload; - applies are synchronous (the single-thread queue and the flush barrier are gone), so a completed refresh procedure means the change is already visible on the server; - the timestamp watermark rules are unchanged: stale batches are dropped, a reload never moves the watermark backwards, and a reload serializes with applies so an update arriving during its scan is applied after the swap; - the periodic reload chore becomes internal to AclStore and runs on the region server only; the master keeps its snapshot in step at write time and does not need one. The store is created before registering with the master, so a push dispatched right after registration cannot land before it exists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.