* [OpenStack training](#openstack-training)
  * [Introduction](#introduction)
  * [Install openstack cli](#install-openstack-cli)
  * [Instance](#instance)
    * [Boot](#boot)
    * [Ping](#ping)
    * [Security rules](#security-rules)
    * [Connect with ssh](#connect-with-ssh)
    * [Delete the instance](#delete-the-instance)
  * [Private networks](#private-networks)
    * [Create a private network and subnet](#create-a-private-network-and-subnet)
    * [Create a router](#create-a-router)
    * [Boot](#boot-1)
    * [Floating IP](#floating-ip)
    * [Connect with ssh](#connect-with-ssh-1)
  * [Bonus](#bonus)


# OpenStack training

## Introduction
The goal of this workshop is to manipulate and manage OpenStack API from CLI.

## Install `openstack` cli
First, install `openstack` cli from pip, inside a virtual env
```
# Create the virtual env
python3 -m venv /opt/oscli

# Enable the virtual env
source /opt/oscli/bin/activate

# Upgrade pip
pip install --upgrade pip

# Install openstack client
pip install python-openstackclient
```

## Load your openstack credentials

Load in your shell the variables that allow you to communicate with OVH OpenStack Public Cloud
```
source /root/openrc
```

## Instance
This part will help you manage some compute resources of the cloud.

You will be dealing with different components:

- **keypair** (ssh-key private and public keys) will be used to connect to your server
- **image** is the base OS your server will be booted from
- **flavor** is the _size_ of your server. i.e. how many CPU, RAM, disk you want
- **network** is the network your instance will be connected to
- **security group** and **security rules** are firewall rules applied to your server

#### keypair
Make sure you have a ssh key:
```
$ ls ~/.ssh/id_rsa*
# If you do not have any key there:
# ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""
# This will generate both private and public keys in ~/.ssh/ folder
```

Upload the public key to the cloud
```
openstack keypair create --public-key ~/.ssh/id_rsa.pub isen
```

You can list the available keys and see the detail of a key with the following commands:
```
openstack keypair list

# Display the detail of a keypair:
openstack keypair show isen
```

#### image
Let's list the available images using the following command:
```
openstack image list
```

This will output a long table with the names and IDs of the available images:
```
+--------------------------------------+-----------+--------+
| ID                                   | Name      | Status |
+--------------------------------------+-----------+--------+
| 96b2b90b-ab15-456f-a467-6da0890768e9 | Debian 12 | active |
| 9c9f0f71-c91d-467e-80d0-620c2c514e98 | cirros    | active |
+--------------------------------------+-----------+--------+

```


You can see the details of the image with the following command:
```
openstack image show 'Debian 12'

# Or using its ID
openstack image show 96b2b90b-ab15-456f-a467-6da0890768e9
```

#### flavor
We need to determine the specifications of the VM we want to run. For this we need to choose a flavor in the list displayed by the following command:
```
openstack flavor list
```

```
+--------------------------------------+--------+------+------+-----------+-------+-----------+
| ID                                   | Name   |  RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+--------+------+------+-----------+-------+-----------+
| 6640fe80-5662-4532-947d-bf8702cc14ec | medium | 2048 |   20 |         0 |     2 | True      |
| a994d90e-6eee-4a04-8eee-de207649b6a2 | small  | 1024 |   10 |         0 |     1 | True      |
| db32e0cd-3580-4ed0-ad9a-fe71593bafeb | large  | 4086 |   50 |         0 |     4 | True      |
+--------------------------------------+--------+------+------+-----------+-------+-----------+

```

#### network
List the networks
```
openstack network list
```

```
+--------------------------------------+--------+----------------------------------------------------------------------------+
| ID                                   | Name   | Subnets                                                                    |
+--------------------------------------+--------+----------------------------------------------------------------------------+
| 44ac3af5-bab9-4d3b-9423-6241c9c334e4 | public | 6b6358f8-4492-4975-80fa-12324aea6682, 7b323fdb-268d-45e0-ba39-deb8c856c07c |
+--------------------------------------+--------+----------------------------------------------------------------------------+

```

### Boot
Now that you gathered all necessary information, it's time to boot your first instance using:
```
openstack server create ...  # command to be completed

# help
openstack help server create
```

Q: what command did you use to boot a `small` `Debian 12` instance using your `keypair` on `public` network?

When done, you will have an output like:
```
+-----------------------------+-----------------------------------------------------+
| Field                       | Value                                               |
+-----------------------------+-----------------------------------------------------+
| OS-DCF:diskConfig           | MANUAL                                              |
| OS-EXT-AZ:availability_zone |                                                     |
| OS-EXT-STS:power_state      | NOSTATE                                             |
| OS-EXT-STS:task_state       | scheduling                                          |
| OS-EXT-STS:vm_state         | building                                            |
| OS-SRV-USG:launched_at      | None                                                |
| OS-SRV-USG:terminated_at    | None                                                |
| accessIPv4                  |                                                     |
| accessIPv6                  |                                                     |
| addresses                   |                                                     |
| adminPass                   | ...                                                 |
| config_drive                |                                                     |
| created                     | 2018-12-21T14:01:07Z                                |
| flavor                      | small (3c83dfbd-abdb-43d0-b041-3ac44009c2f7)        |
| hostId                      |                                                     |
| id                          | 369ad246-8c48-40f9-ada1-269c0844b34c                |
| image                       | Debian 12 (d60f629d-7f22-4db8-9f4a-cf480a26856f)    |
| key_name                    | mykey                                               |
| name                        | myvm01                                              |
| progress                    | 0                                                   |
| project_id                  | 88c8667...                                          |
| properties                  |                                                     |
| security_groups             | name='default'                                      |
| status                      | BUILD                                               |
| updated                     | 2018-12-21T14:01:07Z                                |
| user_id                     | 12843a2...                                          |
| volumes_attached            |                                                     |
+-----------------------------+-----------------------------------------------------+
```

Notice that the `status` is `BUILD` and the `OS-EXT-STS:vm_state` field is `building`. Also the field `addresses` is empty which means no IP address has been assigned to it yet.

You can run this command to check the progress of the VM:
```
openstack server show myvm01

# Or with its id:
openstack server show 369ad246-8c48-40f9-ada1-269c0844b34c
```

As soon as your instance will be ready, the `status` will be `ACTIVE` and an IPv4 should have been assigned to the instance.


### Ping
Try to ping the IP of your server

Q: is it working?

### Security rules
By default, the `security rules` applied to your server are closing all connections:
```
openstack security group rule list
```

Add a `rule` to allow ICMP (ping):
```
openstack security group rule create --protocol icmp --ingress default
```
Q: is ping working now?

### Connect with ssh
Now, add a `rule`to allow `ssh` (tcp/22) and try connecting to your instance with SSH:
```
ssh debian@xxx.yyy.zzz.aaa
```

### Delete the instance
Q: which command can you use to delete the instance?

## Private networks

This part will help you manage some network resources of the cloud.

You will be dealing with different components:

- **networks** (approximatively) represent the [layer 2](https://en.wikipedia.org/wiki/Data_link_layer) in the OSI model
- **subnets** are encapsulated in the networks and carry the [layer 3](https://en.wikipedia.org/wiki/Network_layer) information
- **routers** are used to interconnect networks
- **floating ips** can be attached to a server connected to private networks in order to be reached from internet

### Create a private network and subnet

By default only a `public` network is provided but some use case require the instances to be connected on a dedicated `private` network.

OpenStack provides the functionality to create `private` networks in your project (and only for you), while the `public` one is available for all users.

Let's start by simply creating a network:
```
openstack network create private
```

Then create the subnet:
```
openstack subnet create \
     --network private \
     --subnet-range "192.168.42.0/24" \
     --gateway 192.168.42.1 \
     --dns-nameserver 1.1.1.1 \
     "192.168.42.0/24"
```

### Create a router
```
openstack router create router1
```
Then attach this router to your private network:
```
openstack router add subnet router1 192.168.42.0/24
```

Q: which IP address the router is having in your private network?

Finally add an external gateway to your router
```
openstack router set --external-gateway public router1
```
Q: which IP addres the router is having as external gateway?

### Boot
Like in first part, boot an instance, but connected to your `private` network this time

Q: can you access to your instance in SSH?

### Floating IP
Create a `floating ip` from `public` network
```
openstack floating ip create public
```

Attach your `floating ip` to your instance:
```
openstack server add floating ip myprivateserver xxx.yyy.www.bbb
```

### Connect with ssh
```
ssh debian@xxx.yyy.zzz.aaa  # floating ip
```

Q: what IP can you see on ens3 interface of the instance?

## Bonus

Try to deploy `demo-flask` with cloud-init


## Bonus 2

Take a look at the [skyline WebUI](http://skyline.54.36.119.253.xip.opensteak.fr) and try to boot another instance from there.
