From 9aef38abfc553df7d25cfb96760ec7034bd1f3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=A3rebe=20-=20Romain=20GERARD?= Date: Fri, 26 Apr 2024 13:14:48 +0200 Subject: [PATCH] feat(byok): Add demo up command --- cmd/demo.go | 79 +++++++++++++ cmd/demo_scripts/create_qovery_demo.sh | 152 +++++++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 cmd/demo.go create mode 100755 cmd/demo_scripts/create_qovery_demo.sh diff --git a/cmd/demo.go b/cmd/demo.go new file mode 100644 index 00000000..ef605f4d --- /dev/null +++ b/cmd/demo.go @@ -0,0 +1,79 @@ +package cmd + +import ( + _ "embed" + "github.com/qovery/qovery-cli/utils" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "os" + "os/exec" + "os/user" +) + +var demoCmd = &cobra.Command{ + Use: "demo [up|destroy]", + Short: "Create a demo kubernetes cluster with Qovery installed on your local machine", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + currentContext, err := utils.CurrentContext() + if err != nil { + log.Errorf("Cannot get current Qovery context %s", currentContext) + os.Exit(1) + } + organizationId := string(currentContext.OrganizationId) + if organizationId == "" { + log.Errorf("Qovery context is not set. Use `qovery context set` first") + os.Exit(1) + } + + _, token, err := utils.GetAccessToken() + if err != nil { + log.Errorf("Cannot get Bearer or Token to access Qovery API. Please use `qovery auth` first: %s", err) + utils.PrintlnError(err) + os.Exit(1) + } + + if args[0] == "up" { + err := os.WriteFile("create_demo_cluster.sh", demoScriptsCreate, 0700) + if err != nil { + log.Errorf("Cannot write file to disk: %s", err) + os.Exit(1) + } + + cmd := exec.Command("/bin/sh", "create_demo_cluster.sh", demoClusterName, organizationId, string(token)) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Errorf("Error executing the command %s", err) + } + os.Exit(0) + } + + if args[0] == "destroy" { + panic("Destroy is not yet implemented") + } + + log.Errorf("Unknown command %s. Only `up` and `destroy` are supported", args[0]) + }, +} +var ( + demoClusterName string +) + +//go:embed demo_scripts/create_qovery_demo.sh +var demoScriptsCreate []byte + +func init() { + var userName string + currentUser, err := user.Current() + if err != nil { + userName = "qovery" + } else { + userName = currentUser.Username + } + + var demoCmd = demoCmd + demoCmd.Flags().StringVarP(&demoClusterName, "cluster-name", "c", "local-demo-"+userName, "The name of the cluster to create") + + rootCmd.AddCommand(demoCmd) +} diff --git a/cmd/demo_scripts/create_qovery_demo.sh b/cmd/demo_scripts/create_qovery_demo.sh new file mode 100755 index 00000000..58a91eff --- /dev/null +++ b/cmd/demo_scripts/create_qovery_demo.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +set -euo pipefail + +CLUSTER_NAME=$1 +ORGANIZATION_ID=$2 +if [ "${3:0:4}" = "qov_" ] +then + AUTHORIZATION_HEADER="Authorization: Token $3" +else + AUTHORIZATION_HEADER="Authorization: Bearer $3" +fi + +function get_or_create_on_premise_account() { + accountId=$(curl -s --fail-with-body -H "${AUTHORIZATION_HEADER}" -H 'Content-Type: application/json' https://api.qovery.com/organization/${ORGANIZATION_ID}/onPremise/credentials | jq -r .results[0].id) + if [ "$accountId" == "null" ] + then + accountId=$(curl -s -X POST --fail-with-body -H "${AUTHORIZATION_HEADER}" -H 'Content-Type: application/json' -d '{"name": "on-premise"}' https://api.qovery.com/organization/${ORGANIZATION_ID}/onPremise/credentials | jq -r .id) + fi + + echo $accountId +} + +function get_or_create_demo_cluster() { + accountId=$1 + clusterName=$2 + clusterId=$(curl -s -X GET --fail-with-body -H "${AUTHORIZATION_HEADER}" -H 'Content-Type: application/json' https://api.qovery.com/organization/${ORGANIZATION_ID}/cluster | jq -r '.results[] | select(.name=="'$clusterName'") | .id') + + if [ "$clusterId" == "" ] + then + payload='{"name":"'$2'","region":"on-premise","cloud_provider":"ON_PREMISE","kubernetes":"SELF_MANAGED", "production": false,"features":[],"cloud_provider_credentials":{"cloud_provider":"ON_PREMISE","credentials":{"id":"'${accountId}'","name":"on-premise"},"region":"unknown"}}' + clusterId=$(curl -s -X POST --fail-with-body -H "${AUTHORIZATION_HEADER}" -H 'Content-Type: application/json' -d "${payload}" https://api.qovery.com/organization/${ORGANIZATION_ID}/cluster | jq -r .id) + fi + + echo $clusterId +} + +function get_cluster_values() { + clusterId=$1 + curl -s -X GET --fail-with-body -H "${AUTHORIZATION_HEADER}" -H 'Content-Type: application/x-yaml' https://api.qovery.com/organization/${ORGANIZATION_ID}/cluster/${clusterId}/installationHelmValues +} + +function get_or_create_cluster() { + clusterName=$1 + clusterExist=$(k3d cluster list -o json | jq '.[] | select(.name=="'$clusterName'") | .name') + if [ "$clusterExist" == "" ] + then + k3d cluster create --k3s-arg "--disable=traefik@server:*" $clusterName --registry-create qovery-registry.lan + else + k3d cluster start $clusterName + fi +} + +function install_or_upgrade_helm_charts() { + releaseExist=$(helm list -n qovery -o json | jq '.[] | select(.name=="qovery") | .name') + if [ "$releaseExist" == "" ] + then + set -x + helm upgrade --install --create-namespace -n qovery -f values.yaml --atomic \ + --set services.certificates.cert-manager-configs.enabled=false \ + --set services.certificates.qovery-cert-manager-webhook.enabled=false \ + --set services.qovery.qovery-cluster-agent.enabled=false \ + --set services.qovery.qovery-engine.enabled=false \ + qovery qovery/qovery + fi + + set -x + helm upgrade --install --create-namespace -n qovery -f values.yaml --wait --atomic qovery qovery/qovery + set +x +} + +function install_deps() { + if which jq >/dev/null; then + echo "jq already installed" + else + echo "jq command is missing. Please use your package manager to install it" + fi + + if which grep >/dev/null; then + echo "grep already installed" + else + echo "grep command is missing. Please use your package manager to install it" + fi + + if which curl >/dev/null; then + echo "curl already installed" + else + echo "curl command is missing. Please use your package manager to install it" + fi + + if which k3d >/dev/null; then + echo "k3d already installed" + else + echo "Installing k3d" + curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v5.6.3 bash + fi + + if which helm >/dev/null; then + echo "helm already installed" + else + echo "Installing HELM" + curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + fi + + echo "All dependencies are installed" +} + + +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo 'Checking and installing dependencies' +echo '""""""""""""""""""""""""""""""""""""""""""""' +install_deps + +accountId=$(get_or_create_on_premise_account) +clusterId=$(get_or_create_demo_cluster ${accountId} ${CLUSTER_NAME}) + +echo '' +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo 'Fetching Qovery values to setup your cluster' +echo '""""""""""""""""""""""""""""""""""""""""""""' +get_cluster_values ${clusterId} > values.yaml +echo "" >> values.yaml +curl -s -L https://raw.githubusercontent.com/Qovery/qovery-chart/main/charts/qovery/values-demo-local.yaml | grep -vE 'set-by-customer|^qovery:' >> values.yaml +echo 'Helm values written into values.yaml' + + +echo '' +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo 'Installing Qovery helm repositories' +echo '""""""""""""""""""""""""""""""""""""""""""""' +helm repo add qovery https://helm.qovery.com +helm repo update + +echo '' +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo "Creating $CLUSTER_NAME kube cluster" +echo '""""""""""""""""""""""""""""""""""""""""""""' +get_or_create_cluster $CLUSTER_NAME + +echo '' +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo 'Installing Qovery helm charts' +echo '""""""""""""""""""""""""""""""""""""""""""""' +install_or_upgrade_helm_charts + + +echo '' +echo '""""""""""""""""""""""""""""""""""""""""""""' +echo "Qovery demo cluster is now installed !!!!" +echo "The kubeconfig is correctly set, so you can connect to it directly with kubectl or k9s" +echo "To delete/stop/start your cluster, use k3d cluster xxxx" +echo '""""""""""""""""""""""""""""""""""""""""""""'