diff --git a/components/BUILD.yaml b/components/BUILD.yaml index b050a8a981a47f..689fcb1e5623f7 100644 --- a/components/BUILD.yaml +++ b/components/BUILD.yaml @@ -71,6 +71,7 @@ packages: - components/ws-proxy:docker - components/ide-proxy:docker - components/kots-config-check/database:docker + - components/kots-config-check/storage:docker - test:docker - dev/version-manifest:app config: diff --git a/components/kots-config-check/storage/BUILD.yaml b/components/kots-config-check/storage/BUILD.yaml new file mode 100644 index 00000000000000..092e70770d9e31 --- /dev/null +++ b/components/kots-config-check/storage/BUILD.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the GNU Affero General Public License (AGPL). +# See License-AGPL.txt in the project root for license information. + +packages: + - name: docker + type: docker + argdeps: + - imageRepoBase + srcs: + - entrypoint.sh + config: + dockerfile: leeway.Dockerfile + metadata: + helm-component: kots-config-check.storage + image: + - ${imageRepoBase}/kots-config-check/storage:${version} + - ${imageRepoBase}/kots-config-check/storage:commit-${__git_commit} diff --git a/components/kots-config-check/storage/entrypoint.sh b/components/kots-config-check/storage/entrypoint.sh new file mode 100755 index 00000000000000..80ab376b7a5346 --- /dev/null +++ b/components/kots-config-check/storage/entrypoint.sh @@ -0,0 +1,172 @@ +#!/bin/bash +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the GNU Affero General Public License (AGPL). +# See License-AGPL.txt in the project root for license information. + +set -euo pipefail + +STORE_PROVIDER="${1:-""}" +STORE_LOCATION="${2:-""}" +AZURE_ACCOUNT_NAME="${3:-""}" +AZURE_ACCESS_KEY="${4:-""}" +GCP_PROJECT_ID="${5:-""}" +GCP_SERVICE_ACCOUNT_KEY="${6:-""}" +S3_ENDPOINT="${7:-""}" +S3_ACCESS_KEY_ID="${8:-""}" +S3_SECRET_ACCESS_KEY="${9:-""}" +S3_BUCKET_NAME="${10:-""}" + +bucket_name="kots-check-${RANDOM}-${RANDOM}" +downloaded_file=/tmp/download +file_name="kots-check-file" +file_contents="$(date)" +uploaded_file=/tmp/upload + +echo "${file_contents}" > "${uploaded_file}" + +connection="false" + +function test_azure() { + echo "Using Azure storage" + + echo "Create a container" + az storage container create \ + --account-name "${AZURE_ACCOUNT_NAME}" \ + --account-key "${AZURE_ACCESS_KEY}" \ + --name "${bucket_name}" || return 1 + + echo "Upload a file" + az storage blob upload \ + --account-name "${AZURE_ACCOUNT_NAME}" \ + --account-key "${AZURE_ACCESS_KEY}" \ + --container-name "${bucket_name}" \ + --file "${uploaded_file}" \ + --name "${file_name}" || return 1 + + echo "Download the file" + az storage blob download \ + --account-name "${AZURE_ACCOUNT_NAME}" \ + --account-key "${AZURE_ACCESS_KEY}" \ + --container-name "${bucket_name}" \ + --file "${downloaded_file}" \ + --name "${file_name}" || return 1 + + echo "Compare the file" + diff "${downloaded_file}" "${uploaded_file}" || return 1 + + echo "Delete the container" + az storage container delete \ + --name "${bucket_name}" \ + --account-name "${AZURE_ACCOUNT_NAME}" \ + --account-key "${AZURE_ACCESS_KEY}" || return 1 +} + +function test_gcp() { + echo "Using GCP storage" + + echo "${GCP_SERVICE_ACCOUNT_KEY}" | base64 -d > /tmp/creds.json + + gcloud auth activate-service-account --project="${GCP_PROJECT_ID}" --key-file=/tmp/creds.json + + echo "Create bucket" + gsutil mb \ + -l "${STORE_LOCATION}" \ + "gs://${bucket_name}" || return 1 + + echo "Upload a file" + gsutil cp \ + "${uploaded_file}" \ + "gs://${bucket_name}/${file_name}" || return 1 + + echo "Download a file" + gsutil cp \ + "gs://${bucket_name}/${file_name}" \ + "${downloaded_file}" || return 1 + + echo "Compare the file" + diff "${downloaded_file}" "${uploaded_file}" || return 1 + + echo "Delete bucket" + gsutil rm -r \ + "gs://${bucket_name}" || return 1 +} + +function test_s3() { + echo "Using S3 storage" + + create_bucket="1" + s3_bucket_name="${bucket_name}" + if [ -n "${S3_BUCKET_NAME}" ]; then + echo "Specify bucket name" + create_bucket="0" + s3_bucket_name="${S3_BUCKET_NAME}" + fi + + echo "Bucket name: ${s3_bucket_name}" + + mc alias set s3 "https://${S3_ENDPOINT}" "${S3_ACCESS_KEY_ID}" "${S3_SECRET_ACCESS_KEY}" + + if [ "${create_bucket}" = "1" ]; then + echo "Create bucket" + mc mb \ + --region="${STORE_LOCATION}" \ + "s3/${s3_bucket_name}" || return 1 + fi + + echo "Upload a file" + mc cp \ + "${uploaded_file}" \ + "s3/${s3_bucket_name}/${file_name}" || return 1 + + echo "Download a file" + mc cp \ + "s3/${s3_bucket_name}/${file_name}" \ + "${downloaded_file}" || return 1 + + echo "Compare the file" + diff "${downloaded_file}" "${uploaded_file}" || return 1 + + if [ "${create_bucket}" = "1" ]; then + echo "Delete bucket" + mc rb \ + --force \ + "s3/${s3_bucket_name}" || return 1 + else + echo "Delete file" + mc rm \ + --force \ + "s3/${s3_bucket_name}/${file_name}" || return 1 + fi +} + +case "${STORE_PROVIDER}" in + azure) + if test_azure; then + connection="true" + fi + ;; + gcp) + if test_gcp; then + connection="true" + fi + ;; + incluster) + echo "Using in-cluster storage" + connection="true" + ;; + s3) + if test_s3; then + connection="true" + fi + ;; + *) + echo "Unknown storage type: '${STORE_PROVIDER}'" + exit 1 + ;; +esac + +if [ "${connection}" = "true" ]; then + echo "connection: ok" +else + echo "connection: error" +fi diff --git a/components/kots-config-check/storage/leeway.Dockerfile b/components/kots-config-check/storage/leeway.Dockerfile new file mode 100644 index 00000000000000..27381a9573f434 --- /dev/null +++ b/components/kots-config-check/storage/leeway.Dockerfile @@ -0,0 +1,13 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the GNU Affero General Public License (AGPL). +# See License-AGPL.txt in the project root for license information. + +FROM mcr.microsoft.com/azure-cli +RUN apk add --no-cache bash curl python3 +# GSUtil +RUN curl -sSL https://sdk.cloud.google.com | bash +ENV PATH $PATH:/root/google-cloud-sdk/bin +# Minio client +COPY --from=minio/mc /usr/bin/mc /usr/local/bin/mc +COPY entrypoint.sh /entrypoint.sh +ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/install/kots/manifests/kots-preflight.yaml b/install/kots/manifests/kots-preflight.yaml index b5a135ca1c2dda..1d2c8d7a1dcf20 100644 --- a/install/kots/manifests/kots-preflight.yaml +++ b/install/kots/manifests/kots-preflight.yaml @@ -29,6 +29,21 @@ spec: - -c args: - semver --coerce --range '>=5.4.0' $(uname -r) || echo invalid + - run: + collectorName: storage + image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/storage:sje-kots-storage-check.9 + name: storage + args: + - '{{repl ConfigOption "store_provider" }}' # STORE_PROVIDER + - '{{repl ConfigOption "store_region" }}' # STORE_LOCATION + - '{{repl ConfigOption "store_azure_account_name" }}' # AZURE_ACCOUNT_NAME + - '{{repl ConfigOption "store_azure_access_key" }}' # AZURE_ACCESS_KEY + - '{{repl ConfigOption "store_gcp_project" }}' # GCP_PROJECT_ID + - '{{repl ConfigOption "store_gcp_credentials" }}' # GCP_SERVICE_ACCOUNT_KEY + - '{{repl ConfigOption "store_s3_endpoint" }}' # S3_ENDPOINT + - '{{repl ConfigOption "store_s3_access_key_id" }}' # S3_ACCESS_KEY_ID + - '{{repl ConfigOption "store_s3_secret_access_key" }}' # S3_SECRET_ACCESS_KEY + - '{{repl ConfigOption "store_s3_bucket" }}' # S3_BUCKET_NAME analyzers: - clusterVersion: outcomes: @@ -184,3 +199,13 @@ spec: message: Database version is valid - warn: message: Database version could not be verified. This should be MySQL 5.7 + - textAnalyze: + checkName: Object storage connection is valid + fileName: storage/storage.log + regexGroups: 'connection: (?P\w+)' + outcomes: + - pass: + when: "Connection == ok" + message: Object storage connection is valid + - fail: + message: Object storage connection is invalid. Please check your settings and that the resource is accessible from your cluster diff --git a/install/kots/manifests/kots-support-bundle.yaml b/install/kots/manifests/kots-support-bundle.yaml index 2771cf3c4d1c14..d3e6bec9050912 100644 --- a/install/kots/manifests/kots-support-bundle.yaml +++ b/install/kots/manifests/kots-support-bundle.yaml @@ -20,6 +20,21 @@ spec: - '{{repl ConfigOption "db_port" }}' # DB_PORT - '{{repl ConfigOption "db_cloudsql_instance" }}' # CloudSQL instances - '{{repl ConfigOption "db_gcp_credentials" }}' # CloudSQL credentials file + - run: + collectorName: storage + image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/storage:sje-kots-storage-check.9 + name: storage + args: + - '{{repl ConfigOption "store_provider" }}' # STORE_PROVIDER + - '{{repl ConfigOption "store_region" }}' # STORE_LOCATION + - '{{repl ConfigOption "store_azure_account_name" }}' # AZURE_ACCOUNT_NAME + - '{{repl ConfigOption "store_azure_access_key" }}' # AZURE_ACCESS_KEY + - '{{repl ConfigOption "store_gcp_project" }}' # GCP_PROJECT_ID + - '{{repl ConfigOption "store_gcp_credentials" }}' # GCP_SERVICE_ACCOUNT_KEY + - '{{repl ConfigOption "store_s3_endpoint" }}' # S3_ENDPOINT + - '{{repl ConfigOption "store_s3_access_key_id" }}' # S3_ACCESS_KEY_ID + - '{{repl ConfigOption "store_s3_secret_access_key" }}' # S3_SECRET_ACCESS_KEY + - '{{repl ConfigOption "store_s3_bucket" }}' # S3_BUCKET_NAME - clusterInfo: {} - clusterResources: {} - logs: