Skip to content

Commit

Permalink
refactor device certificate management
Browse files Browse the repository at this point in the history
  • Loading branch information
reubenmiller committed Sep 9, 2024
1 parent 9d8eeab commit 932f330
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 47 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,20 @@ jobs:
with:
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}

- uses: taiki-e/install-action@just

- uses: reubenmiller/setup-go-c8y-cli@main
- name: install c8y-tedge extension
run: c8y extension install thin-edge/c8y-tedge

- name: create .env file
run: |
touch .env
./scripts/manage.sh init "$DEVICE_ID"
just init "$DEVICE_ID"
echo "DEVICE_ID=$DEVICE_ID" >> .env
echo 'C8Y_BASEURL="${{ secrets.C8Y_BASEURL }}"' >> .env
C8Y_DOMAIN=$(echo "${{ secrets.C8Y_BASEURL }}" | sed -E 's|^https?://||g')
C8Y_DOMAIN=$(echo "${{ secrets.C8Y_BASEURL }}" | sed 's|.*://||g')
echo 'C8Y_USER="${{ secrets.C8Y_USER }}"' >> .env
echo 'C8Y_PASSWORD="${{ secrets.C8Y_PASSWORD }}"' >> .env
Expand All @@ -66,7 +68,7 @@ jobs:
- name: Upload certificate
run: |
./scripts/manage.sh upload
just upload
- uses: actions/setup-python@v5
with:
Expand All @@ -75,8 +77,6 @@ jobs:
cache-dependency-path: |
tests/requirements.txt
- uses: taiki-e/install-action@just

- name: Install dependencies
run: |
just venv
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.env
tmp/
device-certs/
*.tar
.venv/
output/
41 changes: 13 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ After the project pre-requisites have been installed, you can start the containe
1. Create a `.env` file containing the environment variables (see the [Providing the device certificate by environment variables](./README.md#providing-the-device-certificate-by-environment-variables) for details on how to provide the device certificate)

```sh
# Device certificate (public/private)
CERTPRIVATE=<base64_encoded_private_key>
CERTPUBLIC=<base64_encoded_public_cert>

# Which c8y instance you want to connect to
TEDGE_C8Y_URL=example.cumulocity.com

Expand All @@ -45,7 +41,19 @@ After the project pre-requisites have been installed, you can start the containe
SERVICE_TEDGE_MAPPER_C8Y=1
```

2. Start the container (using docker compose)
2. Init the device certificate (stored under `./device-cert)
```sh
just init "$DEVICE_ID"
```
3. Upload the device certificate to Cumulocity IoT
```sh
just upload
```
4. Start the container (using docker compose)
```sh
# using justfile task
Expand All @@ -61,29 +69,6 @@ After the project pre-requisites have been installed, you can start the containe
just run-container
```
### Providing the device certificate by environment variables

The thin-edge.io certificate (both public and private keys) are provided to the container via environment variables.

The following environment variables are used to provide the certificate to the container's startup script `50_configure.sh` which is called by s6-overlay when the container starts up:
* `CERTPRIVATE` - Device certificate private key (base64 encoded)
* `CERTPUBLIC` - Device certificate public key (base64 encoded)
The environment variables are base64 encoded to avoid any shell quoting problems with whitespace any other unexpected characters. If you have the certificate files (public and private key), then you generate the encoded values using the following one-liners:
```sh
cat /etc/tedge/device-certs/tedge-private-key.pem | base64 | tr -d '\n' | xargs printf 'CERTPRIVATE=%s\n'
cat /etc/tedge/device-certs/tedge-certificate.pem | base64 | tr -d '\n' | xargs printf 'CERTPUBLIC=%s\n'
```
You can copy the output to your `.env` file (or set the environment variables yourself). An example of the `.env` file is shown below:
```sh
CERTPRIVATE=LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tsS0tCk1JR0hBZ0bBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZ2lHcDE3eEZ5VlcvZXlka1kKaE4rM05McWtMM3dIK0d3c1BSZnFmZk1NQU9taFJBTkNBQVEyRVhSNnFnb3JNcldPUzQyNVlRT21DbFVsWWZHdwp6alRySnF6WnZjOTVkTzJnNUZEb1Z4ZFZSUuc5MWJNOFNvdDFVWnlZMklEaXpSUzBHZ3c0NgCBQUklWQVRFIEtFWS0tLS0tCd==
CERTPUBLIC=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ4RENDQVdxZ0F3SUJBZ0lVRlFOelh5eUNqTEpMQmxQVWRJeWUzNW9pUzZNd0NnWUlLb1pJemowRUSXcKU0RFY01Cb0dBMVVFQXd3VGRHVmtaMlZmWTI5dWRHRnBibVZ5WHpBd01URVNNQkFHQTFVRUNnd0pWR2hwYmlgpaR2RsTVJRd0VnWURVFMREF0VVpYTjBJRVJsZG1salpUQWVGdzB5TkRBMk1EWXdPREV3TXpaYUZ3MHlOVEEyCk1EWXdPREV3TXpaYU1FZ3hIREFhQmdkJBTU1FM1JsWkdkbFgyTnZiblJoYVc1bGNsOHdNREV4RWpBUUJnTlYKQkFvTUNWUm9hVzRnUldSblpURVVNQklHQTFVRUN3d0xWR1Z6NCRVpYWnBZMlV3V1RBVEJnY3Foa2pPUFFJQgpCZ2dxaGtqT1BRTUJCd05DQUFRMkVjZxZ29yTXJXT1M0MjVZUU9tQ2xVbFlmR3d6alRySnF6WnZjOTVkeTluCk8yZzVGRG9WeGRWUlFHOTFiTThTL3QxVVp5WTJJRGl6UlMwR2d3NDZvekl3TURBZEJnTlZIUTRFRmdRVUZRTnoKWHl5Q2pMSkxCbFBVZEl5ZTM1b2lTNk13ROSQpBREJGQWlFQSs1Z09Gem5LQ0lNSFVWODFJVzhMZkhFUzE0SXdGR3Y3Q2dzZjd2ZzNhck1DSUR1cGpsRjBFaHozCkx6d1VURySTR6YmRGbzc1WWVKODBXNXg1V1hlZzEzCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
```
## Project structure
|Directory|Description|
Expand Down
5 changes: 1 addition & 4 deletions cont-init.d/50_configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ fi
MAPPERS="c8y az aws"
for MAPPER in $MAPPERS; do
if tedge config get "${MAPPER}.url" 2>/dev/null; then
if ! tedge connect "$MAPPER" --test 2>/dev/null; then
echo "Connecting $MAPPER" >&2
tedge reconnect "$MAPPER" ||:
fi
tedge reconnect "$MAPPER" ||:
fi
done
8 changes: 8 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ DEFAULT_OUTPUT_TYPE := "oci,dest=" + IMAGE + ".tar"

RELEASE_VERSION := env_var_or_default("RELEASE_VERSION", `date +'%Y%m%d.%H%M'`)

# Initialize the device certificate
init *ARGS:
./scripts/manage.sh init {{ARGS}}

# Upload device certificate to Cumulocity IoT
upload *ARGS:
CI=true ./scripts/manage.sh upload {{ARGS}}

# Start the compose project
start *ARGS:
docker compose up --build {{ARGS}}
Expand Down
23 changes: 14 additions & 9 deletions scripts/manage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ if [ -n "$CI" ]; then
set -x
fi

mkdir -p tmp
DEVICE_CERTS="$(pwd)/device-certs"
mkdir -p "$DEVICE_CERTS"

show_common_name() {
docker run $DOCKER_OPTIONS -v "$(pwd)/tmp/:/etc/tedge/device-certs" ghcr.io/thin-edge/tedge:latest tedge config get device.id | sed 's/\r$//g'
docker run $DOCKER_OPTIONS -v "$DEVICE_CERTS:/etc/tedge/device-certs" ghcr.io/thin-edge/tedge:latest tedge config get device.id | sed 's/\r$//g'
}

create_cert() {
COMMON_NAME="$1"
docker run $DOCKER_OPTIONS --user root -v "$(pwd)/tmp/:/etc/tedge/device-certs" ghcr.io/thin-edge/tedge:latest tedge cert create --device-id "$COMMON_NAME"
docker run $DOCKER_OPTIONS --user root -v "$DEVICE_CERTS:/etc/tedge/device-certs" ghcr.io/thin-edge/tedge:latest tedge cert create --device-id "$COMMON_NAME"
}

upload() {
Expand All @@ -37,7 +38,7 @@ upload() {
c8y devicemanagement certificates create \
--force \
--name "$COMMON_NAME" \
--file "tmp/tedge-certificate.pem" \
--file "$DEVICE_CERTS/tedge-certificate.pem" \
--autoRegistrationEnabled \
--status ENABLED \
--silentStatusCodes 409 \
Expand All @@ -49,13 +50,17 @@ main() {
shift
case "$ACTION" in
init)
if [ $# -lt 1 ]; then
echo "Missing required argument. COMMON_NAME" >&2
DEVICE_ID=${DEVICE_ID:-$1}
if [ -z "$DEVICE_ID" ]; then
echo "Missing required argument or DEVICE_ID env variable. COMMON_NAME" >&2
exit 1
fi
rm -rf tmp/
mkdir -p tmp/
create_cert "$1"
mkdir -p "$DEVICE_CERTS"
create_cert "$DEVICE_ID"
;;
delete)
echo "Removing device certificates: $DEVICE_CERTS"
rm -rf "$DEVICE_CERTS"
;;
upload)
upload
Expand Down

0 comments on commit 932f330

Please sign in to comment.