blob: 2eb69f5d245d6326c28e0b063fc88c391805d1b3 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Apache Ozone Documentation">
<title>Documentation for Apache Ozone</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/ozonedoc.css" rel="stylesheet">
<link href="../swagger-resources/swagger-ui.css" rel="stylesheet">
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '34']);
var d=document, g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#sidebar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="../index.html" class="navbar-left ozone-logo">
<img src="../ozone-logo-small.png"/>
</a>
<a class="navbar-brand hidden-xs" href="../index.html">
Apache Ozone/HDDS Documentation
</a>
<a class="navbar-brand visible-xs-inline" href="#">Apache Ozone</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="https://github.com/apache/ozone">Source</a></li>
<li><a href="https://ozone.apache.org">Apache Ozone</a></li>
<li><a href="https://apache.org">ASF</a></li>
</ul>
</div>
</div>
</nav>
<div class="wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-sm-2 col-md-2 sidebar" id="sidebar">
<ul class="nav nav-sidebar">
<li class="">
<a href="../index.html">
<span>Overview</span>
</a>
</li>
<li class="">
<a href="../start.html">
<span>Getting Started</span>
</a>
</li>
<li class="">
<a href="../concept.html">
<span>Architecture</span>
</a>
<ul class="nav">
<li class="">
<a href="../concept/overview.html">Overview</a>
</li>
<li class="">
<a href="../concept/ozonemanager.html">Ozone Manager</a>
</li>
<li class="">
<a href="../concept/storagecontainermanager.html">Storage Container Manager</a>
</li>
<li class="">
<a href="../concept/containers.html">Containers</a>
</li>
<li class="">
<a href="../concept/datanodes.html">Datanodes</a>
</li>
<li class="">
<a href="../concept/recon.html">Recon</a>
</li>
</ul>
</li>
<li class="">
<a href="../feature.html">
<span>Features</span>
</a>
<ul class="nav">
<li class="">
<a href="../feature/decommission.html">Decommissioning</a>
</li>
<li class="">
<a href="../feature/om-ha.html">OM High Availability</a>
</li>
<li class="">
<a href="../feature/erasurecoding.html">Ozone Erasure Coding</a>
</li>
<li class="">
<a href="../feature/snapshot.html">Ozone Snapshot</a>
</li>
<li class="">
<a href="../feature/scm-ha.html">SCM High Availability</a>
</li>
<li class="">
<a href="../feature/streaming-write-pipeline.html">Streaming Write Pipeline</a>
</li>
<li class="">
<a href="../feature/dn-merge-rocksdb.html">Merge Container RocksDB in DN</a>
</li>
<li class="">
<a href="../feature/prefixfso.html">Prefix based File System Optimization</a>
</li>
<li class="">
<a href="../feature/topology.html">Topology awareness</a>
</li>
<li class="">
<a href="../feature/quota.html">Quota in Ozone</a>
</li>
<li class="">
<a href="../feature/recon.html">Recon Server</a>
</li>
<li class="">
<a href="../feature/observability.html">Observability</a>
</li>
<li class="">
<a href="../feature/nonrolling-upgrade.html">Non-Rolling Upgrades and Downgrades</a>
</li>
<li class="">
<a href="../feature/s3-multi-tenancy.html">
<span>S3 Multi-Tenancy</span>
</a>
<ul class="nav">
<li class="">
<a href="../feature/s3-multi-tenancy-setup.html">Setup</a>
</li>
<li class="active">
<a href="../feature/s3-tenant-commands.html">Tenant commands</a>
</li>
<li class="">
<a href="../feature/s3-multi-tenancy-access-control.html">Access Control</a>
</li>
</ul>
</li>
<li class="">
<a href="../feature/reconfigurability.html">Reconfigurability</a>
</li>
</ul>
</li>
<li class="">
<a href="../interface.html">
<span>Client Interfaces</span>
</a>
<ul class="nav">
<li class="">
<a href="../interface/ofs.html">Ofs (Hadoop compatible)</a>
</li>
<li class="">
<a href="../interface/o3fs.html">O3fs (Hadoop compatible)</a>
</li>
<li class="">
<a href="../interface/s3.html">S3 Protocol</a>
</li>
<li class="">
<a href="../interface/cli.html">Command Line Interface</a>
</li>
<li class="">
<a href="../interface/reconapi.html">Recon API</a>
</li>
<li class="">
<a href="../interface/javaapi.html">Java API</a>
</li>
<li class="">
<a href="../interface/csi.html">CSI Protocol</a>
</li>
<li class="">
<a href="../interface/httpfs.html">HttpFS Gateway</a>
</li>
</ul>
</li>
<li class="">
<a href="../security.html">
<span>Security</span>
</a>
<ul class="nav">
<li class="">
<a href="../security/secureozone.html">Securing Ozone</a>
</li>
<li class="">
<a href="../security/securingtde.html">Transparent Data Encryption</a>
</li>
<li class="">
<a href="../security/gdpr.html">GDPR in Ozone</a>
</li>
<li class="">
<a href="../security/securingdatanodes.html">Securing Datanodes</a>
</li>
<li class="">
<a href="../security/securingozonehttp.html">Securing HTTP</a>
</li>
<li class="">
<a href="../security/securings3.html">Securing S3</a>
</li>
<li class="">
<a href="../security/securityacls.html">Ozone ACLs</a>
</li>
<li class="">
<a href="../security/securitywithranger.html">Apache Ranger</a>
</li>
</ul>
</li>
<li class="">
<a href="../tools.html">
<span>Tools</span>
</a>
</li>
<li class="">
<a href="../recipe.html">
<span>Recipes</span>
</a>
</li>
<li><a href="../design.html"><span><b>Design docs</b></span></a></li>
<li class="visible-xs"><a href="#">References</a>
<ul class="nav">
<li><a href="https://github.com/apache/ozone"><span class="glyphicon glyphicon-new-window" aria-hidden="true"></span> Source</a></li>
<li><a href="https://ozone.apache.org"><span class="glyphicon glyphicon-new-window" aria-hidden="true"></span> Apache Ozone</a></li>
<li><a href="https://apache.org"><span class="glyphicon glyphicon-new-window" aria-hidden="true"></span> ASF</a></li>
</ul></li>
</ul>
</div>
<div class="col-sm-10 col-sm-offset-2 col-md-10 col-md-offset-2 main-content">
<div class="col-md-9">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="../index.html">Home</a></li>
<li class="breadcrumb-item" aria-current="page"><a href="../feature.html">Features</a></li>
<li class="breadcrumb-item active" aria-current="page">Tenant commands</li>
</ol>
</nav>
<div class="pull-right">
</div>
<div class="col-md-9">
<h1>Tenant commands</h1>
<!---
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>For a higher level understanding of multi-tenancy architecture, see <a href="../feature/s3-multi-tenancy.html">Multi-Tenancy feature</a>.</p>
<p>All Multi-Tenancy subcommands are located under CLI <code>ozone tenant</code>.</p>
<p>The commands below assume a Kerberized Ozone cluster with Ranger install. Enabling HTTPS on S3 Gateway is optional but recommended.</p>
<p>The exit code of a successful tenant command should be <code>0</code>.
A non-zero exit code indicates failure, which should be accompanied an error message.</p>
<h2 id="quick-start">Quick Start</h2>
<h3 id="setup">Setup</h3>
<p>Follow the <a href="../feature/s3-multi-tenancy-setup.html">Multi-Tenancy Setup</a> guide if you haven&rsquo;t done so.</p>
<p>If the OzoneManagers are running in HA, append <code>--om-service-id=</code> accordingly to the commands.</p>
<h3 id="create-a-tenant">Create a tenant</h3>
<p>Create a new tenant in the current Ozone cluster.
This operation requires Ozone cluster administrator privilege.</p>
<p>Apart from adding new OM DB entries, creating a tenant also does the following in the background:</p>
<ol>
<li>Creates a volume of the exact same name. Therefore, volume name restrictions apply to the tenant name as well. Specifying a custom volume name during tenant creation is not supported yet. Tenant volume cannot be changed once the tenant is created.</li>
<li>Creates two new Ranger roles, <code>tenantName-UserRole</code> and <code>tenantName-AdminRole</code>.</li>
<li>Creates new Ranger policies that allows all tenant users to list and create buckets by default under the tenant volume, but only bucket owners and tenant admins are allowed to access the bucket contents.</li>
</ol>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant <span style="color:#f92672">[</span>--verbose<span style="color:#f92672">]</span> create &lt;TENANT_NAME&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ kinit -kt /etc/security/keytabs/om.keytab om/om@EXAMPLE.COM
bash-4.2$ ozone tenant create tenantone
2022-02-16 00:00:00,000 <span style="color:#f92672">[</span>main<span style="color:#f92672">]</span> INFO rpc.RpcClient: Creating Tenant: <span style="color:#e6db74">&#39;tenantone&#39;</span>, with new volume: <span style="color:#e6db74">&#39;tenantone&#39;</span>
</code></pre></div><p>Verbose output example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ kinit -kt /etc/security/keytabs/om.keytab om/om@EXAMPLE.COM
bash-4.2$ ozone tenant --verbose create tenantone
2022-02-16 00:00:00,000 <span style="color:#f92672">[</span>main<span style="color:#f92672">]</span> INFO rpc.RpcClient: Creating Tenant: <span style="color:#e6db74">&#39;tenantone&#39;</span>, with new volume: <span style="color:#e6db74">&#39;tenantone&#39;</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;tenantId&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>
<span style="color:#f92672">}</span>
</code></pre></div><h3 id="list-tenants">List tenants</h3>
<p>List all tenants in an Ozone cluster. Optionally, use <code>--json</code> to print the detailed result in JSON.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant list <span style="color:#f92672">[</span>--json<span style="color:#f92672">]</span>
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant list
tenantone
</code></pre></div><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant list --json
<span style="color:#f92672">[</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;tenantId&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;bucketNamespaceName&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;userRoleName&#34;</span>: <span style="color:#e6db74">&#34;tenantone-UserRole&#34;</span>,
<span style="color:#e6db74">&#34;adminRoleName&#34;</span>: <span style="color:#e6db74">&#34;tenantone-AdminRole&#34;</span>,
<span style="color:#e6db74">&#34;bucketNamespacePolicyName&#34;</span>: <span style="color:#e6db74">&#34;tenantone-VolumeAccess&#34;</span>,
<span style="color:#e6db74">&#34;bucketPolicyName&#34;</span>: <span style="color:#e6db74">&#34;tenantone-BucketAccess&#34;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span>
</code></pre></div><h3 id="assign-a-user-to-a-tenant">Assign a user to a tenant</h3>
<p>The first user in a tenant must be assigned by an Ozone cluster administrator.</p>
<p>By default when user <code>testuser</code> is assigned to tenant <code>tenantone</code>, the generated Access ID for the user in this tenant is <code>tenantone$testuser</code>.</p>
<ul>
<li>Be sure to enclose the Access ID in single quotes in Bash when using it so it doesn&rsquo;t get expanded as environment variables.</li>
</ul>
<p>It is possible to assign a user to multiple tenants.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant <span style="color:#f92672">[</span>--verbose<span style="color:#f92672">]</span> user assign &lt;USER_NAME&gt; --tenant<span style="color:#f92672">=</span>&lt;TENANT_NAME&gt;
</code></pre></div><p><code>&lt;USER_NAME&gt;</code> should be a short user name for a Kerberos principal, e.g. <code>testuser</code> when the Kerberos principal is <code>testuser/scm@EXAMPLE.COM</code></p>
<p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user assign testuser --tenant<span style="color:#f92672">=</span>tenantone
export AWS_ACCESS_KEY_ID<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
export AWS_SECRET_ACCESS_KEY<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;&lt;GENERATED_SECRET&gt;&#39;</span>
bash-4.2$ ozone tenant user assign testuser --tenant<span style="color:#f92672">=</span>tenantone
TENANT_USER_ACCESS_ID_ALREADY_EXISTS accessId <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span> already exists!
</code></pre></div><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant --verbose user assign testuser2 --tenant<span style="color:#f92672">=</span>tenantone
export AWS_ACCESS_KEY_ID<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;tenantone$testuser2&#39;</span>
export AWS_SECRET_ACCESS_KEY<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;&lt;GENERATED_SECRET&gt;&#39;</span>
Assigned <span style="color:#e6db74">&#39;testuser2&#39;</span> to <span style="color:#e6db74">&#39;tenantone&#39;</span> with accessId <span style="color:#e6db74">&#39;tenantone$testuser2&#39;</span>.
</code></pre></div><h3 id="assign-a-user-as-a-tenant-admin">Assign a user as a tenant admin</h3>
<p>The first user in a tenant must be assigned by an Ozone cluster administrator.</p>
<p>Both delegated and non-delegated tenant admin can assign and revoke <strong>regular</strong> tenant users.</p>
<p>The only difference between delegated tenant admin and non-delegated tenant admin is that delegated tenant admin can assign and revoke tenant <strong>admins</strong> in the tenant,
while non-delegated tenant admin can&rsquo;t.</p>
<p>By default, <code>ozone tenant assignadmin</code> assigns a <strong>non-delegated</strong> tenant admin.
To assign a <strong>delegated</strong> tenant admin, specify <code>--delegated</code> or <code>-d</code>.</p>
<p>It is possible to assign a user to be tenant admins in multiple tenants. Just a reminder, the user would have a different access ID under each tenant.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant user assignadmin &lt;ACCESS_ID&gt; <span style="color:#f92672">[</span>-d|--delegated<span style="color:#f92672">]</span> --tenant<span style="color:#f92672">=</span>&lt;TENANT_NAME&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user assignadmin <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span> --tenant<span style="color:#f92672">=</span>tenantone
</code></pre></div><p>By default, if the command succeeds, it exits with <code>0</code> and prints nothing. Use <code>--verbose</code> to print the result in JSON.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant --verbose user assignadmin <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span> --tenant<span style="color:#f92672">=</span>tenantone
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;accessId&#34;</span>: <span style="color:#e6db74">&#34;tenantone</span>$testuser<span style="color:#e6db74">&#34;</span>,
<span style="color:#e6db74">&#34;tenantId&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;isAdmin&#34;</span>: true,
<span style="color:#e6db74">&#34;isDelegatedAdmin&#34;</span>: true
<span style="color:#f92672">}</span>
</code></pre></div><p>Once <code>testuser</code> becomes a tenant admin of <code>tenantone</code>, one can kinit as <code>testuser</code> and assign new users to the tenant,
even new tenant admins (if delegated). Example commands for illustration:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kinit -kt /etc/security/keytabs/testuser.keytab testuser/scm@EXAMPLE.COM
ozone tenant user assign testuser2 --tenant<span style="color:#f92672">=</span>tenantone
ozone tenant user assignadmin <span style="color:#e6db74">&#39;tenantone$testuser2&#39;</span> --tenant<span style="color:#f92672">=</span>tenantone
</code></pre></div><h3 id="list-users-in-a-tenant">List users in a tenant</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant user list <span style="color:#f92672">[</span>--json<span style="color:#f92672">]</span> &lt;TENANT_NAME&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user list tenantone
- User <span style="color:#e6db74">&#39;testuser&#39;</span> with accessId <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
- User <span style="color:#e6db74">&#39;testuser2&#39;</span> with accessId <span style="color:#e6db74">&#39;tenantone$testuser2&#39;</span>
</code></pre></div><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user list --json tenantone
<span style="color:#f92672">[</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;user&#34;</span>: <span style="color:#e6db74">&#34;testuser&#34;</span>,
<span style="color:#e6db74">&#34;accessId&#34;</span>: <span style="color:#e6db74">&#34;tenantone</span>$testuser<span style="color:#e6db74">&#34;</span>
<span style="color:#f92672">}</span>,
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;user&#34;</span>: <span style="color:#e6db74">&#34;testuser2&#34;</span>,
<span style="color:#e6db74">&#34;accessId&#34;</span>: <span style="color:#e6db74">&#34;tenantone</span>$testuser2<span style="color:#e6db74">&#34;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span>
</code></pre></div><h3 id="get-tenant-user-info">Get tenant user info</h3>
<p>This command lists all tenants a user is assigned to.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant user info <span style="color:#f92672">[</span>--json<span style="color:#f92672">]</span> &lt;USER_NAME&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user info testuser
User <span style="color:#e6db74">&#39;testuser&#39;</span> is assigned to:
- Tenant <span style="color:#e6db74">&#39;tenantone&#39;</span> delegated admin with accessId <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
</code></pre></div><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user info --json testuser
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;user&#34;</span>: <span style="color:#e6db74">&#34;testuser&#34;</span>,
<span style="color:#e6db74">&#34;tenants&#34;</span>: <span style="color:#f92672">[</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;accessId&#34;</span>: <span style="color:#e6db74">&#34;tenantone</span>$testuser<span style="color:#e6db74">&#34;</span>,
<span style="color:#e6db74">&#34;tenantId&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;isAdmin&#34;</span>: true,
<span style="color:#e6db74">&#34;isDelegatedAdmin&#34;</span>: true
<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span>
<span style="color:#f92672">}</span>
</code></pre></div><h3 id="revoke-a-tenant-admin">Revoke a tenant admin</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant <span style="color:#f92672">[</span>--verbose<span style="color:#f92672">]</span> user revokeadmin &lt;ACCESS_ID&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user revokeadmin <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
</code></pre></div><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant --verbose user revokeadmin <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;accessId&#34;</span>: <span style="color:#e6db74">&#34;tenantone</span>$testuser<span style="color:#e6db74">&#34;</span>,
<span style="color:#e6db74">&#34;isAdmin&#34;</span>: false,
<span style="color:#e6db74">&#34;isDelegatedAdmin&#34;</span>: false
<span style="color:#f92672">}</span>
</code></pre></div><h3 id="revoke-user-access-from-a-tenant">Revoke user access from a tenant</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant <span style="color:#f92672">[</span>--verbose<span style="color:#f92672">]</span> user revoke &lt;ACCESS_ID&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant user revoke <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
</code></pre></div><p>With verbose output:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant --verbose user revoke <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>
Revoked accessId <span style="color:#e6db74">&#39;tenantone$testuser&#39;</span>.
</code></pre></div><h3 id="delete-a-tenant">Delete a tenant</h3>
<p>In order to be able to delete a tenant, the tenant has to be empty. i.e. All users need to be revoked before a tenant can be deleted.
Otherwise OM will throw <code>TENANT_NOT_EMPTY</code> exception and refuse to delete the tenant.</p>
<p>Note that it is intentional by design that the volume created and associated with the tenant during tenant creation is not removed.
An admin has to remove the volume manually as prompt in the CLI, if deemed necessary.</p>
<p>Verbose option, in addition, will print the Ozone Manager RAW response in JSON.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone tenant <span style="color:#f92672">[</span>--verbose<span style="color:#f92672">]</span> delete &lt;TENANT_NAME&gt;
</code></pre></div><p>Example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant delete tenantone
Deleted tenant <span style="color:#e6db74">&#39;tenantone&#39;</span>.
But the associated volume <span style="color:#e6db74">&#39;tenantone&#39;</span> is not removed. To delete it, run
ozone sh volume delete tenantone
</code></pre></div><p>With verbose output:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone tenant --verbose delete tenantone
Deleted tenant <span style="color:#e6db74">&#39;tenantone&#39;</span>.
But the associated volume <span style="color:#e6db74">&#39;tenantone&#39;</span> is not removed. To delete it, run
ozone sh volume delete tenantone
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;tenantId&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;volumeName&#34;</span>: <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;volumeRefCount&#34;</span>: <span style="color:#ae81ff">0</span>
<span style="color:#f92672">}</span>
</code></pre></div><p>If an Ozone cluster admin (or whoever has the permission to delete the volume in Ranger) tries delete a volume before the tenant is deleted using the command above,
the <code>ozone sh volume delete</code> command would fail because the volume reference count is not zero:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone sh volume delete tenantone
VOLUME_IS_REFERENCED Volume reference count is not zero <span style="color:#f92672">(</span>1<span style="color:#f92672">)</span>. Ozone features are enabled on this volume. Try <span style="color:#e6db74">`</span>ozone tenant delete &lt;tenantId&gt;<span style="color:#e6db74">`</span> first.
</code></pre></div><h2 id="creating-bucket-links">Creating bucket links</h2>
<p>Bucket links can be used to allow access to buckets outside of the tenant volume.</p>
<p>Bucket (sym)links are a special type of bucket that points to other buckets in the same Ozone cluster. It is similar to POSIX symbolic links.</p>
<p>An example to create a bucket link:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ ozone tenant linkbucket /vol1/bucket1 /tenantone/linked-bucket1
</code></pre></div><p>The command above creates a bucket symlink <code>linked-bucket1</code> in volume <code>tenantone</code>, which points to <code>bucket1</code> in <code>vol1</code>.</p>
<p>As long as the user running this command has the permission to create a bucket in the target volume <code>tenantone</code>, the command will succeed.</p>
<ul>
<li>The link bucket command itself does not check for permission to access the source volume and bucket.</li>
<li>The link bucket command will not even check if the source volume and bucket exists.</li>
<li>Permission check will be performed when the bucket symlink is actually accessed.
<ul>
<li>In order to grant a user in tenant <code>tenantone</code> access the bucket, a new policy should be added by a Ranger admin that allow that user intended permissions (<code>READ, WRITE, LIST, CREATE, DELETE, ...</code>) to the source bucket <code>bucket1</code> in volume <code>vol1</code>.</li>
</ul>
</li>
<li>At the moment, <code>ozone tenant linkbucket</code> command is equivalent to <code>ozone sh bucket link</code> command (see <strong>Expose any volume</strong> section in <a href="../interface/s3.html">S3 protocol</a>).</li>
</ul>
<h2 id="example-accessing-a-bucket-in-a-tenant-volume-via-s3-gateway-using-s3-api">Example: Accessing a bucket in a tenant volume via S3 Gateway using S3 API</h2>
<p>Here is an example of accessing the bucket using AWS CLI in the Docker Compose cluster, with tenant <code>tenantone</code> created and <code>testuser</code> assigned to the tenant.</p>
<h3 id="configure-aws-cli">Configure AWS CLI</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ aws configure
AWS Access Key ID <span style="color:#f92672">[</span>****************fslf<span style="color:#f92672">]</span>: tenantone$testuser
AWS Secret Access Key <span style="color:#f92672">[</span>****************fslf<span style="color:#f92672">]</span>: &lt;GENERATED_SECRET&gt;
Default region name <span style="color:#f92672">[</span>us-west-1<span style="color:#f92672">]</span>:
Default output format <span style="color:#f92672">[</span>None<span style="color:#f92672">]</span>:
</code></pre></div><h3 id="list-buckets-create-a-bucket">List buckets, create a bucket</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-buckets
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Buckets&#34;</span>: <span style="color:#f92672">[]</span>
<span style="color:#f92672">}</span>
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 create-bucket --bucket bucket-test1
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Location&#34;</span>: <span style="color:#e6db74">&#34;http://s3g:9878/bucket-test1&#34;</span>
<span style="color:#f92672">}</span>
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-buckets
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Buckets&#34;</span>: <span style="color:#f92672">[</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Name&#34;</span>: <span style="color:#e6db74">&#34;bucket-test1&#34;</span>,
<span style="color:#e6db74">&#34;CreationDate&#34;</span>: <span style="color:#e6db74">&#34;2022-02-16T00:05:00.000Z&#34;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span>
<span style="color:#f92672">}</span>
</code></pre></div><p>In the Docker Compose cluster, the AWS CLI might report <code>AccessDenied</code> because it uses a mocked Ranger endpoint (which can&rsquo;t be used to perform authorization). A production Ranger setup uses <a href="https://github.com/apache/ranger/blob/master/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java"><code>RangerOzoneAuthorizer</code></a> in OM for authorization while the <code>ozonesecure</code> Docker Compose cluster still uses <code>OzoneNativeAuthorizer</code>. So a workaround is to set the volume owner to <code>testuser</code> to gain full access, as <code>OzoneNativeAuthorizer</code> grants the volume owner full permission:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">ozone sh volume update tenantone --user<span style="color:#f92672">=</span>testuser
</code></pre></div><p>The bucket created with <code>aws s3api</code> is also visible under Ozone CLI:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ ozone sh bucket list /tenantone
<span style="color:#f92672">[</span> <span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;metadata&#34;</span> : <span style="color:#f92672">{</span> <span style="color:#f92672">}</span>,
<span style="color:#e6db74">&#34;volumeName&#34;</span> : <span style="color:#e6db74">&#34;tenantone&#34;</span>,
<span style="color:#e6db74">&#34;name&#34;</span> : <span style="color:#e6db74">&#34;bucket-test1&#34;</span>,
<span style="color:#e6db74">&#34;storageType&#34;</span> : <span style="color:#e6db74">&#34;DISK&#34;</span>,
<span style="color:#e6db74">&#34;versioning&#34;</span> : false,
<span style="color:#e6db74">&#34;usedBytes&#34;</span> : 0,
<span style="color:#e6db74">&#34;usedNamespace&#34;</span> : 0,
<span style="color:#e6db74">&#34;creationTime&#34;</span> : <span style="color:#e6db74">&#34;2022-02-16T00:05:00.000Z&#34;</span>,
<span style="color:#e6db74">&#34;modificationTime&#34;</span> : <span style="color:#e6db74">&#34;2022-02-16T00:05:00.000Z&#34;</span>,
<span style="color:#e6db74">&#34;quotaInBytes&#34;</span> : -1,
<span style="color:#e6db74">&#34;quotaInNamespace&#34;</span> : -1,
<span style="color:#e6db74">&#34;bucketLayout&#34;</span> : <span style="color:#e6db74">&#34;OBJECT_STORE&#34;</span>,
<span style="color:#e6db74">&#34;owner&#34;</span> : <span style="color:#e6db74">&#34;root&#34;</span>,
<span style="color:#e6db74">&#34;link&#34;</span> : false
<span style="color:#f92672">}</span> <span style="color:#f92672">]</span>
</code></pre></div><h3 id="put-object-key-to-a-bucket-list-objects">Put object (key) to a bucket, list objects</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ aws s3api --endpoint-url http://s3g:9878 put-object --bucket bucket-test1 --key file1 --body README.md
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-objects --bucket bucket-test1
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Contents&#34;</span>: <span style="color:#f92672">[</span>
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;Key&#34;</span>: <span style="color:#e6db74">&#34;file1&#34;</span>,
<span style="color:#e6db74">&#34;LastModified&#34;</span>: <span style="color:#e6db74">&#34;2022-02-16T00:10:00.000Z&#34;</span>,
<span style="color:#e6db74">&#34;ETag&#34;</span>: <span style="color:#e6db74">&#34;e99f93dedfe22e9a133dc3c634f14634&#34;</span>,
<span style="color:#e6db74">&#34;Size&#34;</span>: 3811,
<span style="color:#e6db74">&#34;StorageClass&#34;</span>: <span style="color:#e6db74">&#34;STANDARD&#34;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span>
<span style="color:#f92672">}</span>
</code></pre></div><h3 id="get-object-key-from-a-bucket">Get object (key) from a bucket</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">bash-4.2$ aws s3api --endpoint-url http://s3g:9878 get-object --bucket bucket-test1 --key file1 file1-get.txt
<span style="color:#f92672">{</span>
<span style="color:#e6db74">&#34;AcceptRanges&#34;</span>: <span style="color:#e6db74">&#34;bytes&#34;</span>,
<span style="color:#e6db74">&#34;LastModified&#34;</span>: <span style="color:#e6db74">&#34;Wed, 16 Feb 2022 00:10:00 GMT&#34;</span>,
<span style="color:#e6db74">&#34;ContentLength&#34;</span>: 3811,
<span style="color:#e6db74">&#34;CacheControl&#34;</span>: <span style="color:#e6db74">&#34;no-cache&#34;</span>,
<span style="color:#e6db74">&#34;ContentType&#34;</span>: <span style="color:#e6db74">&#34;application/octet-stream&#34;</span>,
<span style="color:#e6db74">&#34;Expires&#34;</span>: <span style="color:#e6db74">&#34;Wed, 16 Feb 2022 00:15:00 GMT&#34;</span>,
<span style="color:#e6db74">&#34;Metadata&#34;</span>: <span style="color:#f92672">{}</span>
<span style="color:#f92672">}</span>
bash-4.2$ diff file1-get.txt README.md
</code></pre></div>
<a class="btn btn-success btn-lg" href="../feature/s3-multi-tenancy-access-control.html">Next >></a>
</div>
</div>
</div>
</div>
</div>
<div class="push"></div>
</div>
<footer class="footer">
<div class="container">
<span class="small text-muted">
Version: 1.5.0-SNAPSHOT, Last Modified: February 27, 2024 <a class="hide-child link primary-color" href="https://github.com/apache/ozone/commit/7939faf7d6c904bf1e4ad32baa5d6d0c1de19003">7939faf</a>
</span>
</div>
</footer>
<script src="../js/jquery-3.5.1.min.js"></script>
<script src="../js/ozonedoc.js"></script>
<script src="../js/bootstrap.min.js"></script>
</body>
</html>