-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Protecting Your Assets with Replicated (#327)
TL;DR ----- Adds a lab to show license features and custom metrics Details ------- Offers a new lab focusing on things you can do with the Replicated license. Takes the learner through the following steps: 1. What is the Replicated license? 2. Creating a customer and their license. 3. Using the Replicated proxy registry to protect your private images. 4. Using license Helm values in your templatess. 5. Custom license entitlements 6. Validating license entitlements with the Replcated SDK 7. Sending custom metrics to measure license usage The last two steps use shell commands to walk through SDK capabilities a vendor will usually work with in their application code. This is a deliberate choiceto avoid losing some learners based on programming language. We can consider future labs using the SDK from different languages.
- Loading branch information
Showing
59 changed files
with
2,553 additions
and
41 deletions.
There are no files selected for viewing
106 changes: 106 additions & 0 deletions
106
instruqt/protecting-your-assets/01-the-replicated-license/assignment.md
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,106 @@ | ||
--- | ||
slug: the-replicated-license | ||
id: frbo6izjilr1 | ||
type: challenge | ||
title: The Replicated License | ||
teaser: Understanding the role of the Replicated license | ||
notes: | ||
- type: text | ||
contents: Understanding the Replicated license | ||
tabs: | ||
- title: License File | ||
type: code | ||
hostname: shell | ||
path: /home/replicant | ||
difficulty: basic | ||
timelimit: 400 | ||
--- | ||
|
||
👋 Introduction | ||
=============== | ||
|
||
The Replicated Platform provides a license that identifies each of your | ||
customers and entitles them to install your software. These customer licenses | ||
provide several default entitlements such as the type of license and whether | ||
(and when) it expries. Replicated provides the license file to you as a | ||
downloadable asset and embeds it into your Helm chart when you include the | ||
Replicated SDK. A digital signature confirms it hasn't been tampered with. | ||
|
||
How Licenses Work | ||
================ | ||
|
||
Each customer you create for your application in the Replicated Vendor Portal | ||
has a license associated with it. The main purpose of the license is to | ||
identify which software the user is entitled to. The entitlement is determined | ||
by two attributes of the license: the application and the release channel. The | ||
platform knows the application the customer was created for, and you specify | ||
the release channel when you create the customer. You can change the channel at | ||
any time. We'll discuss release channels shortly. | ||
|
||
The other core attribute of the license is its type. Each customer license has | ||
one of the following types: | ||
|
||
* **Development:** The Development type can be used internally by the | ||
development team for testing and integration. | ||
* **Trial:** The Trial type can be used for customers who are on 2-4 week | ||
trials of your software. | ||
* **Paid:** The Paid type identifies the customer as a paying customer for | ||
which additional information can be provided. | ||
* **Community:** The Community type is designed for a free or low cost version | ||
of your application. For more details about this type, see Community | ||
Licenses. | ||
|
||
You can change the license type of an existing license. You'll most often do | ||
this when a customer who has been trying your software decides to make a | ||
purchase. | ||
|
||
The other common features of all licenses are an expiration date and flags for | ||
enabling several Replicated Platform features. License need not expire, and you | ||
have full control over the expiration date that you set. Replicated features | ||
may change over time and have sensible defaults based on your subscription. | ||
|
||
Release Channels | ||
================ | ||
|
||
Before we create our first customer, let's briefly discuss release channels. | ||
If you've completed another lab like [Avoiding Installation | ||
Pitfalls](https://play.instruqt.com/replicated/tracks/avoiding-installation-pitfalls) | ||
or [Closing the Support Information | ||
Gap](https://play.instruqt.com/replicated/tracks/closing-infromation-gap) then | ||
you may already be familiar with them. If you haven't, then here's a quick introduction. | ||
|
||
The [Distributing Your Application with | ||
Replicated](https://play.instruqt.com/replicated/tracks/distributing-with-replicated) | ||
lab covers release channels in the most depth if you'd like more information. | ||
|
||
Release channels, at their most basic, map releases to customers. Each customer | ||
is assigned to a specific channel, and any relase can be provided to as many | ||
channels as you want. There are three default channels: `Unstable`, `Beta`, and | ||
`Stable`. Think of `Stable` as your GA software and `Unstable` as releases that | ||
you're planning to test and/or distribute internally. `Beta` is, of course, for | ||
beta releases. | ||
|
||
Those are the defaults, but you can have as many channels as you like. Some | ||
vendors drop one of the defaults and only have two channels, while others add | ||
channels for additional stages in the software lifecycle like `Alpha` or `Long | ||
Term Support`. Your team should consider the right set of release channels as | ||
you work through your implementation. | ||
|
||
License Files | ||
============= | ||
|
||
The customer license is defined in a format that's easy both to read and to | ||
parse. A basic license is in the file `Geeglo.yaml` that you can open in the | ||
editor showing in the "License File" tab. You'll notice that it's a YAML | ||
formatted file with the same structure as a Kubernetes object. The object is | ||
interpreted by the Replicated Platform components rather than the Kubernetes | ||
cluster to avoid needing any special permissions. | ||
|
||
![Opening the Geeglo License File](../assets/opening-the-license-file.png) | ||
|
||
In most installation scenarios, neither you nor your customer will need to | ||
interact directly with their license file. Instead, the platform embeds it into | ||
install artifacts like the your Helm chart and the Replicated Embedded Cluster | ||
binary. The exception is installing into an existing cluster using the | ||
Replicated Admin Console. The console will prompt for the customer to uploaed | ||
there license as one of the first steps to the install. |
5 changes: 3 additions & 2 deletions
5
...sets/01-validate-connectivity/check-shell → ...ets/01-the-replicated-license/check-shell
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 |
---|---|---|
@@ -1,9 +1,10 @@ | ||
#!/bin/sh | ||
#!/usr/bin/env bash | ||
# | ||
# This script runs when the platform check the challenge. | ||
# | ||
# The platform determines if the script was successful using the exit code of this | ||
# script. If the exit code is not 0, the script fails. | ||
# | ||
|
||
kubectl get nodes | ||
set -euxo pipefail | ||
exit 0 |
33 changes: 33 additions & 0 deletions
33
instruqt/protecting-your-assets/01-the-replicated-license/setup-shell
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,33 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
HOME_DIR=/home/replicant | ||
|
||
# Wait for Instruqt bootstrap to be complete | ||
while [ ! -f /opt/instruqt/bootstrap/host-bootstrap-completed ] | ||
do | ||
echo "Waiting for Instruqt to finish booting the VM" | ||
sleep 1 | ||
done | ||
|
||
# convenience library for Replicated lab lifecycle scripts | ||
source /etc/profile.d/header.sh | ||
|
||
# there's only one app created by the automation, so just grab the first in the list | ||
access_token=$(get_api_token) | ||
app_slug=$(curl --header 'Accept: application/json' --header "Authorization: ${access_token}" https://api.replicated.com/vendor/v3/apps | jq -r '.apps[0].slug') | ||
|
||
agent variable set USERNAME $(get_username) | ||
|
||
agent variable set PASSWORD $(get_password) | ||
agent variable set REPLICATED_API_TOKEN ${access_token} | ||
agent variable set REPLICATED_APP ${app_slug} | ||
|
||
helm show values --version 0.4.1 \ | ||
oci://registry.replicated.com/${app_slug}/slackernews 2>/dev/null \ | ||
| yq .replicated.license \ | ||
> ${HOME_DIR}/Geeglo.yaml | ||
|
||
chown replicant ${HOME_DIR}/Geeglo.yaml |
10 changes: 10 additions & 0 deletions
10
instruqt/protecting-your-assets/01-the-replicated-license/solve-shell
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,10 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# This script runs when the platform check the challenge. | ||
# | ||
# The platform determines if the script was successful using the exit code of this | ||
# script. If the exit code is not 0, the script fails. | ||
# | ||
|
||
set -euxo pipefail | ||
exit 0 |
25 changes: 0 additions & 25 deletions
25
instruqt/protecting-your-assets/01-validate-connectivity/assignment.md
This file was deleted.
Oops, something went wrong.
101 changes: 101 additions & 0 deletions
101
instruqt/protecting-your-assets/02-create-a-customer/assignment.md
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,101 @@ | ||
--- | ||
slug: create-a-customer | ||
id: f0ayvnopkkyv | ||
type: challenge | ||
title: Creating a Customer License | ||
teaser: Time to add a customer and configure their license | ||
notes: | ||
- type: text | ||
contents: | | ||
Add a customer to your application and configure their license | ||
tabs: | ||
- title: Vendor Portal | ||
type: website | ||
url: https://vendor.replicated.com | ||
new_window: true | ||
- title: Shell | ||
type: terminal | ||
hostname: shell | ||
workdir: /home/replicant | ||
difficulty: basic | ||
timelimit: 600 | ||
--- | ||
|
||
|
||
Creating a Customer License | ||
=========================== | ||
|
||
Let's connect to the Replicated Vendor Portal and create a new customer. This | ||
will also create their license. Click on the "Open External Window" button to | ||
open a new browser window and access the portal. Log in with these credentials: | ||
|
||
Username: `[[ Instruqt-Var key="USERNAME" hostname="shell" ]]`<br/> | ||
Password: `[[ Instruqt-Var key="PASSWORD" hostname="shell" ]]` | ||
|
||
You'll land on the "Channels" page showing the default release channels and an | ||
added channel for releases with long-term support. | ||
|
||
![Vendor Portal Release Channels](../assets/vendor-portal-landing.png) | ||
|
||
To create a customer, select "Customers" from the menu on the left, and you'll | ||
see your two existing customers "Omozan" and "Geeglo". | ||
|
||
![Your Existing Customers](../assets/customer-landing-page.png) | ||
|
||
We're going to assume you're working with a new prospect named "Nitflex" and | ||
create them in the portal. The platform also includes an | ||
[API](https://replicated-vendor-api.readme.io/v3/reference/createapp) you can | ||
use to automate customer creation as part of your existing onboarding workflow. | ||
For the purpose of the lab, click the "+ Create Customer" button to create | ||
"Nitflex" manually. | ||
|
||
![Creating a Customer](../assets/create-customer-button.png) | ||
|
||
Enter the name "NitFlex" and assign them to the `Stable` channel. They've | ||
trying your software for two months, so let's make sure we capture the expiration | ||
date. We also need an email for them to login and install your Helm chart. Note | ||
that we never use that email, it's your customer, not ours. | ||
|
||
Expiration Date: `[[ Instruqt-Var key="LICENSE_EXPIRY" hostname="shell" ]]`<br/> | ||
Customer Email: `[[ Instruqt-Var key="CUSTOMER_EMAIL" hostname="shell" ]]` | ||
|
||
![Customer Details](../assets/new-customer-details.png) | ||
|
||
You should also specify that they are a trial customer, so select the "Trial" | ||
option for the customer type and save your changes. The process will be | ||
the same for a new paid customer with a longer expiration date and a "Paid" | ||
license type. | ||
|
||
Using the License | ||
================= | ||
|
||
The Vendor Portal generated a license for your Nitflex customer and also | ||
configured some credentials based on it. These credentials are for: | ||
|
||
* The Replicated registry for accessing the Slackernews Helm chart | ||
* Our proxy registry that protects your private images | ||
|
||
Let's use the first set of credentials to look at how the license is embedded | ||
into your Helm chart. | ||
|
||
Click on "Helm install instructions" and you'll see a popup with a set of | ||
instructions for this customer to install Slackernews. The first command is the | ||
login command for the Helm registry. | ||
|
||
![Helm Login Command](../assets/helm-login-command.png) | ||
|
||
Use the "Shell" tab in the lab to log into the registry. You'll need to copy | ||
the command from the vendor portal in order to log in. after you login, you can | ||
view the values for the Helm chart using `helm show values`: | ||
|
||
`helm show values oci://registry.replicated.com/[[ Instruqt-Var key="REPLICATED_APP" hostname="shell" ]]/slackernews | less` | ||
|
||
this will show you the default vales from the Helm chart. As you scroll through | ||
the values, you'll see license information injected in two places. The entire | ||
license file is injected as the `license` value for the `replicated` subchart, | ||
and a few details from it are injected under `.global.replicated`. | ||
|
||
One of the global fields is particularly important. The value | ||
`global.replicated.dockerconfigjson` has the required Docker configuration to | ||
access private images using the proxy registry. You will use this value in your | ||
Helm chart to give the cluster access to your private images. |
22 changes: 22 additions & 0 deletions
22
instruqt/protecting-your-assets/02-create-a-customer/check-shell
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,22 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
source /etc/profile.d/header.sh | ||
|
||
result=0 | ||
|
||
# check for release to Unstable | ||
api_token=$(get_api_token) | ||
|
||
# get the app id in order to work with the customer | ||
app_id=$(curl --header "Accept: application/json" --header "Authorization: ${api_token}" https://api.replicated.com/vendor/v3/apps | jq -r '.apps[0].id') | ||
|
||
# get the customer id in order to assure they exist | ||
new_customer=$(curl --header 'Accept: application/json' --header "Authorization: ${api_token}" "https://api.replicated.com/vendor/v3/app/${app_id}/customers" | jq -r '.customers[] | select( .name == "Nitflex" )') | ||
if [[ -z "${new_customer}" ]] ; then | ||
fail-message $'Please remember to create the customer Nitflex' | ||
let "result = result + 1" | ||
fi | ||
|
||
exit ${result} |
22 changes: 22 additions & 0 deletions
22
instruqt/protecting-your-assets/02-create-a-customer/cleanup-shell
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,22 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
### Assure the tmux session exists | ||
# | ||
# In a test scenario Instuqt does not run the user shell for the | ||
# challenge, which means the tmux session is never established. We | ||
# need to session for the solve scripts for other challenges to | ||
# succeed, so let's create it here. | ||
# | ||
|
||
if ! tmux has-session -t shell ; then | ||
tmux new-session -d -s shell su - replicant | ||
fi | ||
|
||
# clear the tmux pane and scrollback to look like a fresh shell | ||
tmux clear-history -t shell | ||
tmux send-keys -t shell clear ENTER | ||
|
||
exit 0 |
18 changes: 18 additions & 0 deletions
18
instruqt/protecting-your-assets/02-create-a-customer/setup-shell
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,18 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
source /etc/profile.d/header.sh | ||
|
||
# get the customer id, since it's the password for the Helm installation | ||
# and users like to copy/paste | ||
api_token=$(get_api_token) | ||
app_id=$(curl --header 'Accept: application/json' --header "Authorization: ${api_token}" https://api.replicated.com/vendor/v3/apps | jq -r '.apps[0].id') | ||
|
||
# email for the customer the user will create | ||
new_customer_email=${INSTRUQT_PARTICIPANT_ID}@nitflex.tv | ||
# help the user out by telling them the expiration date for a 30-day trial | ||
license_expiry=$(date -d "+2 months" "+%B %d, %Y") | ||
|
||
agent variable set LICENSE_EXPIRY "${license_expiry}" | ||
agent variable set CUSTOMER_EMAIL "${new_customer_email}" |
22 changes: 22 additions & 0 deletions
22
instruqt/protecting-your-assets/02-create-a-customer/solve-shell
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,22 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
source /etc/profile.d/header.sh | ||
|
||
# get the customer id, since it's the password for the Helm installation | ||
# and users like to copy/paste | ||
api_token=$(get_api_token) | ||
app_id=$(curl --header 'Accept: application/json' --header "Authorization: ${api_token}" https://api.replicated.com/vendor/v3/apps | jq -r '.apps[0].id') | ||
app_slug=$(curl --header 'Accept: application/json' --header "Authorization: ${api_token}" https://api.replicated.com/vendor/v3/apps | jq -r '.apps[0].slug') | ||
|
||
# provide an email address for the new customer | ||
customer_email="${INSTRUQT_PARTICIPANT_ID}@nitflex.tv" | ||
|
||
# create the new customer and keep track of the ID | ||
customer_id=$(replicated customer create --name "Nitflex" --email ${customer_email} --channel Stable --expires-in 1460h --type trial --kots-install=false --output json --app ${app_slug} --token ${api_token} | jq -r .id) | ||
|
||
# make sure the customer has a paid license | ||
updated_customer=$(curl --header 'Accept: application/json' --header "Authorization: ${api_token}" "https://api.replicated.com/vendor/v3/app/${app_id}/customer/${customer_id}" | \ | ||
jq -c --arg appId "${app_id}" '.customer | {"app_id": $appId, "name": .name, "email": .email, "channel_id": .channels[0].id, "expires_at": .expiresAt, "type": "trial", "is_airgap_enabled": .airgap, "is_gitops_supported": .isGitopsSupported, "is_identity_service_supported": .isIdentityServiceSupported, "is_geoaxis_supported": .isGeoaxisSupported, "is_snapshot_supported": .isSnapshotSupported, "is_support_bundle_upload_enabled": .isSupportBundleUploadEnabled, "entitlementValues":[]}') | ||
|
Oops, something went wrong.