001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.access;
019
020import java.io.IOException;
021import java.util.List;
022import java.util.Map;
023import java.util.Optional;
024import java.util.Set;
025import org.apache.hadoop.hbase.HBaseInterfaceAudience;
026import org.apache.hadoop.hbase.NamespaceDescriptor;
027import org.apache.hadoop.hbase.TableName;
028import org.apache.hadoop.hbase.client.BalanceRequest;
029import org.apache.hadoop.hbase.client.Mutation;
030import org.apache.hadoop.hbase.client.RegionInfo;
031import org.apache.hadoop.hbase.client.SnapshotDescription;
032import org.apache.hadoop.hbase.client.TableDescriptor;
033import org.apache.hadoop.hbase.coprocessor.CoreCoprocessor;
034import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
035import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
036import org.apache.hadoop.hbase.coprocessor.MasterObserver;
037import org.apache.hadoop.hbase.coprocessor.ObserverContext;
038import org.apache.hadoop.hbase.master.MasterServices;
039import org.apache.hadoop.hbase.net.Address;
040import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings;
041import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
042import org.apache.hadoop.hbase.replication.SyncReplicationState;
043import org.apache.yetus.audience.InterfaceAudience;
044import org.slf4j.Logger;
045import org.slf4j.LoggerFactory;
046
047@CoreCoprocessor
048@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
049public class MasterReadOnlyController extends AbstractReadOnlyController
050  implements MasterCoprocessor, MasterObserver {
051
052  private static final Logger LOG = LoggerFactory.getLogger(MasterReadOnlyController.class);
053
054  private MasterServices masterServices;
055
056  @Override
057  public Optional<MasterObserver> getMasterObserver() {
058    return Optional.of(this);
059  }
060
061  @Override
062  public TableDescriptor preCreateTableRegionsInfos(
063    ObserverContext<MasterCoprocessorEnvironment> ctx, TableDescriptor desc) throws IOException {
064    internalReadOnlyGuard();
065    return MasterObserver.super.preCreateTableRegionsInfos(ctx, desc);
066  }
067
068  @Override
069  public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
070    TableDescriptor desc, RegionInfo[] regions) throws IOException {
071    internalReadOnlyGuard();
072    MasterObserver.super.preCreateTable(ctx, desc, regions);
073  }
074
075  @Override
076  public void preCreateTableAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
077    TableDescriptor desc, RegionInfo[] regions) throws IOException {
078    internalReadOnlyGuard();
079    MasterObserver.super.preCreateTableAction(ctx, desc, regions);
080  }
081
082  @Override
083  public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
084    throws IOException {
085    internalReadOnlyGuard();
086    MasterObserver.super.preDeleteTable(ctx, tableName);
087  }
088
089  @Override
090  public void preDeleteTableAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
091    TableName tableName) throws IOException {
092    internalReadOnlyGuard();
093    MasterObserver.super.preDeleteTableAction(ctx, tableName);
094  }
095
096  @Override
097  public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
098    TableName tableName) throws IOException {
099    internalReadOnlyGuard();
100    MasterObserver.super.preTruncateTable(ctx, tableName);
101  }
102
103  @Override
104  public void preTruncateTableAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
105    TableName tableName) throws IOException {
106    internalReadOnlyGuard();
107    MasterObserver.super.preTruncateTableAction(ctx, tableName);
108  }
109
110  @Override
111  public TableDescriptor preModifyTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
112    TableName tableName, TableDescriptor currentDescriptor, TableDescriptor newDescriptor)
113    throws IOException {
114    internalReadOnlyGuard();
115    return MasterObserver.super.preModifyTable(ctx, tableName, currentDescriptor, newDescriptor);
116  }
117
118  @Override
119  public String preModifyTableStoreFileTracker(ObserverContext<MasterCoprocessorEnvironment> ctx,
120    TableName tableName, String dstSFT) throws IOException {
121    internalReadOnlyGuard();
122    return MasterObserver.super.preModifyTableStoreFileTracker(ctx, tableName, dstSFT);
123  }
124
125  @Override
126  public String preModifyColumnFamilyStoreFileTracker(
127    ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName, byte[] family,
128    String dstSFT) throws IOException {
129    internalReadOnlyGuard();
130    return MasterObserver.super.preModifyColumnFamilyStoreFileTracker(ctx, tableName, family,
131      dstSFT);
132  }
133
134  @Override
135  public void preModifyTableAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
136    TableName tableName, TableDescriptor currentDescriptor, TableDescriptor newDescriptor)
137    throws IOException {
138    internalReadOnlyGuard();
139    MasterObserver.super.preModifyTableAction(ctx, tableName, currentDescriptor, newDescriptor);
140  }
141
142  @Override
143  public void preSplitRegion(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName,
144    byte[] splitRow) throws IOException {
145    internalReadOnlyGuard();
146    MasterObserver.super.preSplitRegion(c, tableName, splitRow);
147  }
148
149  @Override
150  public void preSplitRegionAction(ObserverContext<MasterCoprocessorEnvironment> c,
151    TableName tableName, byte[] splitRow) throws IOException {
152    internalReadOnlyGuard();
153    MasterObserver.super.preSplitRegionAction(c, tableName, splitRow);
154  }
155
156  @Override
157  public void preSplitRegionBeforeMETAAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
158    byte[] splitKey, List<Mutation> metaEntries) throws IOException {
159    internalReadOnlyGuard();
160    MasterObserver.super.preSplitRegionBeforeMETAAction(ctx, splitKey, metaEntries);
161  }
162
163  @Override
164  public void preSplitRegionAfterMETAAction(ObserverContext<MasterCoprocessorEnvironment> ctx)
165    throws IOException {
166    internalReadOnlyGuard();
167    MasterObserver.super.preSplitRegionAfterMETAAction(ctx);
168  }
169
170  @Override
171  public void preTruncateRegion(ObserverContext<MasterCoprocessorEnvironment> c,
172    RegionInfo regionInfo) {
173    try {
174      internalReadOnlyGuard();
175    } catch (IOException e) {
176      LOG.info("Region truncation of region {} not allowed in read-only mode",
177        regionInfo.getRegionNameAsString());
178    }
179    MasterObserver.super.preTruncateRegion(c, regionInfo);
180  }
181
182  @Override
183  public void preTruncateRegionAction(ObserverContext<MasterCoprocessorEnvironment> c,
184    RegionInfo regionInfo) {
185    try {
186      internalReadOnlyGuard();
187    } catch (IOException e) {
188      LOG.info("Region truncation of region {} not allowed in read-only mode",
189        regionInfo.getRegionNameAsString());
190    }
191    MasterObserver.super.preTruncateRegionAction(c, regionInfo);
192  }
193
194  @Override
195  public void preMergeRegionsAction(final ObserverContext<MasterCoprocessorEnvironment> ctx,
196    final RegionInfo[] regionsToMerge) throws IOException {
197    internalReadOnlyGuard();
198    MasterObserver.super.preMergeRegionsAction(ctx, regionsToMerge);
199  }
200
201  @Override
202  public void preMergeRegionsCommitAction(ObserverContext<MasterCoprocessorEnvironment> ctx,
203    RegionInfo[] regionsToMerge, List<Mutation> metaEntries) throws IOException {
204    internalReadOnlyGuard();
205    MasterObserver.super.preMergeRegionsCommitAction(ctx, regionsToMerge, metaEntries);
206  }
207
208  @Override
209  public void preSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
210    SnapshotDescription snapshot, TableDescriptor tableDescriptor) throws IOException {
211    internalReadOnlyGuard();
212    MasterObserver.super.preSnapshot(ctx, snapshot, tableDescriptor);
213  }
214
215  @Override
216  public void preCloneSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
217    SnapshotDescription snapshot, TableDescriptor tableDescriptor) throws IOException {
218    internalReadOnlyGuard();
219    MasterObserver.super.preCloneSnapshot(ctx, snapshot, tableDescriptor);
220  }
221
222  @Override
223  public void preRestoreSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
224    SnapshotDescription snapshot, TableDescriptor tableDescriptor) throws IOException {
225    internalReadOnlyGuard();
226    MasterObserver.super.preRestoreSnapshot(ctx, snapshot, tableDescriptor);
227  }
228
229  @Override
230  public void preDeleteSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
231    SnapshotDescription snapshot) throws IOException {
232    internalReadOnlyGuard();
233    MasterObserver.super.preDeleteSnapshot(ctx, snapshot);
234  }
235
236  @Override
237  public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
238    NamespaceDescriptor ns) throws IOException {
239    internalReadOnlyGuard();
240    MasterObserver.super.preCreateNamespace(ctx, ns);
241  }
242
243  @Override
244  public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
245    NamespaceDescriptor currentNsDescriptor, NamespaceDescriptor newNsDescriptor)
246    throws IOException {
247    internalReadOnlyGuard();
248    MasterObserver.super.preModifyNamespace(ctx, currentNsDescriptor, newNsDescriptor);
249  }
250
251  @Override
252  public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
253    String namespace) throws IOException {
254    internalReadOnlyGuard();
255    MasterObserver.super.preDeleteNamespace(ctx, namespace);
256  }
257
258  @Override
259  public void preMasterStoreFlush(ObserverContext<MasterCoprocessorEnvironment> ctx)
260    throws IOException {
261    internalReadOnlyGuard();
262    MasterObserver.super.preMasterStoreFlush(ctx);
263  }
264
265  @Override
266  public void preSetUserQuota(ObserverContext<MasterCoprocessorEnvironment> ctx, String userName,
267    GlobalQuotaSettings quotas) throws IOException {
268    internalReadOnlyGuard();
269    MasterObserver.super.preSetUserQuota(ctx, userName, quotas);
270  }
271
272  @Override
273  public void preSetUserQuota(ObserverContext<MasterCoprocessorEnvironment> ctx, String userName,
274    TableName tableName, GlobalQuotaSettings quotas) throws IOException {
275    internalReadOnlyGuard();
276    MasterObserver.super.preSetUserQuota(ctx, userName, tableName, quotas);
277  }
278
279  @Override
280  public void preSetUserQuota(ObserverContext<MasterCoprocessorEnvironment> ctx, String userName,
281    String namespace, GlobalQuotaSettings quotas) throws IOException {
282    internalReadOnlyGuard();
283    MasterObserver.super.preSetUserQuota(ctx, userName, namespace, quotas);
284  }
285
286  @Override
287  public void preSetTableQuota(ObserverContext<MasterCoprocessorEnvironment> ctx,
288    TableName tableName, GlobalQuotaSettings quotas) throws IOException {
289    internalReadOnlyGuard();
290    MasterObserver.super.preSetTableQuota(ctx, tableName, quotas);
291  }
292
293  @Override
294  public void preSetNamespaceQuota(ObserverContext<MasterCoprocessorEnvironment> ctx,
295    String namespace, GlobalQuotaSettings quotas) throws IOException {
296    internalReadOnlyGuard();
297    MasterObserver.super.preSetNamespaceQuota(ctx, namespace, quotas);
298  }
299
300  @Override
301  public void preSetRegionServerQuota(ObserverContext<MasterCoprocessorEnvironment> ctx,
302    String regionServer, GlobalQuotaSettings quotas) throws IOException {
303    internalReadOnlyGuard();
304    MasterObserver.super.preSetRegionServerQuota(ctx, regionServer, quotas);
305  }
306
307  @Override
308  public void preMergeRegions(final ObserverContext<MasterCoprocessorEnvironment> ctx,
309    final RegionInfo[] regionsToMerge) throws IOException {
310    internalReadOnlyGuard();
311    MasterObserver.super.preMergeRegions(ctx, regionsToMerge);
312  }
313
314  @Override
315  public void preMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
316    Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
317    internalReadOnlyGuard();
318    MasterObserver.super.preMoveServersAndTables(ctx, servers, tables, targetGroup);
319  }
320
321  @Override
322  public void preMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
323    Set<Address> servers, String targetGroup) throws IOException {
324    internalReadOnlyGuard();
325    MasterObserver.super.preMoveServers(ctx, servers, targetGroup);
326  }
327
328  @Override
329  public void preMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
330    Set<TableName> tables, String targetGroup) throws IOException {
331    internalReadOnlyGuard();
332    MasterObserver.super.preMoveTables(ctx, tables, targetGroup);
333  }
334
335  @Override
336  public void preAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
337    throws IOException {
338    internalReadOnlyGuard();
339    MasterObserver.super.preAddRSGroup(ctx, name);
340  }
341
342  @Override
343  public void preRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
344    throws IOException {
345    internalReadOnlyGuard();
346    MasterObserver.super.preRemoveRSGroup(ctx, name);
347  }
348
349  @Override
350  public void preBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String groupName,
351    BalanceRequest request) throws IOException {
352    internalReadOnlyGuard();
353    MasterObserver.super.preBalanceRSGroup(ctx, groupName, request);
354  }
355
356  @Override
357  public void preRemoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
358    Set<Address> servers) throws IOException {
359    internalReadOnlyGuard();
360    MasterObserver.super.preRemoveServers(ctx, servers);
361  }
362
363  @Override
364  public void preRenameRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String oldName,
365    String newName) throws IOException {
366    internalReadOnlyGuard();
367    MasterObserver.super.preRenameRSGroup(ctx, oldName, newName);
368  }
369
370  @Override
371  public void preUpdateRSGroupConfig(ObserverContext<MasterCoprocessorEnvironment> ctx,
372    String groupName, Map<String, String> configuration) throws IOException {
373    internalReadOnlyGuard();
374    MasterObserver.super.preUpdateRSGroupConfig(ctx, groupName, configuration);
375  }
376
377  @Override
378  public void preAddReplicationPeer(ObserverContext<MasterCoprocessorEnvironment> ctx,
379    String peerId, ReplicationPeerConfig peerConfig) throws IOException {
380    internalReadOnlyGuard();
381    MasterObserver.super.preAddReplicationPeer(ctx, peerId, peerConfig);
382  }
383
384  @Override
385  public void preRemoveReplicationPeer(ObserverContext<MasterCoprocessorEnvironment> ctx,
386    String peerId) throws IOException {
387    internalReadOnlyGuard();
388    MasterObserver.super.preRemoveReplicationPeer(ctx, peerId);
389  }
390
391  @Override
392  public void preEnableReplicationPeer(ObserverContext<MasterCoprocessorEnvironment> ctx,
393    String peerId) throws IOException {
394    internalReadOnlyGuard();
395    MasterObserver.super.preEnableReplicationPeer(ctx, peerId);
396  }
397
398  @Override
399  public void preDisableReplicationPeer(ObserverContext<MasterCoprocessorEnvironment> ctx,
400    String peerId) throws IOException {
401    internalReadOnlyGuard();
402    MasterObserver.super.preDisableReplicationPeer(ctx, peerId);
403  }
404
405  @Override
406  public void preUpdateReplicationPeerConfig(ObserverContext<MasterCoprocessorEnvironment> ctx,
407    String peerId, ReplicationPeerConfig peerConfig) throws IOException {
408    internalReadOnlyGuard();
409    MasterObserver.super.preUpdateReplicationPeerConfig(ctx, peerId, peerConfig);
410  }
411
412  @Override
413  public void preTransitReplicationPeerSyncReplicationState(
414    ObserverContext<MasterCoprocessorEnvironment> ctx, String peerId, SyncReplicationState state)
415    throws IOException {
416    internalReadOnlyGuard();
417    MasterObserver.super.preTransitReplicationPeerSyncReplicationState(ctx, peerId, state);
418  }
419
420  @Override
421  public void preGrant(ObserverContext<MasterCoprocessorEnvironment> ctx,
422    UserPermission userPermission, boolean mergeExistingPermissions) throws IOException {
423    internalReadOnlyGuard();
424    MasterObserver.super.preGrant(ctx, userPermission, mergeExistingPermissions);
425  }
426
427  @Override
428  public void preRevoke(ObserverContext<MasterCoprocessorEnvironment> ctx,
429    UserPermission userPermission) throws IOException {
430    internalReadOnlyGuard();
431    MasterObserver.super.preRevoke(ctx, userPermission);
432  }
433}