-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/Initialize the solution #1
Changes from 28 commits
349a630
df335a0
d8b7564
67c0434
d85fa4d
214ed35
5339aac
a620911
01f232d
f34485a
0dd77c6
5e01ccd
07a22b0
600983d
e8baba0
6803f8a
9a148e1
7c2936b
0951396
91abe14
a13d32d
47ab19e
50233a9
51d9b64
1d5efe9
663298a
adb737b
a1b15b2
6d6c7e4
0e64be3
2727508
db02037
bed3709
abcbbce
aeb3e77
e06ab43
5c405b2
7b001be
0395cc5
bf40152
6c3ca52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# sets global approvers | ||
* @devpro @hierynomus |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- develop | ||
schedule: | ||
- cron: "0 2 * * 1-5" | ||
workflow_dispatch: {} | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checks-out the repository | ||
uses: actions/checkout@v4 | ||
- name: Lints Markdown files | ||
uses: DavidAnson/markdownlint-cli2-action@v16 | ||
with: | ||
globs: '**/*.md' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# ref. https://github.com/DavidAnson/markdownlint | ||
default: true | ||
MD013: # Line length | ||
line_length: 240 |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,52 @@ | ||
# lab-setup | ||
# Lab Setup | ||
|
||
[![CI](https://github.com/SUSE/lab-setup/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/SUSE/lab-setup/actions/workflows/ci.yml) | ||
|
||
Welcome! You'll find in this repository some IT material to help setup your lab environments. | ||
|
||
It is used internally at SUSE (the goal being to capitalize and factorize), but is open to everyone. Feel free to contribute and share feedback! | ||
|
||
## Getting started | ||
|
||
### Shell scripting | ||
|
||
* Download and source the files (here targetting `develop` branch but you can chose the revision you want): | ||
|
||
```bash | ||
SETUP_FOLDER=lab-setup | ||
curl -sfL https://raw.githubusercontent.com/SUSE/lab-setup/feature/init-solution/scripts/download.sh \ | ||
| GIT_REVISION=refs/heads/develop sh -s -- -o $SETUP_FOLDER | ||
. $SETUP_FOLDER/scripts/index.sh | ||
``` | ||
|
||
* Call a function: | ||
|
||
```bash | ||
# create a Kubernetes cluster (K3s distribution) | ||
k3s_create_cluster v1.23 | ||
``` | ||
|
||
* Look at a concrete sample: | ||
|
||
* [samples/scripting/rancher_installation.sh](samples/scripting/rancher_installation.sh) | ||
|
||
* Browse the available functions: | ||
|
||
Name | Source | ||
-----------------------------------------------|--------------------------------------------------------------------------------------------- | ||
`k3s_create_cluster` | [scripts/k3s/cluster-lifecycle.sh](scripts/k3s/cluster-lifecycle.sh) | ||
`k3s_copy_kubeconfig` | [scripts/k3s/cluster-lifecycle.sh](scripts/k3s/cluster-lifecycle.sh) | ||
`k8s_install_certmanager` | [scripts/kubernetes/certificate-management.sh](scripts/kubernetes/certificate-management.sh) | ||
`k8s_create_letsencryptclusterissuer` | [scripts/kubernetes/certificate-management.sh](scripts/kubernetes/certificate-management.sh) | ||
`k8s_wait_fornodesandpods` | [scripts/kubernetes/cluster-status.sh](scripts/kubernetes/cluster-status.sh) | ||
`rancher_list_clusters` | [scripts/rancher/cluster-actions.sh](scripts/rancher/cluster-actions.sh) | ||
`rancher_create_customcluster` | [scripts/rancher/cluster-actions.sh](scripts/rancher/cluster-actions.sh) | ||
`rancher_get_clusterid` | [scripts/rancher/cluster-actions.sh](scripts/rancher/cluster-actions.sh) | ||
`rancher_get_clusterregistrationcommand` | [scripts/rancher/cluster-actions.sh](scripts/rancher/cluster-actions.sh) | ||
`rancher_install_withcertmanagerclusterissuer` | [scripts/rancher/manager-lifecycle.sh](scripts/rancher/manager-lifecycle.sh) | ||
`rancher_first_login` | [scripts/rancher/manager-lifecycle.sh](scripts/rancher/manager-lifecycle.sh) | ||
`rancher_wait_capiready` | [scripts/rancher/manager-lifecycle.sh](scripts/rancher/manager-lifecycle.sh) | ||
`rancher_update_serverurl` | [scripts/rancher/manager-settings.sh](scripts/rancher/manager-settings.sh) | ||
`rancher_login_withpassword` | [scripts/rancher/user-actions.sh](scripts/rancher/user-actions.sh) | ||
`rancher_update_password` | [scripts/rancher/user-actions.sh](scripts/rancher/user-actions.sh) | ||
`rancher_create_apikey` | [scripts/rancher/user-actions.sh](scripts/rancher/user-actions.sh) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/bin/bash | ||
|
||
# downloads and sources shared scripts | ||
SETUP_FOLDER=temp | ||
curl -sfL https://raw.githubusercontent.com/SUSE/lab-setup/feature/init-solution/scripts/download.sh \ | ||
| GIT_REVISION=refs/heads/feature/init-solution sh -s -- -o $SETUP_FOLDER | ||
. $SETUP_FOLDER/scripts/index.sh | ||
|
||
# defines variables | ||
K3S_VERSION='v1.23' | ||
CERTMANAGER_VERSION='v1.11.0' | ||
LETSENCRYPT_EMAIL_ADDRESS='[email protected]' | ||
RANCHER_REPOSITORY='latest' | ||
RANCHER_VERSION='2.8.2' | ||
RANCHER_DOMAIN="rancher.${HOSTNAME}.${_SANDBOX_ID}.instruqt.io" | ||
RANCHER_REPLICAS='1' | ||
ADMIN_PASSWORD='Sus3R@ncherR0x' | ||
INGRESS_CLASSNAME='traefik' | ||
DOWNSTREAM_CLUSTER_NAME='demo' | ||
RKE2_K8S_VERSION='v1.27.16+rke2r1' | ||
|
||
# create management cluster | ||
k3s_create_cluster $K3S_VERSION | ||
k3s_copy_kubeconfig | ||
k8s_wait_fornodesandpods | ||
kubectl get nodes | ||
kubectl get pods -A | ||
k8s_install_certmanager $CERTMANAGER_VERSION | ||
k8s_create_letsencryptclusterissuer $INGRESS_CLASSNAME $LETSENCRYPT_EMAIL_ADDRESS | ||
kubectl get clusterissuers | ||
|
||
# install and initialize Rancher | ||
rancher_install_withcertmanagerclusterissuer $RANCHER_REPOSITORY $RANCHER_VERSION $RANCHER_REPLICAS $RANCHER_DOMAIN letsencrypt-prod | ||
RANCHER_URL="https://${RANCHER_DOMAIN}" | ||
rancher_first_login $RANCHER_URL $ADMIN_PASSWORD | ||
rancher_create_apikey $RANCHER_URL $LOGIN_TOKEN 'Automation API Key' | ||
echo "DEBUG API_TOKEN=${API_TOKEN}" | ||
rancher_list_clusters $RANCHER_URL $API_TOKEN | ||
rancher_wait_capiready | ||
|
||
# creates downstream cluster | ||
rancher_create_customcluster $RANCHER_URL $API_TOKEN $DOWNSTREAM_CLUSTER_NAME $RKE2_K8S_VERSION | ||
rancher_get_clusterregistrationcommand $RANCHER_URL $API_TOKEN $CLUSTER_ID | ||
|
||
# executes the registration from downstream server | ||
echo "Registering downstream cluster (RKE2)..." | ||
ssh -o StrictHostKeyChecking=accept-new downstream1 "${REGISTRATION_COMMAND} --etcd --controlplane --worker" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#!/bin/sh | ||
|
||
# Usage: | ||
# curl ... | ENV_VAR=... sh - | ||
# or | ||
# ENV_VAR=... ./setup.sh | ||
# | ||
# Examples: | ||
# Downloading scripts from a "develop" branch in a temp local folder "temp": | ||
# curl -sfL https://raw.githubusercontent.com/SUSE/lab-setup/feature/init-solution/scripts/setup.sh | GIT_REVISION=refs/heads/develop sh -s -- -o temp | ||
# Downloading scripts from a specific revision "d8b7564fbf91473074e86b598ae06c7e4e522b9f" in the default local folder: | ||
# curl -sfL https://raw.githubusercontent.com/SUSE/lab-setup/feature/init-solution/scripts/setup.sh | GIT_REVISION=d8b7564fbf91473074e86b598ae06c7e4e522b9f sh - | ||
# Testing locally the setup script: | ||
# GIT_REVISION=refs/heads/feature/init-solution ./lab-setup/scripts/setup.sh -o temp | ||
# | ||
# Environment variables: | ||
# - GIT_REVISION | ||
# Git revision (refs/heads/<branch-name>, refs/tags/vX.Y.Z for a tag, xxxxxxxxxxxxxxxx for a commit hashcode) | ||
# - OUTPUT_FOLDER | ||
# Output folder, where the scripts folder will be created with script directory tree inside, overriden if -o is used | ||
|
||
info() { | ||
echo '[INFO] ' "$@" | ||
} | ||
|
||
warn() { | ||
echo '[WARN] ' "$@" >&2 | ||
} | ||
|
||
fatal() { | ||
echo '[ERROR] ' "$@" >&2 | ||
exit 1 | ||
} | ||
|
||
verify_system() { | ||
info 'Verify system requirements' | ||
if [ -x /usr/bin/git ] || type git > /dev/null 2>&1; then | ||
return | ||
fi | ||
fatal 'Git is not installed in the machine' | ||
} | ||
|
||
setup_env() { | ||
info 'Setup variables' | ||
case "$1" in | ||
("-o") | ||
OUTPUT_FOLDER=$2 | ||
shift | ||
shift | ||
;; | ||
(*) | ||
OUTPUT_FOLDER=${OUTPUT_FOLDER:-'lab-setup'} | ||
;; | ||
esac | ||
|
||
GIT_REVISION=${GIT_REVISION:-'refs/heads/develop'} | ||
GIT_REPO_NAME='lab-setup' | ||
GIT_FOLDER=$(echo "$GIT_REVISION" | sed 's/\//-/g' | sed 's/refs-//' | sed 's/heads-//') | ||
} | ||
|
||
download() { | ||
info 'Download scripts' | ||
wget https://github.com/SUSE/${GIT_REPO_NAME}/archive/${GIT_REVISION}.zip -O ${GIT_REPO_NAME}.zip | ||
unzip -o ${GIT_REPO_NAME}.zip | ||
mkdir -p ${OUTPUT_FOLDER} | ||
if [ -d ${OUTPUT_FOLDER}/scripts ]; then | ||
info "Delete ${OUTPUT_FOLDER}/scripts" | ||
rm -rf ${OUTPUT_FOLDER}/scripts | ||
fi | ||
mv ${GIT_REPO_NAME}-${GIT_FOLDER}/scripts ${OUTPUT_FOLDER} | ||
} | ||
|
||
cleanup() { | ||
info 'Clean-up' | ||
rm -f ${GIT_REPO_NAME}.zip | ||
rm -rf ${GIT_REPO_NAME}-${GIT_FOLDER} | ||
} | ||
|
||
{ | ||
verify_system | ||
setup_env "$@" | ||
download | ||
cleanup | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
SCRIPT_FOLDER=$(dirname "${BASH_SOURCE[0]}") | ||
for file in ${SCRIPT_FOLDER}/*/*.sh | ||
do { | ||
echo "Sourcing ${file}" | ||
. $file | ||
} | ||
done |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Collection of functions to manage K3s cluster lifecycle | ||
|
||
####################################### | ||
# Create a K3s cluster | ||
# Arguments: | ||
# K3s version | ||
# Examples: | ||
# k3s_create_cluster "v1.23" | ||
####################################### | ||
k3s_create_cluster() { | ||
local version=$1 | ||
|
||
echo "Create management cluster (K3s)..." | ||
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL="${version}" K3S_KUBECONFIG_MODE="644" sh - | ||
} | ||
|
||
####################################### | ||
# Copy K3s kubeconfig file to local user file | ||
# Arguments: | ||
# None | ||
# Examples: | ||
# k3s_copy_kubeconfig | ||
####################################### | ||
k3s_copy_kubeconfig() { | ||
mkdir -p ~/.kube | ||
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config | ||
chmod 600 ~/.kube/config | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Collection of functions to add components to manage certificates in a Kubernetes cluster | ||
|
||
####################################### | ||
# Install cert-manager and wait for the the application to be running | ||
# Arguments: | ||
# cert-manager version | ||
# Examples: | ||
# k8s_install_certmanager "v1.11.0" | ||
####################################### | ||
k8s_install_certmanager() { | ||
local version=$1 | ||
|
||
echo "Installing cert-manager..." | ||
helm repo add jetstack https://charts.jetstack.io | ||
helm repo update | ||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${version}/cert-manager.crds.yaml | ||
helm upgrade --install cert-manager jetstack/cert-manager \ | ||
--namespace cert-manager --create-namespace \ | ||
--version ${version} \ | ||
2>/dev/null | ||
kubectl wait pods -n cert-manager -l app.kubernetes.io/instance=cert-manager --for condition=Ready 2>/dev/null | ||
} | ||
|
||
####################################### | ||
# Create certificate cluster issuers using Let's Encrypt | ||
# Arguments: | ||
# Ingress class name (traefik, nginx, etc.) | ||
# administrator email address (to receive notifications for Let's Encrypt) | ||
# Examples: | ||
# k8s_create_letsencryptclusterissuer traefik [email protected] | ||
####################################### | ||
k8s_create_letsencryptclusterissuer() { | ||
local ingressClassname=$1 | ||
local emailAddress=$2 | ||
|
||
echo "Creating certificate issuers using Let's Encrypt..." | ||
helm repo add devpro https://devpro.github.io/helm-charts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one we might want to move at some point in time There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! Added a TODO, really need to do this one (as for the container images) |
||
helm repo update | ||
helm upgrade --install letsencrypt devpro/letsencrypt --namespace cert-manager \ | ||
--set ingress.className=${ingressClassname} \ | ||
--set registration.emailAddress=${emailAddress} \ | ||
2>/dev/null | ||
while [ "$(kubectl get clusterissuers -o json | jq '.items != null')" != "true" ]; do | ||
echo "Waiting for ClusterIssuers to be available..." | ||
sleep 5 | ||
done | ||
while kubectl get clusterissuers -o json | jq -e '.items[] | select(.status.conditions[] | select(.type == "Ready" and .status != "True"))' > /dev/null; do | ||
sleep 1 | ||
done | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Collection of functions to add query status on a Kubernetes cluster | ||
|
||
####################################### | ||
# Wait for the Kubernetes cluster to be available (checking nodes and pods) | ||
# Arguments: | ||
# None | ||
# Examples: | ||
# k8s_wait_fornodesandpods | ||
####################################### | ||
k8s_wait_fornodesandpods() { | ||
# checks nodes are ready | ||
while ! kubectl get nodes --no-headers 2>/dev/null | grep -q .; do | ||
echo "Waiting for nodes to be available..." | ||
sleep 5 | ||
done | ||
while true; do | ||
NOT_READY_NODES=$(kubectl get nodes --no-headers 2>/dev/null | grep -v " Ready" | wc -l) | ||
if [ "$NOT_READY_NODES" -eq 0 ]; then | ||
echo "All nodes are ready." | ||
break | ||
else | ||
sleep 5 | ||
fi | ||
done | ||
|
||
# checks pods are completed or running | ||
while ! kubectl get pods --all-namespaces --no-headers 2>/dev/null | grep -q .; do | ||
echo "Waiting for pods to be available..." | ||
sleep 5 | ||
done | ||
while true; do | ||
NOT_READY_PODS=$(kubectl get pods --all-namespaces --field-selector=status.phase!=Running,status.phase!=Succeeded --no-headers 2>/dev/null | wc -l) | ||
if [ "$NOT_READY_PODS" -eq 0 ]; then | ||
echo "All pods are in Running or Completed status." | ||
break | ||
else | ||
sleep 5 | ||
fi | ||
done | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should also verify
jq
present as a lot of commands depend on it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks