Skip to content

Latest commit

 

History

History
793 lines (579 loc) · 44.3 KB

04.md

File metadata and controls

793 lines (579 loc) · 44.3 KB

+++ date = "2016-02-25" draft = false weight = 4 title = "Lab 04 - Keystone" +++

Lab Duration: 60 minutes

Lab Objective

The objective of this lab is to further your understanding of OpenStack Identity service (Keystone). Having appropriate credentials is required if you wish to use any CLI tools to query on the OpenStack services.

To use an OpenStack cloud, you need to authenticate against the Identity service Keystone (which returns a Token and the Service Catalog). To request an authentication token, you must supply a payload of credentials in the authentication request. Credentials are usually a combination of your user name and password, and optionally, the name or ID of the tenant in which your cloud runs. When you send API requests, you include the token in an HTTP header called the "X-Auth-Token" header.

If you access multiple OpenStack services, you must get a token for each service. A token is valid for a limited time before it expires. A token can also become invalid for other reasons. For example, if the roles for a user change, existing tokens for that user are invalid. Credentials allow OpenStack services to determine where your service endpoints and your authentication information are located.

1. Understanding permissions

  1. SSH to your controller as root, you might use:
  1. Once logged into the controller, type the following command (it won't work!):

    [root@controller ~]# nova flavor-list

    ERROR (CommandError): You must provide a username or user id via --os-username, --os-user-id, env[OS_USERNAME] or env[OS_USER_ID]
    

    This command results in an error because Nova doesn't know who you are.

    • Does nova know that you have permissions to issue flavor-list?
    • Consider how Horizon works. Does ALWAYS Horizon know who you are?
    • HINT: To use Horizon, you have to login as a user (admin, aliceanderson, bobbarker, etc.)
  2. Let's try another command that won't work!

    [root@controller ~]# keystone tenant-list

    Another error!? That's alright... Keystone doesn't know who you are. Do you have permissions to view the current tenants?

  3. We focusing on the permissions required to issue a command successfully without an error. We only chose flavor-list as a example.

    [root@controller ~]# nova --os-auth-url=http://192.168.0.10:5000/v2.0 --os-tenant-name=admin --os-user-name=admin --os-password=alta3 flavor-list

    +----+----------------+-----------+------+-----------+------+-------+-------------+-----------+
    | ID | Name           | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
    +----+----------------+-----------+------+-----------+------+-------+-------------+-----------+
    | 1  | m1.tiny        | 512       | 1    | 0         |      | 1     | 1.0         | True      |
    | 2  | m1.small       | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
    | 3  | m1.medium      | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
    | 4  | m1.large       | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
    | 5  | m1.xlarge      | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
    +----+----------------+-----------+------+-----------+------+-------+-------------+-----------+
    

    Now the flavors are displayed. This is because you issued a command that included values of environmental variables that disclose your permissions. Nova can use this information to make an API call to the Keystone service and determine if you (admin) have sufficient permissions to execute the command (flavor-list) ID: Unique ID (integer or UUID) for the flavor.
    Name: A descriptive name, such as xx.size_name, is conventional but not required, though some third-party tools may rely on it.
    Memory_MB: Virtual machine memory in megabytes.
    Disk: Virtual root disk size in gigabytes. This is an ephemeral disk the base image is copied into. You don't use it when you boot from a persistent volume. The "0" size is a special case that uses the native base image size as the size of the ephemeral root volume.
    Ephemeral: Specifies the size of a secondary ephemeral data disk. This is an empty, unformatted disk and exists only for the life of the instance.
    Swap: Optional swap space allocation for the instance.
    VCPUs: Number of virtual CPUs presented to the instance.
    RXTX_Factor: Optional property that allows created servers to have a different bandwidth cap from that defined in the network they are attached to. This factor is multiplied by the rxtx_base property of the network. Default value is 1.0 (that is, the same as the attached network).
    Is_Public: Boolean value that indicates whether the flavor is available to all users or private. Private flavors do not get the current tenant assigned to them. Defaults to True.
    extra_specs: Additional optional restrictions on which compute nodes the flavor can run on. This is implemented as key-value pairs that must match against the corresponding key-value pairs on compute nodes. Can be used to implement things like special resources (such as flavors that can run only on compute nodes with GPU hardware).

  4. So it worked, but we had to include a long list of credentials. If you'd like, trying using just Nova flavor-list again (without the --flags).

    [root@controller ~]# nova flavor-list

    Once again, it didn't work. Clearly the credentials are required every time you issue commands to manipulate your OpenStack cloud.

  5. Use the nova help commands to better understand the credentials:

    "nova -h" will display help for the nova command "grep" means "display only these lines that contain the following search string" Therefore, "nova -h | grep os-auth-url" means display help, and only display the lines that contain os-auth-url

    [root@controller ~]# nova -h

    [root@controller ~]# nova -h | grep os-auth-url

    [root@controller ~]# nova -h | grep os-tenant-name

    [root@controller ~]# nova -h | grep os-user-name

    [root@controller ~]# nova -h | grep os-password

    The purpose of issuing these commands is so that you know what the flags are that you are setting

  6. Let's go a step further and issue the same command, but this time include a debug flag and see if we can deep dive into what is going on!

    [root@controller ~]#

    nova --os-auth-url=http://192.168.0.10:5000/v2.0 --os-tenant-name=admin --os-user-name=admin --os-password=alta3 --debug flavor-list

    Debug attempts to display the processes that are going on in the background to make this possible. We'll spend some more time checking out some of the returned information in the next lab, for now, we just wanted you to be aware that it was possible.

    DEBUG (v2:76) Making authentication request to http://192.168.0.10:5000/v2.0/tokens                                                                           |
    INFO (connectionpool:238) Resetting dropped connection: 192.168.0.10                                                                                          |
    DEBUG (connectionpool:383) "POST /v2.0/tokens HTTP/1.1" 200 3974                                                                                              |
    DEBUG (iso8601:184) Parsed 2015-10-21T04:27:26Z into {'tz_sign': None, 'second_fraction': None, 'hour': u'04', 'daydash': u'21', 'tz_hour': None, 'month': Non|
    e, 'timezone': u'Z', 'second': u'26', 'tz_minute': None, 'year': u'2015', 'separator': u'T', 'monthdash': u'10', 'day': None, 'minute': u'27'} with default ti|
    mezone <iso8601.iso8601.Utc object at 0x22229d0>                                                                                                              |
    DEBUG (iso8601:140) Got u'2015' for 'year' with default None                                                                                                  |
    DEBUG (iso8601:140) Got u'10' for 'monthdash' with default 1                                                                                                  |
    DEBUG (iso8601:140) Got 10 for 'month' with default 10                                                                                                        |
    DEBUG (iso8601:140) Got u'21' for 'daydash' with default 1                                                                                                    |
    DEBUG (iso8601:140) Got 21 for 'day' with default 21                                                                                                          |
    DEBUG (iso8601:140) Got u'04' for 'hour' with default None                                                                                                    |
    DEBUG (iso8601:140) Got u'27' for 'minute' with default None                                                                                                  |
    DEBUG (iso8601:140) Got u'26' for 'second' with default None                                                                                                  |
    DEBUG (session:195) REQ: curl -g -i -X GET http://192.168.0.10:8774/v2/300b2cc45c3846939e589310ae714e46/flavors/detail -H "User-Agent: python-novaclient" -H "|
    Accept: application/json" -H "X-Auth-Token: {SHA1}914b01c69b7491be6cd35d89a3f7c55e90603dfe"                                                                   |
    INFO (connectionpool:203) Starting new HTTP connection (1): 192.168.0.10                                                                                      |
    DEBUG (connectionpool:383) "GET /v2/300b2cc45c3846939e589310ae714e46/flavors/detail HTTP/1.1" 200 2089                                                        |
    DEBUG (session:224) RESP: [200] date: Wed, 21 Oct 2015 03:27:27 GMT connection: keep-alive content-type: application/json content-length: 2089 x-compute-reque|
    st-id: req-980927ce-3964-441f-bb9a-58437a05b130                                                                                                               |
    RESP BODY: {"flavors": [{"name": "m1.tiny", "links": [{"href": "http://192.168.0.10:8774/v2/300b2cc45c3846939e589310ae714e46/flavors/1", "rel": "self"}, {"hre|
    f": "http://192.168.0.10:8774/300b2cc45c3846939e589310ae714e46/flavors/1", "rel": "bookmark"}], "ram": 512, "OS-FLV-DISABLED:disabled": false, "vcpus": 1, "sw|
    ap": "", "os-flavor-access:is_public": true, "rxtx_factor": 1.0, "OS-FLV-EXT-DATA:ephemeral": 0, "disk": 1, "id": "1"}, {"name": "m1.small", "links": [{"href"|
    : "http://192.168.0.10:8774/v2/300b2cc45c3846939e589310ae714e46/flavors/2", "rel": "self"}, {"href": "http://192.168.0.10:8774/300b2cc45c3846939e589310ae714e4|
    6/flavors/2", "rel": "bookmark"}], "ram": 2048, "OS-FLV-DISABLED:disabled": false, "vcpus": 1, "swap": "", "os-flavor-access:is_public": true, "rxtx_factor": |
    1.0, "OS-FLV-EXT-DATA:ephemeral": 0, "disk": 20, "id": "2"}, {"name": "m1.medium", "links": [{"href": "http://192.168.0.10:8774/v2/300b2cc45c3846939e589310ae7|
    14e46/flavors/3", "rel": "self"}, {"href": "http://192.168.0.10:8774/300b2cc45c3846939e589310ae714e46/flavors/3", "rel": "bookmark"}], "ram": 4096, "OS-FLV-DI|
    SABLED:disabled": false, "vcpus": 2, "swap": "", "os-flavor-access:is_public": true, "rxtx_factor": 1.0, "OS-FLV-EXT-DATA:ephemeral": 0, "disk": 40, "id": "3"|
    }, {"name": "m1.large", "links": [{"href": "http://192.168.0.10:8774/v2/300b2cc45c3846939e589310ae714e46/flavors/4", "rel": "self"}, {"href": "http://192.168.|
    0.10:8774/300b2cc45c3846939e589310ae714e46/flavors/4", "rel": "bookmark"}], "ram": 8192, "OS-FLV-DISABLED:disabled": false, "vcpus": 4, "swap": "", "os-flavor|
    -access:is_public": true, "rxtx_factor": 1.0, "OS-FLV-EXT-DATA:ephemeral": 0, "disk": 80, "id": "4"}, {"name": "m1.xlarge", "links": [{"href": "http://192.168|
    .0.10:8774/v2/300b2cc45c3846939e589310ae714e46/flavors/5", "rel": "self"}, {"href": "http://192.168.0.10:8774/300b2cc45c3846939e589310ae714e46/flavors/5", "re|
    l": "bookmark"}], "ram": 16384, "OS-FLV-DISABLED:disabled": false, "vcpus": 8, "swap": "", "os-flavor-access:is_public": true, "rxtx_factor": 1.0, "OS-FLV-EXT|
    -DATA:ephemeral": 0, "disk": 160, "id": "5"}]}                                                                                                                |
    
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
    | 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
    | 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
    | 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
    | 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    

2. Getting User Credentials (source keystonerc_admin)

So what we've all figured out by this point, is that setting flag on every CLI command involves far too much typing. Let's make our commands easier to issue by setting some environmental variables for our current bash session. NOTE: If environmental vs shell variables, and parent vs child sessions are new terms for you, that is OK. There is a small section at the conclusion of this lab that will make it more clear.

  1. Display the contents of the keystonerc_admin file

    [root@controller ~]# cat keystonerc_admin

    Comments have been added to the output, your output will lack the comments (lines that begin with #).

    # This is the user name
    export OS_USERNAME=admin
    # This is the tenant, or project
    export OS_TENANT_NAME=admin
    # Password for the above user
    export OS_PASSWORD=alta3
    # The Identity API served through Keystone
    export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/
    # The OpenStack Region
    export OS_REGION_NAME=RegionOne
    # Appends the CLI prompt with keystone_admin
    export PS1='`[\u@\h \W(keystone_admin)]\$ '
    

    The export commands within this file will mark each VAR for automatic export to the environment of subsequently executed commands (i.e. make the local shell variable VAR global). Essentially, we can set all of our permissions in this file, source this file, and then not have to ever type our permissions again as they'll always be available to the bash environment.

    NOTE: The name of this file may change slightly depending on your environment. RDO deployments use the formatting structure keystonerc_$USER

    For more info on regions: http://docs.openstack.org/openstack-ops/content/scaling.html#segregate_cloud

  2. Display a list of the environmental variables currently set

    [root@controller ~]# printenv

    Look over the displayed entries. Do you see any mention of the aforementioned credentials, such as OS_TENANT_NAME or OS_USERNAME? (Feel free to use grep if you'd like.)

    XDG_SESSION_ID=16
    HOSTNAME=controller.localdomain
    SELINUX_ROLE_REQUESTED=
    TERM=screen
    SHELL=/bin/bash
    HISTSIZE=1000
    SSH_CLIENT=71.251.147.235 52298 22
    SELINUX_USE_CURRENT_RANGE=
    SSH_TTY=/dev/pts/0
    USER=root
    LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34
    ;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.t
    zo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.
    tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7
    z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=
    01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.og
    m=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=
    01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;3
    6:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:
    *.xspf=01;36:
    MAIL=/var/spool/mail/root
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    LANG=en_US.UTF-8
    SELINUX_LEVEL_REQUESTED=
    HISTCONTROL=ignoredups
    SHLVL=1
    HOME=/root
    LOGNAME=root
    SSH_CONNECTION=71.251.147.235 52298 192.168.0.10 22
    LESSOPEN=||/usr/bin/lesspipe.sh %s
    XDG_RUNTIME_DIR=/run/user/0
    _=/usr/bin/printenv
    
  3. Set the environmental variables found in keystonerc_admin

    [root@controller ~]# source keystonerc_admin

    This is a bash shell built-in command that executes the content of the file passed as a argument in the current shell. It is synonymous with ' . ' (period). After executing the above command, the CLI line will change. This is just a reminder that you are now passing commands to the OpenStack services as some user (in this case admin).

    Notice that your CLI prompt has changed to indicate that you are now 'sourced' with admin permissions

    [root@controller ~(keystone_admin)]#
    
  4. Once again, display a list of the environmental variables currently set.

    [root@controller ~(keystone_admin)]# printenv

    Look over the displayed entries. Now you will see a listing for the variables contained within keystonerc_admin, such as OS_TENANT_NAME and OS_USERNAME. Just for your understanding, these entries are only set for this current bash session. If you type exit, then reconnect as root, these variables will unset themselves. If you want to remove them manually, use the unset command.

    XDG_SESSION_ID=16
    HOSTNAME=controller.localdomain
    SELINUX_ROLE_REQUESTED=
    TERM=screen
    SHELL=/bin/bash
    HISTSIZE=1000
    SSH_CLIENT=71.251.147.235 52298 22
    OS_REGION_NAME=RegionOne   <-------------------
    SELINUX_USE_CURRENT_RANGE=
    SSH_TTY=/dev/pts/0
    USER=root
    LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34
    ;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.t
    zo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.
    tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7
    z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=
    01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.og
    m=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=
    01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;3
    6:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:
    *.xspf=01;36:
    MAIL=/var/spool/mail/root
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    OS_PASSWORD=alta3  <-----------------
    LANG=en_US.UTF-8
    PS1=[\u@\h \W(keystone_admin)]\$
    SELINUX_LEVEL_REQUESTED=
    OS_AUTH_URL=http://192.168.0.10:5000/v2.0/
    HISTCONTROL=ignoredups
    OS_USERNAME=admin  <-------------------
    SHLVL=1
    HOME=/root
    OS_TENANT_NAME=admin  <----------------------
    LOGNAME=root
    SSH_CONNECTION=71.251.147.235 52298 192.168.0.10 22
    LESSOPEN=||/usr/bin/lesspipe.sh %s
    XDG_RUNTIME_DIR=/run/user/0
    _=/usr/bin/printenv
    
  5. Flex your new admin environmental-variable-given powers

    [root@controller ~(keystone_admin)]# nova flavor-list

    This time it should just work without having to type the extra permissions. Try executing a few more commands to the other OpenStack services as well.

    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
    | 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
    | 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
    | 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
    | 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    
  6. Issue a few more commands.

    [root@controller ~(keystone_admin)]# keystone tenant-create --name temp_tenant

    [root@controller ~(keystone_admin)]# keystone user-list

  7. This should launch the python-openstackclient.

    OpenStack is attempting to 'unite' all of the OpenStack commands inside of a common python 'wrapper', or a platform that allows you to issue a common set of commands for every OpenStack service. This is why some CLI commands are receiving depreciation warnings. Some people are using it, some are not, but we think it is important to know it exists.

    [root@controller ~(keystone_admin)]# openstack

    (openstack) help

    (openstack) exit

    The permissions still apply! If you have sourced the keystonerc_admin file, then launch the python-openstackclient, then you are issuing commands to OpenStack as admin.

3. Creating a keystonerc_chestercopperpot file for Chester Copperpot of Vault Tek

Remember our buddy Chester Copperpot of Vault Tek? You should see him when you issued the previous command keystone user-list.

Let's make it easy for us to execute OpenStack commands as Chester Copperpot who is part of the project vault_tek at the CLI.

  1. Set the environmental variables found in keystonerc_admin if this is not already done

    [root@controller ~(keystone_admin)]# source keystonerc_admin

  2. List the keystone users

    [root@controller ~(keystone_admin)]# keystone user-list

    +----------------------------------+------------------+---------+---------------------------+
    |                id                |       name       | enabled |           email           |
    +----------------------------------+------------------+---------+---------------------------+
    | e9483918caa940a48fe882ba092c7e0b |      admin       |   True  |       root@localhost      |
    | 5bbecabeb2a74aff9dc27f9a8675de45 |  aliceanderson   |   True  |                           |
    | 641761fe08b74a42b2b3497a38f06020 |    bobbarker     |   True  |                           |
    | 9b1f9b36d7354b1ea121ccfbae339d8b |    ceilometer    |   True  |    ceilometer@localhost   |
    | 5b1e70851c2e451c8c0848f60b338e90 | chestercopperpot |   True  | chester@vault_tek.example |
    | e96c13b017b341a79808ebc9f04afa98 |      cinder      |   True  |      cinder@localhost     |
    | 92b130a947e342adb476431b041ed43c |       demo       |   True  |                           |
    | f02ffa49234a401d8461406c5ef5780d |     gandalf      |   True  |  [email protected] |
    | 6146821b56ed4ca18f82b0f90afd278c |      glance      |   True  |      glance@localhost     |
    | ff5f550ecf064e65bd45d2d0b91bbdab |     neutron      |   True  |     neutron@localhost     |
    | d3125ab7d2eb4ba0a23d480eee988419 |       nova       |   True  |       nova@localhost      |
    | 4c8da8951ad34d4498d534e2efb842ec |      swift       |   True  |      swift@localhost      |
    +----------------------------------+------------------+---------+---------------------------+
    
  3. Look at the user chestercopperpot, and note his tenantID

    [root@controller ~(keystone_admin)]# keystone user-get chestercopperpot

    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |    chester@vault_tek.example     |
    | enabled  |               True               |
    |    id    | 5b1e70851c2e451c8c0848f60b338e90 |
    |   name   |         chestercopperpot         |
    | tenantId | 5ca9bad4f0e94b2eb0fac330dff988d9 |
    | username |         chestercopperpot         |
    +----------+----------------------------------+
    
  4. Find the tenant name for chester's tenantID value by comparing the tenantID above with the id below (should be vault_tek)

    [root@controller ~(keystone_admin)]# keystone tenant-list

    +----------------------------------+-------------+---------+
    |                id                |     name    | enabled |
    +----------------------------------+-------------+---------+
    | edb80920a0e84fbb85372d50a18e8d98 |   acme_inc  |   True  |
    | 300b2cc45c3846939e589310ae714e46 |    admin    |   True  |
    | a9c27d47441e432c8529f8f30ea3261e |     demo    |   True  |
    | 85a11a1515f94848be7aa5b56adec8bf |   services  |   True  |
    | 5e244f171df344cebc2bcce91fc90d96 | temp_tenant |   True  |
    | 5005fe4c52144d1299fddb9cfc1f9b48 |  the_shire  |   True  |
    | 5ca9bad4f0e94b2eb0fac330dff988d9 |  vault_tek  |   True  |
    +----------------------------------+-------------+---------+
    
  5. While we are on a roll, lets try a few additional commands. Lets use tenant-get to discover the name if we only know the id!

    [root@controller ~(keystone_admin)]# keystone tenant-get 5ca9bad4f0e94b2eb0fac330dff988d9 <-- Put YOUR ID here!!!

    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |                                  |
    |   enabled   |               True               |
    |      id     | 5ca9bad4f0e94b2eb0fac330dff988d9 |
    |     name    |            vault_tek             |
    +-------------+----------------------------------+
    
  6. Yet another way, suppose we only know the tenant name, not the id.

    [root@controller ~(keystone_admin)]# keystone tenant-get vault_tek

    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |                                  |
    |   enabled   |               True               |
    |      id     | 5ca9bad4f0e94b2eb0fac330dff988d9 |
    |     name    |            vault_tek             |
    +-------------+----------------------------------+
    
  7. Make a copy of the keystonerc_admin file, then open it in nano so we can edit it.

    (keystone_admin)# cp keystonerc_admin keystonerc_chestercopperpot

  8. Throughout the rest of the lab, you may use either nano or vim.

    nano:

    (keystone_admin)# nano keystonerc_chestercopperpot

    vim:

    (keystone_admin)# vim keystonerc_chestercopperpot

  9. Edit keystonerc_chestercopperpot so it looks like the following.

     export OS_USERNAME=chestercopperpot
     export OS_TENANT_NAME=vault_tek
     export OS_PASSWORD=fa5tpa55w0rd
     export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/
     export OS_REGION_NAME=RegionOne
     export PS1='[\u@\h \W(keystone_chestercopperpot)]\$ '
     

    Nano hints:
    When you're done editing changes, do the following:
    press CTRL + O (to write out aka save)
    press ENTER (to confirm save)
    press CTRL + X (to exit)

  10. Display the contents of keystonerc_chestercopperpot and verify that they are correct

    [root@controller ~(keystone_admin)# cat keystonerc_chestercopperpot

    export OS_USERNAME=chestercopperpot
    export OS_TENANT_NAME=vault_tek
    export OS_PASSWORD=fa5tpa55w0rd
    export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/
    export OS_REGION_NAME=RegionOne
    export PS1='[\u@\h \W(keystone_chestercopperpot)]\$ '
    
  11. Set global variables in the current shell to correspond with the user chestercopperpot

    [root@controller ~(keystone_admin)# source keystonerc_chestercopperpot

  12. Note the CLI changed. Run commands and see how the results differ from chester's perspective.

    [root@controller ~(keystone_chestercopperpot)# nova flavor-list

    OK, this worked!

    [root@controller ~(keystone_chestercopperpot)# keystone tenant-list

    This should result in an HTTP 403 failure, as the user chestercopperpot does not have sufficient permissions to issue this keystone command.

  13. Let's repeat the process for the user aliceanderson

    [root@controller ~(keystone_chestercopperpot)# cp keystonerc_admin keystonerc_aliceanderson

    Use the editor (nano or vim) of your choice to edit the file.

    nano: [root@controller ~(keystone_chestercopperpot)# nano keystonerc_aliceanderson
    vim: [root@controller ~(keystone_chestercopperpot)# vim keystonerc_aliceanderson

  14. Edit keystonerc_aliceanderson so it looks like the following (or copy and paste is fine):

    export OS_USERNAME=aliceanderson
    export OS_TENANT_NAME=acme_inc
    export OS_PASSWORD=fa5tpa55w0rd
    export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/   
    export OS_REGION_NAME=RegionOne
    export PS1='[\u@\h \W(keystone_aliceanderson)]\$ '
    

    Nano hints:
    When you're done editing changes, do the following:
    press CTRL + O (to write out aka save)
    press ENTER (to confirm save)
    press CTRL + X (to exit)

  15. Display the contents of keystonerc_aliceanderson and verify that they are correct

    [root@controller ~(keystone_admin)# cat keystonerc_aliceanderson

  16. Finally, lets repeat the process again for user bobbarker, using the editor of your choice.c

    [root@controller ~(keystone_chestercopperpot)# cp keystonerc_admin keystonerc_bobbarker

    nano: [root@controller ~(keystone_chestercopperpot)# nano keystonerc_bobbarker
    vim: [root@controller ~(keystone_chestercopperpot)# vim keystonerc_bobbarker

  17. Edit keystonerc_bobbarker so it looks like the following (copy and paste is fine):

    export OS_USERNAME=bobbarker                       
    export OS_TENANT_NAME=acme_inc   
    export OS_PASSWORD=fa5tpa55w0rd          
    export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/  
    export OS_REGION_NAME=RegionOne
    export PS1='[\u@\h \W(keystone_bobbarker)]\$ '     
    

    Nano hints:
    When you're done editing changes, do the following:
    press CTRL + O (to write out aka save)
    press ENTER (to confirm save)
    press CTRL + X (to exit)

  18. Display the contents of keystonerc_bobbarker and verify that they are correct

    [root@controller ~(keystone_chestercopperpot)# cat keystonerc_bobbarker

4. Using the OpenStack Horizon Dashboard to assist in creating a keystonerc file for new user Doris Day of Vault Tek

  1. Log in to the OpenStack Horizon Dashboard as chestercopperpot // fa5tpa55w0rd

  2. Click on Project > Compute > Access & Security

  3. Click on the tab API Access

  4. In the upper right corner, click on the button Download OpenStack RC File

    enter image description here

  5. This file will download locally. Open it in your favorite text editor. The file you open will look similar to the one shown below. If your "favorite" text editor is Microsoft Notepad or Microsoft Word, then it is recommended you take 2 minutes and go download Notepad++

    bash
    #!/bin/bash
    # To use an OpenStack cloud you need to authenticate against the Identity
    # service named keystone, which returns a **Token** and **Service Catalog**.
    # The catalog contains the endpoints for all services the user/tenant has
    # access to - such as Compute, Image Service, Identity, Object Storage, Block
    # Storage, and Networking (code-named nova, glance, keystone, swift,
    # cinder, and neutron).
    #
    #
    # *NOTE*: Using the 2.0 *Identity API* does not necessarily mean any other
    # OpenStack API is version 2.0. For example, your cloud provider may implement
    # Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
    # only for the Identity API served through keystone.
    export OS_AUTH_URL=http://192.168.0.10:5000/v2.0
    #
    #
    # With the addition of Keystone we have standardized on the term **tenant**
    # as the entity that owns the resources.
    export OS_TENANT_ID=57dc930957f243438e532163269138d1
    export OS_TENANT_NAME="vault_tek"
    export OS_PROJECT_NAME="vault_tek"
    #
    #
    # In addition to the owning entity (tenant), OpenStack stores the entity
    # performing the action as the **user**.
    export OS_USERNAME="chestercopperpot"
    #
    #    #    #    #  LOOK AT THIS     #    #    #    #
    # With Keystone you pass the keystone password.
    echo "Please enter your OpenStack Password: "
    read -sr OS_PASSWORD_INPUT
    export OS_PASSWORD=$OS_PASSWORD_INPUT
    #    #    #    # END LOOK AT THIS  #    #    #    #
    #
    # If your configuration has multiple regions, we set that information here.
    # OS_REGION_NAME is optional and only valid in certain environments.
    export OS_REGION_NAME="RegionOne"
    #
    #
    # Don't leave a blank variable, unset it if it was empty
    if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
    

    This file is a bit fancier than the previous one we studied, but it is well commented. There are two key differences between this file and ours:

    1. The first is that this file will require the user to enter their password instead of storing it locally as plain-text. In production, this is desirable, as asking users to enter their password will prevent admins from having to manage security and permissions on user files because they contain plain-text passwords.

    2. The second difference is that this file also sets some additional environmental variables, which could be problematic, as our other keystonerc_.* files do NOT set these variables. If we source back to another user without first unsetting these variables, we might get ourselves into trouble. So instead of using this file, let's just borrow the piece of code that asks the user for the password. It is shown below for reference:

    # With Keystone you pass the keystone password. 
    echo "Please enter your OpenStack Password: "
    read -sr OS_PASSWORD_INPUT
    export OS_PASSWORD=$OS_PASSWORD_INPUT
    
  6. We're done in Horizon for now. Return to your SSH session with the controller and source keystone_admin

    [root@controller ~]# source keystonerc_admin

  7. Let's create a new user (Doris Day) within the vault_tek vault_tek project (tenant) and then create a source file that prompts for a password.

    [root@controller ~(keystone_admin)]# keystone user-create --name dorisday --tenant vault_tek --pass fa5tpa55w0rd --email dorisday@vault_tek.example

    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |    dorisday@vault_tek.example    |
    | enabled  |               True               |
    |    id    | 8086288736dc4147bf38ffaf07acd9b5 |	
    |   name   |             dorisday             |
    | tenantId | 8f6d4710d774466f96858af6fa69aaa3 |
    | username |             dorisday             |
    +----------+----------------------------------+
    
  8. Create a file we can source for Doris Day of Vault Tek.

    nano: [root@controller ~(keystone_admin)]# nano keystonerc_dorisday
    vim [root@controller ~(keystone_admin)]# vim keystonerc_dorisday

  9. Edit keystonerc_dorisday so it looks like the following:

     export OS_USERNAME=dorisday
     export OS_TENANT_NAME=vault_tek
     echo "Please enter your OpenStack Password: "   
     read -sr OS_PASSWORD_INPUT
     export OS_PASSWORD=$OS_PASSWORD_INPUT
     export OS_AUTH_URL=http://192.168.0.10:5000/v2.0/
     export OS_REGION_NAME=RegionOne
     export PS1='[\u@\h \W(keystone_dorisday)]\$ '
     

    Nano hints:
    When you're done editing changes, do the following:
    press CTRL + O (to write out aka save)
    press ENTER (to confirm save)
    press CTRL + X (to exit)

  10. Confirm that the file was saved correctly, by displaying the output with cat, and then source keystonerc_dorisday

    [root@controller ~(keystone_admin)]# source keystonerc_dorisday

    Please enter your OpenStack Password: fa5tpa55w0rd

  • QUESTION: Is this mechanism of prompting for a password more secure? Why or why not?
  1. Make sure the file works. Test by issuing a CLI command requiring authentication.

    [root@controller ~(keystone_dorisday)]# nova flavor-list

    If output like this is displayed, then it worked!

    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    | 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
    | 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
    | 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
    | 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
    | 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
    +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
    

    Great job! You are all done with this lab. If you are done early, go onto the next section. It will teach you a little bit more about what is going on when you run the source command.

5. OPTIONAL: Linux variables

In OpenStack, we learned that we could type out the --os-tenant-name, --os-user-name, --os-password, and --os-auth-url along with every command, or we could set these values so they persist. If you are not a master of the CLI, you might be curious about how this worked! Understanding how it works might also help you in troubleshooting. After all, what if you ran a source file (set environmental variables), and wish you could un-run that source file (unset environmental variables).

Variables can be of two basic types: shell variables, or environmental variables. Shell variables are only available within the current session, whereas environmental variables are available to the current session, as well as any spawned sessions. What is a session? You're in one right now. The Bash shell that you are sitting at is a 'session'. If you were to type bash, you'd launch another session that would be considered a 'child' session, where your current session would be the 'parent'.

If a child session is spawned by a parent session, environmental variables will be made available to the child sessions, whereas a shell variable will not. To better understand the difference, perform this quick procedure; define a shell variable, and then an environmental variable within parent and child bash shells.

  1. Create a shell variable within the current session. Convention says it should be all caps. Because the string we've defined includes a bang, we are using single quotes to surround 'Hello OpenStack!'.

    [root@controller ~]# LEARNING_VAR='Hello OpenStack!'

  2. Great! We can confirm that this is a shell variable that will not be passed down to child processes by grepping within output from set

    [root@controller ~]# set | grep LEARNING_VAR

  3. LEARNING_VAR='Hello OpenStack!' should be displayed. Now confirm it is not an environmental variable by performing the same procedure with printenv.

    [root@controller ~]# printenv | grep LEARNING_VAR

    No output should be returned, as printenv will only print environmental variables.

  4. Let's take a moment to demonstrate how to access any shell or environmental variable. When the shell encounters a $ sign, it takes it to mean that it should substitute the value of the variable when it comes across it. Type the following command.

    [root@controller ~]# echo $LEARNING_VAR

    The string Hello OpenStack! should be displayed.

  5. If you type 'bash', you'll spawn a child shell. Think of this as accessing a 'shell within a shell'. Within this child session our variable, $LEARNING_VAR, should not be available.

    [root@controller ~]# bash

    [root@controller ~]# echo $LEARNING_VAR

    No output should be displayed. Hopefully, why no output was display is clear. This is a child session, and was not passed the previous shell variables. Remember, shell variables are only good for the current shell. Type the following to test this assertion.

  6. Type exit to close the child session and return to the original session.

    [root@controller ~]# exit

    [root@controller ~]# echo $LEARNING_VAR

    Once again, the string Hello OpenStack! should be displayed, as we have returned to the parent shell (the shell we started in).

  7. Now let's make LEARNING_VAR an environmental variable by using the export command.

    [root@controller ~]# export LEARNING_VAR='OpenStack Hello!'

    [root@controller ~]# printenv | grep LEARNING_VAR

  8. Now, run the same experiment with a minor change, export LEARNING_VAR='Hello OpenStack!' then Hello Openstack rather than Openstack Hello should be displayed. Once again, spawn a child shell.

    [root@controller ~]# bash

    [root@controller ~]# echo $LEARNING_VAR

    Hello OpenStack! should be displayed.

  9. Confirm that it is still set as an environmental variable.

    [root@controller ~]# printenv | grep LEARNING_VAR

  10. Now let's set an environmental variable from within our current child shell.

    [root@controller ~]# export NEW_LEARNING_VAR='Bonjour OpenStack!'

  11. Confirm that it was indeed set as an environmental variable. Then exit the child session and return to the parent shell.

    [root@controller ~]# printenv | grep NEW_LEARNING_VAR

    [root@controller ~]# exit

  12. Now see if the environmental variable NEW_LEARNING_VAR is still available.

    [root@controller ~]# printenv | grep NEW_LEARNING_VAR

    No output is returned. This is because NEW_LEARNING_VAR was an environmental variable set in the child shell. Emphasis on the word 'was', because when we exited our child shell, that environmental variable was destroyed.

  13. The original variable, LEARNING_VAR can be changed back into a shell variable (demoted), by using export and the -n flag.

    [root@controller ~]# export -n LEARNING_VAR

  14. Test that it is no longer a global variable, but still a shell variable

    [root@controller ~]# printenv | grep LEARNING_VAR

    No output will be shown as LEARNING_VAR is no longer an environmental variable.

    [root@controller ~]# echo $LEARNING_VAR

    Hello OpenStack! should be displayed, as LEARNING_VAR is now a shell variable.

    [root@controller ~]# set | grep LEARNING_VAR

    LEARNING_VAR='Hello OpenStack!' will be displayed, confirming LEARNING_VAR exists as a shell variable.

  15. A shell and environmental variable can be completely removed by issuing the unset command.

    [root@controller ~]# unset LEARNING_VAR

    [root@controller ~]# echo $LEARNING_VAR

    Nothing will be displayed, as LEARNING_VAR has been unset

    [root@controller ~]# set | grep LEARNING_VAR

    Nothing will be displayed.