View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.security.visibility;
19  
20  import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
21  
22  import java.io.IOException;
23  import java.util.Map;
24  
25  import com.google.protobuf.HBaseZeroCopyByteString;
26  import org.apache.hadoop.classification.InterfaceAudience;
27  import org.apache.hadoop.classification.InterfaceStability;
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.client.HTable;
31  import org.apache.hadoop.hbase.client.coprocessor.Batch;
32  import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
33  import org.apache.hadoop.hbase.ipc.ServerRpcController;
34  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsRequest;
35  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
36  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.SetAuthsRequest;
37  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabel;
38  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsRequest;
39  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
40  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsService;
41  import org.apache.hadoop.hbase.util.Bytes;
42  
43  import com.google.protobuf.ServiceException;
44  
45  /**
46   * Utility client for doing visibility labels admin operations.
47   */
48  @InterfaceAudience.Public
49  @InterfaceStability.Evolving
50  public class VisibilityClient {
51  
52    /**
53     * Utility method for adding label to the system.
54     * 
55     * @param conf
56     * @param label
57     * @return VisibilityLabelsResponse
58     * @throws Throwable
59     */
60    public static VisibilityLabelsResponse addLabel(Configuration conf, final String label)
61        throws Throwable {
62      return addLabels(conf, new String[] { label });
63    }
64  
65    /**
66     * Utility method for adding labels to the system.
67     * 
68     * @param conf
69     * @param labels
70     * @return VisibilityLabelsResponse
71     * @throws Throwable
72     */
73    public static VisibilityLabelsResponse addLabels(Configuration conf, final String[] labels)
74        throws Throwable {
75      HTable ht = null;
76      try {
77        ht = new HTable(conf, LABELS_TABLE_NAME.getName());
78        Batch.Call<VisibilityLabelsService, VisibilityLabelsResponse> callable = 
79            new Batch.Call<VisibilityLabelsService, VisibilityLabelsResponse>() {
80          ServerRpcController controller = new ServerRpcController();
81          BlockingRpcCallback<VisibilityLabelsResponse> rpcCallback = 
82              new BlockingRpcCallback<VisibilityLabelsResponse>();
83  
84          public VisibilityLabelsResponse call(VisibilityLabelsService service) throws IOException {
85            VisibilityLabelsRequest.Builder builder = VisibilityLabelsRequest.newBuilder();
86            for (String label : labels) {
87              if (label.length() > 0) {
88                VisibilityLabel.Builder newBuilder = VisibilityLabel.newBuilder();
89                newBuilder.setLabel(HBaseZeroCopyByteString.wrap(Bytes.toBytes(label)));
90                builder.addVisLabel(newBuilder.build());
91              }
92            }
93            service.addLabels(controller, builder.build(), rpcCallback);
94            return rpcCallback.get();
95          }
96        };
97        Map<byte[], VisibilityLabelsResponse> result = ht.coprocessorService(
98            VisibilityLabelsService.class, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
99            callable);
100       return result.values().iterator().next(); // There will be exactly one region for labels
101                                                 // table and so one entry in result Map.
102     } finally {
103       if (ht != null) {
104         ht.close();
105       }
106     }
107   }
108 
109   /**
110    * Sets given labels globally authorized for the user.
111    * @param conf
112    * @param auths
113    * @param user
114    * @return VisibilityLabelsResponse
115    * @throws Throwable
116    */
117   public static VisibilityLabelsResponse setAuths(Configuration conf, final String[] auths,
118       final String user) throws Throwable {
119     return setOrClearAuths(conf, auths, user, true);
120   }
121 
122   /**
123    * @param conf
124    * @param user
125    * @return labels, the given user is globally authorized for.
126    * @throws Throwable
127    */
128   public static GetAuthsResponse getAuths(Configuration conf, final String user) throws Throwable {
129     HTable ht = null;
130     try {
131       ht = new HTable(conf, LABELS_TABLE_NAME.getName());
132       Batch.Call<VisibilityLabelsService, GetAuthsResponse> callable = 
133           new Batch.Call<VisibilityLabelsService, GetAuthsResponse>() {
134         ServerRpcController controller = new ServerRpcController();
135         BlockingRpcCallback<GetAuthsResponse> rpcCallback = 
136             new BlockingRpcCallback<GetAuthsResponse>();
137 
138         public GetAuthsResponse call(VisibilityLabelsService service) throws IOException {
139           GetAuthsRequest.Builder getAuthReqBuilder = GetAuthsRequest.newBuilder();
140           getAuthReqBuilder.setUser(HBaseZeroCopyByteString.wrap(Bytes.toBytes(user)));
141           service.getAuths(controller, getAuthReqBuilder.build(), rpcCallback);
142           return rpcCallback.get();
143         }
144       };
145       Map<byte[], GetAuthsResponse> result = ht.coprocessorService(VisibilityLabelsService.class,
146           HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, callable);
147       return result.values().iterator().next(); // There will be exactly one region for labels
148                                                 // table and so one entry in result Map.
149     } finally {
150       if (ht != null) {
151         ht.close();
152       }
153     }
154   }
155 
156   /**
157    * Removes given labels from user's globally authorized list of labels.
158    * @param conf
159    * @param auths
160    * @param user
161    * @return VisibilityLabelsResponse
162    * @throws Throwable
163    */
164   public static VisibilityLabelsResponse clearAuths(Configuration conf, final String[] auths,
165       final String user) throws Throwable {
166     return setOrClearAuths(conf, auths, user, false);
167   }
168 
169   private static VisibilityLabelsResponse setOrClearAuths(Configuration conf, final String[] auths,
170       final String user, final boolean setOrClear) throws IOException, ServiceException, Throwable {
171     HTable ht = null;
172     try {
173       ht = new HTable(conf, LABELS_TABLE_NAME.getName());
174       Batch.Call<VisibilityLabelsService, VisibilityLabelsResponse> callable = 
175           new Batch.Call<VisibilityLabelsService, VisibilityLabelsResponse>() {
176         ServerRpcController controller = new ServerRpcController();
177         BlockingRpcCallback<VisibilityLabelsResponse> rpcCallback = 
178             new BlockingRpcCallback<VisibilityLabelsResponse>();
179 
180         public VisibilityLabelsResponse call(VisibilityLabelsService service) throws IOException {
181           SetAuthsRequest.Builder setAuthReqBuilder = SetAuthsRequest.newBuilder();
182           setAuthReqBuilder.setUser(HBaseZeroCopyByteString.wrap(Bytes.toBytes(user)));
183           for (String auth : auths) {
184             if (auth.length() > 0) {
185               setAuthReqBuilder.addAuth(HBaseZeroCopyByteString.wrap(Bytes.toBytes(auth)));
186             }
187           }
188           if (setOrClear) {
189             service.setAuths(controller, setAuthReqBuilder.build(), rpcCallback);
190           } else {
191             service.clearAuths(controller, setAuthReqBuilder.build(), rpcCallback);
192           }
193           return rpcCallback.get();
194         }
195       };
196       Map<byte[], VisibilityLabelsResponse> result = ht.coprocessorService(
197           VisibilityLabelsService.class, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
198           callable);
199       return result.values().iterator().next(); // There will be exactly one region for labels
200                                                 // table and so one entry in result Map.
201     } finally {
202       if (ht != null) {
203         ht.close();
204       }
205     }
206   }
207 }