Introduction

I recently needed to setup a demo environment. The goal is to have a self-contained virtual demo environment that can run on a laptop. It will consist of 3 virtual machines. A Windows Server 2008R2 running NetBackup. A virtual appliance SteelStore and a Ubuntu Linux VM running OpenStack Swift. The main challenge is keeping the memory footprint small enough.

SteelStore is an appliance designed for storing large amounts of data from a backup application, such as NetBackup, in the cloud. An example use case is backing up data and using a service like Amazon AWS S3 or Glacier to store the backup files.

For this project, I wanted to have a small object store in a Linux VM so that I could run a complete demo configuration on my MacBook Pro. The object store needed to be able to persist the data between reboots. This is one of the reasons I chose not to use DevStack. Instead I decided to use a a single-node OpenStack Swift configuration.

Virtual machines:

  • Windows 2008R2 with Veritas NetBackup 7
  • Ubuntu server 14.04 LTS with OpenStack Swift
  • NetApp SteelStore 3.2 virtual appliance

OpenStack

OpenStack is a set of software packages designed to work together to manage a cloud infrastructure. OpenStack services manage compute, networking and storage. OpenStack runs on standard hardware and provides a cloud type service for managing infrastructure in a data center.

OpenStack consists of a set of software packages each offering specific services

  • KeyStone - Identity Service
  • Glance - Image Service
  • Nova - Compute Service
  • Cinder - Block Storage Service
  • Swift - Object Storage Service
  • Neutron - Networking Service

OpenStack is available in several forms. There are many options on obtaining OpenStack including options that provide services and support. For a list look at the OpenStack marketplace.

This guide uses the Ubuntu distribution.

Note: The OpenStack options are evolving quickly. As new releases are available you should review and consider current options.

Prerequisites

Before starting, there are a some items that should be determined before starting the installation.

The first thing is to deploy an Ubuntu server VM.

You should also read through the installation instructions for OpenStack to become familiar with the process.

One important thing to understand is that there is a graphical management tool, Horizon. However, it requires several other services that I am not installing. So there will be no graphical management tool as part of this guide. You may also want to review the capabilities of Horizon with respect to managing Swift. At the time I wrote this article, it offered limited use with Swift.

Since the goal is to have a working Swift object storage server, the only other service installed here is Keystone for authentication. It is possible to setup Swift without Keystone, however, I think the installation using Keystone is the better option.

List of Accounts and Passwords

Software Account Description Password
mysql root db administrator changeme1
mysql keystone keystone account changeme1
linux user keystone keystone account changeme1
linux user mbraden My user accont changeme1
keystone admin token 15aa7aa7e4123454526c
keystone admin Keystone admin user changeme1
keystone SSaccount Used by the SteelStore appliance changeme1
keystone swift Swift user changeme1


You should create passwords for the above accounts and not use the “chageme1” password. I am listing it for example only. Also, each of the accounts should have a different password.

List of hostnames

Hostname Description IP
stack-1 Ubuntu server VM for Swift 192.168.84.80


Note: Add the host and IP to the /etc/hosts table. Make sure to reserve the IP address in DHCP or use a static IP. My system runs VMware Fusion and I usually reserve the IP in DHCP.

Parameters for configuring the SteelStore cloud settings

http://stack-1:5000/v2.0

Setting Parameter
Server stack-1
URL /v2.0/tokens
Port 5000
User SSaccount
Password changeme1


Note: When setting up the port to access in SteelStore, give the keystone authentication port which will return the URL to the Swift object store.

mbraden@stack-1:~$ keystone tenant-list
+----------------------------------+----------+---------+
|                id                |   name   | enabled |
+----------------------------------+----------+---------+
| 3b736b6c6926427c80eafa4b0d0d6067 | SStenant |   True  |


mbraden@stack-1:~$ keystone endpoint-list
+----------------------------------+-----------+-------------------------------------------+-------------------------------------------+---------------------------+----------------------------------+
|                id                |   region  |                 publicurl                 |                internalurl                |          adminurl         |            service_id            |
+----------------------------------+-----------+-------------------------------------------+-------------------------------------------+---------------------------+----------------------------------+
| 8aa01890173d4364898da3e8792a4717 | regionOne |          http://stack-1:5000/v2.0         |          http://stack-1:5000/v2.0         | http://stack-1:35357/v2.0 | f9ee67c0361b47ab9ef1d1d7d4f7b6e9 |
| 8c4b1231179e4563b34522b105e16aaf | regionOne | http://stack-1:8080/v1/AUTH_%(tenant_id)s | http://stack-1:8080/v1/AUTH_%(tenant_id)s |    http://stack-1:8080    | 5f0a6cb562fc453c813aba7aa056dbf7 |
+----------------------------------+-----------+-------------------------------------------+-------------------------------------------+---------------------------+----------------------------------+

Install OpenStack Prerequisites

The installation begins with a freshly setup Ubuntu Linux VM. The first step is to configure the cloud repositories that contain the OpenStack software components.

Configure the software repository for cloud

These are the current repositories I used. If you intend to install on a different version of Ubuntu or a different distribution of Linux, you should get the repository information that matches the version and distribution of Linux you are using.

sudo apt-get install python-software-properties
sudo apt-get install software-properties-common
sudo add-apt-repository cloud-archive:icehouse
sudo apt-get update

Example

mbraden@stack-1:~$ sudo apt-get install python-software-properties

mbraden@stack-1:~$ sudo apt-get install software-properties-common

mbraden@stack-1:~$ sudo add-apt-repository cloud-archive:icehouse

Install MySQL Database

A database needs to be installed for the services to use. Since we are making a combination controller and Swift node the database will be installed on this system. These steps use MySQL as the database.

sudo apt-get install python-mysqldb mysql-server

Configure MySQL

MySQL is configured by editing the my.nf file. I am using vi to edit the file.

Edit the /etc/mysql/my.cnf file and set the bind-address to 0.0.0.0 to allow all nodes access (default is loopback).

sudo vi /etc/mysql/my.cnf

#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           = 127.0.0.1
bind-address            = 0.0.0.0
#
# Settings for openstack
#
default-storage-engine = innodb
innodb_file_per_table
collation-server = utf8_general_ci
init-connect = 'SET NAMES utf8'
character-set-server = utf8

After modifying the configuration file, restart mysql.

sudo service mysql restart

Next it is a good idea to secure the MySQL server. There is a post installation utility that helps. When prompted to remove anonymous users, answer “Y”. You can change other parameters based on your specific needs.

MySQL Post-installation Setup Example:

mbraden@stack-1:~$ sudo mysql_install_db
mbraden@stack-1:~$ sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!


In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Perform a Distribution Upgrade for Ubuntu

If it hasn’t been done yet, it is a good idea to update the Ubuntu software to get the most recent security fixes.

sudo apt-get dist-upgrade
sudo reboot

Install a messaging server

For a multi-node configuration you would install a messaging server such as RabbitMQ.

For a single-node configuration, this is not needed.

Install OpenStack Service - Keystone

Once the database is installed and configured, the next step is to install the OpenStack services and configure them. This install starts with Keystone and continues with Swift.

Install Keystone Identity Service

sudo apt-get install keystone

Configure Keystone to use MySQL

In this section the database configuration in Keystone will be changed from the default of sqlite to MySQL.

Now, open the keystone configuration file in an editor and make the following changes.

sudo vi /etc/keystone/keystone.conf

First comment out sqlite, then add the connection for our database.

connection = mysql://keystone:changeme1@openstack1/keystone

Delete the sqlite default db

Delete the sample sqlite database file.

sudo rm /var/lib/keystone/keystone.db

Create a Keystone Instance in MySQL

Create the database instance for Keystone in the MySQL database installed in previous steps.

Make sure you use the same MySQL ROOT password you set previously.

$ mysql -u root -p
mysql>  #enter commands below at the mysql prompt


CREATE DATABASE keystone;

GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \
IDENTIFIED BY 'changeme1';

GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \
  IDENTIFIED BY 'changeme1';


GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \
IDENTIFIED BY 'changeme1';

GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \
  IDENTIFIED BY 'changeme1';


exit

Create the Database Tables for the Identity Service

In order for Keystone to be able to use the database, you will need to create the tables it requires.

Change the log dir permissions

sudo chmod -R 644 /var/log/keystone/
sudo chown keystone:keystone /etc/keystone/policy.json
sudo chown keystone:keystone /etc/keystone/

Set a password for the keystone user (was automatically created)

mbraden@stack-1:~$ sudo passwd keystone
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

Use the keystone utility to configure the database.

keystone keystone-manage db_sync

mbraden@stack-1:~$ keystone-manage db_sync
mbraden@stack-1:~$ 

Verify the Tables are Properly Created

Use the following commands to verify the database tables were properly created. If they do not list as expected, resolve any problems before continuing with the configuration.

#mysql -u keystone -p mysql>use keystone mysql>show tables;

mbraden@stack-1:~$ mysql -u keystone -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 52
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use keystone
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------------+
| Tables_in_keystone    |
+-----------------------+
| assignment            |
| credential            |
| domain                |
| endpoint              |
| group                 |
| id_mapping            |
| migrate_version       |
| policy                |
| project               |
| region                |
| revocation_event      |
| role                  |
| service               |
| token                 |
| trust                 |
| trust_role            |
| user                  |
| user_group_membership |
+-----------------------+
18 rows in set (0.01 sec)

mysql> exit

Create the Keystone Authentication Token

Keystone uses a token for authentication. It is basically a hex string and is easily generated using openssl.

mbraden@stack-1:~$ openssl rand -hex 10
15aa7aa7e4123454526c
mbraden@stack-1:~$ 

Edit /etc/keystone/keystone.conf and change the [DEFAULT] section, replacing ADMIN_TOKEN with the results of the openssl command.

In this case I am using vi again to edit the configuration file.

mbraden@stack-1:~$ sudo vi /etc/keystone/keystone.conf

#
admin_token=15aa7aa7e4123454526c

Configure the Log Directory

Edit the /etc/keystone/keystone.conf file and update the [DEFAULT]/logdir section as follows.

# Deprecated group/name - [DEFAULT]/logdir
log_dir=/var/log/keystone

Restart the Keystone Service

Now that the configuration files are updated to the appropriate values, restart the Keystone service for them to take effect.

sudo service keystone restart

mbraden@stack-1:~$ sudo service keystone restart
keystone stop/waiting
keystone start/running, process 4809
mbraden@stack-1:~$ 

Setup Purge of Tokens Hourly

The purge of tokens is performed using a CRON job. Verify there isn’t a CRON job created first.

mbraden@stack-1:~$ sudo crontab -l -u keystone
no crontab for keystone

Then use crontab -e to edit the CRON tab for the keystone Linux user account.

sudo crontab -e -u keystone

Add the following line:

@hourly /usr/bin/keystone-manage token_flush >/var/log/keystone/keystone-tokenflush.log 2>&1

Verify this is set correctly using crontab -l for the keystone user account.

mbraden@stack-1:~$ sudo crontab -l -u keystone
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
@hourly /usr/bin/keystone-manage token_flush >/var/log/keystone/keystone-tokenflush.log 2>&1

mbraden@stack-1:~$ 

Perform the Initial Keystone Configuration

Define users, tenants, and roles

export OS_SERVICE_TOKEN=15aa7aa7e4123454526c
export OS_SERVICE_ENDPOINT=http://openstack1:35357/v2.0

export OS_SERVICE_ENDPOINT=http://openstack1:35357/v2.0/

--os-token 15aa7aa7e4123454526c
--os-endpoint http://stack-1:35357/v2.0

List users

keystone user-list

Create the admin user:

Create an admin user in the Keystone user list.

keystone user-create --name=admin --pass=changeme1 --email=stack@openstack1

stack@openstack1:~$ keystone user-create --name=admin --pass=changeme1 --email=stack@openstack1
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |         stack@openstack1         |
| enabled  |               True               |
|    id    | 01b3b9b076684036b51be8321cf188e8 |
|   name   |              admin               |
| username |              admin               |
+----------+----------------------------------+
stack@openstack1:~$ keystone user-list
+----------------------------------+-------+---------+------------------+
|                id                |  name | enabled |      email       |
+----------------------------------+-------+---------+------------------+
| 01b3b9b076684036b51be8321cf188e8 | admin |   True  | stack@openstack1 |
+----------------------------------+-------+---------+------------------+
stack@openstack1:~$

Create the Admin Role

Create a role called admin.

keystone role-create --name=admin

stack@openstack1:~$ keystone role-create --name=admin
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|    id    | 2065626d35804f7d94fc76594758a45e |
|   name   |              admin               |

Create the Admin Tenant

Create a tenant for admin.

keystone tenant-create --name=admin --description="Admin Tenant"

stack@openstack1:~$ keystone tenant-create --name=admin --description="Admin Tenant"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |           Admin Tenant           |
|   enabled   |               True               |
|      id     | 04af154ad7e14968a3972b04978535f5 |
|     name    |              admin               |
+-------------+----------------------------------+

Map the Admin Role, Tenant and User

Map the admin user, admin role, and admin tenant together using the user-role-add option:

keystone user-role-add --user=admin --tenant=admin --role=admin

Create the member role

Create the member role. This is a generic role used to identify members. If this role is not created it is not possible to use the user accounts.

mbraden@stack-1:~$ keystone role-create --name=_member_
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|    id    | a1d501dca3274a0fb7e4636cc21bb4aa |
|   name   |             _member_             |
+----------+----------------------------------+

Map admin to member role

Map the admin user, member role, and admin tenant:

keystone user-role-add --user=admin --role=_member_ --tenant=admin

mbraden@stack-1:~$ keystone user-role-add --user=admin --role=_member_ --tenant=admin
mbraden@stack-1:~$ 

Create Normal Users

Now create the users in Keystone that you wish to have access to the system. Since I am setting this up for use with a SteelStore appliance, I am creating a user for it called SSaccount.

If you wish to have additional user accounts for Swift, you can create those now using the same steps.

keystone user-create --name=SSaccount --pass=changeme1 --email=root@stack-1

keystone tenant-create --name=SStenant --description="SteelStore Tenant"

keystone user-role-add --user=SSaccount --role=_member_ --tenant=SStenant

stack@openstack1:~$ keystone user-create --name=SSaccount --pass=changeme1 --email=root@stack-1
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |           root@stack-1           |
| enabled  |               True               |
|    id    | f7fcd9fe19314e3ba965c4d15db2c65f |
|   name   |            SSaccount             |
| username |            SSaccount             |
+----------+----------------------------------+
stack@openstack1:~$
stack@openstack1:~$ keystone tenant-create --name=SStenant --description="SteelStore Tenant"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |        SteelStore Tenant         |
|   enabled   |               True               |
|      id     | 3eabe7b1bb614e75895703417b62f640 |
|     name    |             SStenant             |
+-------------+----------------------------------+
stack@openstack1:~$
stack@openstack1:~$ keystone user-role-add --user=SSaccount --role=_member_ --tenant=SStenant
stack@openstack1:~$

Create a Service Tenant

keystone tenant-create --name=service --description="Service Tenant"

stack@openstack1:~$ keystone tenant-create --name=service --description="Service Tenant"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |          Service Tenant          |
|   enabled   |               True               |
|      id     | 845075ca1b45498896a798bc9ba2ffc4 |
|     name    |             service              |
+-------------+----------------------------------+

Define the Keystone Service

Define the service for Keystone with a description as OpenStack Identity.

keystone service-create --name=keystone --type=identity --description="OpenStack Identity"

stack@openstack1:~$ keystone service-create --name=keystone --type=identity --description="OpenStack Identity"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |        OpenStack Identity        |
|   enabled   |               True               |
|      id     | 87a771f057c54a6088e41c6bc6724dc5 |
|     name    |             keystone             |
|     type    |             identity             |
+-------------+----------------------------------+

Define the Keystone Service Endpoint

Using the hostname, define the service endpoint for Keystone.

The endpoing is how a client accesses the service’s API. An endpoint is basically a URL used by an application to access the service.

keystone endpoint-create \
  --service-id=$(keystone service-list | awk '/ identity / {print $2}') \
  --publicurl=http://openstack1:5000/v2.0 \
  --internalurl=http://openstack1:5000/v2.0 \
  --adminurl=http://openstack1:35357/v2.0
stack@openstack1:~$ keystone endpoint-create \
>   --service-id=$(keystone service-list | awk '/ identity / {print $2}') \
>   --publicurl=http://openstack1:5000/v2.0 \
>   --internalurl=http://openstack1:5000/v2.0 \
>   --adminurl=http://openstack1:35357/v2.0
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
|   adminurl  |   http://openstack1:35357/v2.0   |
|      id     | 989cbca79b3f4a5bb661851ec353e7cc |
| internalurl |   http://openstack1:5000/v2.0    |
|  publicurl  |   http://openstack1:5000/v2.0    |
|    region   |            regionOne             |
|  service_id | 87a771f057c54a6088e41c6bc6724dc5 |
+-------------+----------------------------------+
stack@openstack1:~$

Verify the Keystone Configuration

Now using the keystone utility, verify the configuration is correct.

unset OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT

keystone –os-username=admin –os-password=changeme1 \ –os-auth-url=http://openstack1:35357/v2.0 token-get

keystone –os-username=admin –os-password=changeme1 \ –os-tenant-name=admin –os-auth-url=http://openstack1:35357/v2.0 \ token-get

mbraden@stack-1:~$ keystone --os-username=admin --os-password=changeme1 \
>   --os-auth-url=http://stack-1:35357/v2.0 token-get
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
| expires  |       2015-02-12T18:42:26Z       |
|    id    | 30ac7e2de53d448db56ea251ecdafb17 |
| user_id  | 5aa3129cbfa9424aacc86c4619395ae1 |
+----------+----------------------------------+

mbraden@stack-1:~$ keystone --os-username=admin --os-password=changeme1 \
>   --os-tenant-name=admin --os-auth-url=http://stack-1:35357/v2.0 \
>   token-get
+-----------+----------------------------------+
|  Property |              Value               |
+-----------+----------------------------------+
|  expires  |       2015-02-12T18:44:19Z       |
|     id    | da23b4eb70f94da6a36fbc30cb25f270 |
| tenant_id | 156a3c3dacfe4399be35544ae4d97a6c |
|  user_id  | 5aa3129cbfa9424aacc86c4619395ae1 |
+-----------+----------------------------------+

Create Environment Scripts

In order to change the identity when testing or running OpenStack utilities, its best to create script files that contain the needed environment settings.

The following example shows using admin-openrc.sh to quickly setup for admin.

mbraden@stack-1:~$ vi admin-openrc.sh
mbraden@stack-1:~$ cat admin-openrc.sh 
# Openstack admin env vars
export OS_USERNAME=admin
export OS_PASSWORD=changeme1
export OS_TENANT_NAME=admin
export OS_AUTH_URL=http://openstack1:35357/v2.0
mbraden@stack-1:~$ . ./admin-openrc.sh 
stack@openstack1:~$ keystone token-get
+-----------+----------------------------------+
|  Property |              Value               |
+-----------+----------------------------------+
|  expires  |       2015-02-21T07:12:36Z       |
|     id    | 05aeef5b4e4242fa9d645c69b7a10490 |
| tenant_id | 04af154ad7e14968a3972b04978535f5 |
|  user_id  | 01b3b9b076684036b51be8321cf188e8 |
	
mbraden@stack-1:~$ keystone user-list
+----------------------------------+-----------+---------+---------------+
|                id                |    name   | enabled |     email     |
+----------------------------------+-----------+---------+---------------+
| 58c0426f70dc409eb15dbb13c378c911 | SSaccount |   True  |  root@stack-1 |
| 5aa3129cbfa9424aacc86c4619395ae1 |   admin   |   True  | mbraden@stack |
+----------------------------------+-----------+---------+---------------+

Install OpenStack Service - Swift

Swift uses nodes with dedicated functions. The proxy node is where applications or systems communicate to access Swift storage.

Since this installation is a single-node configuration the Swift nodes types of proxy and storage will be installed on the same node we are using as an OpenStack controller and a Keystone identity node.

Install Swift Packages

Install packages for proxy and storage.

sudo apt-get install swift swift-account swift-container swift-object xfsprogs \
                     swift-proxy memcached python-keystoneclient \
                     python-swiftclient python-webob curl

Configure Keystone for Swift

Create the swift user in Keystone along with a swift role. Then create a service and map it to the swift user and role.

keystone user-create –name=swift –pass=changeme1 –email=root@openstack1

keystone user-role-add –user=swift –tenant=service –role=admin

keystone service-create –name=swift –type=object-store \ –description=”OpenStack Object Storage”

stack@openstack1:~$ keystone user-create --name=swift --pass=changeme1 --email=root@openstack1
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |         root@openstack1          |
| enabled  |               True               |
|    id    | a5cbac35df334075ac7e904c8666724a |
|   name   |              swift               |
| username |              swift               |
+----------+----------------------------------+
stack@openstack1:~$ keystone user-role-add --user=swift --tenant=service --role=admin
stack@openstack1:~$ keystone service-create --name=swift --type=object-store \
>   --description="OpenStack Object Storage"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |     OpenStack Object Storage     |
|   enabled   |               True               |
|      id     | 136ea4df576c44cc8757e3bb07742109 |
|     name    |              swift               |
|     type    |           object-store           |
+-------------+----------------------------------+
stack@openstack1:~$

Create the Swift Service Endpoint

The endpoint is how a client accesses the service’s API. An endpoint is basically a URL used by an application to access the service.

Any client that wants to store or access objects in Swift will need the endpoint to talk to the Swift storage nodes. The actual endpoint for the storage API will be used to talk to a storage node through the proxy.

keystone endpoint-create \ –service-id=$(keystone service-list | awk ‘/ object-store / {print $2}’) \ –publicurl=’http://openstack1:8080/v1/AUTH_%(tenant_id)s’ \ –internalurl=’http://openstack1:8080/v1/AUTH_%(tenant_id)s’ \ –adminurl=http://openstack1:8080

stack@openstack1:~$ keystone endpoint-create \
>   --service-id=$(keystone service-list | awk '/ object-store / {print $2}') \
>   --publicurl='http://openstack1:8080/v1/AUTH_%(tenant_id)s' \
>   --internalurl='http://openstack1:8080/v1/AUTH_%(tenant_id)s' \
>   --adminurl=http://openstack1:8080
+-------------+----------------------------------------------+
|   Property  |                    Value                     |
+-------------+----------------------------------------------+
|   adminurl  |            http://openstack1:8080            |
|      id     |       57b7b13eec744d5f98cd3a6c6254251f       |
| internalurl | http://openstack1:8080/v1/AUTH_%(tenant_id)s |
|  publicurl  | http://openstack1:8080/v1/AUTH_%(tenant_id)s |
|    region   |                  regionOne                   |
|  service_id |       136ea4df576c44cc8757e3bb07742109       |
+-------------+----------------------------------------------+
stack@openstack1:~$
stack@openstack1:~$

Configure the Swift Service

The /etc/swift directory should have been created automatically during the installation of the Swift packages.

This directory contains the swift.conf file that contains the configuration parameters used by the Swift service.

Create the Swift Hash

Swift uses a hashing mechanism to store data. There are numerous articles that describe how Swift stores data and what the concept of a Ring is. I suggest doing an internet search to find out more if you are interested. There are a lot of good discussions at various technical levels.

For all Swift clusters, there will be one cluster-wide unique string called the Swift hash or Swift hash path prefix/suffix. These are values that you create that are used in storing data in your Swift storage nodes.

The hash value should be kept secret similar to an administrator password. This hash value is applied to all storage nodes within a single Swift cluster. Each node will have the same hash value.

The hash is secret because it is similar to a “salt” value used in encryption. The purpose is to give a secret value that gets added before a hash is generated so that it will not be possible for someone to guess the hash value of an object.

These values should be kept secret and are required for any new storage nodes.

You can use openssl to generate a random value for you.

openssl rand -hex 5 openssl rand -hex 5

Example

`` mbraden@stack-1:~$ openssl rand -hex 5 40864ec014 mbraden@stack-1:~$ openssl rand -hex 5 b7887ac16c


## Create the Swift Configuration File

The Swift configuration file, `/etc/swift/swift.conf` needs to be created manually. Create the
file and add the swift hash values to this file.

Example:

sudo vi /etc/swift/swift.conf

[swift-hash]

random unique string that can never change (DO NOT LOSE)

swift_hash_path_prefix = 40864ec014 swift_hash_path_suffix = b7887ac16c


## Create Storage for Use by Swift

There are a couple of options for creating storage locations needed by Swift. Since this is a
lab system and not a production system, I do not have a system with multiple disk devices. I
am using a single VM with a single virtual disk. It would be possible to add 10 or 12 virtual
disks to the Linux VM to more closely approximate a production system. However, I prefer to
keep the VM setup simple by using either the one disk it has or adding a single disk.

In my case, I setup multiple labs each needing a Swift instance. I have used both the loopback
device (Option 1) and added a second disk (Option 2). Either of these work well.


Option 1 - Using a Loopback Device

This option creates one large file in the local disk filesystem and accesses it like a separate
disk using a loopback device.

The following steps create the file to use for the disk, format the "disk" and add the disk
to the fstab so that it is mounted at boot.

sudo mkdir -p /srv/node/sdb1 sudo truncate -s 10GB /srv/swift-disk sudo mkfs.xfs /srv/swift-disk


Edit /etc/fstab and add an entry at the end of the file for this new device.

sudo vi /etc/fstab

/srv/swift-disk /srv/node/sdb1 xfs loop,noatime,nodiratime,nobarrier,logbufs=8 0 0


Option 2 - Add a Second Virtual Disk

In this option, a second virtual disk was added to the VM.

sudo fdisk /dev/sdb sudo mkfs.xfs /dev/sdb1 sudo mkdir -p /srv/node/sdb1


Edit /etc/fstab and add an entry at the end of the file for this new device.

sudo vi /etc/fstab

/dev/sdb1 /srv/node/sdb1 xfs noatime,nodiratime,nobarrier,logbufs=8 0 0


## Continue Disk Setup

After using one of the above options to create a disk used for storage with Swift, perform the
following tasks. They apply to either option listed above.

Mount the disk device and set the permissions to make the swift user owner.

sudo mount /srv/node/sdb1 sudo chown -R swift:swift /srv/node



## Setup rsync


Create /etc/rsyncd.conf

sudo vi /etc/rsyncd.conf

Add the following to the `/etc/rsyncd.conf` file.

uid = swift gid = swift log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid address = 127.0.0.1 [account] max connections = 2 path = /srv/node/ read only = false lock file = /var/lock/account.lock [container] max connections = 2 path = /srv/node/ read only = false lock file = /var/lock/container.lock [object] max connections = 2 path = /srv/node/ read only = false lock file = /var/lock/object.lock



### Edit and enable rsync

Edit `/etc/default/rsync` and add the RSYNC_ENABLE shown below.

sudo vi /etc/default/rsync

RSYNC_ENABLE=true


### Start the rsync Service

sudo service rsync start


### Verify rsync is Accepting Connections


rsync rsync://pub@localhost/

stack@openstack1:~$ sudo service rsync start

  • Starting rsync daemon rsync [ OK ] stack@openstack1:~$ rsync rsync://pub@localhost/ account container object stack@openstack1:~$ ```

Setup Recon Cache

sudo mkdir -p /var/swift/recon
sudo chown -R swift:swift /var/swift/recon

Setup swift proxy

Leave the default for memcached to list on loopback interface.

/etc/memcached.conf
-l 127.0.0.1

Verify memcached is Running

sudo service --status-all

Check for memcached in the list of services.

Create /etc/swift/proxy-server.conf

Create the swift proxy configuration file and add the information below to the file.

Note: Make sure you change the admin_password to match the password you assigned.

sudo vi /etc/swift/proxy-server.conf

[DEFAULT]
bind_port = 8080
user = swift
[pipeline:main]
pipeline = healthcheck cache authtoken keystoneauth proxy-server
[app:proxy-server]
use = egg:swift#proxy
allow_account_management = true
account_autocreate = true
[filter:keystoneauth]
use = egg:swift#keystoneauth
operator_roles = Member,admin,swiftoperator
[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
# Delaying the auth decision is required to support token-less
# usage for anonymous referrers ('.r:*').
delay_auth_decision = true
# auth_* settings refer to the Keystone server
auth_protocol = http
auth_host = openstack1
auth_port = 35357
# the service tenant and swift username and password created in Keystone
admin_tenant_name = service
admin_user = swift
admin_password = changeme1
[filter:cache]
use = egg:swift#memcache
[filter:catch_errors]
use = egg:swift#catch_errors
[filter:healthcheck]
use = egg:swift#healthcheck

Create the account, container, and object rings

Each Swift storage node will have 3 rings configured. The Rings are described in the Swift architectural overview.

sudo chown swift:swift /etc/swift
cd /etc/swift

Then execute the following:

sudo -u swift swift-ring-builder account.builder create 8 3 1
sudo -u swift swift-ring-builder container.builder create 8 3 1
sudo -u swift swift-ring-builder object.builder create 8 3 1

sudo -u swift swift-ring-builder account.builder add z1-127.0.0.1:6002R127.0.0.1:6005/sdb1 100
sudo -u swift swift-ring-builder container.builder add z1-127.0.0.1:6001R127.0.0.1:6004/sdb1 100
sudo -u swift swift-ring-builder object.builder add z1-127.0.0.1:6000R127.0.0.1:6003/sdb1 100

sudo -u swift swift-ring-builder account.builder
sudo -u swift swift-ring-builder container.builder
sudo -u swift swift-ring-builder object.builder

sudo -u swift swift-ring-builder account.builder rebalance
sudo -u swift swift-ring-builder container.builder rebalance
sudo -u swift swift-ring-builder object.builder rebalance

Example of the above commands:

stack@openstack1:~$ cd /etc/swift/
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder account.builder create 8 3 1
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder container.builder create 8 3 1
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder object.builder create 8 3 1
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder account.builder add z1-127.0.0.1:6002R127.0.0.1:6005/sdb1 100
sudo -u swift swift-ring-builder object.builder add z1-127.0.0.1:6000R127.0.0.1:6003/sdb1 100
WARNING: No region specified for z1-127.0.0.1:6002R127.0.0.1:6005/sdb1. Defaulting to region 1.
Device d0r1z1-127.0.0.1:6002R127.0.0.1:6005/sdb1_"" with 100.0 weight got id 0
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder container.builder add z1-127.0.0.1:6001R127.0.0.1:6004/sdb1 100
WARNING: No region specified for z1-127.0.0.1:6001R127.0.0.1:6004/sdb1. Defaulting to region 1.
Device d0r1z1-127.0.0.1:6001R127.0.0.1:6004/sdb1_"" with 100.0 weight got id 0
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder object.builder add z1-127.0.0.1:6000R127.0.0.1:6003/sdb1 100
WARNING: No region specified for z1-127.0.0.1:6000R127.0.0.1:6003/sdb1. Defaulting to region 1.
Device d0r1z1-127.0.0.1:6000R127.0.0.1:6003/sdb1_"" with 100.0 weight got id 0
stack@openstack1:/etc/swift$
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder account.builder
account.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 100.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6002       127.0.0.1              6005      sdb1 100.00          0 -100.00
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder container.builder
container.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 100.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6001       127.0.0.1              6004      sdb1 100.00          0 -100.00
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder object.builder
object.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 100.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6000       127.0.0.1              6003      sdb1 100.00          0 -100.00
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder account.builder rebalance
Reassigned 256 (100.00%) partitions. Balance is now 0.00.
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder container.builder rebalance
Reassigned 256 (100.00%) partitions. Balance is now 0.00.
stack@openstack1:/etc/swift$ sudo -u swift swift-ring-builder object.builder rebalance
Reassigned 256 (100.00%) partitions. Balance is now 0.00.
stack@openstack1:/etc/swift$

Verify Ring Contents

After creating the Ring, verify using the following commands:

cd /etc/swift swift-ring-builder account.builder swift-ring-builder container.builder swift-ring-builder object.builder

Example of output when performing the above verify commands.

mbraden@stack-1:/etc/swift$ swift-ring-builder account.builder
account.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 0.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6002       127.0.0.1              6005      sdb1 100.00        768    0.00 
mbraden@stack-1:/etc/swift$ swift-ring-builder container.builder
container.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 0.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6001       127.0.0.1              6004      sdb1 100.00        768    0.00 
mbraden@stack-1:/etc/swift$ swift-ring-builder object.builder
object.builder, build version 1
256 partitions, 3.000000 replicas, 1 regions, 1 zones, 1 devices, 0.00 balance
The minimum number of hours before a partition can be reassigned is 1
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       127.0.0.1  6000       127.0.0.1              6003      sdb1 100.00        768    0.00 
mbraden@stack-1:/etc/swift$ 

Restart the proxy service

Restart the swift proxy service so the new settings take effect.

sudo service swift-proxy restart

Start the Storage Services

The following command starts the storage services:

for service in \ swift-object swift-object-replicator swift-object-updater swift-object-auditor \ swift-container swift-container-replicator swift-container-updater swift-container-auditor \ swift-account swift-account-replicator swift-account-reaper swift-account-auditor; do \ sudo service $service start; done

Example of starting the storage services:

mbraden@stack-1:/etc/swift$ for service in \
>   swift-object swift-object-replicator swift-object-updater swift-object-auditor \
>   swift-container swift-container-replicator swift-container-updater swift-container-auditor \
>   swift-account swift-account-replicator swift-account-reaper swift-account-auditor; do \
>       sudo service $service start; done
swift-object start/running
swift-object-replicator start/running
swift-object-updater start/running
swift-object-auditor start/running
swift-container start/running
swift-container-replicator start/running
swift-container-updater start/running
swift-container-auditor start/running
swift-account start/running
swift-account-replicator start/running
swift-account-reaper start/running
swift-account-auditor start/running
mbraden@stack-1:/etc/swift$ 

Another way is to start all services using the following command:

swift-init all start

Verify the Swift Service is Working

Use the command swift stat to show if Swift is responding correctly.

mbraden@stack-1:/etc/swift$ swift stat
        Account: AUTH_156a3c3dacfe4399be35544ae4d97a6c
     Containers: 0
        Objects: 0
          Bytes: 0
   Content-Type: text/plain; charset=utf-8
    X-Timestamp: 1424319891.54659
     X-Trans-Id: tx58dfa78e1a904f8699faf-0054e56593
X-Put-Timestamp: 1424319891.54659
mbraden@stack-1:/etc/swift$

Test Upload and Download of Files

The final test is to actually upload some files and download them to verify the service is working.

Create some sample files to upload using vi.

cd

vi test.txt
add some text

vi test2.txt
add some text

Then use the swift utility to transfer the files.

swift upload myfiles test.txt swift upload myfiles test2.txt

The following example shows output from transferring these files:

mbraden@stack-1:~$ swift upload myfiles test.txt
test.txt
mbraden@stack-1:~$ swift upload myfiles test2.txt
test2.txt
mbraden@stack-1:~$

Now move the original files to a new file name.

mv test.txt test.txt.orig
mv test2.txt test2.txt.orig
swift download myfiles

Then download the files from the swift service.

mbraden@stack-1:~$ swift download myfiles
test.txt [auth 0.089s, headers 0.103s, total 0.103s, 0.004 MB/s]
test2.txt [auth 0.104s, headers 0.118s, total 0.118s, 0.005 MB/s]
mbraden@stack-1:~$ 

You can compare the files with checksums or view them to ensure they are the same as the original files you created.

Create the Container

The container created here is basically the same as a bucket in Amazon Web Services S3 object storage. It is the path where the files uploaded by the appliance will be stored.

The container is created by specifying the name with the post command.

swift post sstest1

Example of creating, listing and setting permissions:

stack@openstack1:~$ swift post sstest1
stack@openstack1:~$ swift list
sstest1
stack@openstack1:~$

stack@openstack1:~$ swift stat sstest1
         Account: AUTH_3eabe7b1bb614e75895703417b62f640
       Container: sstest1
         Objects: 0
           Bytes: 0
        Read ACL:
       Write ACL:
         Sync To:
        Sync Key:
   Accept-Ranges: bytes
X-Storage-Policy: Policy-0
     X-Timestamp: 1424500431.67006
      X-Trans-Id: tx03a1d4af638741039c0aa-0054e826fc
    Content-Type: text/plain; charset=utf-8

stack@openstack1:~$ swift post -r 'SSaccount' sstest1
stack@openstack1:~$ swift post -w 'SSaccount' sstest1
stack@openstack1:~$ swift stat sstest1
         Account: AUTH_3eabe7b1bb614e75895703417b62f640
       Container: sstest1
         Objects: 0
           Bytes: 0
        Read ACL: SSaccount
       Write ACL: SSaccount
         Sync To:
        Sync Key:
   Accept-Ranges: bytes
X-Storage-Policy: Policy-0
     X-Timestamp: 1424500431.67006
      X-Trans-Id: tx2017e188cd974a5085251-0054e82730
    Content-Type: text/plain; charset=utf-8
stack@openstack1:~$

References

OpenStack Installation for Icehouse

Troubleshooting keystone

Swift Command Reference

mbraden@stack-1:~$ swift --help
Usage: swift [--version] [--help] [--os-help] [--snet] [--verbose]
             [--debug] [--info] [--quiet] [--auth <auth_url>]
             [--auth-version <auth_version>] [--user <username>]
             [--key <api_key>] [--retries <num_retries>]
             [--os-username <auth-user-name>] [--os-password <auth-password>]
             [--os-user-id <auth-user-id>]
             [--os-user-domain-id <auth-user-domain-id>]
             [--os-user-domain-name <auth-user-domain-name>]
             [--os-tenant-id <auth-tenant-id>]
             [--os-tenant-name <auth-tenant-name>]
             [--os-project-id <auth-project-id>]
             [--os-project-name <auth-project-name>]
             [--os-project-domain-id <auth-project-domain-id>]
             [--os-project-domain-name <auth-project-domain-name>]
             [--os-auth-url <auth-url>] [--os-auth-token <auth-token>]
             [--os-storage-url <storage-url>] [--os-region-name <region-name>]
             [--os-service-type <service-type>]
             [--os-endpoint-type <endpoint-type>]
             [--os-cacert <ca-certificate>] [--insecure]
             [--no-ssl-compression]
             <subcommand> [--help]

Command-line interface to the OpenStack Swift API.

Positional arguments:
  <subcommand>
    delete               Delete a container or objects within a container.
    download             Download objects from containers.
    list                 Lists the containers for the account or the objects
                         for a container.
    post                 Updates meta information for the account, container,
                         or object; creates containers if not present.
    stat                 Displays information for the account, container,
                         or object.
    upload               Uploads files or directories to the given container.
    capabilities         List cluster capabilities.
    tempurl              Create a temporary URL

Examples:
  swift download --help

  swift -A https://auth.api.rackspacecloud.com/v1.0 -U user -K api_key stat -v

  swift --os-auth-url https://api.example.com/v2.0 --os-tenant-name tenant \
      --os-username user --os-password password list

  swift --os-auth-url https://api.example.com/v3 --auth-version 3\
      --os-project-name project1 --os-project-domain-name domain1 \
      --os-username user --os-user-domain-name domain1 \
      --os-password password list

  swift --os-auth-url https://api.example.com/v3 --auth-version 3\
      --os-project-id 0123456789abcdef0123456789abcdef \
      --os-user-id abcdef0123456789abcdef0123456789 \
      --os-password password list

  swift --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \
      --os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \
      list

  swift list --lh

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  --os-help             Show OpenStack authentication options.
  -s, --snet            Use SERVICENET internal network.
  -v, --verbose         Print more info.
  --debug               Show the curl commands and results of all http queries
                        regardless of result status.
  --info                Show the curl commands and results of all http queries
                        which return an error.
  -q, --quiet           Suppress status output.
  -A AUTH, --auth=AUTH  URL for obtaining an auth token.
  -V AUTH_VERSION, --auth-version=AUTH_VERSION
                        Specify a version for authentication. Defaults to 1.0.
  -U USER, --user=USER  User name for obtaining an auth token.
  -K KEY, --key=KEY     Key for obtaining an auth token.
  -R RETRIES, --retries=RETRIES
                        The number of times to retry a failed connection.
  --insecure            Allow swiftclient to access servers without having to
                        verify the SSL certificate. Defaults to
                        env[SWIFTCLIENT_INSECURE] (set to 'true' to enable).
  --no-ssl-compression  This option is deprecated and not used anymore. SSL
                        compression should be disabled by default by the
                        system SSL library.
mbraden@stack-1:~$ 

Keystone command Reference

mbraden@stack-1:~$ keystone --help
usage: keystone [--version] [--debug] [--os-username <auth-user-name>]
                [--os-password <auth-password>]
                [--os-tenant-name <auth-tenant-name>]
                [--os-tenant-id <tenant-id>] [--os-auth-url <auth-url>]
                [--os-region-name <region-name>]
                [--os-identity-api-version <identity-api-version>]
                [--os-token <service-token>]
                [--os-endpoint <service-endpoint>] [--os-cache]
                [--force-new-token] [--stale-duration <seconds>] [--insecure]
                [--os-cacert <ca-certificate>] [--os-cert <certificate>]
                [--os-key <key>] [--timeout <seconds>]
                <subcommand> ...

Pending deprecation: Command-line interface to the OpenStack Identity API.
This CLI is pending deprecation in favor of python-openstackclient. For a
Python library, continue using python-keystoneclient.

Positional arguments:
  <subcommand>
    catalog             List service catalog, possibly filtered by service.
    ec2-credentials-create
                        Create EC2-compatible credentials for user per tenant.
    ec2-credentials-delete
                        Delete EC2-compatible credentials.
    ec2-credentials-get
                        Display EC2-compatible credentials.
    ec2-credentials-list
                        List EC2-compatible credentials for a user.
    endpoint-create     Create a new endpoint associated with a service.
    endpoint-delete     Delete a service endpoint.
    endpoint-get        Find endpoint filtered by a specific attribute or
                        service type.
    endpoint-list       List configured service endpoints.
    password-update     Update own password.
    role-create         Create new role.
    role-delete         Delete role.
    role-get            Display role details.
    role-list           List all roles.
    service-create      Add service to Service Catalog.
    service-delete      Delete service from Service Catalog.
    service-get         Display service from Service Catalog.
    service-list        List all services in Service Catalog.
    tenant-create       Create new tenant.
    tenant-delete       Delete tenant.
    tenant-get          Display tenant details.
    tenant-list         List all tenants.
    tenant-update       Update tenant name, description, enabled status.
    token-get           Display the current user token.
    user-create         Create new user.
    user-delete         Delete user.
    user-get            Display user details.
    user-list           List users.
    user-password-update
                        Update user password.
    user-role-add       Add role to user.
    user-role-list      List roles granted to a user.
    user-role-remove    Remove role from user.
    user-update         Update user's name, email, and enabled status.
    discover            Discover Keystone servers, supported API versions and
                        extensions.
    bootstrap           Grants a new role to a new user on a new tenant, after
                        creating each.
    bash-completion     Prints all of the commands and options to stdout.
    help                Display help about this program or one of its
                        subcommands.

Optional arguments:
  --version             Shows the client version and exits.
  --debug               Prints debugging output onto the console, this
                        includes the curl request and response calls. Helpful
                        for debugging and understanding the API calls.
  --os-username <auth-user-name>
                        Name used for authentication with the OpenStack
                        Identity service. Defaults to env[OS_USERNAME].
  --os-password <auth-password>
                        Password used for authentication with the OpenStack
                        Identity service. Defaults to env[OS_PASSWORD].
  --os-tenant-name <auth-tenant-name>
                        Tenant to request authorization on. Defaults to
                        env[OS_TENANT_NAME].
  --os-tenant-id <tenant-id>
                        Tenant to request authorization on. Defaults to
                        env[OS_TENANT_ID].
  --os-auth-url <auth-url>
                        Specify the Identity endpoint to use for
                        authentication. Defaults to env[OS_AUTH_URL].
  --os-region-name <region-name>
                        Specify the region to use. Defaults to
                        env[OS_REGION_NAME].
  --os-identity-api-version <identity-api-version>
                        Specify Identity API version to use. Defaults to
                        env[OS_IDENTITY_API_VERSION] or 2.0.
  --os-token <service-token>
                        Specify an existing token to use instead of retrieving
                        one via authentication (e.g. with username &
                        password). Defaults to env[OS_SERVICE_TOKEN].
  --os-endpoint <service-endpoint>
                        Specify an endpoint to use instead of retrieving one
                        from the service catalog (via authentication).
                        Defaults to env[OS_SERVICE_ENDPOINT].
  --os-cache            Use the auth token cache. Defaults to env[OS_CACHE].
  --force-new-token     If the keyring is available and in use, token will
                        always be stored and fetched from the keyring until
                        the token has expired. Use this option to request a
                        new token and replace the existing one in the keyring.
  --stale-duration <seconds>
                        Stale duration (in seconds) used to determine whether
                        a token has expired when retrieving it from keyring.
                        This is useful in mitigating process or network
                        delays. Default is 30 seconds.
  --insecure            Explicitly allow client to perform "insecure" TLS
                        (https) requests. The server's certificate will not be
                        verified against any certificate authorities. This
                        option should be used with caution.
  --os-cacert <ca-certificate>
                        Specify a CA bundle file to use in verifying a TLS
                        (https) server certificate. Defaults to
                        env[OS_CACERT].
  --os-cert <certificate>
                        Defaults to env[OS_CERT].
  --os-key <key>        Defaults to env[OS_KEY].
  --timeout <seconds>   Set request timeout (in seconds).

See "keystone help COMMAND" for help on a specific command.
mbraden@stack-1:~$