-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Ryan Winter <[email protected]>
- Loading branch information
1 parent
be00f31
commit 9202797
Showing
4 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/bash | ||
|
||
mkdir certs | ||
|
||
# create root CA | ||
echo == Creating root CA == | ||
step certificate create --profile root-ca "my root ca" certs/root_ca.crt certs/root_ca.key | ||
|
||
# create intermediate CA | ||
echo == Creating intermediate CA == | ||
step certificate create --profile intermediate-ca "my intermediate ca" \ | ||
certs/intermediate_ca.crt certs/intermediate_ca.key \ | ||
--ca certs/root_ca.crt --ca-key certs/root_ca.key | ||
|
||
# create client certificate | ||
echo == Creating client certificate == | ||
step certificate create client \ | ||
certs/client.crt certs/client.key \ | ||
--not-after 8760h \ | ||
--no-password --insecure \ | ||
--ca certs/intermediate_ca.crt --ca-key certs/intermediate_ca.key | ||
|
||
# create client trust bundle configmap used to validate x509 client connections | ||
kubectl delete configmap client-ca-trust-bundle -n azure-iot-operations | ||
kubectl create configmap client-ca-trust-bundle -n azure-iot-operations \ | ||
--from-literal=client_ca.pem="$(cat certs/intermediate_ca.crt certs/root_ca.crt)" | ||
|
||
# download the MQTT broker trust bundle | ||
kubectl get secret azure-iot-operations-aio-ca-certificate \ | ||
-n cert-manager \ | ||
-o jsonpath='{.data.ca\.crt}' | base64 -d > certs/broker-ca.crt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
# Azure IoT Operations state store CLI tool | ||
|
||
The state store CLI tool can be used to manage keys and values in the Azure IoT Operations state store. The tool is a standalone self-sufficient binary application, and doesn't require the installation of additional libraries or frameworks. | ||
|
||
Supported platforms: | ||
|
||
* Linux (tested on Ubuntu 24.04) | ||
* Windows 11 | ||
|
||
> [!IMPORTANT] | ||
> The tool is designed to run on a standalone machine with access to the Azure IoT Operations cluster. This is not designed to run on the cluster itself. | ||
## Prerequisites | ||
|
||
On the machine where the tool will be run, the following are required: | ||
|
||
1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/) which will be used to configure the MQTT Broker | ||
|
||
1. Clone the `explore-iot-operations` repository, and enter the state store cli directory: | ||
|
||
```shell | ||
git clone https://github.com/Azure-Samples/explore-iot-operations | ||
cd explore-iot-operations/tools/state-store-cli | ||
``` | ||
|
||
1. Download the state store CLI from the [latest GitHub release](https://github.com/Azure-Samples/explore-iot-operations/releases?q=state-store-cli) and save it in the `state-store-cli` directory | ||
|
||
1. **OPTIONAL**: If MQTT broker authentication is required, [install step](https://smallstep.com/docs/step-cli/installation/) to generate the required certificates | ||
|
||
## Setup | ||
|
||
### Setup with no authentication | ||
|
||
If security is not a requirement, due to the cluster being used for non-production purposes, enabling a non-authenticated BrokerListener is the simplest approach. | ||
|
||
1. Create a new `BrokerListener` by applying the following: | ||
|
||
```shell | ||
kubectl apply -f yaml/listener-open.yaml | ||
``` | ||
|
||
### Setup with authentication | ||
|
||
If security is a requirement, then you will need to expose the MQTT broker using TLS and x509 certificate authentication: | ||
|
||
1. Run `generate-credentials.sh` to create the x.509 device certificates and download the MQTT broker trust bundle: | ||
|
||
```bash | ||
./generate-credentials.sh | ||
``` | ||
|
||
1. Inspect the output for errors and make corrections if necessary | ||
|
||
1. Edit the following section of `yaml/listener-x509.yaml` and add the correct public DNS or IP address for your kubernetes cluster: | ||
|
||
```yaml | ||
san: | ||
dns: | ||
- localhost | ||
ip: | ||
- 127.0.0.1 | ||
``` | ||
|
||
1. Create a new `BrokerListener`:: | ||
|
||
```shell | ||
kubectl apply -f yaml/listener-x509.yaml | ||
``` | ||
|
||
> [!NOTE] | ||
> The `certs` directory will contain the following files which will be used the state store cli tool for authenticating with the MQTT broker: | ||
> | ||
> * `broker-ca.crt` : The MQTT broker server certificate | ||
> * `client.crt` : The device certificate for authentication with MQTT broker | ||
> * `client.key` : The device private key for authentication with MQTT broker | ||
|
||
## Usage | ||
|
||
For accessing help directly from the console just type `statestore --help`. | ||
|
||
```shell | ||
$ ./statestore --help | ||
Allows managing key/value pairs in the MQ State Store. | ||
Usage: statestore [OPTIONS] <COMMAND> | ||
Commands: | ||
get Gets the value of an existing key | ||
set Sets a key and value | ||
delete Deletes an existing key and value | ||
help Print this message or the help of the given subcommand(s) | ||
Options: | ||
-n, --hostname <HOSTNAME> | ||
MQ broker hostname | ||
[default: localhost] | ||
-p, --port <PORT> | ||
MQ broker port number | ||
[default: 8883] | ||
--notls | ||
Do not use TLS for connection with MQ broker | ||
-T, --cafile <CAFILE> | ||
Trusted certificate bundle for TLS connection | ||
-C, --certfile <CERTFILE> | ||
Client authentication certificate file | ||
-K, --keyfile <KEYFILE> | ||
Client authentication private key file | ||
-P, --keypasswordfile <KEYPASSWORDFILE> | ||
Password for private key file | ||
--verbose | ||
Verbose logging (errors) | ||
-h, --help | ||
Print help (see a summary with '-h') | ||
-V, --version | ||
Print version | ||
``` | ||
|
||
Help specific to each command can be printed through calling `statestore <command> --help`. | ||
|
||
```shell | ||
$ ./statestore get --help | ||
Gets the value of an existing key | ||
Usage: statestore get [OPTIONS] --key <KEY> | ||
Options: | ||
-k, --key <KEY> | ||
Device State Store key name to retrieve | ||
-f, --valuefile <VALUEFILE> | ||
File where to write the key value. If not provided, the value is written to stdout | ||
-n, --hostname <HOSTNAME> | ||
MQ broker hostname [default: localhost] | ||
-p, --port <PORT> | ||
MQ broker port number [default: 8883] | ||
--notls | ||
Do not use TLS for connection with MQ broker | ||
-T, --cafile <CAFILE> | ||
Trusted certificate bundle for TLS connection | ||
-C, --certfile <CERTFILE> | ||
Client authentication certificate file | ||
-K, --keyfile <KEYFILE> | ||
Client authentication private key file | ||
-P, --keypasswordfile <KEYPASSWORDFILE> | ||
Password for private key file | ||
--verbose | ||
Verbose logging (errors) | ||
-h, --help | ||
Print help | ||
``` | ||
|
||
## Examples | ||
|
||
For the examples below, assume: | ||
|
||
- The MQTT broker is named `mybroker.net`, on port `8883` or `1883` | ||
- The MQTT brokers trusted CA certificate bundle is available locally as saved locally at `./certs/broker-ca.crt` | ||
- Client certificates are set in the AIO MQ Broker, and saved locally at `./certs/client.crt` and `./certs/client.key`. | ||
|
||
### X.509 authentication with TLS | ||
|
||
To retrieve an existing key: | ||
|
||
```shell | ||
./statestore get -n "mybroker.net" -k "keyName1" -f "./keyValue1.txt" -T "./certs/broker-ca.crt" -C "./certs/client.crt" -K "./certs/client.key" | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Prints the value of an existing key to the console.</br>If `--valuefile` argument is provided, the value is written to the provided file if the key exists.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port, bad CA certificate).</br>- Authentication failures (bad certificates)</br>- The key does not exist.</br>- Cannot write value to file (if `--valuefile` is used).| | ||
|
||
To set the value of a key: | ||
|
||
```shell | ||
./statestore set -n "mybroker.net" -k "keyName1" --value "keyValue1" -T "./certs/broker-ca.crt" -C "./certs/client.crt" -K "./certs/client.key" | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Sets the value of a key in the state store.</br>If `--valuefile` (short, `-f`) argument is provided (instead of `--value`), the value is read from the provided file.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port, bad CA certificate).</br>- Authentication failures (bad certificates)</br>- Cannot read file (if `--valuefile` is used).| | ||
|
||
To delete an existing key: | ||
|
||
```shell | ||
./statestore delete -n "mybroker.net" -k "keyName1" -T "./certs/broker-ca.crt" -C "./certs/client.crt" -K "./certs/client.key" | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Deletes an existing key in the state store.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port, bad CA certificate).</br>- Authentication failures (bad certificates)</br>- Key does not exist.| | ||
|
||
### No authentication, no TLS | ||
|
||
> [!CAUTION] | ||
> The use of non-secure connections with the MQTT broker is highly discouraged. The option is provided for testing purposes only and it is recommended to use secure connections in production environments. | ||
|
||
To retrieve an existing key: | ||
|
||
```shell | ||
./statestore get -n "mybroker.net" -k "keyName1" -f "./keyValue1.txt" --notls | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Prints the value of an existing key to the console.</br>If `--valuefile` argument is provided, the value is written to the provided file if the key exists.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port).</br>- The key does not exist.</br>- Cannot write value to file (if `--valuefile` is used).| | ||
|
||
To set the value of a key: | ||
|
||
```shell | ||
./statestore set -n "mybroker.net" -k "keyName1" --value "keyValue1" --notls | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Sets the value of a key in the state store.</br>If `--valuefile` (short, `-f`) argument is provided (instead of `--value`), the value is read from the provided file.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port).</br>- Cannot read file (if `--valuefile` is used).| | ||
|
||
To delete an existing key: | ||
|
||
```shell | ||
./statestore delete -n "mybroker.net" -k "keyName1" --notls | ||
``` | ||
|
||
||| | ||
|-|-| | ||
|Outcome|Deletes an existing key in the state store.| | ||
|Return|Zero (0) on success, non-zero on error.| | ||
|Possible errors|- Not able to connect (no internet, bad hostname and/or port).</br>- Key does not exist.| | ||
|
||
## Limitations | ||
|
||
The following features are **not** supported by the state store CLI tool: | ||
|
||
- `vdel`, `observer` and `unobserve` operations | ||
- SAT authentication |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
apiVersion: mqttbroker.iotoperations.azure.com/v1 | ||
kind: BrokerListener | ||
metadata: | ||
name: listener-open | ||
namespace: azure-iot-operations | ||
spec: | ||
brokerRef: default | ||
serviceType: LoadBalancer | ||
serviceName: aio-open-listener | ||
ports: | ||
- port: 1883 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
apiVersion: mqttbroker.iotoperations.azure.com/v1 | ||
kind: BrokerListener | ||
metadata: | ||
name: listener-x509 | ||
namespace: azure-iot-operations | ||
spec: | ||
brokerRef: default | ||
serviceType: LoadBalancer | ||
ports: | ||
- port: 8883 | ||
authenticationRef: default-x509 | ||
tls: | ||
mode: automatic | ||
certManagerCertificateSpec: | ||
issuerRef: | ||
name: azure-iot-operations-aio-certificate-issuer | ||
kind: ClusterIssuer | ||
group: cert-manager.io | ||
san: | ||
dns: | ||
- localhost | ||
ip: | ||
- 127.0.0.1 | ||
--- | ||
apiVersion: mqttbroker.iotoperations.azure.com/v1 | ||
kind: BrokerAuthentication | ||
metadata: | ||
name: default-x509 | ||
namespace: azure-iot-operations | ||
spec: | ||
authenticationMethods: | ||
- method: X509 | ||
x509Settings: | ||
trustedClientCaCert: client-ca-trust-bundle |