From b59f37e0b52cf5a55228a0bcc5525aa2ee523756 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 13:00:32 +0100 Subject: [PATCH 01/17] Intrim commit --- plugins/builder/Dockerfile | 9 + plugins/builder/scripts/build-script.sh | 235 ++++++++++++ plugins/builder/scripts/cloudness-utils.sh | 66 ++++ plugins/builder/scripts/deploy-script.sh | 426 +++++++++++++++++++++ plugins/builder/scripts/init-script.sh | 104 +++++ 5 files changed, 840 insertions(+) create mode 100644 plugins/builder/scripts/build-script.sh create mode 100644 plugins/builder/scripts/cloudness-utils.sh create mode 100644 plugins/builder/scripts/deploy-script.sh create mode 100644 plugins/builder/scripts/init-script.sh diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index db238dd..78f3e45 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -24,6 +24,15 @@ RUN curl -sSL https://nixpacks.com/install.sh | bash COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl RUN chmod +x /usr/local/bin/kubectl +# Add shared utilities and scripts +COPY scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh +COPY scripts/init-script.sh /usr/local/lib/init-script.sh +COPY scripts/build-script.sh /usr/local/lib/build-script.sh +COPY scripts/deploy-script.sh /usr/local/lib/deploy-script.sh +RUN chmod +x /usr/local/lib/cloudness-utils.sh /usr/local/lib/init-script.sh /usr/local/lib/build-script.sh /usr/local/lib/deploy-script.sh + +# Auto-source utilities for all sh scripts +ENV ENV="/usr/local/lib/cloudness-utils.sh" ENV PATH="/usr/local/bin:${PATH}" USER user ENTRYPOINT ["/sbin/tini", "--"] \ No newline at end of file diff --git a/plugins/builder/scripts/build-script.sh b/plugins/builder/scripts/build-script.sh new file mode 100644 index 0000000..50bc923 --- /dev/null +++ b/plugins/builder/scripts/build-script.sh @@ -0,0 +1,235 @@ +#!/bin/sh + +# Cloudness Build Script +# This script handles container image building using Dockerfile or Nixpacks + +set -eu + +# ============================================================================== +# Configuration +# ============================================================================== + +# Build type: "dockerfile" or "nixpacks" +: "${CLOUDNESS_BUILD_TYPE:=}" + +# Source paths +: "${CLOUDNESS_BUILD_SOURCE_PATH:=}" +: "${CLOUDNESS_BUILD_DOCKERFILE:=Dockerfile}" + +# Image configuration +: "${CLOUDNESS_BUILD_IMAGE:=}" +: "${CLOUDNESS_BUILD_CACHE_IMAGE:=}" + +# Registry configuration +: "${CLOUDNESS_IMAGE_REGISTRY:=}" +: "${CLOUDNESS_IMAGE_MIRROR_REGISTRY:=}" +: "${CLOUDNESS_MIRROR_ENABLED:=false}" + +# Nixpacks specific +: "${CLOUDNESS_BUILD_CMD:=}" +: "${CLOUDNESS_START_CMD:=}" + +# Build args (JSON or space-separated key=value pairs) +: "${CLOUDNESS_BUILD_ARGS:=}" + +# ============================================================================== +# Validation +# ============================================================================== + +validate_inputs() { + has_errors=0 + + if [ -z "$CLOUDNESS_BUILD_TYPE" ]; then + log_error "CLOUDNESS_BUILD_TYPE is required (dockerfile or nixpacks)" + has_errors=1 + elif [ "$CLOUDNESS_BUILD_TYPE" != "dockerfile" ] && [ "$CLOUDNESS_BUILD_TYPE" != "nixpacks" ]; then + log_error "CLOUDNESS_BUILD_TYPE must be 'dockerfile' or 'nixpacks'" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_BUILD_SOURCE_PATH" ]; then + log_error "CLOUDNESS_BUILD_SOURCE_PATH is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_BUILD_IMAGE" ]; then + log_error "CLOUDNESS_BUILD_IMAGE is required" + has_errors=1 + fi + + if [ "$has_errors" -eq 1 ]; then + return 1 + fi + + return 0 +} + +# ============================================================================== +# BuildKit Configuration +# ============================================================================== + +setup_buildkit_config() { + + BUILDKITD_CONFIG_PATH="$HOME/.config/buildkit/buildkitd.toml" + mkdir -p "$(dirname "$BUILDKITD_CONFIG_PATH")" + > "$BUILDKITD_CONFIG_PATH" + + # Main registry configuration + MAIN_REGISTRY=$(echo "$CLOUDNESS_IMAGE_REGISTRY" | cut -d'/' -f1) + + cat >> "$BUILDKITD_CONFIG_PATH" << EOF +[registry."$MAIN_REGISTRY"] + http = true + insecure = true +EOF + + # Mirror registry configuration + if [ "$CLOUDNESS_MIRROR_ENABLED" = "true" ] && [ -n "$CLOUDNESS_IMAGE_MIRROR_REGISTRY" ]; then + MIRROR_REGISTRY=$(echo "$CLOUDNESS_IMAGE_MIRROR_REGISTRY" | cut -d'/' -f1) + log_info "Configuring mirror registry: $MIRROR_REGISTRY" + + cat >> "$BUILDKITD_CONFIG_PATH" << EOF + +[registry."$MIRROR_REGISTRY"] + http = true + insecure = true + +[registry."docker.io"] + mirrors = ["$CLOUDNESS_IMAGE_MIRROR_REGISTRY"] +EOF + fi + + printf "\n" + log_step "BuildKit configured" +} + +# ============================================================================== +# Build Functions +# ============================================================================== + +build_with_dockerfile() { + print_section "Building with Dockerfile" + + log_info "Dockerfile: $CLOUDNESS_BUILD_DOCKERFILE" + + # Build base command + build_cmd="buildctl-daemonless.sh build \ + --frontend=dockerfile.v0 \ + --local context=$CLOUDNESS_BUILD_SOURCE_PATH \ + --local dockerfile=$CLOUDNESS_BUILD_SOURCE_PATH \ + --opt filename=$CLOUDNESS_BUILD_DOCKERFILE \ + --output type=image,name=$CLOUDNESS_BUILD_IMAGE,push=true" + + # Add cache configuration + if [ -n "$CLOUDNESS_BUILD_CACHE_IMAGE" ]; then + build_cmd="$build_cmd \ + --export-cache type=registry,ref=$CLOUDNESS_BUILD_CACHE_IMAGE,mode=max \ + --import-cache type=registry,ref=$CLOUDNESS_BUILD_CACHE_IMAGE,mode=max" + fi + + # Add build args + if [ -n "$CLOUDNESS_BUILD_ARGS" ]; then + for arg in $CLOUDNESS_BUILD_ARGS; do + build_cmd="$build_cmd --opt build-arg:$arg" + done + fi + + # Execute build + log_info "Starting build..." + if ! eval "$build_cmd"; then + log_error "Dockerfile build failed" + return 1 + fi + + log_step "Image built and pushed successfully" + return 0 +} + +build_with_nixpacks() { + print_section "Building with Nixpacks" + + # Build nixpacks command + nixpacks_cmd="nixpacks build $CLOUDNESS_BUILD_SOURCE_PATH -o $CLOUDNESS_BUILD_SOURCE_PATH" + nixpacks_cmd="$nixpacks_cmd --name $CLOUDNESS_BUILD_IMAGE" + + if [ -n "$CLOUDNESS_BUILD_CMD" ]; then + log_info "Build command: $CLOUDNESS_BUILD_CMD" + nixpacks_cmd="$nixpacks_cmd --build-cmd \"$CLOUDNESS_BUILD_CMD\"" + fi + + if [ -n "$CLOUDNESS_START_CMD" ]; then + log_info "Start command: $CLOUDNESS_START_CMD" + nixpacks_cmd="$nixpacks_cmd --start-cmd \"$CLOUDNESS_START_CMD\"" + fi + + # Add environment variables from build args + if [ -n "$CLOUDNESS_BUILD_ARGS" ]; then + for arg in $CLOUDNESS_BUILD_ARGS; do + key=$(echo "$arg" | cut -d'=' -f1) + value=$(echo "$arg" | cut -d'=' -f2-) + nixpacks_cmd="$nixpacks_cmd --env $key=\"$value\"" + done + fi + + nixpacks_cmd="$nixpacks_cmd" + + # Generate Dockerfile with Nixpacks + log_info "Generating Dockerfile with Nixpacks..." + if ! eval "$nixpacks_cmd"; then + log_error "Nixpacks generation failed" + return 1 + fi + + # Build and push with BuildKit + build_cmd="buildctl-daemonless.sh build \ + --frontend=dockerfile.v0 \ + --local context=$CLOUDNESS_BUILD_SOURCE_PATH \ + --local dockerfile=$CLOUDNESS_BUILD_SOURCE_PATH \ + --opt filename=/.nixpacks/Dockerfile \ + --output type=image,name=$CLOUDNESS_BUILD_IMAGE,push=true" + + # Add cache configuration + if [ -n "$CLOUDNESS_BUILD_CACHE_IMAGE" ]; then + build_cmd="$build_cmd \ + --export-cache type=registry,ref=$CLOUDNESS_BUILD_CACHE_IMAGE \ + --import-cache type=registry,ref=$CLOUDNESS_BUILD_CACHE_IMAGE,mode=max" + fi + + log_info "Building and pushing image..." + if ! eval "$build_cmd"; then + log_error "Image build/push failed" + return 1 + fi + + log_step "Image built and pushed successfully" + return 0 +} + +# ============================================================================== +# Main +# ============================================================================== + +main() { + if ! validate_inputs; then + exit 1 + fi + + setup_buildkit_config + + case "$CLOUDNESS_BUILD_TYPE" in + dockerfile) + if ! build_with_dockerfile; then + exit 1 + fi + ;; + nixpacks) + if ! build_with_nixpacks; then + exit 1 + fi + ;; + esac + + log_success "Build completed successfully!" +} + +main "$@" diff --git a/plugins/builder/scripts/cloudness-utils.sh b/plugins/builder/scripts/cloudness-utils.sh new file mode 100644 index 0000000..8b07bd0 --- /dev/null +++ b/plugins/builder/scripts/cloudness-utils.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# Cloudness Shared Utilities +# Source this file in scripts: . /usr/local/lib/cloudness-utils.sh + +# ============================================================================== +# Colors +# ============================================================================== +readonly CLOUDNESS_RED='\033[1;31m' +readonly CLOUDNESS_GREEN='\033[1;32m' +readonly CLOUDNESS_YELLOW='\033[1;33m' +readonly CLOUDNESS_BLUE='\033[0;34m' +readonly CLOUDNESS_NC='\033[0m' + +# ============================================================================== +# Logging Functions +# ============================================================================== + +log_error() { + printf "${CLOUDNESS_RED}[ERROR]${CLOUDNESS_NC} %s\n" "$*" >&2 +} + +log_warn() { + printf "${CLOUDNESS_YELLOW}[WARN]${CLOUDNESS_NC} %s\n" "$*" +} + +log_info() { + printf "%s\n" "$*" +} + +log_success() { + printf "${CLOUDNESS_GREEN}[SUCCESS]${CLOUDNESS_NC} %s\n" "$*" +} + +log_step() { + printf "%s ${CLOUDNESS_GREEN}✔${CLOUDNESS_NC}\n" "$*" +} + +log_debug() { + if [ "${VERBOSE:-false}" = "true" ]; then + printf "${CLOUDNESS_BLUE}[DEBUG]${CLOUDNESS_NC} %s\n" "$*" + fi +} + +print_section() { + printf "\n" + printf "${CLOUDNESS_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CLOUDNESS_NC}\n" + printf "${CLOUDNESS_BLUE} %s${CLOUDNESS_NC}\n" "$1" + printf "${CLOUDNESS_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CLOUDNESS_NC}\n" +} + +# ============================================================================== +# Helper Functions +# ============================================================================== + +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Run command with optional verbose output +run_command() { + if [ "${VERBOSE:-false}" = "true" ]; then + "$@" + else + "$@" > /dev/null 2>&1 + fi +} diff --git a/plugins/builder/scripts/deploy-script.sh b/plugins/builder/scripts/deploy-script.sh new file mode 100644 index 0000000..94aeeec --- /dev/null +++ b/plugins/builder/scripts/deploy-script.sh @@ -0,0 +1,426 @@ +#!/bin/sh + +# Cloudness Kubernetes Deployment Script +# This script deploys applications to Kubernetes with proper resource management + +set -eu + +# ============================================================================== +# Configuration & Constants +# ============================================================================== + +# Timeout configurations (can be overridden via environment) +readonly ROLLOUT_TIMEOUT_STATELESS="${ROLLOUT_TIMEOUT_STATELESS:-60s}" +readonly ROLLOUT_TIMEOUT_STATEFUL="${ROLLOUT_TIMEOUT_STATEFUL:-120s}" +readonly PVC_RESIZE_TIMEOUT="${PVC_RESIZE_TIMEOUT:-300}" +readonly PVC_RESIZE_POLL_INTERVAL="${PVC_RESIZE_POLL_INTERVAL:-5}" + +# Required environment variables with defaults +: "${CLOUDNESS_DEPLOY_APP_IDENTIFIER:=}" +: "${CLOUDNESS_DEPLOY_APP_NAMESPACE:=}" +: "${CLOUDNESS_DEPLOY_FLAG_APP_TYPE:=}" +: "${CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME:=0}" +: "${CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT:=0}" +: "${CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE:=0}" +: "${CLOUDNESS_DEPLOY_YAML_COMMON:=}" +: "${CLOUDNESS_DEPLOY_YAML_VOLUME:=}" +: "${CLOUDNESS_DEPLOY_YAML_APP:=}" +: "${CLOUDNESS_DEPLOY_YAML_ROUTE:=}" +: "${VERBOSE:=false}" + +# Track cleanup state +CLEANUP_DONE=false + +# ============================================================================== +# Validation Functions +# ============================================================================== + +validate_dependencies() { + missing="" + + if ! command_exists kubectl; then + missing="$missing kubectl" + fi + + if ! command_exists yq; then + missing="$missing yq" + fi + + if [ -n "$missing" ]; then + log_error "Missing required dependencies:$missing" + log_error "Please install them before running this script." + return 1 + fi + + return 0 +} + +validate_environment() { + has_errors=0 + + if [ -z "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" ]; then + log_error " - CLOUDNESS_DEPLOY_APP_IDENTIFIER is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_DEPLOY_APP_NAMESPACE" ]; then + log_error " - CLOUDNESS_DEPLOY_APP_NAMESPACE is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" ]; then + log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE is required" + has_errors=1 + elif [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateless" ] && [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateful" ]; then + log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE must be 'Stateless' or 'Stateful'" + has_errors=1 + fi + + if [ "$has_errors" -eq 1 ]; then + log_error "Environment validation failed" + return 1 + fi + + return 0 +} + +# ============================================================================== +# Kubernetes Operations +# ============================================================================== + +# Returns the resource type based on app type +get_resource_type() { + if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then + echo "deployment" + else + echo "statefulset" + fi +} + +# Returns the opposite resource type (for cleanup) +get_opposite_resource_type() { + if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then + echo "statefulset" + else + echo "deployment" + fi +} + +# Apply Kubernetes configuration from YAML string +kube_apply() { + yaml_string="$1" + error_output="" + + # Skip if empty + if [ -z "$yaml_string" ]; then + return 0 + fi + + # Apply the YAML + if [ "$VERBOSE" = "true" ]; then + if ! printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f -; then + log_error "Failed to apply Kubernetes configuration" + return 1 + fi + else + if ! error_output=$(printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f - 2>&1 >/dev/null); then + log_error "Failed to apply Kubernetes configuration:" + log_error "$error_output" + return 1 + fi + fi + + return 0 +} + +# Delete a Kubernetes resource +kube_delete() { + resource_type="$1" + resource_name="$2" + namespace="$3" + error_output="" + + if [ "$VERBOSE" = "true" ]; then + if ! kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true; then + log_warn "Failed to delete $resource_type/$resource_name" + return 1 + fi + else + if ! error_output=$(kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true 2>&1 >/dev/null); then + log_warn "Failed to delete $resource_type/$resource_name: $error_output" + return 1 + fi + fi + + return 0 +} + +# Wait for rollout to complete +kube_rollout_status() { + resource_type="" + timeout="" + error_output="" + + resource_type=$(get_resource_type) + + if [ "$resource_type" = "deployment" ]; then + timeout="$ROLLOUT_TIMEOUT_STATELESS" + else + timeout="$ROLLOUT_TIMEOUT_STATEFUL" + fi + + if [ "$VERBOSE" = "true" ]; then + if ! kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ + --timeout="$timeout"; then + log_error "Rollout failed, reverting..." + kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true + return 1 + fi + else + if ! error_output=$(kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ + --timeout="$timeout" 2>&1); then + log_error "$error_output" + log_error "Rollout failed, reverting..." + kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" 2>/dev/null || true + return 1 + fi + fi + + return 0 +} + +# Parse storage size to numeric GiB value +parse_size_to_gib() { + size_str="$1" + echo "$size_str" | sed 's/Gi//' +} + +# Wait for PVC to resize +kube_wait_pvc_resize() { + pvc_name="$1" + new_size="$2" + namespace="$CLOUDNESS_DEPLOY_APP_NAMESPACE" + deadline="" + current_time="" + + current_time=$(date +%s) + deadline=$((current_time + PVC_RESIZE_TIMEOUT)) + + while true; do + # Check PVC status + pvc_status="" + pvc_status=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.phase}' 2>/dev/null || echo "") + + if [ "$VERBOSE" = "true" ]; then + log_info "PVC '$pvc_name' status: $pvc_status" + fi + + # Handle WaitForFirstConsumer + if [ "$pvc_status" = "Pending" ]; then + pvc_event="" + pvc_event=$(kubectl get events -n "$namespace" \ + --field-selector "involvedObject.kind=PersistentVolumeClaim,involvedObject.name=$pvc_name" \ + --sort-by=.lastTimestamp \ + -o jsonpath='{.items[-1:].reason}' 2>/dev/null || echo "") + if [ "$pvc_event" = "WaitForFirstConsumer" ]; then + return 0 + fi + fi + + # Check if resize completed + current_size="" + current_size=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.capacity.storage}' 2>/dev/null || echo "0Gi") + + if [ "$VERBOSE" = "true" ]; then + log_info "PVC '$pvc_name' current size: $current_size, target: $new_size" + fi + if [ "$(parse_size_to_gib "$current_size")" -ge "$(parse_size_to_gib "$new_size")" ]; then + return 0 + fi + + # Check for FileSystemResizePending condition + resize_pending="" + resize_pending=$(kubectl get pvc "$pvc_name" -n "$namespace" \ + -o jsonpath='{.status.conditions[?(@.type=="FileSystemResizePending")].status}' 2>/dev/null || echo "") + if [ "$resize_pending" = "True" ]; then + log_info "Volume resized. Remounting application to finalize." + return 0 + fi + + # Check timeout + current_time=$(date +%s) + if [ "$current_time" -ge "$deadline" ]; then + log_error "Timed out after ${PVC_RESIZE_TIMEOUT}s waiting for PVC '$pvc_name' to reach $new_size" + return 1 + fi + + log_info "Waiting for volume '$pvc_name'..." + sleep "$PVC_RESIZE_POLL_INTERVAL" + done +} + +# ============================================================================== +# Deployment Functions +# ============================================================================== + +deploy_common_artifacts() { + print_section "Setting up prerequisite artifacts" + + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_COMMON"; then + log_error "Failed to set up prerequisite artifacts" + return 1 + fi + + log_step "Prerequisite artifacts configured" + return 0 +} + +deploy_volume() { + if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME" -ne 1 ]; then + return 0 + fi + + print_section "Provisioning volumes" + + # Handle remount for volume resize + if [ "$CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT" -eq 1 ]; then + log_info "Volume resize detected, removing statefulset for remount..." + if ! kube_delete "statefulset" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE"; then + log_error "Failed to remove statefulset for remount" + return 1 + fi + fi + + # Apply volume configuration + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_VOLUME"; then + log_error "Failed to apply volume configuration" + return 1 + fi + + # Wait for each PVC to be ready + pvc_data="" + pvc_data=$(printf '%s' "$CLOUDNESS_DEPLOY_YAML_VOLUME" | sed 's/\t/ /g' | \ + yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' - 2>/dev/null || echo "") + + echo "$pvc_data" | while read -r pvc_name new_size; do + # Skip empty lines + pvc_name=$(echo "$pvc_name" | xargs) + new_size=$(echo "$new_size" | xargs) + if [ -z "$pvc_name" ] || [ -z "$new_size" ] || [ "$pvc_name" = "---" ]; then + continue + fi + + if ! kube_wait_pvc_resize "$pvc_name" "$new_size"; then + log_error "Failed to provision PVC '$pvc_name'" + return 1 + fi + done + + log_step "Volumes provisioned" + return 0 +} + +deploy_application() { + print_section "Deploying application" + + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_APP"; then + log_error "Failed to deploy application" + return 1 + fi + + if ! kube_rollout_status; then + return 1 + fi + + log_step "Application deployed" + return 0 +} + +deploy_routes() { + if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE" -ne 1 ]; then + return 0 + fi + + print_section "Configuring HTTP routes" + + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_ROUTE"; then + log_error "Failed to configure HTTP routes" + return 1 + fi + + log_step "HTTP routes configured" + return 0 +} + +# ============================================================================== +# Lifecycle Management +# ============================================================================== + +cleanup() { + if [ "$CLEANUP_DONE" = "true" ]; then + return 0 + fi + CLEANUP_DONE=true + + log_info "Running cleanup..." + + opposite_type="" + opposite_type=$(get_opposite_resource_type) + + kube_delete "$opposite_type" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true +} + +on_exit() { + exit_code=$? + if [ $exit_code -ne 0 ]; then + log_error "Deployment failed with exit code $exit_code" + fi + cleanup + exit $exit_code +} + +# ============================================================================== +# Main Entrypoint +# ============================================================================== + +main() { + # Set up exit trap + trap on_exit EXIT + + # Validate prerequisites + if ! validate_dependencies; then + exit 1 + fi + + if ! validate_environment; then + exit 1 + fi + + # Execute deployment steps + if ! deploy_common_artifacts; then + exit 1 + fi + + if ! deploy_volume; then + exit 1 + fi + + if ! deploy_application; then + exit 1 + fi + + if ! deploy_routes; then + exit 1 + fi + + # Success + echo "" + log_success "Deployment completed successfully!" +} + +# Run main function +main "$@" diff --git a/plugins/builder/scripts/init-script.sh b/plugins/builder/scripts/init-script.sh new file mode 100644 index 0000000..6e16051 --- /dev/null +++ b/plugins/builder/scripts/init-script.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# Cloudness Git Clone Script +# This script handles git repository cloning for the build process + +set -eu + +# ============================================================================== +# Configuration +# ============================================================================== + +: "${CLOUDNESS_GIT_REPO_URL:=}" +: "${CLOUDNESS_GIT_BRANCH:=}" +: "${CLOUDNESS_GIT_COMMIT:=}" +: "${CLOUDNESS_BUILD_PATH:=}" + +# Optional netrc credentials +: "${GIT_MACHINE:=}" +: "${GIT_LOGIN:=}" +: "${GIT_PASSWORD:=}" + +# ============================================================================== +# Validation +# ============================================================================== + +validate_inputs() { + has_errors=0 + + if [ -z "$CLOUDNESS_GIT_REPO_URL" ]; then + log_error "CLOUDNESS_GIT_REPO_URL is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_GIT_BRANCH" ]; then + log_error "CLOUDNESS_GIT_BRANCH is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_BUILD_PATH" ]; then + log_error "CLOUDNESS_BUILD_PATH is required" + has_errors=1 + fi + + if [ "$has_errors" -eq 1 ]; then + return 1 + fi + + return 0 +} + +# ============================================================================== +# Git Operations +# ============================================================================== + +setup_netrc() { + if [ -n "$GIT_MACHINE" ] && [ -n "$GIT_LOGIN" ] && [ -n "$GIT_PASSWORD" ]; then + log_info "Configuring git credentials..." + echo "machine $GIT_MACHINE login $GIT_LOGIN password $GIT_PASSWORD" > ~/.netrc + chmod 600 ~/.netrc + fi +} + +clone_repository() { + print_section "Cloning Repository" + + log_info "Repository: $CLOUDNESS_GIT_REPO_URL" + log_info "Branch: $CLOUDNESS_GIT_BRANCH" + + if ! git clone "$CLOUDNESS_GIT_REPO_URL" --branch "$CLOUDNESS_GIT_BRANCH" "$CLOUDNESS_BUILD_PATH"; then + log_error "Failed to clone repository" + return 1 + fi + + # Checkout specific commit if provided + if [ -n "$CLOUDNESS_GIT_COMMIT" ]; then + log_info "Checking out commit: $CLOUDNESS_GIT_COMMIT" + git -C "$CLOUDNESS_BUILD_PATH" config advice.detachedHead false + if ! git -C "$CLOUDNESS_BUILD_PATH" checkout "$CLOUDNESS_GIT_COMMIT"; then + log_error "Failed to checkout commit $CLOUDNESS_GIT_COMMIT" + return 1 + fi + fi + + log_step "Repository cloned successfully" + return 0 +} + +# ============================================================================== +# Main +# ============================================================================== + +main() { + if ! validate_inputs; then + exit 1 + fi + + setup_netrc + + if ! clone_repository; then + exit 1 + fi +} + +main "$@" From 6ee3f57dd054bf2b16c778aacd0e4151ba588261 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 13:03:51 +0100 Subject: [PATCH 02/17] Intrim commit --- app/pipeline/convert/build_step.go | 144 +--- app/pipeline/convert/const.go | 5 +- app/pipeline/convert/convert.go | 3 +- app/pipeline/convert/deploy_step.go | 23 +- app/pipeline/convert/init_step.go | 24 +- app/pipeline/convert/secret.go | 23 - .../convert/templates/static/kube-script.sh | 670 ++++++++++++------ app/pipeline/convert/utils.go | 29 + .../runner/engine/kubernetes/kubernetes.go | 11 + .../runner/engine/kubernetes/tokube.go | 28 + app/pipeline/types.go | 11 + runbooks/dev/loacalbuilder.md | 11 + 12 files changed, 610 insertions(+), 372 deletions(-) delete mode 100644 app/pipeline/convert/secret.go create mode 100644 runbooks/dev/loacalbuilder.md diff --git a/app/pipeline/convert/build_step.go b/app/pipeline/convert/build_step.go index 54eb5f0..7063d1b 100644 --- a/app/pipeline/convert/build_step.go +++ b/app/pipeline/convert/build_step.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/cloudness-io/cloudness/app/pipeline" - "github.com/cloudness-io/cloudness/app/services/config" specSvc "github.com/cloudness-io/cloudness/app/services/spec" "github.com/cloudness-io/cloudness/types" "github.com/cloudness-io/cloudness/types/enum" @@ -22,136 +21,53 @@ func buildCommandNew( return nil } - switch specSvc.GetBuilder(spec) { - case enum.BuilderTypeDockerfile: - updateDockerFileBuildStep(in, pCtx, spec, step, buildVars) - case enum.BuilderTypeNixpacks: - updateNixpacksBuildStep(in, pCtx, spec, step, buildVars) - } - - addImageSecrets(in, pCtx, step) - addSecrets(pCtx, step, buildVars) - - return nil -} - -func updateDockerFileBuildStep( - in *pipeline.RunnerContextInput, - pCtx *pipeline.RunnerContext, - spec *types.ApplicationSpec, - step *pipeline.Step, - buildVars map[string]string, -) { - var cmd strings.Builder gitSource := spec.Build.Source.Git sourcePath := wsBuildVolumePath if gitSource.BasePath != "" && gitSource.BasePath != "/" { sourcePath = wsBuildVolumePath + gitSource.BasePath } - image, _, cacheImage := specSvc.GetImage(in.Application, in.Deployment, in.Config) - addBuildKitConfig(&cmd, in.Config) + image, _, cacheImage := specSvc.GetImage(in.Application, in.Deployment, in.Config) - // Construct the buildctl-daemonless.sh command - cmd.WriteString(fmt.Sprintf(`buildctl-daemonless.sh build \ - --frontend=dockerfile.v0 \ - --local context=%[1]s \ - --local dockerfile=%[1]s \ - --opt filename=%[2]s \ - --output type=image,name=%[3]s,push=true `, sourcePath, gitSource.Dockerfile, image)) + // Set common build environment variables + addSecret(pCtx, step, "CLOUDNESS_BUILD_SOURCE_PATH", sourcePath) + addSecret(pCtx, step, "CLOUDNESS_BUILD_IMAGE", image) + addSecret(pCtx, step, "CLOUDNESS_BUILD_CACHE_IMAGE", cacheImage) + addSecret(pCtx, step, "CLOUDNESS_IMAGE_REGISTRY", in.Config.PushRegistryURL) + addSecret(pCtx, step, "CLOUDNESS_IMAGE_MIRROR_REGISTRY", in.Config.MirrorRegistryURL) - if cacheImage != "" { - cmd.WriteString(fmt.Sprintf(`--export-cache type=registry,ref=%s,mode=max `, cacheImage)) - cmd.WriteString(fmt.Sprintf(`--import-cache type=registry,ref=%s,mode=max `, cacheImage)) + if in.Config.MirrorRegistryEnabled && in.Config.MirrorRegistryURL != "" { + addVariable(pCtx, step, "CLOUDNESS_MIRROR_ENABLED", "true") } - // Add BuildArgs + // Set build args as space-separated key=value pairs if len(buildVars) > 0 { + var args []string for k, v := range buildVars { - cmd.WriteString(fmt.Sprintf(`--opt build-arg:%s=%s `, k, v)) // + args = append(args, fmt.Sprintf("%s=%s", k, v)) } + addSecret(pCtx, step, "CLOUDNESS_BUILD_ARGS", strings.Join(args, " ")) } - step.AddScriptCmd(cmd.String()) -} - -func updateNixpacksBuildStep( - in *pipeline.RunnerContextInput, - pCtx *pipeline.RunnerContext, - spec *types.ApplicationSpec, - step *pipeline.Step, - buildVars map[string]string, -) { - gitSource := spec.Build.Source.Git - sourcePath := wsBuildVolumePath - if gitSource.BasePath != "" && gitSource.BasePath != "/" { - sourcePath = wsBuildVolumePath + gitSource.BasePath - } - - image, _, cacheImage := specSvc.GetImage(in.Application, in.Deployment, in.Config) - nixCommand := []string{fmt.Sprintf("nixpacks build %[1]s -o %[1]s", sourcePath)} - nixCommand = append(nixCommand, fmt.Sprintf("--name %s", image)) - if gitSource.BuildCommand != "" { - nixCommand = append(nixCommand, fmt.Sprintf(`--build-cmd "%s"`, gitSource.BuildCommand)) - } - if spec.Deploy.StartCommand != "" { - nixCommand = append(nixCommand, fmt.Sprintf(`--start-cmd "%s"`, spec.Deploy.StartCommand)) - } - - for key, value := range buildVars { - nixCommand = append(nixCommand, fmt.Sprintf(`--env %s="%s"`, key, value)) - } - nixCommand = append(nixCommand, "--verbose") - step.AddScriptCmd(strings.Join(nixCommand, ` `)) - - var cmd strings.Builder - //generate buildkit toml - addBuildKitConfig(&cmd, in.Config) - - // Construct the buildctl-daemonless.sh command - cmd.WriteString(fmt.Sprintf(`buildctl-daemonless.sh build \ - --frontend=dockerfile.v0 \ - --local context=%[1]s \ - --local dockerfile=%[1]s \ - --opt filename=/.nixpacks/Dockerfile \ - --output type=image,name=%[2]s,push=true `, sourcePath, image)) - - if cacheImage != "" { - cmd.WriteString(fmt.Sprintf(`--export-cache type=registry,ref=%s `, cacheImage)) - cmd.WriteString(fmt.Sprintf(`--import-cache type=registry,ref=%s,mode=max `, cacheImage)) + switch specSvc.GetBuilder(spec) { + case enum.BuilderTypeDockerfile: + addVariable(pCtx, step, "CLOUDNESS_BUILD_TYPE", "dockerfile") + addVariable(pCtx, step, "CLOUDNESS_BUILD_DOCKERFILE", gitSource.Dockerfile) + case enum.BuilderTypeNixpacks: + addSecret(pCtx, step, "CLOUDNESS_BUILD_TYPE", "nixpacks") + if gitSource.BuildCommand != "" { + addVariable(pCtx, step, "CLOUDNESS_BUILD_CMD", gitSource.BuildCommand) + } + if spec.Deploy.StartCommand != "" { + addVariable(pCtx, step, "CLOUDNESS_START_CMD", spec.Deploy.StartCommand) + } } - step.AddScriptCmd(cmd.String()) - -} - -func addImageSecrets(in *pipeline.RunnerContextInput, pCtx *pipeline.RunnerContext, step *pipeline.Step) { - image, pullImage, cacheImage := specSvc.GetImage(in.Application, in.Deployment, in.Config) - addSecret(pCtx, step, "CLOUDNESS_BUILD_IMAGE", image) - addSecret(pCtx, step, "CLOUDNESS_BUILD_PULL_IMAGE", pullImage) - addSecret(pCtx, step, "CLOUDNESS_BUILD_CACHE_IMAGE", cacheImage) - addSecret(pCtx, step, "CLOUDNESS_IMAGE_REGISTRY", in.Config.PushRegistryURL) - addSecret(pCtx, step, "CLOUDNESS_IMAGE_MIRROR_REGISTRY", in.Config.MirrorRegistryURL) -} - -func addBuildKitConfig(cmd *strings.Builder, config *config.PipelineConfig) { - //generate buildkit toml - cmd.WriteString(`BUILDKITD_CONFIG_PATH="$HOME/.config/buildkit/buildkitd.toml"` + "\n") - cmd.WriteString(`mkdir -p "$(dirname "$BUILDKITD_CONFIG_PATH")"` + "\n") - cmd.WriteString(`> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(fmt.Sprintf(`MAIN_REGISTRY=$(echo %s | cut -d'/' -f1)`+"\n", config.PushRegistryURL)) - cmd.WriteString(`echo "[registry.\"$MAIN_REGISTRY\"]" >> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(`echo " http = true" >> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(`echo " insecure = true" >> "$BUILDKITD_CONFIG_PATH"` + "\n") + // Add image secrets for other steps + addSecrets(pCtx, step, buildVars) - if config.MirrorRegistryEnabled && config.MirrorRegistryURL != "" { - // Add the mirror configuration - cmd.WriteString(fmt.Sprintf(`MIRROR_REGISTRY=$(echo %s | cut -d'/' -f1)`+"\n", config.MirrorRegistryURL)) - cmd.WriteString(`echo "[registry.\"$MIRROR_REGISTRY\"]" >> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(`echo " http = true" >> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(`echo " insecure = true" >> "$BUILDKITD_CONFIG_PATH"` + "\n") + // Run the build script + step.AddScriptCmd(". /usr/local/lib/build-script.sh") - cmd.WriteString(`echo "[registry.\"docker.io\"]" >> "$BUILDKITD_CONFIG_PATH"` + "\n") - cmd.WriteString(fmt.Sprintf(`echo " mirrors = [\"%s\"]" >> "$BUILDKITD_CONFIG_PATH"`+"\n", config.MirrorRegistryURL)) - } + return nil } diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 3072047..1bda7d3 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -7,9 +7,6 @@ import ( ) const ( - // images - busyBoxImage = "busybox:1.37.0" - // workspace volume wsBuildVolumePath = "/cloudness/workspace/build" @@ -25,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:latest" + return "cloudnessio/builder:1.0.9" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/app/pipeline/convert/convert.go b/app/pipeline/convert/convert.go index dafc05e..59ac9f4 100644 --- a/app/pipeline/convert/convert.go +++ b/app/pipeline/convert/convert.go @@ -13,6 +13,7 @@ func ToRunnerContext(in *pipeline.RunnerContextInput) (*pipeline.RunnerContext, Steps: []*pipeline.Step{}, InitSteps: []*pipeline.Step{}, Secrets: []*pipeline.Secret{}, + Variables: []*pipeline.Variable{}, } pCtx.RunnerName = getRunnerNamespace(pCtx) @@ -59,7 +60,7 @@ func ToRunnerContext(in *pipeline.RunnerContextInput) (*pipeline.RunnerContext, Envs: map[string]string{}, } - step.AddStripCmds("#!/bin/sh\n\n", "set -e") + step.AddStripCmds("#!/bin/sh\n\n", "set -e", ". /usr/local/lib/cloudness-utils.sh") if err := initCommand(step, in, pCtx, spec); err != nil { return nil, err diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index 15ee517..e60c7d0 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -12,7 +12,6 @@ import ( "github.com/cloudness-io/cloudness/types/enum" shlex "github.com/kballard/go-shellquote" - "github.com/rs/zerolog/log" ) func deployCommand( @@ -31,18 +30,16 @@ func deployCommand( return err } - script, common, volume, app, route, err := templates.GenerateKubeTemplates(tmplIn) + _, common, volume, app, route, err := templates.GenerateKubeTemplates(tmplIn) if err != nil { return err } - step.AddScriptCmd(fmt.Sprintf("cd %s", wsDeployVolumePath)) - step.AddScriptCmd(script) - - //General secrets for log sanitization + // General secrets for log sanitization addSecret(pCtx, step, "CLOUDNESS_DEPLOY_APP_IDENTIFIER", name) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_APP_NAMESPACE", namespace) - // flags + + // Flags addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_APP_TYPE", string(in.Application.Type)) if len(tmplIn.Volumes) > 0 { addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME", "1") @@ -50,18 +47,19 @@ func deployCommand( if tmplIn.ServiceDomain != nil { addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE", "1") } - // kube files + + // Kube YAML files addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_COMMON", common) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_VOLUME", volume) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_APP", app) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_ROUTE", route) - // common + // Common deployment info addSecret(pCtx, step, "CLOUDNESS_DEPLOY_TARGET_NAMESPACE", namespace) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_TARGET_NAME", name) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_TARGET_IMAGE", pullImage) - // unmount before update volumes ? + // Unmount before update volumes? needsRemount := "0" if in.ServerRestctions.UnmountBeforeResize { if needsVolumeRemount(in.Deployment, in.PreviousDeployment) { @@ -70,8 +68,10 @@ func deployCommand( } addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT", needsRemount) + // Run the deploy script + step.AddScriptCmd(". /usr/local/lib/deploy-script.sh") + step.VolumeMounts = append(step.VolumeMounts, getDeployVolumeMount(pCtx)) - //TODO: check if deployment is enabled return nil } @@ -171,6 +171,5 @@ func needsVolumeRemount(currDeployment *types.Deployment, prevDeployment *types. } } - log.Error().Msg("Debug: return 4") return false } diff --git a/app/pipeline/convert/init_step.go b/app/pipeline/convert/init_step.go index 2e42e87..243d9d6 100644 --- a/app/pipeline/convert/init_step.go +++ b/app/pipeline/convert/init_step.go @@ -1,8 +1,6 @@ package convert import ( - "fmt" - "github.com/cloudness-io/cloudness/app/pipeline" specSvc "github.com/cloudness-io/cloudness/app/services/spec" "github.com/cloudness-io/cloudness/types" @@ -19,22 +17,24 @@ func initCommand( } gitSource := spec.Build.Source.Git - step.AddScriptCmd(`echo "Git clone started"`) + + // Set environment variables for the init script + addVariable(pCtx, step, "CLOUDNESS_GIT_REPO_URL", gitSource.RepoURL) + addVariable(pCtx, step, "CLOUDNESS_GIT_BRANCH", gitSource.Branch) + addVariable(pCtx, step, "CLOUDNESS_GIT_COMMIT", gitSource.Commit) + addSecret(pCtx, step, "CLOUDNESS_BUILD_PATH", wsBuildVolumePath) + + // Set netrc credentials if provided if in.Netrc != nil { - step.AddScriptCmd(`echo "machine $GIT_MACHINE login $GIT_LOGIN password $GIT_PASSWORD" > ~/.netrc`) - step.AddScriptCmd(`chmod 600 ~/.netrc`) addSecret(pCtx, step, "GIT_LOGIN", in.Netrc.Login) addSecret(pCtx, step, "GIT_PASSWORD", in.Netrc.Password) addSecret(pCtx, step, "GIT_MACHINE", in.Netrc.Machine) } - step.AddScriptCmd(fmt.Sprintf(`git clone %s --branch %s %s;`, gitSource.RepoURL, gitSource.Branch, wsBuildVolumePath)) - if gitSource.Commit != "" { - step.AddScriptCmd(fmt.Sprintf("git -C %s config advice.detachedHead false", wsBuildVolumePath)) - step.AddScriptCmd(fmt.Sprintf("git -C %s checkout %s", wsBuildVolumePath, gitSource.Commit)) - } - step.AddScriptCmd(`echo "Git clone successful"`) - //volume mounts + // Run the init script + step.AddScriptCmd(". /usr/local/lib/init-script.sh") + + // Volume mounts step.VolumeMounts = append(step.VolumeMounts, getBuildVolumeMount(pCtx)) return nil diff --git a/app/pipeline/convert/secret.go b/app/pipeline/convert/secret.go deleted file mode 100644 index d472629..0000000 --- a/app/pipeline/convert/secret.go +++ /dev/null @@ -1,23 +0,0 @@ -package convert - -import ( - "github.com/cloudness-io/cloudness/app/pipeline" -) - -func addSecrets(ctx *pipeline.RunnerContext, step *pipeline.Step, vars map[string]string) { - for key, val := range vars { - addSecret(ctx, step, key, val) - } -} - -func addSecret(ctx *pipeline.RunnerContext, step *pipeline.Step, key string, value string) { - ctx.Secrets = append(ctx.Secrets, &pipeline.Secret{ - Name: key, - Data: value, - Mask: true, - }) - - step.Secrets = append(step.Secrets, &pipeline.SecretEnv{ - Key: key, - }) -} diff --git a/app/pipeline/convert/templates/static/kube-script.sh b/app/pipeline/convert/templates/static/kube-script.sh index 97ed019..38e0d26 100755 --- a/app/pipeline/convert/templates/static/kube-script.sh +++ b/app/pipeline/convert/templates/static/kube-script.sh @@ -1,220 +1,478 @@ +# Cloudness Kubernetes Deployment Script +# This script deploys applications to Kubernetes with proper resource management + +# ============================================================================== +# Configuration & Constants +# ============================================================================== + +# Colors for output +readonly RED='\033[1;31m' +readonly GREEN='\033[1;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' + +# Timeout configurations (can be overridden via environment) +readonly ROLLOUT_TIMEOUT_STATELESS="${ROLLOUT_TIMEOUT_STATELESS:-60s}" +readonly ROLLOUT_TIMEOUT_STATEFUL="${ROLLOUT_TIMEOUT_STATEFUL:-120s}" +readonly PVC_RESIZE_TIMEOUT="${PVC_RESIZE_TIMEOUT:-300}" +readonly PVC_RESIZE_POLL_INTERVAL="${PVC_RESIZE_POLL_INTERVAL:-5}" + +# Required environment variables with defaults : "${CLOUDNESS_DEPLOY_APP_IDENTIFIER:=}" : "${CLOUDNESS_DEPLOY_APP_NAMESPACE:=}" - -# Deployment flags : "${CLOUDNESS_DEPLOY_FLAG_APP_TYPE:=}" : "${CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME:=0}" : "${CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT:=0}" : "${CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE:=0}" - -# Deployment yaml files : "${CLOUDNESS_DEPLOY_YAML_COMMON:=}" : "${CLOUDNESS_DEPLOY_YAML_VOLUME:=}" : "${CLOUDNESS_DEPLOY_YAML_APP:=}" : "${CLOUDNESS_DEPLOY_YAML_ROUTE:=}" +: "${VERBOSE:=false}" + +# Track cleanup state +CLEANUP_DONE=false + +# ============================================================================== +# Logging Functions +# ============================================================================== + +log_error() { + echo -e "${RED}[ERROR]${NC} $*" >&2 +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $*" +} + +log_info() { + echo -e "$*" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $*" +} + +log_step() { + echo -e "$* ${GREEN}✔${NC}" +} + +print_section() { + text="$1" + echo "" + echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + echo -e "${BLUE} ${text}${NC}" + echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" +} + +# ============================================================================== +# Validation Functions +# ============================================================================== + +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +validate_dependencies() { + missing="" + + if ! command_exists kubectl; then + missing="$missing kubectl" + fi + + if ! command_exists yq; then + missing="$missing yq" + fi + + if [ -n "$missing" ]; then + log_error "Missing required dependencies:$missing" + log_error "Please install them before running this script." + return 1 + fi + + return 0 +} + +validate_environment() { + has_errors=0 + + if [ -z "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" ]; then + log_error " - CLOUDNESS_DEPLOY_APP_IDENTIFIER is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_DEPLOY_APP_NAMESPACE" ]; then + log_error " - CLOUDNESS_DEPLOY_APP_NAMESPACE is required" + has_errors=1 + fi + + if [ -z "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" ]; then + log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE is required" + has_errors=1 + elif [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateless" ] && [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateful" ]; then + log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE must be 'Stateless' or 'Stateful'" + has_errors=1 + fi + + if [ "$has_errors" -eq 1 ]; then + log_error "Environment validation failed" + return 1 + fi + + return 0 +} + +# ============================================================================== +# Helper functions +# ============================================================================== + +# Function to run commands with optional output +run_command() { + if [ "$VERBOSE" = "true" ]; then + "$@" + else + "$@" > /dev/null 2>&1 + fi +} + +# ============================================================================== +# Kubernetes Operations +# ============================================================================== + +# Returns the resource type based on app type +get_resource_type() { + if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then + echo "deployment" + else + echo "statefulset" + fi +} + +# Returns the opposite resource type (for cleanup) +get_opposite_resource_type() { + if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then + echo "statefulset" + else + echo "deployment" + fi +} + +# Apply Kubernetes configuration from YAML string +kube_apply() { + yaml_string="$1" + error_output="" + + # Skip if empty + if [ -z "$yaml_string" ]; then + return 0 + fi + + # Apply the YAML + if [ "$VERBOSE" = "true" ]; then + if ! printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f -; then + log_error "Failed to apply Kubernetes configuration" + return 1 + fi + else + if ! error_output=$(printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f - 2>&1 >/dev/null); then + log_error "Failed to apply Kubernetes configuration:" + log_error "$error_output" + return 1 + fi + fi + + return 0 +} + +# Delete a Kubernetes resource +kube_delete() { + resource_type="$1" + resource_name="$2" + namespace="$3" + error_output="" + + if [ "$VERBOSE" = "true" ]; then + if ! kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true; then + log_warn "Failed to delete $resource_type/$resource_name" + return 1 + fi + else + if ! error_output=$(kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true 2>&1 >/dev/null); then + log_warn "Failed to delete $resource_type/$resource_name: $error_output" + return 1 + fi + fi + + return 0 +} + +# Wait for rollout to complete +kube_rollout_status() { + resource_type="" + timeout="" + error_output="" + + resource_type=$(get_resource_type) + + if [ "$resource_type" = "deployment" ]; then + timeout="$ROLLOUT_TIMEOUT_STATELESS" + else + timeout="$ROLLOUT_TIMEOUT_STATEFUL" + fi + + if [ "$VERBOSE" = "true" ]; then + if ! kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ + --timeout="$timeout"; then + log_error "Rollout failed, reverting..." + kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true + return 1 + fi + else + if ! error_output=$(kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ + --timeout="$timeout" 2>&1); then + log_error "$error_output" + log_error "Rollout failed, reverting..." + kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ + -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" 2>/dev/null || true + return 1 + fi + fi + + return 0 +} + +# Parse storage size to numeric GiB value +parse_size_to_gib() { + size_str="$1" + echo "$size_str" | sed 's/Gi//' +} + +# Wait for PVC to resize +kube_wait_pvc_resize() { + pvc_name="$1" + new_size="$2" + namespace="$CLOUDNESS_DEPLOY_APP_NAMESPACE" + deadline="" + current_time="" + + current_time=$(date +%s) + deadline=$((current_time + PVC_RESIZE_TIMEOUT)) + + while true; do + # Check PVC status + pvc_status="" + pvc_status=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.phase}' 2>/dev/null || echo "") + + if [ "$VERBOSE" = "true" ]; then + log_info "PVC '$pvc_name' status: $pvc_status" + fi + + # Handle WaitForFirstConsumer + if [ "$pvc_status" = "Pending" ]; then + pvc_event="" + pvc_event=$(kubectl get events -n "$namespace" \ + --field-selector "involvedObject.kind=PersistentVolumeClaim,involvedObject.name=$pvc_name" \ + --sort-by=.lastTimestamp \ + -o jsonpath='{.items[-1:].reason}' 2>/dev/null || echo "") + if [ "$pvc_event" = "WaitForFirstConsumer" ]; then + return 0 + fi + fi + + # Check if resize completed + current_size="" + current_size=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.capacity.storage}' 2>/dev/null || echo "0Gi") + + if [ "$VERBOSE" = "true" ]; then + log_info "PVC '$pvc_name' current size: $current_size, target: $new_size" + fi + if [ "$(parse_size_to_gib "$current_size")" -ge "$(parse_size_to_gib "$new_size")" ]; then + return 0 + fi + + # Check for FileSystemResizePending condition + resize_pending="" + resize_pending=$(kubectl get pvc "$pvc_name" -n "$namespace" \ + -o jsonpath='{.status.conditions[?(@.type=="FileSystemResizePending")].status}' 2>/dev/null || echo "") + if [ "$resize_pending" = "True" ]; then + log_info "Volume resized. Remounting application to finalize." + return 0 + fi + + # Check timeout + current_time=$(date +%s) + if [ "$current_time" -ge "$deadline" ]; then + log_error "Timed out after ${PVC_RESIZE_TIMEOUT}s waiting for PVC '$pvc_name' to reach $new_size" + return 1 + fi + + log_info "Waiting for volume '$pvc_name'..." + sleep "$PVC_RESIZE_POLL_INTERVAL" + done +} + +# ============================================================================== +# Deployment Functions +# ============================================================================== + +deploy_common_artifacts() { + print_section "Setting up prerequisite artifacts" + + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_COMMON"; then + log_error "Failed to set up prerequisite artifacts" + return 1 + fi + + log_step "Prerequisite artifacts configured" + return 0 +} + +deploy_volume() { + if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME" -ne 1 ]; then + return 0 + fi + + print_section "Provisioning volumes" + + # Handle remount for volume resize + if [ "$CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT" -eq 1 ]; then + log_info "Volume resize detected, removing statefulset for remount..." + if ! kube_delete "statefulset" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE"; then + log_error "Failed to remove statefulset for remount" + return 1 + fi + fi + + # Apply volume configuration + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_VOLUME"; then + log_error "Failed to apply volume configuration" + return 1 + fi + + # Wait for each PVC to be ready + pvc_data="" + pvc_data=$(printf '%s' "$CLOUDNESS_DEPLOY_YAML_VOLUME" | sed 's/\t/ /g' | \ + yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' - 2>/dev/null || echo "") + + echo "$pvc_data" | while read -r pvc_name new_size; do + # Skip empty lines + pvc_name=$(echo "$pvc_name" | xargs) + new_size=$(echo "$new_size" | xargs) + if [ -z "$pvc_name" ] || [ -z "$new_size" ] || [ "$pvc_name" = "---" ]; then + continue + fi + + if ! kube_wait_pvc_resize "$pvc_name" "$new_size"; then + log_error "Failed to provision PVC '$pvc_name'" + return 1 + fi + done + + log_step "Volumes provisioned" + return 0 +} + +deploy_application() { + print_section "Deploying application" + + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_APP"; then + log_error "Failed to deploy application" + return 1 + fi + + if ! kube_rollout_status; then + return 1 + fi + + log_step "Application deployed" + return 0 +} + +deploy_routes() { + if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE" -ne 1 ]; then + return 0 + fi + + print_section "Configuring HTTP routes" -# Define color variables -RED='\033[1;31m' # Bold Red -YELLOW='\033[1;33m' # Bold Yellow -GREEN='\033[1;32m' # Bold Green -RESET='\033[0m' # Resets color -CHECK_MARK='\u2714' # Unicode for Heavy Check Mark (✔) - -# Helper function for logging -error() { echo -e "${RED}[ERROR]${RESET} $*"; } -warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; } -info() { echo -e "$*"; } -success() { echo -e "${GREEN}[SUCCESS]${RESET} $*"; } -success_info() { echo -e "$* ${GREEN}✔${RESET}"; } - -apply_kube_config_from_string() { - local KUBE_YAML_STRING="$1" - local ERROR_MESSAGE="" - - # Check if the YAML string is empty - if [ -z "$KUBE_YAML_STRING" ]; then - return 0 - fi - - # echo "Attempting to apply Kubernetes configuration..." - # echo -e "$KUBE_YAML_STRING" | sed 's/\t/ /g' - - # Apply the YAML using kubectl, capturing stderr into ERROR_MESSAGE - # And redirecting stdout to /dev/null to suppress success messages - if ! ERROR_MESSAGE=$(echo -e "$KUBE_YAML_STRING" | sed 's/\t/ /g' | kubectl apply -f - 2>&1 >/dev/null); then - error "Error applying Kubernetes configuration:" - error "$ERROR_MESSAGE" - return 1 # Indicate failure - else - return 0 # Indicate success - fi -} - -rollout_status() { - local ROLLOUT_ERROR="" - - if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then - if ! ROLLOUT_ERROR=$(kubectl rollout status deployment/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" --timeout=20s >&1 >/dev/null); then - error "$ROLLOUT_ERROR" - error "Error rolling out deployment, reverting..." - kubectl rollout undo deployment/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" - return 1 - fi - else - if ! ROLLOUT_ERROR=$(kubectl rollout status statefulset/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" --timeout=2m >&1 >/dev/null); then - error "$ROLLOUT_ERROR" - error "Error rolling out deployment, reverting..." - kubectl rollout undo statefulset/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" - return 1 - fi - fi + if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_ROUTE"; then + log_error "Failed to configure HTTP routes" + return 1 + fi + + log_step "HTTP routes configured" + return 0 } +# ============================================================================== +# Lifecycle Management +# ============================================================================== + cleanup() { - info "Running clean up..." - local CLEANUP_ERROR="" - - if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then - if ! CLEANUP_ERROR=$(kubectl delete statefulset/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" --ignore-not-found=true 2>&1 >/dev/null); then - error "$CLEANUP_ERROR" - warn "Error cleaning up deployment, Skipping..." - fi - else - if ! CLEANUP_ERROR=$(kubectl delete deployment/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" --ignore-not-found=true 2>&1 >/dev/null); then - error "$CLEANUP_ERROR" - warn "Error cleaning up deployment, Skipping..." - fi - fi -} - -wait_for_pvc_resize() { - PVC_NAME="$1" - NEW_SIZE="$2" - NAMESPACE="$CLOUDNESS_DEPLOY_APP_NAMESPACE" - - TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-300}" # 5 minutes - SLEEP_SECONDS="${SLEEP_SECONDS:-5}" - - local current_time=$(date +%s) - local deadline=$(expr "$current_time" + "$TIMEOUT_SECONDS") - - check_resize_pending() { - kubectl get pvc "$PVC_NAME" -n "$NAMESPACE" -o jsonpath='{.status.conditions[?(@.type=="FileSystemResizePending")].status}' 2>/dev/null - } - - # Function to parse a storage string (e.g., "11Gi") and convert to GiB - parse_size_to_gib() { - local size_str=$1 - local value=$(echo "$size_str" | sed 's/Gi//') - # Use 'bc' for floating-point arithmetic if necessary - echo "$value" - } - - check_pvc_status() { - kubectl get pvc "$PVC_NAME" -n "$NAMESPACE" -o jsonpath='{.status.phase}' 2>/dev/null - } - - get_pvc_event() { - kubectl get events -n "$NAMESPACE" --field-selector involvedObject.kind=PersistentVolumeClaim,involvedObject.name="$PVC_NAME" --sort-by=.lastTimestamp -o jsonpath='{.items[-1:].reason}' 2>/dev/null - } - - while true; do - PVC_STATUS=$(check_pvc_status) - # Handle WaitForFirstConsumer specifically - if [ "$PVC_STATUS" == "Pending" ]; then - PVC_EVENT=$(get_pvc_event) - if [ "$PVC_EVENT" == "WaitForFirstConsumer" ]; then - return 0 - fi - fi - - CURRENT_SIZE=$(kubectl get pvc $PVC_NAME -n $NAMESPACE -o jsonpath='{.status.capacity.storage}') - if [ $(parse_size_to_gib "$CURRENT_SIZE") -ge $(parse_size_to_gib "$NEW_SIZE") ]; then - return 0 # Exit the function with success status - fi - - # Check for FileSystemResizePending condition - if [ "$(check_resize_pending)" == "True" ]; then - info "Volume has been resized. Remounting application to finalize resize." - return 0 - fi - - # Timeout - current_time=$(date +%s) - if [ "$current_time" -ge "$deadline" ]; then - info "⏱️ Timed out after ${TIMEOUT_SECONDS}s waiting for PVC '$PVC_NAME' to reach $NEW_SIZE." - return 1 - fi - - echo "Waiting for Volume..." - sleep "$SLEEP_SECONDS" - done -} - -################################################ MAIN ################################# - -# Applying common artifacts namespace, service account, role, rolebinding, configmap, secrets... -if apply_kube_config_from_string "$CLOUDNESS_DEPLOY_YAML_COMMON"; then - success_info "Setting up prequestic artifacts." -else - error "Error setting up prequestic artifacts. Exiting..." - return 1 -fi - -# Apply volume/pvc configuration -if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME" -eq 1 ]; then - if [ "$CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT" -eq 1 ]; then #if the volume is scaled up and needs remount for changes to apply - #delete the statefulset before scaling up the volume - if !(kubectl delete statefulset/"$CLOUDNESS_DEPLOY_APP_IDENTIFIER" -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" --ignore-not-found=true 2>&1 >/dev/null); then - error "Error cleaning up deployment, Skipping..." - return 1 - fi - fi - if apply_kube_config_from_string "$CLOUDNESS_DEPLOY_YAML_VOLUME"; then - # Iterate through each PVC found - PVC_DATA=$(echo -e "$CLOUDNESS_DEPLOY_YAML_VOLUME" | sed 's/\t/ /g' | yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' -) - echo "$PVC_DATA" | while read -r PVC_NAME NEW_SIZE; do - PVC_NAME=$(echo "$PVC_NAME" | xargs) - NEW_SIZE=$(echo "$NEW_SIZE" | xargs) - if [ -z "$PVC_NAME" ] || [ -z "$NEW_SIZE" ]; then #discard ---- and empty lines - continue - fi - - if ! wait_for_pvc_resize "$PVC_NAME" "$NEW_SIZE"; then - error "Failed to resize or confirm PVC '$PVC_NAME'. Check logs above for details." - return 1 - fi - done - - success_info "Volume provisioned." - else - "Error setting up volume. Exiting..." - return 1 - fi - -fi - -if ! apply_kube_config_from_string "$CLOUDNESS_DEPLOY_YAML_APP"; then - error "Error deploying application. Exiting..." - return 1 -fi - -if rollout_status; then - success_info "Application deployment." -else - #logs are handles in rollout_status method - return 1 -fi - -if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE" -eq 1 ]; then - if apply_kube_config_from_string "$CLOUDNESS_DEPLOY_YAML_ROUTE"; then - success_info "HTTP routes configured." - else - error "Error setting up http routes. Exiting..." - return 1 - fi -fi - -cleanup - -success "Deployment completed successfully." + if [ "$CLEANUP_DONE" = "true" ]; then + return 0 + fi + CLEANUP_DONE=true + + log_info "Running cleanup..." + + opposite_type="" + opposite_type=$(get_opposite_resource_type) + + kube_delete "$opposite_type" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true +} + +on_exit() { + exit_code=$? + if [ $exit_code -ne 0 ]; then + log_error "Deployment failed with exit code $exit_code" + fi + cleanup + exit $exit_code +} + +# ============================================================================== +# Main Entrypoint +# ============================================================================== + +main() { + # Set up exit trap + trap on_exit EXIT + + # Validate prerequisites + if ! validate_dependencies; then + exit 1 + fi + + if ! validate_environment; then + exit 1 + fi + + # Execute deployment steps + if ! deploy_common_artifacts; then + exit 1 + fi + + if ! deploy_volume; then + exit 1 + fi + + if ! deploy_application; then + exit 1 + fi + + if ! deploy_routes; then + exit 1 + fi + + # Success + echo "" + log_success "Deployment completed successfully!" +} + +# Run main function +main "$@" diff --git a/app/pipeline/convert/utils.go b/app/pipeline/convert/utils.go index 6b19149..b05f41c 100644 --- a/app/pipeline/convert/utils.go +++ b/app/pipeline/convert/utils.go @@ -61,3 +61,32 @@ func replaceEnvVars(input string, vars map[string]*types.Variable) string { return builder.String() } + +func addSecrets(ctx *pipeline.RunnerContext, step *pipeline.Step, vars map[string]string) { + for key, val := range vars { + addSecret(ctx, step, key, val) + } +} + +func addSecret(ctx *pipeline.RunnerContext, step *pipeline.Step, key string, value string) { + ctx.Secrets = append(ctx.Secrets, &pipeline.Secret{ + Name: key, + Data: value, + Mask: true, + }) + + step.Secrets = append(step.Secrets, &pipeline.SecretEnv{ + Key: key, + }) +} + +func addVariable(ctx *pipeline.RunnerContext, step *pipeline.Step, key string, value string) { + ctx.Variables = append(ctx.Variables, &pipeline.Variable{ + Name: key, + Value: value, + }) + + step.Variables = append(step.Variables, &pipeline.VariableEnv{ + Key: key, + }) +} diff --git a/app/pipeline/runner/engine/kubernetes/kubernetes.go b/app/pipeline/runner/engine/kubernetes/kubernetes.go index 88495c8..f29bed8 100644 --- a/app/pipeline/runner/engine/kubernetes/kubernetes.go +++ b/app/pipeline/runner/engine/kubernetes/kubernetes.go @@ -107,6 +107,11 @@ func (e *kube) Setup(rCtx context.Context, pCtx *pipeline.RunnerContext) error { return err } + _, err = e.client.CoreV1().ConfigMaps(e.nameSpace).Create(rCtx, toConfigMap(pCtx), metav1.CreateOptions{}) + if err != nil { + return err + } + _, err = e.client.CoreV1().Pods(e.nameSpace).Create(rCtx, toPod(e.nameSpace, pCtx), metav1.CreateOptions{}) if err != nil { return err @@ -301,6 +306,12 @@ func (e *kube) Destroy(ctx context.Context, pCtx *pipeline.RunnerContext) error return err } + // delete configmap + err = e.client.CoreV1().ConfigMaps(e.nameSpace).Delete(ctx, pCtx.RunnerName, metav1.DeleteOptions{}) + if err != nil { + return err + } + return e.client.CoreV1().Pods(e.nameSpace).Delete(ctx, pCtx.RunnerName, metav1.DeleteOptions{}) } diff --git a/app/pipeline/runner/engine/kubernetes/tokube.go b/app/pipeline/runner/engine/kubernetes/tokube.go index 7c904b2..077e00c 100644 --- a/app/pipeline/runner/engine/kubernetes/tokube.go +++ b/app/pipeline/runner/engine/kubernetes/tokube.go @@ -52,6 +52,20 @@ func toSecret(p *pipeline.RunnerContext) *v1.Secret { } } +func toConfigMap(p *pipeline.RunnerContext) *v1.ConfigMap { + stringData := make(map[string]string) + for _, s := range p.Variables { + stringData[s.Name] = s.Value + } + + return &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: p.RunnerName, + }, + Data: stringData, + } +} + func toPod(nameSpace string, p *pipeline.RunnerContext) *v1.Pod { resource := toResources(p) return &v1.Pod{ @@ -157,6 +171,20 @@ func toEnv(s *pipeline.Step, p *pipeline.RunnerContext) []v1.EnvVar { }, }) } + + for _, varEnv := range s.Variables { + envs = append(envs, v1.EnvVar{ + Name: varEnv.Key, + ValueFrom: &v1.EnvVarSource{ + ConfigMapKeyRef: &v1.ConfigMapKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: p.RunnerName, + }, + Key: varEnv.Key, + }, + }, + }) + } return envs } diff --git a/app/pipeline/types.go b/app/pipeline/types.go index 36afdd7..45e760e 100644 --- a/app/pipeline/types.go +++ b/app/pipeline/types.go @@ -37,6 +37,7 @@ type ( Steps []*Step InitSteps []*Step Secrets []*Secret + Variables []*Variable ResourcesLimit *ResourcesLimit } @@ -50,6 +51,7 @@ type ( Envs map[string]string VolumeMounts []*VolumeMount Secrets []*SecretEnv + Variables []*VariableEnv Privileged bool RestartPolicy RestartPolicy @@ -63,10 +65,19 @@ type ( Mask bool } + Variable struct { + Name string + Value string + } + SecretEnv struct { Key string } + VariableEnv struct { + Key string + } + Volume struct { ID string Size int64 diff --git a/runbooks/dev/loacalbuilder.md b/runbooks/dev/loacalbuilder.md new file mode 100644 index 0000000..d6db937 --- /dev/null +++ b/runbooks/dev/loacalbuilder.md @@ -0,0 +1,11 @@ + +cd plugins/builder/ + +## Quick Start (All-in-One) + +```bash +export IMAGE_TAG="1.0.0" && \ + docker build . -t cloudnessio/builder:${IMAGE_TAG} && \ + sudo docker save cloudnessio/builder:${IMAGE_TAG} | \ + sudo ctr -a /run/k3s/containerd/containerd.sock -n=k8s.io images import - +``` \ No newline at end of file From 8f6e3b36cc856b0188858a5bb451d15fbb81611a Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 17:43:05 +0530 Subject: [PATCH 03/17] Move yaml files to configMap --- app/pipeline/convert/deploy_step.go | 32 ++++++++++++--- .../runner/engine/kubernetes/tokube.go | 37 +++++++++++++++++ app/pipeline/types.go | 39 ++++++++++++------ plugins/builder/scripts/deploy-script.sh | 41 ++++++++++++------- 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index e60c7d0..7423669 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -1,7 +1,6 @@ package convert import ( - "encoding/base64" "fmt" "net/url" @@ -35,6 +34,18 @@ func deployCommand( return err } + // Add YAML files as ConfigFiles (will be mounted from ConfigMap) + addConfigFile(pCtx, "common.yaml", common) + addConfigFile(pCtx, "volume.yaml", volume) + addConfigFile(pCtx, "app.yaml", app) + addConfigFile(pCtx, "route.yaml", route) + + // Mount ConfigFiles to deploy path + step.ConfigFileMounts = append(step.ConfigFileMounts, &pipeline.ConfigFileMount{ + Path: wsDeployVolumePath, + Keys: []string{"common.yaml", "volume.yaml", "app.yaml", "route.yaml"}, + }) + // General secrets for log sanitization addSecret(pCtx, step, "CLOUDNESS_DEPLOY_APP_IDENTIFIER", name) addSecret(pCtx, step, "CLOUDNESS_DEPLOY_APP_NAMESPACE", namespace) @@ -48,11 +59,8 @@ func deployCommand( addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE", "1") } - // Kube YAML files - addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_COMMON", common) - addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_VOLUME", volume) - addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_APP", app) - addSecret(pCtx, step, "CLOUDNESS_DEPLOY_YAML_ROUTE", route) + // Deploy path for script to find YAML files + addSecret(pCtx, step, "CLOUDNESS_DEPLOY_PATH", wsDeployVolumePath) // Common deployment info addSecret(pCtx, step, "CLOUDNESS_DEPLOY_TARGET_NAMESPACE", namespace) @@ -173,3 +181,15 @@ func needsVolumeRemount(currDeployment *types.Deployment, prevDeployment *types. return false } + +// addConfigFile adds a file to the ConfigMap for mounting +func addConfigFile(pCtx *pipeline.RunnerContext, filename string, content string) { + if content == "" { + return + } + pCtx.ConfigFiles = append(pCtx.ConfigFiles, &pipeline.ConfigFile{ + Key: filename, + Filename: filename, + Content: content, + }) +} diff --git a/app/pipeline/runner/engine/kubernetes/tokube.go b/app/pipeline/runner/engine/kubernetes/tokube.go index 077e00c..610cd86 100644 --- a/app/pipeline/runner/engine/kubernetes/tokube.go +++ b/app/pipeline/runner/engine/kubernetes/tokube.go @@ -58,6 +58,11 @@ func toConfigMap(p *pipeline.RunnerContext) *v1.ConfigMap { stringData[s.Name] = s.Value } + // Add ConfigFiles to ConfigMap + for _, cf := range p.ConfigFiles { + stringData[cf.Key] = cf.Content + } + return &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: p.RunnerName, @@ -202,6 +207,21 @@ func toVolume(p *pipeline.RunnerContext) []v1.Volume { }, }) } + + // Add ConfigMap volume for file mounts if there are ConfigFiles + if len(p.ConfigFiles) > 0 { + volumes = append(volumes, v1.Volume{ + Name: "configfiles", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: p.RunnerName, + }, + }, + }, + }) + } + return volumes } @@ -214,6 +234,23 @@ func toVolumeMounts(s *pipeline.Step) []v1.VolumeMount { ReadOnly: v.Readonly, }) } + + // Add ConfigFileMount volumes + for _, cfm := range s.ConfigFileMounts { + var items []v1.KeyToPath + for _, key := range cfm.Keys { + items = append(items, v1.KeyToPath{ + Key: key, + Path: key, // Use key as filename + }) + } + volumeMounts = append(volumeMounts, v1.VolumeMount{ + Name: "configfiles", + MountPath: cfm.Path, + ReadOnly: true, + }) + } + return volumeMounts } diff --git a/app/pipeline/types.go b/app/pipeline/types.go index 45e760e..dd9d2b3 100644 --- a/app/pipeline/types.go +++ b/app/pipeline/types.go @@ -38,22 +38,24 @@ type ( InitSteps []*Step Secrets []*Secret Variables []*Variable + ConfigFiles []*ConfigFile // Files to add to ConfigMap ResourcesLimit *ResourcesLimit } Step struct { - Name string - Image string - Command []string - Args []string - ScriptCommands []string - WorkingDir string - Envs map[string]string - VolumeMounts []*VolumeMount - Secrets []*SecretEnv - Variables []*VariableEnv - Privileged bool - RestartPolicy RestartPolicy + Name string + Image string + Command []string + Args []string + ScriptCommands []string + WorkingDir string + Envs map[string]string + VolumeMounts []*VolumeMount + Secrets []*SecretEnv + Variables []*VariableEnv + ConfigFileMounts []*ConfigFileMount // ConfigMap file mounts + Privileged bool + RestartPolicy RestartPolicy //housekeeping Liveness *Liveness @@ -78,6 +80,19 @@ type ( Key string } + // ConfigFile represents a file to be mounted from ConfigMap + ConfigFile struct { + Key string // Key in ConfigMap + Filename string // Filename when mounted + Content string // File content + } + + // ConfigFileMount represents a mounted ConfigMap as files + ConfigFileMount struct { + Path string // Mount path directory + Keys []string // Keys to mount as files + } + Volume struct { ID string Size int64 diff --git a/plugins/builder/scripts/deploy-script.sh b/plugins/builder/scripts/deploy-script.sh index 94aeeec..d1c862c 100644 --- a/plugins/builder/scripts/deploy-script.sh +++ b/plugins/builder/scripts/deploy-script.sh @@ -22,12 +22,15 @@ readonly PVC_RESIZE_POLL_INTERVAL="${PVC_RESIZE_POLL_INTERVAL:-5}" : "${CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME:=0}" : "${CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT:=0}" : "${CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE:=0}" -: "${CLOUDNESS_DEPLOY_YAML_COMMON:=}" -: "${CLOUDNESS_DEPLOY_YAML_VOLUME:=}" -: "${CLOUDNESS_DEPLOY_YAML_APP:=}" -: "${CLOUDNESS_DEPLOY_YAML_ROUTE:=}" +: "${CLOUDNESS_DEPLOY_PATH:=}" : "${VERBOSE:=false}" +# YAML file paths (set from CLOUDNESS_DEPLOY_PATH) +CLOUDNESS_DEPLOY_YAML_COMMON="" +CLOUDNESS_DEPLOY_YAML_VOLUME="" +CLOUDNESS_DEPLOY_YAML_APP="" +CLOUDNESS_DEPLOY_YAML_ROUTE="" + # Track cleanup state CLEANUP_DONE=false @@ -76,11 +79,22 @@ validate_environment() { has_errors=1 fi + if [ -z "$CLOUDNESS_DEPLOY_PATH" ]; then + log_error " - CLOUDNESS_DEPLOY_PATH is required" + has_errors=1 + fi + if [ "$has_errors" -eq 1 ]; then log_error "Environment validation failed" return 1 fi + # Set YAML file paths from deploy path (mounted from ConfigMap) + CLOUDNESS_DEPLOY_YAML_COMMON="$CLOUDNESS_DEPLOY_PATH/common.yaml" + CLOUDNESS_DEPLOY_YAML_VOLUME="$CLOUDNESS_DEPLOY_PATH/volume.yaml" + CLOUDNESS_DEPLOY_YAML_APP="$CLOUDNESS_DEPLOY_PATH/app.yaml" + CLOUDNESS_DEPLOY_YAML_ROUTE="$CLOUDNESS_DEPLOY_PATH/route.yaml" + return 0 } @@ -106,24 +120,24 @@ get_opposite_resource_type() { fi } -# Apply Kubernetes configuration from YAML string +# Apply Kubernetes configuration from YAML file kube_apply() { - yaml_string="$1" + yaml_file="$1" error_output="" - # Skip if empty - if [ -z "$yaml_string" ]; then + # Skip if file doesn't exist or is empty + if [ ! -f "$yaml_file" ] || [ ! -s "$yaml_file" ]; then return 0 fi # Apply the YAML if [ "$VERBOSE" = "true" ]; then - if ! printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f -; then - log_error "Failed to apply Kubernetes configuration" + if ! kubectl apply -f "$yaml_file"; then + log_error "Failed to apply Kubernetes configuration from $yaml_file" return 1 fi else - if ! error_output=$(printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f - 2>&1 >/dev/null); then + if ! error_output=$(kubectl apply -f "$yaml_file" 2>&1 >/dev/null); then log_error "Failed to apply Kubernetes configuration:" log_error "$error_output" return 1 @@ -301,10 +315,9 @@ deploy_volume() { return 1 fi - # Wait for each PVC to be ready + # Wait for each PVC to be ready (read from file) pvc_data="" - pvc_data=$(printf '%s' "$CLOUDNESS_DEPLOY_YAML_VOLUME" | sed 's/\t/ /g' | \ - yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' - 2>/dev/null || echo "") + pvc_data=$(yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' "$CLOUDNESS_DEPLOY_YAML_VOLUME" 2>/dev/null || echo "") echo "$pvc_data" | while read -r pvc_name new_size; do # Skip empty lines From fe31f4cca7b1ad1db06a4b50cbfa6c8de2f1d68e Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 13:19:10 +0100 Subject: [PATCH 04/17] Intrim commit- everything old is working --- app/pipeline/convert/const.go | 2 +- app/pipeline/convert/deploy_step.go | 1 + app/pipeline/runner/engine/kubernetes/tokube.go | 5 ----- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 1bda7d3..114b29a 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.9" + return "cloudnessio/builder:1.0.10" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index 7423669..cc23345 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -1,6 +1,7 @@ package convert import ( + "encoding/base64" "fmt" "net/url" diff --git a/app/pipeline/runner/engine/kubernetes/tokube.go b/app/pipeline/runner/engine/kubernetes/tokube.go index 610cd86..252831e 100644 --- a/app/pipeline/runner/engine/kubernetes/tokube.go +++ b/app/pipeline/runner/engine/kubernetes/tokube.go @@ -244,11 +244,6 @@ func toVolumeMounts(s *pipeline.Step) []v1.VolumeMount { Path: key, // Use key as filename }) } - volumeMounts = append(volumeMounts, v1.VolumeMount{ - Name: "configfiles", - MountPath: cfm.Path, - ReadOnly: true, - }) } return volumeMounts From 8be1b07db314e5b37deb2bb8810d7c52284cbe2b Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 18:00:39 +0530 Subject: [PATCH 05/17] Fix script logs printing --- plugins/builder/scripts/build-script.sh | 4 ++-- plugins/builder/scripts/cloudness-utils.sh | 10 +++++----- plugins/builder/scripts/deploy-script.sh | 9 ++------- plugins/builder/scripts/init-script.sh | 4 +++- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/plugins/builder/scripts/build-script.sh b/plugins/builder/scripts/build-script.sh index 50bc923..adf9dde 100644 --- a/plugins/builder/scripts/build-script.sh +++ b/plugins/builder/scripts/build-script.sh @@ -70,6 +70,7 @@ validate_inputs() { setup_buildkit_config() { + printf "\n" BUILDKITD_CONFIG_PATH="$HOME/.config/buildkit/buildkitd.toml" mkdir -p "$(dirname "$BUILDKITD_CONFIG_PATH")" > "$BUILDKITD_CONFIG_PATH" @@ -99,7 +100,6 @@ EOF EOF fi - printf "\n" log_step "BuildKit configured" } @@ -141,7 +141,6 @@ build_with_dockerfile() { return 1 fi - log_step "Image built and pushed successfully" return 0 } @@ -229,6 +228,7 @@ main() { ;; esac + echo "" log_success "Build completed successfully!" } diff --git a/plugins/builder/scripts/cloudness-utils.sh b/plugins/builder/scripts/cloudness-utils.sh index 8b07bd0..2d00faa 100644 --- a/plugins/builder/scripts/cloudness-utils.sh +++ b/plugins/builder/scripts/cloudness-utils.sh @@ -16,23 +16,23 @@ readonly CLOUDNESS_NC='\033[0m' # ============================================================================== log_error() { - printf "${CLOUDNESS_RED}[ERROR]${CLOUDNESS_NC} %s\n" "$*" >&2 + printf "%b\n" "${CLOUDNESS_RED}❌ $*${CLOUDNESS_NC}" >&2 } log_warn() { - printf "${CLOUDNESS_YELLOW}[WARN]${CLOUDNESS_NC} %s\n" "$*" + printf "%b\n" "${CLOUDNESS_YELLOW}⚠️ $*${CLOUDNESS_NC}" } log_info() { - printf "%s\n" "$*" + printf "%b\n" "$*" } log_success() { - printf "${CLOUDNESS_GREEN}[SUCCESS]${CLOUDNESS_NC} %s\n" "$*" + printf "%b\n" "${CLOUDNESS_GREEN}✅ $*${CLOUDNESS_NC}" } log_step() { - printf "%s ${CLOUDNESS_GREEN}✔${CLOUDNESS_NC}\n" "$*" + printf "%b\n" "${CLOUDNESS_GREEN}✔ $*${CLOUDNESS_NC}" } log_debug() { diff --git a/plugins/builder/scripts/deploy-script.sh b/plugins/builder/scripts/deploy-script.sh index d1c862c..39ff3c7 100644 --- a/plugins/builder/scripts/deploy-script.sh +++ b/plugins/builder/scripts/deploy-script.sh @@ -282,7 +282,6 @@ kube_wait_pvc_resize() { # ============================================================================== deploy_common_artifacts() { - print_section "Setting up prerequisite artifacts" if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_COMMON"; then log_error "Failed to set up prerequisite artifacts" @@ -298,8 +297,6 @@ deploy_volume() { return 0 fi - print_section "Provisioning volumes" - # Handle remount for volume resize if [ "$CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT" -eq 1 ]; then log_info "Volume resize detected, removing statefulset for remount..." @@ -338,8 +335,6 @@ deploy_volume() { } deploy_application() { - print_section "Deploying application" - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_APP"; then log_error "Failed to deploy application" return 1 @@ -358,8 +353,6 @@ deploy_routes() { return 0 fi - print_section "Configuring HTTP routes" - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_ROUTE"; then log_error "Failed to configure HTTP routes" return 1 @@ -403,6 +396,8 @@ on_exit() { main() { # Set up exit trap trap on_exit EXIT + + print_section "Deploying application" # Validate prerequisites if ! validate_dependencies; then diff --git a/plugins/builder/scripts/init-script.sh b/plugins/builder/scripts/init-script.sh index 6e16051..923336a 100644 --- a/plugins/builder/scripts/init-script.sh +++ b/plugins/builder/scripts/init-script.sh @@ -81,7 +81,6 @@ clone_repository() { fi fi - log_step "Repository cloned successfully" return 0 } @@ -99,6 +98,9 @@ main() { if ! clone_repository; then exit 1 fi + + echo "" + log_success "Repository cloned successfully!" } main "$@" From d15ba5d7a041dba2807a68595724dafaca6667f2 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 13:43:16 +0100 Subject: [PATCH 06/17] Improve logging --- app/pipeline/convert/const.go | 2 +- plugins/builder/scripts/build-script.sh | 4 ---- plugins/builder/scripts/cloudness-utils.sh | 6 +++--- plugins/builder/scripts/deploy-script.sh | 2 -- plugins/builder/scripts/init-script.sh | 1 - 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 114b29a..58c9c36 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.10" + return "cloudnessio/builder:1.0.13" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/plugins/builder/scripts/build-script.sh b/plugins/builder/scripts/build-script.sh index adf9dde..56d3106 100644 --- a/plugins/builder/scripts/build-script.sh +++ b/plugins/builder/scripts/build-script.sh @@ -87,7 +87,6 @@ EOF # Mirror registry configuration if [ "$CLOUDNESS_MIRROR_ENABLED" = "true" ] && [ -n "$CLOUDNESS_IMAGE_MIRROR_REGISTRY" ]; then MIRROR_REGISTRY=$(echo "$CLOUDNESS_IMAGE_MIRROR_REGISTRY" | cut -d'/' -f1) - log_info "Configuring mirror registry: $MIRROR_REGISTRY" cat >> "$BUILDKITD_CONFIG_PATH" << EOF @@ -99,8 +98,6 @@ EOF mirrors = ["$CLOUDNESS_IMAGE_MIRROR_REGISTRY"] EOF fi - - log_step "BuildKit configured" } # ============================================================================== @@ -228,7 +225,6 @@ main() { ;; esac - echo "" log_success "Build completed successfully!" } diff --git a/plugins/builder/scripts/cloudness-utils.sh b/plugins/builder/scripts/cloudness-utils.sh index 2d00faa..a5f0bee 100644 --- a/plugins/builder/scripts/cloudness-utils.sh +++ b/plugins/builder/scripts/cloudness-utils.sh @@ -20,7 +20,7 @@ log_error() { } log_warn() { - printf "%b\n" "${CLOUDNESS_YELLOW}⚠️ $*${CLOUDNESS_NC}" + printf "%b\n" "${CLOUDNESS_YELLOW}⚠️ $*${CLOUDNESS_NC}" } log_info() { @@ -28,11 +28,11 @@ log_info() { } log_success() { - printf "%b\n" "${CLOUDNESS_GREEN}✅ $*${CLOUDNESS_NC}" + printf "%b\n" "${CLOUDNESS_GREEN}✔ $*${CLOUDNESS_NC}" } log_step() { - printf "%b\n" "${CLOUDNESS_GREEN}✔ $*${CLOUDNESS_NC}" + printf "%b\n" "$* ${CLOUDNESS_GREEN}✔${CLOUDNESS_NC}" } log_debug() { diff --git a/plugins/builder/scripts/deploy-script.sh b/plugins/builder/scripts/deploy-script.sh index 39ff3c7..98ebd74 100644 --- a/plugins/builder/scripts/deploy-script.sh +++ b/plugins/builder/scripts/deploy-script.sh @@ -425,8 +425,6 @@ main() { exit 1 fi - # Success - echo "" log_success "Deployment completed successfully!" } diff --git a/plugins/builder/scripts/init-script.sh b/plugins/builder/scripts/init-script.sh index 923336a..baeab36 100644 --- a/plugins/builder/scripts/init-script.sh +++ b/plugins/builder/scripts/init-script.sh @@ -99,7 +99,6 @@ main() { exit 1 fi - echo "" log_success "Repository cloned successfully!" } From 98df254f9280a6abbf43cebf8a762e9513cd0ae6 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 13:48:32 +0100 Subject: [PATCH 07/17] Remove kubescripts from templating since we have it in dockerbuild --- app/pipeline/convert/const.go | 2 +- app/pipeline/convert/deploy_step.go | 2 +- .../convert/templates/static/kube-script.sh | 478 ------------------ app/pipeline/convert/templates/templates.go | 4 +- 4 files changed, 3 insertions(+), 483 deletions(-) delete mode 100755 app/pipeline/convert/templates/static/kube-script.sh diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 58c9c36..d26897d 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.13" + return "cloudnessio/builder:1.0.14" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index cc23345..999a2c8 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -30,7 +30,7 @@ func deployCommand( return err } - _, common, volume, app, route, err := templates.GenerateKubeTemplates(tmplIn) + common, volume, app, route, err := templates.GenerateKubeTemplates(tmplIn) if err != nil { return err } diff --git a/app/pipeline/convert/templates/static/kube-script.sh b/app/pipeline/convert/templates/static/kube-script.sh deleted file mode 100755 index 38e0d26..0000000 --- a/app/pipeline/convert/templates/static/kube-script.sh +++ /dev/null @@ -1,478 +0,0 @@ -# Cloudness Kubernetes Deployment Script -# This script deploys applications to Kubernetes with proper resource management - -# ============================================================================== -# Configuration & Constants -# ============================================================================== - -# Colors for output -readonly RED='\033[1;31m' -readonly GREEN='\033[1;32m' -readonly YELLOW='\033[1;33m' -readonly BLUE='\033[0;34m' -readonly NC='\033[0m' - -# Timeout configurations (can be overridden via environment) -readonly ROLLOUT_TIMEOUT_STATELESS="${ROLLOUT_TIMEOUT_STATELESS:-60s}" -readonly ROLLOUT_TIMEOUT_STATEFUL="${ROLLOUT_TIMEOUT_STATEFUL:-120s}" -readonly PVC_RESIZE_TIMEOUT="${PVC_RESIZE_TIMEOUT:-300}" -readonly PVC_RESIZE_POLL_INTERVAL="${PVC_RESIZE_POLL_INTERVAL:-5}" - -# Required environment variables with defaults -: "${CLOUDNESS_DEPLOY_APP_IDENTIFIER:=}" -: "${CLOUDNESS_DEPLOY_APP_NAMESPACE:=}" -: "${CLOUDNESS_DEPLOY_FLAG_APP_TYPE:=}" -: "${CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME:=0}" -: "${CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT:=0}" -: "${CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE:=0}" -: "${CLOUDNESS_DEPLOY_YAML_COMMON:=}" -: "${CLOUDNESS_DEPLOY_YAML_VOLUME:=}" -: "${CLOUDNESS_DEPLOY_YAML_APP:=}" -: "${CLOUDNESS_DEPLOY_YAML_ROUTE:=}" -: "${VERBOSE:=false}" - -# Track cleanup state -CLEANUP_DONE=false - -# ============================================================================== -# Logging Functions -# ============================================================================== - -log_error() { - echo -e "${RED}[ERROR]${NC} $*" >&2 -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $*" -} - -log_info() { - echo -e "$*" -} - -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $*" -} - -log_step() { - echo -e "$* ${GREEN}✔${NC}" -} - -print_section() { - text="$1" - echo "" - echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" - echo -e "${BLUE} ${text}${NC}" - echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" -} - -# ============================================================================== -# Validation Functions -# ============================================================================== - -command_exists() { - command -v "$1" >/dev/null 2>&1 -} - -validate_dependencies() { - missing="" - - if ! command_exists kubectl; then - missing="$missing kubectl" - fi - - if ! command_exists yq; then - missing="$missing yq" - fi - - if [ -n "$missing" ]; then - log_error "Missing required dependencies:$missing" - log_error "Please install them before running this script." - return 1 - fi - - return 0 -} - -validate_environment() { - has_errors=0 - - if [ -z "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" ]; then - log_error " - CLOUDNESS_DEPLOY_APP_IDENTIFIER is required" - has_errors=1 - fi - - if [ -z "$CLOUDNESS_DEPLOY_APP_NAMESPACE" ]; then - log_error " - CLOUDNESS_DEPLOY_APP_NAMESPACE is required" - has_errors=1 - fi - - if [ -z "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" ]; then - log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE is required" - has_errors=1 - elif [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateless" ] && [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" != "Stateful" ]; then - log_error " - CLOUDNESS_DEPLOY_FLAG_APP_TYPE must be 'Stateless' or 'Stateful'" - has_errors=1 - fi - - if [ "$has_errors" -eq 1 ]; then - log_error "Environment validation failed" - return 1 - fi - - return 0 -} - -# ============================================================================== -# Helper functions -# ============================================================================== - -# Function to run commands with optional output -run_command() { - if [ "$VERBOSE" = "true" ]; then - "$@" - else - "$@" > /dev/null 2>&1 - fi -} - -# ============================================================================== -# Kubernetes Operations -# ============================================================================== - -# Returns the resource type based on app type -get_resource_type() { - if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then - echo "deployment" - else - echo "statefulset" - fi -} - -# Returns the opposite resource type (for cleanup) -get_opposite_resource_type() { - if [ "$CLOUDNESS_DEPLOY_FLAG_APP_TYPE" = "Stateless" ]; then - echo "statefulset" - else - echo "deployment" - fi -} - -# Apply Kubernetes configuration from YAML string -kube_apply() { - yaml_string="$1" - error_output="" - - # Skip if empty - if [ -z "$yaml_string" ]; then - return 0 - fi - - # Apply the YAML - if [ "$VERBOSE" = "true" ]; then - if ! printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f -; then - log_error "Failed to apply Kubernetes configuration" - return 1 - fi - else - if ! error_output=$(printf '%s' "$yaml_string" | sed 's/\t/ /g' | kubectl apply -f - 2>&1 >/dev/null); then - log_error "Failed to apply Kubernetes configuration:" - log_error "$error_output" - return 1 - fi - fi - - return 0 -} - -# Delete a Kubernetes resource -kube_delete() { - resource_type="$1" - resource_name="$2" - namespace="$3" - error_output="" - - if [ "$VERBOSE" = "true" ]; then - if ! kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true; then - log_warn "Failed to delete $resource_type/$resource_name" - return 1 - fi - else - if ! error_output=$(kubectl delete "$resource_type/$resource_name" -n "$namespace" --ignore-not-found=true 2>&1 >/dev/null); then - log_warn "Failed to delete $resource_type/$resource_name: $error_output" - return 1 - fi - fi - - return 0 -} - -# Wait for rollout to complete -kube_rollout_status() { - resource_type="" - timeout="" - error_output="" - - resource_type=$(get_resource_type) - - if [ "$resource_type" = "deployment" ]; then - timeout="$ROLLOUT_TIMEOUT_STATELESS" - else - timeout="$ROLLOUT_TIMEOUT_STATEFUL" - fi - - if [ "$VERBOSE" = "true" ]; then - if ! kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ - -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ - --timeout="$timeout"; then - log_error "Rollout failed, reverting..." - kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ - -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true - return 1 - fi - else - if ! error_output=$(kubectl rollout status "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ - -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" \ - --timeout="$timeout" 2>&1); then - log_error "$error_output" - log_error "Rollout failed, reverting..." - kubectl rollout undo "$resource_type/$CLOUDNESS_DEPLOY_APP_IDENTIFIER" \ - -n "$CLOUDNESS_DEPLOY_APP_NAMESPACE" 2>/dev/null || true - return 1 - fi - fi - - return 0 -} - -# Parse storage size to numeric GiB value -parse_size_to_gib() { - size_str="$1" - echo "$size_str" | sed 's/Gi//' -} - -# Wait for PVC to resize -kube_wait_pvc_resize() { - pvc_name="$1" - new_size="$2" - namespace="$CLOUDNESS_DEPLOY_APP_NAMESPACE" - deadline="" - current_time="" - - current_time=$(date +%s) - deadline=$((current_time + PVC_RESIZE_TIMEOUT)) - - while true; do - # Check PVC status - pvc_status="" - pvc_status=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.phase}' 2>/dev/null || echo "") - - if [ "$VERBOSE" = "true" ]; then - log_info "PVC '$pvc_name' status: $pvc_status" - fi - - # Handle WaitForFirstConsumer - if [ "$pvc_status" = "Pending" ]; then - pvc_event="" - pvc_event=$(kubectl get events -n "$namespace" \ - --field-selector "involvedObject.kind=PersistentVolumeClaim,involvedObject.name=$pvc_name" \ - --sort-by=.lastTimestamp \ - -o jsonpath='{.items[-1:].reason}' 2>/dev/null || echo "") - if [ "$pvc_event" = "WaitForFirstConsumer" ]; then - return 0 - fi - fi - - # Check if resize completed - current_size="" - current_size=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.status.capacity.storage}' 2>/dev/null || echo "0Gi") - - if [ "$VERBOSE" = "true" ]; then - log_info "PVC '$pvc_name' current size: $current_size, target: $new_size" - fi - if [ "$(parse_size_to_gib "$current_size")" -ge "$(parse_size_to_gib "$new_size")" ]; then - return 0 - fi - - # Check for FileSystemResizePending condition - resize_pending="" - resize_pending=$(kubectl get pvc "$pvc_name" -n "$namespace" \ - -o jsonpath='{.status.conditions[?(@.type=="FileSystemResizePending")].status}' 2>/dev/null || echo "") - if [ "$resize_pending" = "True" ]; then - log_info "Volume resized. Remounting application to finalize." - return 0 - fi - - # Check timeout - current_time=$(date +%s) - if [ "$current_time" -ge "$deadline" ]; then - log_error "Timed out after ${PVC_RESIZE_TIMEOUT}s waiting for PVC '$pvc_name' to reach $new_size" - return 1 - fi - - log_info "Waiting for volume '$pvc_name'..." - sleep "$PVC_RESIZE_POLL_INTERVAL" - done -} - -# ============================================================================== -# Deployment Functions -# ============================================================================== - -deploy_common_artifacts() { - print_section "Setting up prerequisite artifacts" - - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_COMMON"; then - log_error "Failed to set up prerequisite artifacts" - return 1 - fi - - log_step "Prerequisite artifacts configured" - return 0 -} - -deploy_volume() { - if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME" -ne 1 ]; then - return 0 - fi - - print_section "Provisioning volumes" - - # Handle remount for volume resize - if [ "$CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT" -eq 1 ]; then - log_info "Volume resize detected, removing statefulset for remount..." - if ! kube_delete "statefulset" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE"; then - log_error "Failed to remove statefulset for remount" - return 1 - fi - fi - - # Apply volume configuration - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_VOLUME"; then - log_error "Failed to apply volume configuration" - return 1 - fi - - # Wait for each PVC to be ready - pvc_data="" - pvc_data=$(printf '%s' "$CLOUDNESS_DEPLOY_YAML_VOLUME" | sed 's/\t/ /g' | \ - yq -r 'select(.kind == "PersistentVolumeClaim") | .metadata.name + " " + .spec.resources.requests.storage' - 2>/dev/null || echo "") - - echo "$pvc_data" | while read -r pvc_name new_size; do - # Skip empty lines - pvc_name=$(echo "$pvc_name" | xargs) - new_size=$(echo "$new_size" | xargs) - if [ -z "$pvc_name" ] || [ -z "$new_size" ] || [ "$pvc_name" = "---" ]; then - continue - fi - - if ! kube_wait_pvc_resize "$pvc_name" "$new_size"; then - log_error "Failed to provision PVC '$pvc_name'" - return 1 - fi - done - - log_step "Volumes provisioned" - return 0 -} - -deploy_application() { - print_section "Deploying application" - - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_APP"; then - log_error "Failed to deploy application" - return 1 - fi - - if ! kube_rollout_status; then - return 1 - fi - - log_step "Application deployed" - return 0 -} - -deploy_routes() { - if [ "$CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE" -ne 1 ]; then - return 0 - fi - - print_section "Configuring HTTP routes" - - if ! kube_apply "$CLOUDNESS_DEPLOY_YAML_ROUTE"; then - log_error "Failed to configure HTTP routes" - return 1 - fi - - log_step "HTTP routes configured" - return 0 -} - -# ============================================================================== -# Lifecycle Management -# ============================================================================== - -cleanup() { - if [ "$CLEANUP_DONE" = "true" ]; then - return 0 - fi - CLEANUP_DONE=true - - log_info "Running cleanup..." - - opposite_type="" - opposite_type=$(get_opposite_resource_type) - - kube_delete "$opposite_type" "$CLOUDNESS_DEPLOY_APP_IDENTIFIER" "$CLOUDNESS_DEPLOY_APP_NAMESPACE" || true -} - -on_exit() { - exit_code=$? - if [ $exit_code -ne 0 ]; then - log_error "Deployment failed with exit code $exit_code" - fi - cleanup - exit $exit_code -} - -# ============================================================================== -# Main Entrypoint -# ============================================================================== - -main() { - # Set up exit trap - trap on_exit EXIT - - # Validate prerequisites - if ! validate_dependencies; then - exit 1 - fi - - if ! validate_environment; then - exit 1 - fi - - # Execute deployment steps - if ! deploy_common_artifacts; then - exit 1 - fi - - if ! deploy_volume; then - exit 1 - fi - - if ! deploy_application; then - exit 1 - fi - - if ! deploy_routes; then - exit 1 - fi - - # Success - echo "" - log_success "Deployment completed successfully!" -} - -# Run main function -main "$@" diff --git a/app/pipeline/convert/templates/templates.go b/app/pipeline/convert/templates/templates.go index 7485dee..426ad21 100644 --- a/app/pipeline/convert/templates/templates.go +++ b/app/pipeline/convert/templates/templates.go @@ -32,7 +32,6 @@ func init() { kubePVC = getTemplate("2-pvc.yaml") kubeApp = getTemplate("3-app.yaml") kubeHttproute = getTemplate("4-httproute.yaml") - kubeScripts = getFileContent("kube-script.sh") } func getFileContent(fileName string) string { @@ -90,8 +89,7 @@ type ( } ) -func GenerateKubeTemplates(input *TemplateIn) (script string, common string, pvc string, app string, route string, err error) { - script = kubeScripts +func GenerateKubeTemplates(input *TemplateIn) (common string, pvc string, app string, route string, err error) { common, err = renderTemplate(kubeCommon, input) if err != nil { return From 5fb5d5f2e80f268cc32385d571fa96c9a32ed4c7 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 18:32:25 +0530 Subject: [PATCH 08/17] Switch deployer scripts to go kube client --- app/pipeline/convert/deploy_step.go | 4 +- plugins/builder/Dockerfile | 12 + plugins/deployer/config.go | 118 +++++++ plugins/deployer/deployer.go | 458 ++++++++++++++++++++++++++++ plugins/deployer/logger.go | 66 ++++ plugins/deployer/main.go | 40 ++- 6 files changed, 694 insertions(+), 4 deletions(-) create mode 100644 plugins/deployer/config.go create mode 100644 plugins/deployer/deployer.go create mode 100644 plugins/deployer/logger.go diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index 999a2c8..1e0d820 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -77,8 +77,8 @@ func deployCommand( } addSecret(pCtx, step, "CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT", needsRemount) - // Run the deploy script - step.AddScriptCmd(". /usr/local/lib/deploy-script.sh") + // Run the Go-based deployer binary + step.AddScriptCmd("cloudness-deploy") step.VolumeMounts = append(step.VolumeMounts, getDeployVolumeMount(pCtx)) return nil diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index 78f3e45..78e82be 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -10,6 +10,14 @@ ARG TARGETPLATFORM ARG NIXPACKS_VERSION ARG KUBECTL_VERSION +# Build the deployer binary +FROM golang:1.25-alpine AS deployer-builder +WORKDIR /build +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /deployer ./plugins/deployer + FROM bitnami/kubectl:${KUBECTL_VERSION} AS kubectl FROM ${BASE_IMAGE} AS base @@ -24,6 +32,10 @@ RUN curl -sSL https://nixpacks.com/install.sh | bash COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl RUN chmod +x /usr/local/bin/kubectl +# Add deployer binary +COPY --from=deployer-builder /deployer /usr/local/bin/cloudness-deploy +RUN chmod +x /usr/local/bin/cloudness-deploy + # Add shared utilities and scripts COPY scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh COPY scripts/init-script.sh /usr/local/lib/init-script.sh diff --git a/plugins/deployer/config.go b/plugins/deployer/config.go new file mode 100644 index 0000000..5eafa3f --- /dev/null +++ b/plugins/deployer/config.go @@ -0,0 +1,118 @@ +package main + +import ( + "fmt" + "os" + "strconv" +) + +// Config holds all deployment configuration from environment variables +type Config struct { + // Application identifiers + AppIdentifier string + AppNamespace string + AppType AppType // "Stateless" or "Stateful" + + // Feature flags + HasVolume bool + HasRoute bool + NeedRemount bool + + // YAML file paths + DeployPath string + CommonYAMLPath string + VolumeYAMLPath string + AppYAMLPath string + RouteYAMLPath string + + // Timeouts + RolloutTimeoutStateless int // seconds + RolloutTimeoutStateful int // seconds + PVCResizeTimeout int // seconds + PVCResizePollInterval int // seconds + + // Options + Verbose bool +} + +type AppType string + +const ( + AppTypeStateless AppType = "Stateless" + AppTypeStateful AppType = "Stateful" +) + +// LoadConfigFromEnv loads configuration from environment variables +func LoadConfigFromEnv() (*Config, error) { + cfg := &Config{ + AppIdentifier: os.Getenv("CLOUDNESS_DEPLOY_APP_IDENTIFIER"), + AppNamespace: os.Getenv("CLOUDNESS_DEPLOY_APP_NAMESPACE"), + AppType: AppType(os.Getenv("CLOUDNESS_DEPLOY_FLAG_APP_TYPE")), + DeployPath: os.Getenv("CLOUDNESS_DEPLOY_PATH"), + HasVolume: os.Getenv("CLOUDNESS_DEPLOY_FLAG_HAS_VOLUME") == "1", + HasRoute: os.Getenv("CLOUDNESS_DEPLOY_FLAG_HAS_ROUTE") == "1", + NeedRemount: os.Getenv("CLOUDNESS_DEPLOY_FLAG_NEED_REMOUNT") == "1", + Verbose: os.Getenv("VERBOSE") == "true", + + // Defaults + RolloutTimeoutStateless: getEnvInt("ROLLOUT_TIMEOUT_STATELESS", 60), + RolloutTimeoutStateful: getEnvInt("ROLLOUT_TIMEOUT_STATEFUL", 120), + PVCResizeTimeout: getEnvInt("PVC_RESIZE_TIMEOUT", 300), + PVCResizePollInterval: getEnvInt("PVC_RESIZE_POLL_INTERVAL", 5), + } + + // Validate required fields + if cfg.AppIdentifier == "" { + return nil, fmt.Errorf("CLOUDNESS_DEPLOY_APP_IDENTIFIER is required") + } + if cfg.AppNamespace == "" { + return nil, fmt.Errorf("CLOUDNESS_DEPLOY_APP_NAMESPACE is required") + } + if cfg.AppType != AppTypeStateless && cfg.AppType != AppTypeStateful { + return nil, fmt.Errorf("CLOUDNESS_DEPLOY_FLAG_APP_TYPE must be 'Stateless' or 'Stateful', got '%s'", cfg.AppType) + } + if cfg.DeployPath == "" { + return nil, fmt.Errorf("CLOUDNESS_DEPLOY_PATH is required") + } + + // Set YAML file paths + cfg.CommonYAMLPath = cfg.DeployPath + "/common.yaml" + cfg.VolumeYAMLPath = cfg.DeployPath + "/volume.yaml" + cfg.AppYAMLPath = cfg.DeployPath + "/app.yaml" + cfg.RouteYAMLPath = cfg.DeployPath + "/route.yaml" + + return cfg, nil +} + +func getEnvInt(key string, defaultVal int) int { + if v := os.Getenv(key); v != "" { + if i, err := strconv.Atoi(v); err == nil { + return i + } + } + return defaultVal +} + +// ResourceType returns the Kubernetes resource type for this app +func (c *Config) ResourceType() string { + if c.AppType == AppTypeStateless { + return "Deployment" + } + return "StatefulSet" +} + +// OppositeResourceType returns the opposite resource type (for cleanup) +func (c *Config) OppositeResourceType() string { + if c.AppType == AppTypeStateless { + return "StatefulSet" + } + return "Deployment" +} + +// RolloutTimeout returns the appropriate timeout based on app type +func (c *Config) RolloutTimeout() int { + if c.AppType == AppTypeStateless { + return c.RolloutTimeoutStateless + } + return c.RolloutTimeoutStateful +} diff --git a/plugins/deployer/deployer.go b/plugins/deployer/deployer.go new file mode 100644 index 0000000..33d53ff --- /dev/null +++ b/plugins/deployer/deployer.go @@ -0,0 +1,458 @@ +package main + +import ( + "bufio" + "bytes" + "context" + "fmt" + "io" + "os" + "strings" + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + "k8s.io/apimachinery/pkg/types" + yamlutil "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/discovery" + "k8s.io/client-go/discovery/cached/memory" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" +) + +// Deployer handles Kubernetes deployments +type Deployer struct { + config *Config + clientset kubernetes.Interface + dynamicClient dynamic.Interface + mapper meta.RESTMapper + log *Logger +} + +// NewDeployer creates a new deployer instance +func NewDeployer(cfg *Config) (*Deployer, error) { + // Get in-cluster config + restConfig, err := rest.InClusterConfig() + if err != nil { + return nil, fmt.Errorf("failed to get in-cluster config: %w", err) + } + + // Create clientset + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return nil, fmt.Errorf("failed to create kubernetes client: %w", err) + } + + // Create dynamic client + dynamicClient, err := dynamic.NewForConfig(restConfig) + if err != nil { + return nil, fmt.Errorf("failed to create dynamic client: %w", err) + } + + // Create discovery client and mapper + dc, err := discovery.NewDiscoveryClientForConfig(restConfig) + if err != nil { + return nil, fmt.Errorf("failed to create discovery client: %w", err) + } + mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc)) + + return &Deployer{ + config: cfg, + clientset: clientset, + dynamicClient: dynamicClient, + mapper: mapper, + log: NewLogger(cfg.Verbose), + }, nil +} + +// Deploy runs the full deployment workflow +func (d *Deployer) Deploy(ctx context.Context) error { + d.log.Section("Deploying application") + + // Step 1: Apply common artifacts (namespace, service account, etc.) + if err := d.applyCommonArtifacts(ctx); err != nil { + return fmt.Errorf("failed to apply common artifacts: %w", err) + } + d.log.Step("Prerequisite artifacts configured") + + // Step 2: Handle volumes (if any) + if d.config.HasVolume { + if err := d.deployVolumes(ctx); err != nil { + return fmt.Errorf("failed to deploy volumes: %w", err) + } + d.log.Step("Volumes provisioned") + } + + // Step 3: Deploy application + if err := d.deployApplication(ctx); err != nil { + return fmt.Errorf("failed to deploy application: %w", err) + } + d.log.Step("Application deployed") + + // Step 4: Configure routes (if any) + if d.config.HasRoute { + if err := d.deployRoutes(ctx); err != nil { + return fmt.Errorf("failed to deploy routes: %w", err) + } + d.log.Step("HTTP routes configured") + } + + // Cleanup: Remove opposite resource type + d.cleanup(ctx) + + d.log.Success("Deployment completed successfully!") + return nil +} + +// applyCommonArtifacts applies common Kubernetes resources +func (d *Deployer) applyCommonArtifacts(ctx context.Context) error { + return d.applyYAMLFile(ctx, d.config.CommonYAMLPath) +} + +// deployVolumes handles PVC creation and resizing +func (d *Deployer) deployVolumes(ctx context.Context) error { + // Handle remount for volume resize + if d.config.NeedRemount { + d.log.Info("Volume resize detected, removing statefulset for remount...") + if err := d.deleteStatefulSet(ctx); err != nil { + d.log.Warn("Failed to remove statefulset: %v", err) + } + } + + // Apply volume configuration + if err := d.applyYAMLFile(ctx, d.config.VolumeYAMLPath); err != nil { + return err + } + + // Wait for PVCs to be ready + return d.waitForPVCs(ctx) +} + +// deployApplication deploys the main application and waits for rollout +func (d *Deployer) deployApplication(ctx context.Context) error { + if err := d.applyYAMLFile(ctx, d.config.AppYAMLPath); err != nil { + return err + } + + return d.waitForRollout(ctx) +} + +// deployRoutes applies route/ingress configuration +func (d *Deployer) deployRoutes(ctx context.Context) error { + return d.applyYAMLFile(ctx, d.config.RouteYAMLPath) +} + +// applyYAMLFile reads and applies a YAML file containing one or more manifests +func (d *Deployer) applyYAMLFile(ctx context.Context, filepath string) error { + // Check if file exists and has content + info, err := os.Stat(filepath) + if os.IsNotExist(err) || (err == nil && info.Size() == 0) { + d.log.Debug("Skipping empty or non-existent file: %s", filepath) + return nil + } + if err != nil { + return fmt.Errorf("failed to stat file %s: %w", filepath, err) + } + + data, err := os.ReadFile(filepath) + if err != nil { + return fmt.Errorf("failed to read file %s: %w", filepath, err) + } + + return d.applyYAML(ctx, data) +} + +// applyYAML applies YAML content containing one or more Kubernetes manifests +func (d *Deployer) applyYAML(ctx context.Context, yamlData []byte) error { + decoder := yamlutil.NewYAMLOrJSONDecoder(bufio.NewReader(bytes.NewReader(yamlData)), 4096) + decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + + for { + var rawObj runtime.RawExtension + if err := decoder.Decode(&rawObj); err != nil { + if err == io.EOF { + break + } + return fmt.Errorf("failed to decode yaml: %w", err) + } + + if rawObj.Raw == nil { + continue + } + + obj := &unstructured.Unstructured{} + _, gvk, err := decUnstructured.Decode(rawObj.Raw, nil, obj) + if err != nil { + return fmt.Errorf("failed to decode object: %w", err) + } + + // Get the REST mapping for this GVK + mapping, err := d.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return fmt.Errorf("failed to get REST mapping for %v: %w", gvk, err) + } + + // Get the resource interface + var dr dynamic.ResourceInterface + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + ns := obj.GetNamespace() + if ns == "" { + ns = d.config.AppNamespace + obj.SetNamespace(ns) + } + dr = d.dynamicClient.Resource(mapping.Resource).Namespace(ns) + } else { + dr = d.dynamicClient.Resource(mapping.Resource) + } + + // Apply using server-side apply + d.log.Debug("Applying %s/%s in %s", gvk.Kind, obj.GetName(), obj.GetNamespace()) + _, err = dr.Patch(ctx, obj.GetName(), types.ApplyPatchType, rawObj.Raw, metav1.PatchOptions{ + FieldManager: "cloudness-deployer", + }) + if err != nil { + // Fall back to Create/Update + _, err = dr.Create(ctx, obj, metav1.CreateOptions{}) + if errors.IsAlreadyExists(err) { + _, err = dr.Update(ctx, obj, metav1.UpdateOptions{}) + } + if err != nil { + return fmt.Errorf("failed to apply %s/%s: %w", gvk.Kind, obj.GetName(), err) + } + } + } + + return nil +} + +// waitForRollout waits for the deployment/statefulset to roll out +func (d *Deployer) waitForRollout(ctx context.Context) error { + timeout := time.Duration(d.config.RolloutTimeout()) * time.Second + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + d.log.Error("Rollout timed out after %v, reverting...", timeout) + d.rollback(context.Background()) // Use background context for rollback + return fmt.Errorf("rollout timed out") + case <-ticker.C: + ready, err := d.checkRolloutStatus(ctx) + if err != nil { + d.log.Debug("Error checking rollout status: %v", err) + continue + } + if ready { + return nil + } + } + } +} + +// checkRolloutStatus checks if the deployment/statefulset is ready +func (d *Deployer) checkRolloutStatus(ctx context.Context) (bool, error) { + if d.config.AppType == AppTypeStateless { + deploy, err := d.clientset.AppsV1().Deployments(d.config.AppNamespace).Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) + if err != nil { + return false, err + } + return d.isDeploymentReady(deploy), nil + } + + sts, err := d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) + if err != nil { + return false, err + } + return d.isStatefulSetReady(sts), nil +} + +func (d *Deployer) isDeploymentReady(deploy *appsv1.Deployment) bool { + if deploy.Generation != deploy.Status.ObservedGeneration { + return false + } + for _, cond := range deploy.Status.Conditions { + if cond.Type == appsv1.DeploymentAvailable && cond.Status == corev1.ConditionTrue { + if deploy.Status.UpdatedReplicas == *deploy.Spec.Replicas && + deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { + return true + } + } + } + return false +} + +func (d *Deployer) isStatefulSetReady(sts *appsv1.StatefulSet) bool { + if sts.Generation != sts.Status.ObservedGeneration { + return false + } + return sts.Status.UpdatedReplicas == *sts.Spec.Replicas && + sts.Status.ReadyReplicas == *sts.Spec.Replicas +} + +// rollback rolls back a failed deployment +func (d *Deployer) rollback(ctx context.Context) { + if d.config.AppType == AppTypeStateless { + // For deployments, we can use rollout undo + deploys := d.clientset.AppsV1().Deployments(d.config.AppNamespace) + deploy, err := deploys.Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) + if err != nil { + d.log.Error("Failed to get deployment for rollback: %v", err) + return + } + + // Set revision to previous + if deploy.Annotations == nil { + deploy.Annotations = make(map[string]string) + } + deploy.Annotations["deployment.kubernetes.io/revision"] = "" + + _, err = deploys.Update(ctx, deploy, metav1.UpdateOptions{}) + if err != nil { + d.log.Error("Failed to rollback deployment: %v", err) + } + } + // StatefulSets don't support automatic rollback +} + +// waitForPVCs waits for all PVCs to be bound or resized +func (d *Deployer) waitForPVCs(ctx context.Context) error { + // Read PVC names from the volume YAML + data, err := os.ReadFile(d.config.VolumeYAMLPath) + if err != nil { + return nil // No volume file, skip + } + + pvcNames := d.extractPVCNames(data) + if len(pvcNames) == 0 { + return nil + } + + timeout := time.Duration(d.config.PVCResizeTimeout) * time.Second + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + for _, pvcName := range pvcNames { + if err := d.waitForPVC(ctx, pvcName); err != nil { + return err + } + } + + return nil +} + +// extractPVCNames extracts PVC names from YAML content +func (d *Deployer) extractPVCNames(yamlData []byte) []string { + var names []string + decoder := yamlutil.NewYAMLOrJSONDecoder(bufio.NewReader(bytes.NewReader(yamlData)), 4096) + + for { + var obj unstructured.Unstructured + if err := decoder.Decode(&obj); err != nil { + break + } + if obj.GetKind() == "PersistentVolumeClaim" { + names = append(names, obj.GetName()) + } + } + return names +} + +// waitForPVC waits for a single PVC to be ready +func (d *Deployer) waitForPVC(ctx context.Context, name string) error { + ticker := time.NewTicker(time.Duration(d.config.PVCResizePollInterval) * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return fmt.Errorf("timed out waiting for PVC %s", name) + case <-ticker.C: + pvc, err := d.clientset.CoreV1().PersistentVolumeClaims(d.config.AppNamespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + d.log.Debug("Error getting PVC %s: %v", name, err) + continue + } + + d.log.Debug("PVC %s status: %s", name, pvc.Status.Phase) + + switch pvc.Status.Phase { + case corev1.ClaimBound: + return nil + case corev1.ClaimPending: + // Check for WaitForFirstConsumer + if d.isWaitingForFirstConsumer(ctx, name) { + d.log.Debug("PVC %s waiting for first consumer", name) + return nil + } + } + + // Check for FileSystemResizePending + for _, cond := range pvc.Status.Conditions { + if cond.Type == corev1.PersistentVolumeClaimFileSystemResizePending && cond.Status == corev1.ConditionTrue { + d.log.Info("Volume %s resized. Remounting application to finalize.", name) + return nil + } + } + } + } +} + +// isWaitingForFirstConsumer checks if PVC is pending due to WaitForFirstConsumer +func (d *Deployer) isWaitingForFirstConsumer(ctx context.Context, pvcName string) bool { + events, err := d.clientset.CoreV1().Events(d.config.AppNamespace).List(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("involvedObject.kind=PersistentVolumeClaim,involvedObject.name=%s", pvcName), + }) + if err != nil { + return false + } + + for _, event := range events.Items { + if event.Reason == "WaitForFirstConsumer" { + return true + } + } + return false +} + +// deleteStatefulSet deletes the StatefulSet (for volume remount) +func (d *Deployer) deleteStatefulSet(ctx context.Context) error { + return d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Delete( + ctx, + d.config.AppIdentifier, + metav1.DeleteOptions{}, + ) +} + +// cleanup removes the opposite resource type (cleanup old deployment/statefulset) +func (d *Deployer) cleanup(ctx context.Context) { + d.log.Debug("Running cleanup...") + + var err error + if d.config.AppType == AppTypeStateless { + // Remove any StatefulSet with the same name + err = d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Delete( + ctx, d.config.AppIdentifier, metav1.DeleteOptions{}, + ) + } else { + // Remove any Deployment with the same name + err = d.clientset.AppsV1().Deployments(d.config.AppNamespace).Delete( + ctx, d.config.AppIdentifier, metav1.DeleteOptions{}, + ) + } + + if err != nil && !errors.IsNotFound(err) && !strings.Contains(err.Error(), "not found") { + d.log.Warn("Failed to cleanup opposite resource: %v", err) + } +} diff --git a/plugins/deployer/logger.go b/plugins/deployer/logger.go new file mode 100644 index 0000000..ec8b300 --- /dev/null +++ b/plugins/deployer/logger.go @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + "os" +) + +// Logger provides structured logging with colors +type Logger struct { + verbose bool +} + +// ANSI color codes +const ( + colorRed = "\033[1;31m" + colorGreen = "\033[1;32m" + colorYellow = "\033[1;33m" + colorBlue = "\033[0;34m" + colorReset = "\033[0m" +) + +// NewLogger creates a new logger +func NewLogger(verbose bool) *Logger { + return &Logger{verbose: verbose} +} + +// Error prints an error message +func (l *Logger) Error(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, colorRed+"❌ "+format+colorReset+"\n", args...) +} + +// Warn prints a warning message +func (l *Logger) Warn(format string, args ...interface{}) { + fmt.Printf(colorYellow+"⚠️ "+format+colorReset+"\n", args...) +} + +// Info prints an info message +func (l *Logger) Info(format string, args ...interface{}) { + fmt.Printf(format+"\n", args...) +} + +// Success prints a success message +func (l *Logger) Success(format string, args ...interface{}) { + fmt.Printf(colorGreen+"✔ "+format+colorReset+"\n", args...) +} + +// Step prints a step completion message +func (l *Logger) Step(format string, args ...interface{}) { + msg := fmt.Sprintf(format, args...) + fmt.Printf("%s "+colorGreen+"✔"+colorReset+"\n", msg) +} + +// Debug prints a debug message (only if verbose) +func (l *Logger) Debug(format string, args ...interface{}) { + if l.verbose { + fmt.Printf(colorBlue+"[DEBUG] "+format+colorReset+"\n", args...) + } +} + +// Section prints a section header +func (l *Logger) Section(title string) { + fmt.Println() + fmt.Println(colorBlue + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + colorReset) + fmt.Printf(colorBlue+" %s"+colorReset+"\n", title) + fmt.Println(colorBlue + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + colorReset) +} diff --git a/plugins/deployer/main.go b/plugins/deployer/main.go index c5b00dd..6cda0dc 100644 --- a/plugins/deployer/main.go +++ b/plugins/deployer/main.go @@ -1,9 +1,45 @@ package main import ( - "fmt" + "context" + "os" + "os/signal" + "syscall" ) func main() { - fmt.Println("main") + log := NewLogger(os.Getenv("VERBOSE") == "true") + + // Load configuration + cfg, err := LoadConfigFromEnv() + if err != nil { + log.Error("Configuration error: %v", err) + os.Exit(1) + } + + // Create deployer + deployer, err := NewDeployer(cfg) + if err != nil { + log.Error("Failed to initialize deployer: %v", err) + os.Exit(1) + } + + // Setup context with cancellation + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Handle signals + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-sigCh + log.Warn("Received shutdown signal") + cancel() + }() + + // Run deployment + if err := deployer.Deploy(ctx); err != nil { + log.Error("Deployment failed: %v", err) + os.Exit(1) + } } From f69af7b5e1faa9b516786f3a559f2089557279ed Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Wed, 31 Dec 2025 18:40:03 +0530 Subject: [PATCH 09/17] Fix build paths for deployer plugin --- plugins/builder/Dockerfile | 8 ++++---- runbooks/dev/loacalbuilder.md | 8 +++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index 78e82be..07a69d4 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -37,10 +37,10 @@ COPY --from=deployer-builder /deployer /usr/local/bin/cloudness-deploy RUN chmod +x /usr/local/bin/cloudness-deploy # Add shared utilities and scripts -COPY scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh -COPY scripts/init-script.sh /usr/local/lib/init-script.sh -COPY scripts/build-script.sh /usr/local/lib/build-script.sh -COPY scripts/deploy-script.sh /usr/local/lib/deploy-script.sh +COPY plugins/builder/scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh +COPY plugins/builder/scripts/init-script.sh /usr/local/lib/init-script.sh +COPY plugins/builder/scripts/build-script.sh /usr/local/lib/build-script.sh +COPY plugins/builder/scripts/deploy-script.sh /usr/local/lib/deploy-script.sh RUN chmod +x /usr/local/lib/cloudness-utils.sh /usr/local/lib/init-script.sh /usr/local/lib/build-script.sh /usr/local/lib/deploy-script.sh # Auto-source utilities for all sh scripts diff --git a/runbooks/dev/loacalbuilder.md b/runbooks/dev/loacalbuilder.md index d6db937..8207299 100644 --- a/runbooks/dev/loacalbuilder.md +++ b/runbooks/dev/loacalbuilder.md @@ -1,11 +1,9 @@ - -cd plugins/builder/ - ## Quick Start (All-in-One) ```bash +# Run from project root directory export IMAGE_TAG="1.0.0" && \ - docker build . -t cloudnessio/builder:${IMAGE_TAG} && \ + docker build -f plugins/builder/Dockerfile -t cloudnessio/builder:${IMAGE_TAG} . && \ sudo docker save cloudnessio/builder:${IMAGE_TAG} | \ sudo ctr -a /run/k3s/containerd/containerd.sock -n=k8s.io images import - -``` \ No newline at end of file +``` From 87d858adc1211c473aa243f6d32a64cacd09da47 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 11:35:01 +0530 Subject: [PATCH 10/17] Add go mods for builder --- plugins/builder/Dockerfile | 16 +- plugins/deployer/go.mod | 177 +++++++++ plugins/deployer/go.sum | 660 ++++++++++++++++++++++++++++++++++ runbooks/dev/loacalbuilder.md | 5 +- 4 files changed, 848 insertions(+), 10 deletions(-) create mode 100644 plugins/deployer/go.mod create mode 100644 plugins/deployer/go.sum diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index 07a69d4..adf7cb9 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -10,13 +10,13 @@ ARG TARGETPLATFORM ARG NIXPACKS_VERSION ARG KUBECTL_VERSION -# Build the deployer binary +# Build the deployer binary (has its own go.mod) FROM golang:1.25-alpine AS deployer-builder WORKDIR /build -COPY go.mod go.sum ./ +COPY ../plugins/deployer/go.mod ../plugins/deployer/go.sum ./ RUN go mod download -COPY . . -RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /deployer ./plugins/deployer +COPY ../plugins/deployer/*.go ./ +RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /plugins/deployer . FROM bitnami/kubectl:${KUBECTL_VERSION} AS kubectl FROM ${BASE_IMAGE} AS base @@ -37,10 +37,10 @@ COPY --from=deployer-builder /deployer /usr/local/bin/cloudness-deploy RUN chmod +x /usr/local/bin/cloudness-deploy # Add shared utilities and scripts -COPY plugins/builder/scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh -COPY plugins/builder/scripts/init-script.sh /usr/local/lib/init-script.sh -COPY plugins/builder/scripts/build-script.sh /usr/local/lib/build-script.sh -COPY plugins/builder/scripts/deploy-script.sh /usr/local/lib/deploy-script.sh +COPY scripts/cloudness-utils.sh /usr/local/lib/cloudness-utils.sh +COPY scripts/init-script.sh /usr/local/lib/init-script.sh +COPY scripts/build-script.sh /usr/local/lib/build-script.sh +COPY scripts/deploy-script.sh /usr/local/lib/deploy-script.sh RUN chmod +x /usr/local/lib/cloudness-utils.sh /usr/local/lib/init-script.sh /usr/local/lib/build-script.sh /usr/local/lib/deploy-script.sh # Auto-source utilities for all sh scripts diff --git a/plugins/deployer/go.mod b/plugins/deployer/go.mod new file mode 100644 index 0000000..3010b37 --- /dev/null +++ b/plugins/deployer/go.mod @@ -0,0 +1,177 @@ +module github.com/cloudness-io/cloudness/plugins/deployer + +go 1.25 + +require ( + cloud.google.com/go/profiler v0.4.3 + github.com/Masterminds/squirrel v1.5.4 + github.com/a-h/templ v0.3.943 + github.com/alecthomas/kingpin/v2 v2.4.0 + github.com/cert-manager/cert-manager v1.18.2 + github.com/cloudflare/cloudflare-go v0.116.0 + github.com/coreos/go-semver v0.3.1 + github.com/dchest/uniuri v1.2.0 + github.com/drone/go-scm v1.40.6 + github.com/go-chi/chi/v5 v5.2.3 + github.com/go-logr/logr v1.4.3 + github.com/go-logr/zerologr v1.2.3 + github.com/go-redsync/redsync/v4 v4.15.0 + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/golang-jwt/jwt/v5 v5.3.0 + github.com/google/go-github/v69 v69.2.0 + github.com/google/wire v0.7.0 + github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 + github.com/gotidy/ptr v1.4.0 + github.com/jmoiron/sqlx v1.4.0 + github.com/joho/godotenv v1.5.1 + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/lib/pq v1.10.9 + github.com/maragudk/migrate v0.4.3 + github.com/mattn/go-isatty v0.0.20 + github.com/mattn/go-sqlite3 v1.14.32 + github.com/miekg/dns v1.1.68 + github.com/pkg/errors v0.9.1 + github.com/qri-io/jsonschema v0.2.1 + github.com/redis/go-redis/v9 v9.17.2 + github.com/rs/xid v1.6.0 + github.com/rs/zerolog v1.34.0 + golang.org/x/crypto v0.46.0 + golang.org/x/exp v0.0.0-20250911091902-df9299821621 + golang.org/x/net v0.48.0 + golang.org/x/oauth2 v0.31.0 + golang.org/x/sync v0.19.0 + golang.org/x/text v0.32.0 + k8s.io/api v0.34.1 + k8s.io/apimachinery v0.34.1 + k8s.io/client-go v0.34.1 + sigs.k8s.io/controller-runtime v0.22.1 + sigs.k8s.io/gateway-api v1.4.1 +) + +require ( + cloud.google.com/go v0.122.0 // indirect + cloud.google.com/go/auth v0.16.5 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.8.0 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect + github.com/air-verse/air v1.61.7 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bep/godartsass/v2 v2.3.2 // indirect + github.com/bep/golibsass v1.2.0 // indirect + github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cli/browser v1.3.0 // indirect + github.com/cli/safeexec v1.0.1 // indirect + github.com/creack/pty v1.1.23 // indirect + github.com/daixiang0/gci v0.13.7 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.22.0 // indirect + github.com/go-openapi/jsonreference v0.21.1 // indirect + github.com/go-openapi/swag v0.24.1 // indirect + github.com/go-openapi/swag/cmdutils v0.24.0 // indirect + github.com/go-openapi/swag/conv v0.24.0 // indirect + github.com/go-openapi/swag/fileutils v0.24.0 // indirect + github.com/go-openapi/swag/jsonname v0.24.0 // indirect + github.com/go-openapi/swag/jsonutils v0.24.0 // indirect + github.com/go-openapi/swag/loading v0.24.0 // indirect + github.com/go-openapi/swag/mangling v0.24.0 // indirect + github.com/go-openapi/swag/netutils v0.24.0 // indirect + github.com/go-openapi/swag/stringutils v0.24.0 // indirect + github.com/go-openapi/swag/typeutils v0.24.0 // indirect + github.com/go-openapi/swag/yamlutils v0.24.0 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/gohugoio/hugo v0.139.4 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/subcommands v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/makiuchi-d/arelo v1.15.2 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/natefinch/atomic v1.0.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.23.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/procfs v0.17.0 // indirect + github.com/qri-io/jsonpointer v0.1.1 // indirect + github.com/robert-nix/ansihtml v1.0.1 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cobra v1.9.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tdewolff/parse/v2 v2.7.15 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.39.0 // indirect + golang.org/x/vuln v1.1.4 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/api v0.249.0 // indirect + google.golang.org/genproto v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/grpc v1.75.1 // indirect + google.golang.org/protobuf v1.36.9 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.34.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) \ No newline at end of file diff --git a/plugins/deployer/go.sum b/plugins/deployer/go.sum new file mode 100644 index 0000000..a3bcea2 --- /dev/null +++ b/plugins/deployer/go.sum @@ -0,0 +1,660 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.122.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= +cloud.google.com/go/profiler v0.4.3/go.mod h1:3xFodugWfPIQZWFcXdUmfa+yTiiyQ8fWrdT+d2Sg4J0= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ= +github.com/a-h/templ v0.3.943/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/air-verse/air v1.61.7/go.mod h1:QW4HkIASdtSnwaYof1zgJCSxd41ebvix10t5ubtm9cg= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bep/godartsass/v2 v2.3.2/go.mod h1:Qe5WOS9nVJy7G0jHssXPd3c+Pqk/f7+Tm6k/vahbVgs= +github.com/bep/golibsass v1.2.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cert-manager/cert-manager v1.18.2/go.mod h1:icDJx4kG9BCNpGjBvrmsFd99d+lXUvWdkkcrSSQdIiw= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= +github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.116.0/go.mod h1:Ds6urDwn/TF2uIU24mu7H91xkKP8gSAHxQ44DSZgVmU= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= +github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/drone/go-scm v1.40.6/go.mod h1:DFIJJjhMj0TSXPz+0ni4nyZ9gtTtC40Vh/TGRugtyWw= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zerologr v1.2.3/go.mod h1:BxwGo7y5zgSHYR1BjbnHPyF/5ZjVKfKxAZANVu6E8Ho= +github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= +github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= +github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= +github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= +github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= +github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= +github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= +github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= +github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= +github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= +github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= +github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= +github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= +github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= +github.com/go-redsync/redsync/v4 v4.15.0/go.mod h1:qNp+lLs3vkfZbtA/aM/OjlZHfEr5YTAYhRktFPKHC7s= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gohugoio/hugo v0.139.4/go.mod h1:GPiZJZy5jCGiJ6Jtg0KdhE1JdpBTqhgtsbhpc1n8d5s= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20250903194437-c28834ac2320/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gotidy/ptr v1.4.0/go.mod h1:MjRBG6/IETiiZGWI8LrRtISXEji+8b/jigmj2q0mEyM= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/makiuchi-d/arelo v1.15.2/go.mod h1:StrMnkdxCbMO2dPmRi8s+6AJw1tdvBP0xDYZDFt6etk= +github.com/maragudk/migrate v0.4.3/go.mod h1:vhmL4s+Xz75KU6DPZWRfqb45YyqjYQfcXliA1DsYzvY= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/qri-io/jsonpointer v0.1.1/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= +github.com/qri-io/jsonschema v0.2.1/go.mod h1:g7DPkiOsK1xv6T/Ao5scXRkd+yTFygcANPBaaqW+VrI= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= +github.com/robert-nix/ansihtml v1.0.1/go.mod h1:CJwclxYaTPc2RfcxtanEACsYuTksh4yDXcNeHHKZINE= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20250908214217-97024824d090/go.mod h1:zwJI9HzbJJlw2KXy0wX+lmT2JuZoaKK9JC4ppqmxxjk= +google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= +k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= +k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.22.1/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= +sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/runbooks/dev/loacalbuilder.md b/runbooks/dev/loacalbuilder.md index 8207299..5b35e5c 100644 --- a/runbooks/dev/loacalbuilder.md +++ b/runbooks/dev/loacalbuilder.md @@ -1,9 +1,10 @@ ## Quick Start (All-in-One) ```bash -# Run from project root directory +# Run from plugins directory +cd plugins/builder export IMAGE_TAG="1.0.0" && \ - docker build -f plugins/builder/Dockerfile -t cloudnessio/builder:${IMAGE_TAG} . && \ + docker build -f Dockerfile -t cloudnessio/builder:${IMAGE_TAG} . && \ sudo docker save cloudnessio/builder:${IMAGE_TAG} | \ sudo ctr -a /run/k3s/containerd/containerd.sock -n=k8s.io images import - ``` From 6deac0add6d1a128e0f2502b3e74b830568d829d Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 07:14:34 +0100 Subject: [PATCH 11/17] Move deployer to plugins/builder --- app/pipeline/convert/const.go | 2 +- app/web/public/assets/styles.css | 9 + plugins/builder/Dockerfile | 6 +- plugins/{ => builder}/deployer/config.go | 0 plugins/{ => builder}/deployer/deployer.go | 0 plugins/builder/deployer/go.mod | 65 ++ plugins/builder/deployer/go.sum | 166 ++++++ plugins/{ => builder}/deployer/logger.go | 0 plugins/{ => builder}/deployer/main.go | 0 plugins/deployer/go.mod | 177 ------ plugins/deployer/go.sum | 660 --------------------- 11 files changed, 244 insertions(+), 841 deletions(-) rename plugins/{ => builder}/deployer/config.go (100%) rename plugins/{ => builder}/deployer/deployer.go (100%) create mode 100644 plugins/builder/deployer/go.mod create mode 100644 plugins/builder/deployer/go.sum rename plugins/{ => builder}/deployer/logger.go (100%) rename plugins/{ => builder}/deployer/main.go (100%) delete mode 100644 plugins/deployer/go.mod delete mode 100644 plugins/deployer/go.sum diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index d26897d..212e670 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.14" + return "cloudnessio/builder:1.0.16" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/app/web/public/assets/styles.css b/app/web/public/assets/styles.css index f2c4a93..33eea1f 100644 --- a/app/web/public/assets/styles.css +++ b/app/web/public/assets/styles.css @@ -260,6 +260,9 @@ .pointer-events-none { pointer-events: none; } + .collapse { + visibility: collapse; + } .invisible { visibility: hidden; } @@ -340,6 +343,9 @@ .left-\[-18px\] { left: -18px; } + .isolate { + isolation: isolate; + } .z-10 { z-index: 10; } @@ -572,6 +578,9 @@ .hidden\! { display: none !important; } + .inline { + display: inline; + } .inline-block { display: inline-block; } diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index adf7cb9..08d9d12 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -13,10 +13,10 @@ ARG KUBECTL_VERSION # Build the deployer binary (has its own go.mod) FROM golang:1.25-alpine AS deployer-builder WORKDIR /build -COPY ../plugins/deployer/go.mod ../plugins/deployer/go.sum ./ +COPY ./deployer/go.mod ./deployer/go.sum ./ RUN go mod download -COPY ../plugins/deployer/*.go ./ -RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /plugins/deployer . +COPY ./deployer/*.go ./ +RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o ./deployer . FROM bitnami/kubectl:${KUBECTL_VERSION} AS kubectl FROM ${BASE_IMAGE} AS base diff --git a/plugins/deployer/config.go b/plugins/builder/deployer/config.go similarity index 100% rename from plugins/deployer/config.go rename to plugins/builder/deployer/config.go diff --git a/plugins/deployer/deployer.go b/plugins/builder/deployer/deployer.go similarity index 100% rename from plugins/deployer/deployer.go rename to plugins/builder/deployer/deployer.go diff --git a/plugins/builder/deployer/go.mod b/plugins/builder/deployer/go.mod new file mode 100644 index 0000000..1053251 --- /dev/null +++ b/plugins/builder/deployer/go.mod @@ -0,0 +1,65 @@ +module github.com/cloudness-io/cloudness/plugins/builder/deployer + +go 1.25 + +require ( + k8s.io/api v0.34.1 + k8s.io/apimachinery v0.34.1 + k8s.io/client-go v0.34.1 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-openapi/jsonpointer v0.22.0 // indirect + github.com/go-openapi/jsonreference v0.21.1 // indirect + github.com/go-openapi/swag v0.24.1 // indirect + github.com/go-openapi/swag/cmdutils v0.24.0 // indirect + github.com/go-openapi/swag/conv v0.24.0 // indirect + github.com/go-openapi/swag/fileutils v0.24.0 // indirect + github.com/go-openapi/swag/jsonname v0.24.0 // indirect + github.com/go-openapi/swag/jsonutils v0.24.0 // indirect + github.com/go-openapi/swag/loading v0.24.0 // indirect + github.com/go-openapi/swag/mangling v0.24.0 // indirect + github.com/go-openapi/swag/netutils v0.24.0 // indirect + github.com/go-openapi/swag/stringutils v0.24.0 // indirect + github.com/go-openapi/swag/typeutils v0.24.0 // indirect + github.com/go-openapi/swag/yamlutils v0.24.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect + github.com/onsi/gomega v1.36.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.31.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/time v0.13.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) diff --git a/plugins/builder/deployer/go.sum b/plugins/builder/deployer/go.sum new file mode 100644 index 0000000..4ad6e71 --- /dev/null +++ b/plugins/builder/deployer/go.sum @@ -0,0 +1,166 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= +github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= +github.com/go-openapi/jsonreference v0.21.1 h1:bSKrcl8819zKiOgxkbVNRUBIr6Wwj9KYrDbMjRs0cDA= +github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= +github.com/go-openapi/swag v0.24.1 h1:DPdYTZKo6AQCRqzwr/kGkxJzHhpKxZ9i/oX0zag+MF8= +github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= +github.com/go-openapi/swag/cmdutils v0.24.0 h1:KlRCffHwXFI6E5MV9n8o8zBRElpY4uK4yWyAMWETo9I= +github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= +github.com/go-openapi/swag/conv v0.24.0 h1:ejB9+7yogkWly6pnruRX45D1/6J+ZxRu92YFivx54ik= +github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= +github.com/go-openapi/swag/fileutils v0.24.0 h1:U9pCpqp4RUytnD689Ek/N1d2N/a//XCeqoH508H5oak= +github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= +github.com/go-openapi/swag/jsonname v0.24.0 h1:2wKS9bgRV/xB8c62Qg16w4AUiIrqqiniJFtZGi3dg5k= +github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= +github.com/go-openapi/swag/jsonutils v0.24.0 h1:F1vE1q4pg1xtO3HTyJYRmEuJ4jmIp2iZ30bzW5XgZts= +github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= +github.com/go-openapi/swag/loading v0.24.0 h1:ln/fWTwJp2Zkj5DdaX4JPiddFC5CHQpvaBKycOlceYc= +github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= +github.com/go-openapi/swag/mangling v0.24.0 h1:PGOQpViCOUroIeak/Uj/sjGAq9LADS3mOyjznmHy2pk= +github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= +github.com/go-openapi/swag/netutils v0.24.0 h1:Bz02HRjYv8046Ycg/w80q3g9QCWeIqTvlyOjQPDjD8w= +github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= +github.com/go-openapi/swag/stringutils v0.24.0 h1:i4Z/Jawf9EvXOLUbT97O0HbPUja18VdBxeadyAqS1FM= +github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= +github.com/go-openapi/swag/typeutils v0.24.0 h1:d3szEGzGDf4L2y1gYOSSLeK6h46F+zibnEas2Jm/wIw= +github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= +github.com/go-openapi/swag/yamlutils v0.24.0 h1:bhw4894A7Iw6ne+639hsBNRHg9iZg/ISrOVr+sJGp4c= +github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 h1:c7ayAhbRP9HnEl/hg/WQOM9s0snWztfW6feWXZbGHw0= +github.com/google/pprof v0.0.0-20250903194437-c28834ac2320/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM= +k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= +k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4= +k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY= +k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/plugins/deployer/logger.go b/plugins/builder/deployer/logger.go similarity index 100% rename from plugins/deployer/logger.go rename to plugins/builder/deployer/logger.go diff --git a/plugins/deployer/main.go b/plugins/builder/deployer/main.go similarity index 100% rename from plugins/deployer/main.go rename to plugins/builder/deployer/main.go diff --git a/plugins/deployer/go.mod b/plugins/deployer/go.mod deleted file mode 100644 index 3010b37..0000000 --- a/plugins/deployer/go.mod +++ /dev/null @@ -1,177 +0,0 @@ -module github.com/cloudness-io/cloudness/plugins/deployer - -go 1.25 - -require ( - cloud.google.com/go/profiler v0.4.3 - github.com/Masterminds/squirrel v1.5.4 - github.com/a-h/templ v0.3.943 - github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/cert-manager/cert-manager v1.18.2 - github.com/cloudflare/cloudflare-go v0.116.0 - github.com/coreos/go-semver v0.3.1 - github.com/dchest/uniuri v1.2.0 - github.com/drone/go-scm v1.40.6 - github.com/go-chi/chi/v5 v5.2.3 - github.com/go-logr/logr v1.4.3 - github.com/go-logr/zerologr v1.2.3 - github.com/go-redsync/redsync/v4 v4.15.0 - github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/golang-jwt/jwt/v5 v5.3.0 - github.com/google/go-github/v69 v69.2.0 - github.com/google/wire v0.7.0 - github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 - github.com/gotidy/ptr v1.4.0 - github.com/jmoiron/sqlx v1.4.0 - github.com/joho/godotenv v1.5.1 - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/kelseyhightower/envconfig v1.4.0 - github.com/lib/pq v1.10.9 - github.com/maragudk/migrate v0.4.3 - github.com/mattn/go-isatty v0.0.20 - github.com/mattn/go-sqlite3 v1.14.32 - github.com/miekg/dns v1.1.68 - github.com/pkg/errors v0.9.1 - github.com/qri-io/jsonschema v0.2.1 - github.com/redis/go-redis/v9 v9.17.2 - github.com/rs/xid v1.6.0 - github.com/rs/zerolog v1.34.0 - golang.org/x/crypto v0.46.0 - golang.org/x/exp v0.0.0-20250911091902-df9299821621 - golang.org/x/net v0.48.0 - golang.org/x/oauth2 v0.31.0 - golang.org/x/sync v0.19.0 - golang.org/x/text v0.32.0 - k8s.io/api v0.34.1 - k8s.io/apimachinery v0.34.1 - k8s.io/client-go v0.34.1 - sigs.k8s.io/controller-runtime v0.22.1 - sigs.k8s.io/gateway-api v1.4.1 -) - -require ( - cloud.google.com/go v0.122.0 // indirect - cloud.google.com/go/auth v0.16.5 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.8.0 // indirect - dario.cat/mergo v1.0.1 // indirect - github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect - github.com/air-verse/air v1.61.7 // indirect - github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bep/godartsass/v2 v2.3.2 // indirect - github.com/bep/golibsass v1.2.0 // indirect - github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cli/browser v1.3.0 // indirect - github.com/cli/safeexec v1.0.1 // indirect - github.com/creack/pty v1.1.23 // indirect - github.com/daixiang0/gci v0.13.7 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/emicklei/go-restful/v3 v3.13.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/fatih/color v1.18.0 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.0 // indirect - github.com/go-openapi/jsonreference v0.21.1 // indirect - github.com/go-openapi/swag v0.24.1 // indirect - github.com/go-openapi/swag/cmdutils v0.24.0 // indirect - github.com/go-openapi/swag/conv v0.24.0 // indirect - github.com/go-openapi/swag/fileutils v0.24.0 // indirect - github.com/go-openapi/swag/jsonname v0.24.0 // indirect - github.com/go-openapi/swag/jsonutils v0.24.0 // indirect - github.com/go-openapi/swag/loading v0.24.0 // indirect - github.com/go-openapi/swag/mangling v0.24.0 // indirect - github.com/go-openapi/swag/netutils v0.24.0 // indirect - github.com/go-openapi/swag/stringutils v0.24.0 // indirect - github.com/go-openapi/swag/typeutils v0.24.0 // indirect - github.com/go-openapi/swag/yamlutils v0.24.0 // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.5 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/gohugoio/hugo v0.139.4 // indirect - github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect - github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect - github.com/google/s2a-go v0.1.9 // indirect - github.com/google/subcommands v1.2.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.15.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/yaml v0.3.1 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect - github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect - github.com/makiuchi-d/arelo v1.15.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/natefinch/atomic v1.0.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.23.0 // indirect - github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.65.0 // indirect - github.com/prometheus/procfs v0.17.0 // indirect - github.com/qri-io/jsonpointer v0.1.1 // indirect - github.com/robert-nix/ansihtml v1.0.1 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect - github.com/spf13/cobra v1.9.1 // indirect - github.com/spf13/pflag v1.0.10 // indirect - github.com/tdewolff/parse/v2 v2.7.15 // indirect - github.com/x448/float16 v0.8.4 // indirect - github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.38.0 // indirect - golang.org/x/time v0.13.0 // indirect - golang.org/x/tools v0.39.0 // indirect - golang.org/x/vuln v1.1.4 // indirect - golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.249.0 // indirect - google.golang.org/genproto v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.9 // indirect - gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.34.1 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect - sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect - sigs.k8s.io/yaml v1.6.0 // indirect -) \ No newline at end of file diff --git a/plugins/deployer/go.sum b/plugins/deployer/go.sum deleted file mode 100644 index a3bcea2..0000000 --- a/plugins/deployer/go.sum +++ /dev/null @@ -1,660 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.122.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= -cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= -cloud.google.com/go/profiler v0.4.3/go.mod h1:3xFodugWfPIQZWFcXdUmfa+yTiiyQ8fWrdT+d2Sg4J0= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ= -github.com/a-h/templ v0.3.943/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/air-verse/air v1.61.7/go.mod h1:QW4HkIASdtSnwaYof1zgJCSxd41ebvix10t5ubtm9cg= -github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bep/godartsass/v2 v2.3.2/go.mod h1:Qe5WOS9nVJy7G0jHssXPd3c+Pqk/f7+Tm6k/vahbVgs= -github.com/bep/golibsass v1.2.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cert-manager/cert-manager v1.18.2/go.mod h1:icDJx4kG9BCNpGjBvrmsFd99d+lXUvWdkkcrSSQdIiw= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= -github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.116.0/go.mod h1:Ds6urDwn/TF2uIU24mu7H91xkKP8gSAHxQ44DSZgVmU= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/drone/go-scm v1.40.6/go.mod h1:DFIJJjhMj0TSXPz+0ni4nyZ9gtTtC40Vh/TGRugtyWw= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zerologr v1.2.3/go.mod h1:BxwGo7y5zgSHYR1BjbnHPyF/5ZjVKfKxAZANVu6E8Ho= -github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= -github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= -github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= -github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= -github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= -github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= -github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= -github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= -github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= -github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= -github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= -github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= -github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= -github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= -github.com/go-redsync/redsync/v4 v4.15.0/go.mod h1:qNp+lLs3vkfZbtA/aM/OjlZHfEr5YTAYhRktFPKHC7s= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gohugoio/hugo v0.139.4/go.mod h1:GPiZJZy5jCGiJ6Jtg0KdhE1JdpBTqhgtsbhpc1n8d5s= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20250903194437-c28834ac2320/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18= -github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gotidy/ptr v1.4.0/go.mod h1:MjRBG6/IETiiZGWI8LrRtISXEji+8b/jigmj2q0mEyM= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= -github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= -github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= -github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= -github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= -github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= -github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= -github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/makiuchi-d/arelo v1.15.2/go.mod h1:StrMnkdxCbMO2dPmRi8s+6AJw1tdvBP0xDYZDFt6etk= -github.com/maragudk/migrate v0.4.3/go.mod h1:vhmL4s+Xz75KU6DPZWRfqb45YyqjYQfcXliA1DsYzvY= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -github.com/qri-io/jsonpointer v0.1.1/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= -github.com/qri-io/jsonschema v0.2.1/go.mod h1:g7DPkiOsK1xv6T/Ao5scXRkd+yTFygcANPBaaqW+VrI= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= -github.com/robert-nix/ansihtml v1.0.1/go.mod h1:CJwclxYaTPc2RfcxtanEACsYuTksh4yDXcNeHHKZINE= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= -github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= -golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20250908214217-97024824d090/go.mod h1:zwJI9HzbJJlw2KXy0wX+lmT2JuZoaKK9JC4ppqmxxjk= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= -k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= -k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.22.1/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= -sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 3b56c8de2861e68061d40f8234896a17a8e84c6f Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 07:16:38 +0100 Subject: [PATCH 12/17] Fix docker build for helper --- plugins/builder/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/builder/Dockerfile b/plugins/builder/Dockerfile index 08d9d12..2fda868 100644 --- a/plugins/builder/Dockerfile +++ b/plugins/builder/Dockerfile @@ -33,7 +33,7 @@ COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl RUN chmod +x /usr/local/bin/kubectl # Add deployer binary -COPY --from=deployer-builder /deployer /usr/local/bin/cloudness-deploy +COPY --from=deployer-builder /build/deployer /usr/local/bin/cloudness-deploy RUN chmod +x /usr/local/bin/cloudness-deploy # Add shared utilities and scripts From 8db74befe7ebe8a5e202fce65a84f9c32d24227d Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 12:15:46 +0530 Subject: [PATCH 13/17] Add labeling for artifacts --- .../convert/templates/static/1-common.yaml | 27 +++++++++++++--- .../convert/templates/static/2-pvc.yaml | 5 ++- .../convert/templates/static/3-app.yaml | 31 ++++++++++++++----- .../convert/templates/static/4-httproute.yaml | 14 ++++++--- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/app/pipeline/convert/templates/static/1-common.yaml b/app/pipeline/convert/templates/static/1-common.yaml index ceb76aa..89e114f 100644 --- a/app/pipeline/convert/templates/static/1-common.yaml +++ b/app/pipeline/convert/templates/static/1-common.yaml @@ -2,6 +2,8 @@ apiVersion: v1 kind: Namespace metadata: name: {{ .Namespace }} + labels: + app.kubernetes.io/managed-by: cloudness --- apiVersion: v1 @@ -10,7 +12,10 @@ metadata: name: {{ .Identifier }}-sa namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: serviceaccount + app.kubernetes.io/managed-by: cloudness --- apiVersion: rbac.authorization.k8s.io/v1 @@ -19,7 +24,10 @@ metadata: name: {{ .Identifier }}-role namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: rbac + app.kubernetes.io/managed-by: cloudness rules: - apiGroups: [""] # Core API group resources: ["services"] @@ -32,7 +40,10 @@ metadata: name: {{ .Identifier }}-rolebinding namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: rbac + app.kubernetes.io/managed-by: cloudness subjects: - kind: ServiceAccount name: {{ .Identifier }}-sa @@ -49,7 +60,10 @@ metadata: name: {{ .Identifier }} namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: config + app.kubernetes.io/managed-by: cloudness data: {{- range $key, $value := .Variables }} {{ $key }}: {{ $value }} @@ -62,7 +76,10 @@ metadata: name: {{ .Identifier }} namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: config + app.kubernetes.io/managed-by: cloudness type: Opaque data: {{- range $key, $value := .Secrets }} diff --git a/app/pipeline/convert/templates/static/2-pvc.yaml b/app/pipeline/convert/templates/static/2-pvc.yaml index a3dc8bd..f93dbad 100644 --- a/app/pipeline/convert/templates/static/2-pvc.yaml +++ b/app/pipeline/convert/templates/static/2-pvc.yaml @@ -6,7 +6,10 @@ metadata: name: {{ .VolumeName }} namespace: {{ $.Namespace }} labels: - identifier: {{ $.Identifier }} + app.kubernetes.io/name: {{ $.Identifier }} + app.kubernetes.io/instance: {{ $.Identifier }} + app.kubernetes.io/component: storage + app.kubernetes.io/managed-by: cloudness spec: accessModes: - ReadWriteOnce diff --git a/app/pipeline/convert/templates/static/3-app.yaml b/app/pipeline/convert/templates/static/3-app.yaml index 91afca5..2fabc7f 100644 --- a/app/pipeline/convert/templates/static/3-app.yaml +++ b/app/pipeline/convert/templates/static/3-app.yaml @@ -5,15 +5,22 @@ metadata: name: {{ .Identifier }} namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: app + app.kubernetes.io/managed-by: cloudness spec: selector: matchLabels: - app: {{ .Identifier }} # Must match .spec.template.metadata.labels + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} template: metadata: labels: - app: {{ .Identifier }} # Must match .spec.selector.matchLabels + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: app + app.kubernetes.io/managed-by: cloudness spec: securityContext: runAsUser: 1001 @@ -66,7 +73,10 @@ metadata: name: {{ .Identifier }}-hpa namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: autoscaling + app.kubernetes.io/managed-by: cloudness spec: scaleTargetRef: apiVersion: apps/v1 @@ -96,15 +106,22 @@ metadata: name: {{ .Identifier }} namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: app + app.kubernetes.io/managed-by: cloudness spec: selector: matchLabels: - app: {{ .Identifier }} # Must match .spec.template.metadata.labels + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} template: metadata: labels: - app: {{ .Identifier }} # Must match .spec.selector.matchLabels + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: app + app.kubernetes.io/managed-by: cloudness spec: securityContext: runAsUser: 1001 diff --git a/app/pipeline/convert/templates/static/4-httproute.yaml b/app/pipeline/convert/templates/static/4-httproute.yaml index 481de50..f5e812a 100644 --- a/app/pipeline/convert/templates/static/4-httproute.yaml +++ b/app/pipeline/convert/templates/static/4-httproute.yaml @@ -6,11 +6,14 @@ metadata: name: {{ .Identifier }} namespace: {{ .Namespace }} labels: - app: {{ .Identifier }} - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: service + app.kubernetes.io/managed-by: cloudness spec: selector: - app: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} ports: {{- range $index, $value := .ServicePorts }} - name: {{ $value }}-port @@ -28,7 +31,10 @@ metadata: name: {{ .Identifier }}-http namespace: {{ .Namespace }} labels: - identifier: {{ .Identifier }} + app.kubernetes.io/name: {{ .Identifier }} + app.kubernetes.io/instance: {{ .Identifier }} + app.kubernetes.io/component: ingress + app.kubernetes.io/managed-by: cloudness spec: parentRefs: {{ if .ServiceDomain.Websecure }} From e5392e1c5b6366863fc4438fce735961847a992b Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 09:34:41 +0100 Subject: [PATCH 14/17] Split operators --- app/pipeline/convert/const.go | 2 +- plugins/builder/deployer/deployer.go | 439 ++---------------- plugins/builder/deployer/kubectl.go | 113 +++++ plugins/builder/deployer/operator.go | 20 + plugins/builder/deployer/operator_base.go | 69 +++ .../builder/deployer/operator_statefull.go | 256 ++++++++++ .../builder/deployer/operator_stateless.go | 146 ++++++ 7 files changed, 636 insertions(+), 409 deletions(-) create mode 100644 plugins/builder/deployer/kubectl.go create mode 100644 plugins/builder/deployer/operator.go create mode 100644 plugins/builder/deployer/operator_base.go create mode 100644 plugins/builder/deployer/operator_statefull.go create mode 100644 plugins/builder/deployer/operator_stateless.go diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 212e670..a9f53f6 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.16" + return "cloudnessio/builder:1.0.20" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/plugins/builder/deployer/deployer.go b/plugins/builder/deployer/deployer.go index 33d53ff..db918b6 100644 --- a/plugins/builder/deployer/deployer.go +++ b/plugins/builder/deployer/deployer.go @@ -1,40 +1,20 @@ package main import ( - "bufio" - "bytes" "context" "fmt" - "io" - "os" - "strings" - "time" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer/yaml" - "k8s.io/apimachinery/pkg/types" - yamlutil "k8s.io/apimachinery/pkg/util/yaml" - "k8s.io/client-go/discovery" - "k8s.io/client-go/discovery/cached/memory" - "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - "k8s.io/client-go/restmapper" ) -// Deployer handles Kubernetes deployments +// Deployer handles Kubernetes deployments using hybrid approach: +// - kubectl for applying manifests (battle-tested) +// - client-go for watching/monitoring (efficient) type Deployer struct { - config *Config - clientset kubernetes.Interface - dynamicClient dynamic.Interface - mapper meta.RESTMapper - log *Logger + config *Config + Operator Operator + log *Logger } // NewDeployer creates a new deployer instance @@ -45,414 +25,57 @@ func NewDeployer(cfg *Config) (*Deployer, error) { return nil, fmt.Errorf("failed to get in-cluster config: %w", err) } - // Create clientset + // Create clientset for watching clientset, err := kubernetes.NewForConfig(restConfig) if err != nil { return nil, fmt.Errorf("failed to create kubernetes client: %w", err) } - // Create dynamic client - dynamicClient, err := dynamic.NewForConfig(restConfig) - if err != nil { - return nil, fmt.Errorf("failed to create dynamic client: %w", err) - } - - // Create discovery client and mapper - dc, err := discovery.NewDiscoveryClientForConfig(restConfig) - if err != nil { - return nil, fmt.Errorf("failed to create discovery client: %w", err) + logger := NewLogger(cfg.Verbose) + var operator Operator + switch cfg.AppType { + case AppTypeStateless: + operator = NewStatelessOperator(cfg, clientset, logger) + case AppTypeStateful: + operator = NewStatefulOperator(cfg, clientset, logger) } - mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc)) return &Deployer{ - config: cfg, - clientset: clientset, - dynamicClient: dynamicClient, - mapper: mapper, - log: NewLogger(cfg.Verbose), + config: cfg, + Operator: operator, + log: logger, }, nil } // Deploy runs the full deployment workflow -func (d *Deployer) Deploy(ctx context.Context) error { - d.log.Section("Deploying application") +func (k *Deployer) Deploy(ctx context.Context) error { + k.log.Section("Deploying application") // Step 1: Apply common artifacts (namespace, service account, etc.) - if err := d.applyCommonArtifacts(ctx); err != nil { - return fmt.Errorf("failed to apply common artifacts: %w", err) + if err := k.Operator.ApplyCommon(ctx); err != nil { + return err } - d.log.Step("Prerequisite artifacts configured") + k.log.Step("Access control and storage artifacts configured") // Step 2: Handle volumes (if any) - if d.config.HasVolume { - if err := d.deployVolumes(ctx); err != nil { - return fmt.Errorf("failed to deploy volumes: %w", err) - } - d.log.Step("Volumes provisioned") + if err := k.Operator.Volumes(ctx); err != nil { + return err } // Step 3: Deploy application - if err := d.deployApplication(ctx); err != nil { - return fmt.Errorf("failed to deploy application: %w", err) - } - d.log.Step("Application deployed") - - // Step 4: Configure routes (if any) - if d.config.HasRoute { - if err := d.deployRoutes(ctx); err != nil { - return fmt.Errorf("failed to deploy routes: %w", err) - } - d.log.Step("HTTP routes configured") - } - - // Cleanup: Remove opposite resource type - d.cleanup(ctx) - - d.log.Success("Deployment completed successfully!") - return nil -} - -// applyCommonArtifacts applies common Kubernetes resources -func (d *Deployer) applyCommonArtifacts(ctx context.Context) error { - return d.applyYAMLFile(ctx, d.config.CommonYAMLPath) -} - -// deployVolumes handles PVC creation and resizing -func (d *Deployer) deployVolumes(ctx context.Context) error { - // Handle remount for volume resize - if d.config.NeedRemount { - d.log.Info("Volume resize detected, removing statefulset for remount...") - if err := d.deleteStatefulSet(ctx); err != nil { - d.log.Warn("Failed to remove statefulset: %v", err) - } - } - - // Apply volume configuration - if err := d.applyYAMLFile(ctx, d.config.VolumeYAMLPath); err != nil { + if err := k.Operator.Deploy(ctx); err != nil { return err } + k.log.Step("Application deployed") - // Wait for PVCs to be ready - return d.waitForPVCs(ctx) -} - -// deployApplication deploys the main application and waits for rollout -func (d *Deployer) deployApplication(ctx context.Context) error { - if err := d.applyYAMLFile(ctx, d.config.AppYAMLPath); err != nil { + // Step 4: Configure routes (if any) + if err := k.Operator.Ingress(ctx); err != nil { return err } - return d.waitForRollout(ctx) -} - -// deployRoutes applies route/ingress configuration -func (d *Deployer) deployRoutes(ctx context.Context) error { - return d.applyYAMLFile(ctx, d.config.RouteYAMLPath) -} - -// applyYAMLFile reads and applies a YAML file containing one or more manifests -func (d *Deployer) applyYAMLFile(ctx context.Context, filepath string) error { - // Check if file exists and has content - info, err := os.Stat(filepath) - if os.IsNotExist(err) || (err == nil && info.Size() == 0) { - d.log.Debug("Skipping empty or non-existent file: %s", filepath) - return nil - } - if err != nil { - return fmt.Errorf("failed to stat file %s: %w", filepath, err) - } - - data, err := os.ReadFile(filepath) - if err != nil { - return fmt.Errorf("failed to read file %s: %w", filepath, err) - } - - return d.applyYAML(ctx, data) -} - -// applyYAML applies YAML content containing one or more Kubernetes manifests -func (d *Deployer) applyYAML(ctx context.Context, yamlData []byte) error { - decoder := yamlutil.NewYAMLOrJSONDecoder(bufio.NewReader(bytes.NewReader(yamlData)), 4096) - decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) - - for { - var rawObj runtime.RawExtension - if err := decoder.Decode(&rawObj); err != nil { - if err == io.EOF { - break - } - return fmt.Errorf("failed to decode yaml: %w", err) - } - - if rawObj.Raw == nil { - continue - } - - obj := &unstructured.Unstructured{} - _, gvk, err := decUnstructured.Decode(rawObj.Raw, nil, obj) - if err != nil { - return fmt.Errorf("failed to decode object: %w", err) - } - - // Get the REST mapping for this GVK - mapping, err := d.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return fmt.Errorf("failed to get REST mapping for %v: %w", gvk, err) - } - - // Get the resource interface - var dr dynamic.ResourceInterface - if mapping.Scope.Name() == meta.RESTScopeNameNamespace { - ns := obj.GetNamespace() - if ns == "" { - ns = d.config.AppNamespace - obj.SetNamespace(ns) - } - dr = d.dynamicClient.Resource(mapping.Resource).Namespace(ns) - } else { - dr = d.dynamicClient.Resource(mapping.Resource) - } - - // Apply using server-side apply - d.log.Debug("Applying %s/%s in %s", gvk.Kind, obj.GetName(), obj.GetNamespace()) - _, err = dr.Patch(ctx, obj.GetName(), types.ApplyPatchType, rawObj.Raw, metav1.PatchOptions{ - FieldManager: "cloudness-deployer", - }) - if err != nil { - // Fall back to Create/Update - _, err = dr.Create(ctx, obj, metav1.CreateOptions{}) - if errors.IsAlreadyExists(err) { - _, err = dr.Update(ctx, obj, metav1.UpdateOptions{}) - } - if err != nil { - return fmt.Errorf("failed to apply %s/%s: %w", gvk.Kind, obj.GetName(), err) - } - } - } - - return nil -} - -// waitForRollout waits for the deployment/statefulset to roll out -func (d *Deployer) waitForRollout(ctx context.Context) error { - timeout := time.Duration(d.config.RolloutTimeout()) * time.Second - ctx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - - ticker := time.NewTicker(2 * time.Second) - defer ticker.Stop() - - for { - select { - case <-ctx.Done(): - d.log.Error("Rollout timed out after %v, reverting...", timeout) - d.rollback(context.Background()) // Use background context for rollback - return fmt.Errorf("rollout timed out") - case <-ticker.C: - ready, err := d.checkRolloutStatus(ctx) - if err != nil { - d.log.Debug("Error checking rollout status: %v", err) - continue - } - if ready { - return nil - } - } - } -} - -// checkRolloutStatus checks if the deployment/statefulset is ready -func (d *Deployer) checkRolloutStatus(ctx context.Context) (bool, error) { - if d.config.AppType == AppTypeStateless { - deploy, err := d.clientset.AppsV1().Deployments(d.config.AppNamespace).Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) - if err != nil { - return false, err - } - return d.isDeploymentReady(deploy), nil - } - - sts, err := d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) - if err != nil { - return false, err - } - return d.isStatefulSetReady(sts), nil -} - -func (d *Deployer) isDeploymentReady(deploy *appsv1.Deployment) bool { - if deploy.Generation != deploy.Status.ObservedGeneration { - return false - } - for _, cond := range deploy.Status.Conditions { - if cond.Type == appsv1.DeploymentAvailable && cond.Status == corev1.ConditionTrue { - if deploy.Status.UpdatedReplicas == *deploy.Spec.Replicas && - deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { - return true - } - } - } - return false -} - -func (d *Deployer) isStatefulSetReady(sts *appsv1.StatefulSet) bool { - if sts.Generation != sts.Status.ObservedGeneration { - return false - } - return sts.Status.UpdatedReplicas == *sts.Spec.Replicas && - sts.Status.ReadyReplicas == *sts.Spec.Replicas -} - -// rollback rolls back a failed deployment -func (d *Deployer) rollback(ctx context.Context) { - if d.config.AppType == AppTypeStateless { - // For deployments, we can use rollout undo - deploys := d.clientset.AppsV1().Deployments(d.config.AppNamespace) - deploy, err := deploys.Get(ctx, d.config.AppIdentifier, metav1.GetOptions{}) - if err != nil { - d.log.Error("Failed to get deployment for rollback: %v", err) - return - } - - // Set revision to previous - if deploy.Annotations == nil { - deploy.Annotations = make(map[string]string) - } - deploy.Annotations["deployment.kubernetes.io/revision"] = "" - - _, err = deploys.Update(ctx, deploy, metav1.UpdateOptions{}) - if err != nil { - d.log.Error("Failed to rollback deployment: %v", err) - } - } - // StatefulSets don't support automatic rollback -} - -// waitForPVCs waits for all PVCs to be bound or resized -func (d *Deployer) waitForPVCs(ctx context.Context) error { - // Read PVC names from the volume YAML - data, err := os.ReadFile(d.config.VolumeYAMLPath) - if err != nil { - return nil // No volume file, skip - } - - pvcNames := d.extractPVCNames(data) - if len(pvcNames) == 0 { - return nil - } - - timeout := time.Duration(d.config.PVCResizeTimeout) * time.Second - ctx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - - for _, pvcName := range pvcNames { - if err := d.waitForPVC(ctx, pvcName); err != nil { - return err - } - } + // Cleanup: Remove opposite resource type + k.Operator.Cleanup(ctx) + k.log.Success("Deployment completed successfully!") return nil } - -// extractPVCNames extracts PVC names from YAML content -func (d *Deployer) extractPVCNames(yamlData []byte) []string { - var names []string - decoder := yamlutil.NewYAMLOrJSONDecoder(bufio.NewReader(bytes.NewReader(yamlData)), 4096) - - for { - var obj unstructured.Unstructured - if err := decoder.Decode(&obj); err != nil { - break - } - if obj.GetKind() == "PersistentVolumeClaim" { - names = append(names, obj.GetName()) - } - } - return names -} - -// waitForPVC waits for a single PVC to be ready -func (d *Deployer) waitForPVC(ctx context.Context, name string) error { - ticker := time.NewTicker(time.Duration(d.config.PVCResizePollInterval) * time.Second) - defer ticker.Stop() - - for { - select { - case <-ctx.Done(): - return fmt.Errorf("timed out waiting for PVC %s", name) - case <-ticker.C: - pvc, err := d.clientset.CoreV1().PersistentVolumeClaims(d.config.AppNamespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { - d.log.Debug("Error getting PVC %s: %v", name, err) - continue - } - - d.log.Debug("PVC %s status: %s", name, pvc.Status.Phase) - - switch pvc.Status.Phase { - case corev1.ClaimBound: - return nil - case corev1.ClaimPending: - // Check for WaitForFirstConsumer - if d.isWaitingForFirstConsumer(ctx, name) { - d.log.Debug("PVC %s waiting for first consumer", name) - return nil - } - } - - // Check for FileSystemResizePending - for _, cond := range pvc.Status.Conditions { - if cond.Type == corev1.PersistentVolumeClaimFileSystemResizePending && cond.Status == corev1.ConditionTrue { - d.log.Info("Volume %s resized. Remounting application to finalize.", name) - return nil - } - } - } - } -} - -// isWaitingForFirstConsumer checks if PVC is pending due to WaitForFirstConsumer -func (d *Deployer) isWaitingForFirstConsumer(ctx context.Context, pvcName string) bool { - events, err := d.clientset.CoreV1().Events(d.config.AppNamespace).List(ctx, metav1.ListOptions{ - FieldSelector: fmt.Sprintf("involvedObject.kind=PersistentVolumeClaim,involvedObject.name=%s", pvcName), - }) - if err != nil { - return false - } - - for _, event := range events.Items { - if event.Reason == "WaitForFirstConsumer" { - return true - } - } - return false -} - -// deleteStatefulSet deletes the StatefulSet (for volume remount) -func (d *Deployer) deleteStatefulSet(ctx context.Context) error { - return d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Delete( - ctx, - d.config.AppIdentifier, - metav1.DeleteOptions{}, - ) -} - -// cleanup removes the opposite resource type (cleanup old deployment/statefulset) -func (d *Deployer) cleanup(ctx context.Context) { - d.log.Debug("Running cleanup...") - - var err error - if d.config.AppType == AppTypeStateless { - // Remove any StatefulSet with the same name - err = d.clientset.AppsV1().StatefulSets(d.config.AppNamespace).Delete( - ctx, d.config.AppIdentifier, metav1.DeleteOptions{}, - ) - } else { - // Remove any Deployment with the same name - err = d.clientset.AppsV1().Deployments(d.config.AppNamespace).Delete( - ctx, d.config.AppIdentifier, metav1.DeleteOptions{}, - ) - } - - if err != nil && !errors.IsNotFound(err) && !strings.Contains(err.Error(), "not found") { - d.log.Warn("Failed to cleanup opposite resource: %v", err) - } -} diff --git a/plugins/builder/deployer/kubectl.go b/plugins/builder/deployer/kubectl.go new file mode 100644 index 0000000..5982ad2 --- /dev/null +++ b/plugins/builder/deployer/kubectl.go @@ -0,0 +1,113 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/exec" + "strings" + "time" +) + +type Kubectl struct { + config *Config + log *Logger +} + +func NewKubectl(cfg *Config, log *Logger) *Kubectl { + return &Kubectl{ + config: cfg, + log: log, + } +} + +// ============================================================================= +// kubectl-based Apply +// ============================================================================= + +// ApplyYAMLFile applies a YAML file using kubectl +func (k *Kubectl) ApplyYAMLFile(ctx context.Context, filepath string) error { + // Check if file exists and has content + info, err := os.Stat(filepath) + if os.IsNotExist(err) || (err == nil && info.Size() == 0) { + k.log.Debug("Skipping empty or non-existent file: %s", filepath) + return nil + } + if err != nil { + return fmt.Errorf("failed to stat file %s: %w", filepath, err) + } + + // Use kubectl apply with retry + return k.kubectlApplyWithRetry(ctx, filepath, 3) +} + +// kubectlApplyWithRetry runs kubectl apply with exponential backoff +func (k *Kubectl) kubectlApplyWithRetry(ctx context.Context, filepath string, maxRetries int) error { + var lastErr error + backoff := 1 * time.Second + + for attempt := 0; attempt <= maxRetries; attempt++ { + if attempt > 0 { + k.log.Debug("Retry %d/%d after %v...", attempt, maxRetries, backoff) + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(backoff): + } + backoff *= 2 + } + + err := k.kubectlApply(ctx, filepath) + if err == nil { + return nil + } + + lastErr = err + + // Don't retry on certain errors + if strings.Contains(err.Error(), "invalid") || + strings.Contains(err.Error(), "forbidden") || + strings.Contains(err.Error(), "not found") { + return err + } + } + + return fmt.Errorf("kubectl apply failed after %d retries: %w", maxRetries, lastErr) +} + +// kubectlApply runs kubectl apply -f +func (k *Kubectl) kubectlApply(ctx context.Context, filepath string) error { + args := []string{"apply", "-f", filepath} + + if k.config.Verbose { + k.log.Debug("kubectl %s", strings.Join(args, " ")) + } + + cmd := exec.CommandContext(ctx, "kubectl", args...) + output, err := cmd.CombinedOutput() + + if k.config.Verbose && len(output) > 0 { + k.log.Info("%s", strings.TrimSpace(string(output))) + } + + if err != nil { + return fmt.Errorf("kubectl apply failed: %s: %w", strings.TrimSpace(string(output)), err) + } + + return nil +} + +// Delete runs kubectl delete +func (k *Kubectl) Delete(ctx context.Context, resource, name, namespace string) error { + args := []string{"delete", resource, name, "-n", namespace, "--ignore-not-found=true"} + + cmd := exec.CommandContext(ctx, "kubectl", args...) + output, err := cmd.CombinedOutput() + + if err != nil { + k.log.Debug("kubectl delete failed: %s", strings.TrimSpace(string(output))) + return err + } + + return nil +} diff --git a/plugins/builder/deployer/operator.go b/plugins/builder/deployer/operator.go new file mode 100644 index 0000000..0c58798 --- /dev/null +++ b/plugins/builder/deployer/operator.go @@ -0,0 +1,20 @@ +package main + +import "context" + +type Operator interface { + // ApplyCommon applies common artifact files + ApplyCommon(ctx context.Context) error + + // Volumes handles PVC creation and resizing + Volumes(ctx context.Context) error + + // Deploy deploys the actual application + Deploy(ctx context.Context) error + + // Ingress deploys the ingress + Ingress(ctx context.Context) error + + // Cleanup cleans up resources + Cleanup(ctx context.Context) +} diff --git a/plugins/builder/deployer/operator_base.go b/plugins/builder/deployer/operator_base.go new file mode 100644 index 0000000..b5e92d6 --- /dev/null +++ b/plugins/builder/deployer/operator_base.go @@ -0,0 +1,69 @@ +package main + +import ( + "context" + "fmt" + + appsv1 "k8s.io/api/apps/v1" +) + +type BaseOpeator struct { + config *Config + kubectl *Kubectl + log *Logger +} + +func NewBaseOperator(config *Config, kubectl *Kubectl, log *Logger) *BaseOpeator { + return &BaseOpeator{ + config: config, + kubectl: kubectl, + log: log, + } +} + +func (b *BaseOpeator) ApplyCommon(ctx context.Context) error { + if err := b.kubectl.ApplyYAMLFile(ctx, b.config.CommonYAMLPath); err != nil { + return fmt.Errorf("failed to apply common artifacts: %w", err) + } + return nil +} + +func (b *BaseOpeator) ApplyIngress(ctx context.Context) error { + if b.config.HasRoute { + if err := b.kubectl.ApplyYAMLFile(ctx, b.config.RouteYAMLPath); err != nil { + return fmt.Errorf("failed to deploy routes: %w", err) + } + b.log.Step("HTTP routes configured") + } + return nil +} + +// utils +func isDeploymentReady(deploy *appsv1.Deployment) bool { + if deploy.Generation != deploy.Status.ObservedGeneration { + return false + } + + if deploy.Spec.Replicas == nil { + return false + } + + replicas := *deploy.Spec.Replicas + return deploy.Status.UpdatedReplicas == replicas && + deploy.Status.ReadyReplicas == replicas && + deploy.Status.AvailableReplicas == replicas +} + +func isStatefulSetReady(sts *appsv1.StatefulSet) bool { + if sts.Generation != sts.Status.ObservedGeneration { + return false + } + + if sts.Spec.Replicas == nil { + return false + } + + replicas := *sts.Spec.Replicas + return sts.Status.UpdatedReplicas == replicas && + sts.Status.ReadyReplicas == replicas +} diff --git a/plugins/builder/deployer/operator_statefull.go b/plugins/builder/deployer/operator_statefull.go new file mode 100644 index 0000000..370d005 --- /dev/null +++ b/plugins/builder/deployer/operator_statefull.go @@ -0,0 +1,256 @@ +package main + +import ( + "context" + "fmt" + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" +) + +type StatefulOperator struct { + config *Config + base *BaseOpeator + clientset kubernetes.Interface + kubectl *Kubectl + log *Logger +} + +func NewStatefulOperator(cfg *Config, clientset kubernetes.Interface, log *Logger) *StatefulOperator { + kubectl := NewKubectl(cfg, log) + baseOperator := NewBaseOperator(cfg, kubectl, log) + return &StatefulOperator{ + config: cfg, + base: baseOperator, + clientset: clientset, + kubectl: kubectl, + log: log, + } +} + +func (s *StatefulOperator) ApplyCommon(ctx context.Context) error { + return s.base.ApplyCommon(ctx) +} + +func (s *StatefulOperator) Volumes(ctx context.Context) error { + if s.config.HasVolume { + if err := s.deployVolumes(ctx); err != nil { + return fmt.Errorf("failed to deploy volumes: %w", err) + } + s.log.Step("Volumes provisioned") + } + return nil +} + +func (k *StatefulOperator) Deploy(ctx context.Context) error { + if err := k.kubectl.ApplyYAMLFile(ctx, k.config.AppYAMLPath); err != nil { + return err + } + + return k.waitForRollout(ctx) +} + +func (s *StatefulOperator) Ingress(ctx context.Context) error { return s.base.ApplyIngress(ctx) } + +func (k *StatefulOperator) Cleanup(ctx context.Context) { + k.log.Debug("Running cleanup...") + + err := k.kubectl.Delete(ctx, "deployment", k.config.AppIdentifier, k.config.AppNamespace) + if err != nil && !errors.IsNotFound(err) { + k.log.Debug("Cleanup: %v", err) + } +} + +// waitForRollout waits for the statefulset to roll out using watch +func (k *StatefulOperator) waitForRollout(ctx context.Context) error { + timeout := time.Duration(k.config.RolloutTimeout()) * time.Second + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + return k.watchStatefulSetRollout(ctx) +} + +// watchStatefulSetRollout watches a StatefulSet until it's ready +func (k *StatefulOperator) watchStatefulSetRollout(ctx context.Context) error { + // Get initial state + sts, err := k.clientset.AppsV1().StatefulSets(k.config.AppNamespace).Get(ctx, k.config.AppIdentifier, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get statefulset: %w", err) + } + + if isStatefulSetReady(sts) { + return nil + } + + // Watch for changes + watcher, err := k.clientset.AppsV1().StatefulSets(k.config.AppNamespace).Watch(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", k.config.AppIdentifier), + }) + if err != nil { + return fmt.Errorf("failed to watch statefulset: %w", err) + } + defer watcher.Stop() + + for { + select { + case <-ctx.Done(): + k.log.Error("Rollout timed out") + return fmt.Errorf("statefulset rollout timed out") + case event, ok := <-watcher.ResultChan(): + if !ok { + return fmt.Errorf("watch channel closed") + } + + if event.Type == watch.Error { + continue + } + + sts, ok := event.Object.(*appsv1.StatefulSet) + if !ok { + continue + } + + k.log.Debug("StatefulSet %s: %d/%d ready", + sts.Name, + sts.Status.ReadyReplicas, + *sts.Spec.Replicas) + + if isStatefulSetReady(sts) { + return nil + } + } + } +} + +// ============================================================================= +// Volume Handling (client-go for PVC status checking) +// ============================================================================= + +// deployVolumes handles PVC creation and resizing +func (k *StatefulOperator) deployVolumes(ctx context.Context) error { + // Handle remount for volume resize + if k.config.NeedRemount { + k.log.Info("Volume resize detected, removing statefulset for remount...") + _ = k.kubectl.Delete(ctx, "statefulset", k.config.AppIdentifier, k.config.AppNamespace) + } + + // Apply volume configuration + if err := k.kubectl.ApplyYAMLFile(ctx, k.config.VolumeYAMLPath); err != nil { + return err + } + + // Wait for PVCs using watch (efficient) + return k.waitForPVCs(ctx) +} + +// waitForPVCs waits for all PVCs to be bound or resized +func (k *StatefulOperator) waitForPVCs(ctx context.Context) error { + // List PVCs with our label + pvcs, err := k.clientset.CoreV1().PersistentVolumeClaims(k.config.AppNamespace).List(ctx, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("app.kubernetes.io/instance=%s", k.config.AppIdentifier), + }) + if err != nil { + return fmt.Errorf("failed to list PVCs: %w", err) + } + + if len(pvcs.Items) == 0 { + return nil + } + + timeout := time.Duration(k.config.PVCResizeTimeout) * time.Second + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + for _, pvc := range pvcs.Items { + if err := k.waitForPVC(ctx, pvc.Name); err != nil { + return err + } + } + + return nil +} + +// waitForPVC waits for a single PVC to be ready using watch +func (k *StatefulOperator) waitForPVC(ctx context.Context, name string) error { + // First check current status + pvc, err := k.clientset.CoreV1().PersistentVolumeClaims(k.config.AppNamespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get PVC %s: %w", name, err) + } + + if k.isPVCReady(pvc) { + return nil + } + + // Watch for changes + watcher, err := k.clientset.CoreV1().PersistentVolumeClaims(k.config.AppNamespace).Watch(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", name), + }) + if err != nil { + return fmt.Errorf("failed to watch PVC %s: %w", name, err) + } + defer watcher.Stop() + + k.log.Info("Waiting for volume '%s'...", name) + + for { + select { + case <-ctx.Done(): + return fmt.Errorf("timed out waiting for PVC %s", name) + case event, ok := <-watcher.ResultChan(): + if !ok { + return fmt.Errorf("watch channel closed for PVC %s", name) + } + + if event.Type == watch.Error { + continue + } + + pvc, ok := event.Object.(*corev1.PersistentVolumeClaim) + if !ok { + continue + } + + k.log.Debug("PVC %s status: %s", name, pvc.Status.Phase) + + if k.isPVCReady(pvc) { + return nil + } + } + } +} + +// isPVCReady checks if a PVC is ready for use +func (k *StatefulOperator) isPVCReady(pvc *corev1.PersistentVolumeClaim) bool { + // Bound is ready + if pvc.Status.Phase == corev1.ClaimBound { + return true + } + + // WaitForFirstConsumer - consider ready (will bind when pod schedules) + if pvc.Status.Phase == corev1.ClaimPending { + if pvc.Spec.StorageClassName != nil { + // Check for WaitForFirstConsumer annotation + if ann := pvc.Annotations; ann != nil { + if ann["volume.kubernetes.io/selected-node"] != "" { + return true + } + } + } + } + + // FileSystemResizePending - volume resized, waiting for pod remount + for _, cond := range pvc.Status.Conditions { + if cond.Type == corev1.PersistentVolumeClaimFileSystemResizePending && cond.Status == corev1.ConditionTrue { + k.log.Info("Volume %s resized. Remounting application to finalize.", pvc.Name) + return true + } + } + + return false +} diff --git a/plugins/builder/deployer/operator_stateless.go b/plugins/builder/deployer/operator_stateless.go new file mode 100644 index 0000000..c180e51 --- /dev/null +++ b/plugins/builder/deployer/operator_stateless.go @@ -0,0 +1,146 @@ +package main + +import ( + "context" + "fmt" + "os/exec" + "strings" + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" +) + +type StatelessOperator struct { + config *Config + base *BaseOpeator + clientset kubernetes.Interface + kubectl *Kubectl + log *Logger +} + +func NewStatelessOperator(cfg *Config, clientset kubernetes.Interface, log *Logger) *StatelessOperator { + kubectl := NewKubectl(cfg, log) + baseOperator := NewBaseOperator(cfg, kubectl, log) + return &StatelessOperator{ + config: cfg, + base: baseOperator, + clientset: clientset, + kubectl: kubectl, + log: log, + } +} + +func (s *StatelessOperator) ApplyCommon(ctx context.Context) error { + return s.base.ApplyCommon(ctx) +} + +func (s *StatelessOperator) Volumes(ctx context.Context) error { + return nil +} + +func (s *StatelessOperator) Deploy(ctx context.Context) error { + if err := s.kubectl.ApplyYAMLFile(ctx, s.config.AppYAMLPath); err != nil { + return err + } + + return s.waitForRollout(ctx) +} + +func (s *StatelessOperator) Ingress(ctx context.Context) error { return s.base.ApplyIngress(ctx) } + +func (k *StatelessOperator) Cleanup(ctx context.Context) { + k.log.Debug("Running cleanup...") + + err := k.kubectl.Delete(ctx, "statefulset", k.config.AppIdentifier, k.config.AppNamespace) + if err != nil && !errors.IsNotFound(err) { + k.log.Debug("Cleanup: %v", err) + } +} + +// waitForRollout waits for the deployment to roll out using watch +func (s *StatelessOperator) waitForRollout(ctx context.Context) error { + timeout := time.Duration(s.config.RolloutTimeout()) * time.Second + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + return s.watchDeploymentRollout(ctx) +} + +// watchDeploymentRollout watches a Deployment until it's ready +func (s *StatelessOperator) watchDeploymentRollout(ctx context.Context) error { + // Get initial state + deploy, err := s.clientset.AppsV1().Deployments(s.config.AppNamespace).Get(ctx, s.config.AppIdentifier, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get deployment: %w", err) + } + + if isDeploymentReady(deploy) { + return nil + } + + // Watch for changes + watcher, err := s.clientset.AppsV1().Deployments(s.config.AppNamespace).Watch(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", s.config.AppIdentifier), + }) + if err != nil { + return fmt.Errorf("failed to watch deployment: %w", err) + } + defer watcher.Stop() + + for { + select { + case <-ctx.Done(): + s.log.Error("Rollout timed out, reverting...") + s.rollbackDeployment(context.Background()) + return fmt.Errorf("deployment rollout timed out") + case event, ok := <-watcher.ResultChan(): + if !ok { + return fmt.Errorf("watch channel closed") + } + + if event.Type == watch.Error { + continue + } + + deploy, ok := event.Object.(*appsv1.Deployment) + if !ok { + continue + } + + s.log.Debug("Deployment %s: %d/%d ready", + deploy.Name, + deploy.Status.ReadyReplicas, + *deploy.Spec.Replicas) + + if isDeploymentReady(deploy) { + return nil + } + + // Check for failure conditions + for _, cond := range deploy.Status.Conditions { + if cond.Type == appsv1.DeploymentProgressing && cond.Status == corev1.ConditionFalse { + s.log.Error("Deployment failed: %s", cond.Message) + s.rollbackDeployment(context.Background()) + return fmt.Errorf("deployment failed: %s", cond.Message) + } + } + } + } +} + +// rollbackDeployment rolls back a failed deployment using kubectl +func (k *StatelessOperator) rollbackDeployment(ctx context.Context) { + args := []string{"rollout", "undo", "deployment", k.config.AppIdentifier, "-n", k.config.AppNamespace} + cmd := exec.CommandContext(ctx, "kubectl", args...) + output, err := cmd.CombinedOutput() + if err != nil { + k.log.Error("Failed to rollback: %s", strings.TrimSpace(string(output))) + } else { + k.log.Info("Rolled back deployment") + } +} From 5b0e57ca576e358e16c0437f3450d37ff745522c Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 09:51:28 +0100 Subject: [PATCH 15/17] Fix yaml files formatting --- app/pipeline/convert/const.go | 2 +- app/pipeline/convert/deploy_step.go | 1 - app/pipeline/convert/templates/templates.go | 28 +++++++++---------- app/pipeline/convert/utils.go | 8 ------ .../runner/engine/kubernetes/tokube.go | 14 ++++------ 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index a9f53f6..3393db0 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.20" + return "cloudnessio/builder:1.0.22" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/app/pipeline/convert/deploy_step.go b/app/pipeline/convert/deploy_step.go index 1e0d820..16031b7 100644 --- a/app/pipeline/convert/deploy_step.go +++ b/app/pipeline/convert/deploy_step.go @@ -80,7 +80,6 @@ func deployCommand( // Run the Go-based deployer binary step.AddScriptCmd("cloudness-deploy") - step.VolumeMounts = append(step.VolumeMounts, getDeployVolumeMount(pCtx)) return nil } diff --git a/app/pipeline/convert/templates/templates.go b/app/pipeline/convert/templates/templates.go index 426ad21..54a32de 100644 --- a/app/pipeline/convert/templates/templates.go +++ b/app/pipeline/convert/templates/templates.go @@ -3,24 +3,27 @@ package templates import ( "bytes" "embed" - "strings" "text/template" ) //go:embed static/* var templateFs embed.FS -var statelessTmpl *template.Template -var statelessScripts *template.Template -var statefulTmpl *template.Template -var statefulScripts *template.Template +var ( + statelessTmpl *template.Template + statelessScripts *template.Template + statefulTmpl *template.Template + statefulScripts *template.Template +) // latest -var kubeCommon *template.Template -var kubePVC *template.Template -var kubeApp *template.Template -var kubeHttproute *template.Template -var kubeScripts string +var ( + kubeCommon *template.Template + kubePVC *template.Template + kubeApp *template.Template + kubeHttproute *template.Template + kubeScripts string +) func init() { statelessTmpl = getTemplate("stateless.yaml") @@ -139,10 +142,7 @@ func GenerateKubeStatefulTemplate(input *TemplateIn) (string, error) { } func formatTemplate(buf bytes.Buffer) string { - tmplStr := buf.String() - tmplStr = strings.ReplaceAll(tmplStr, "\n", "\\n") - tmplStr = strings.ReplaceAll(tmplStr, " ", "\\t") - return tmplStr + return buf.String() } func GenerateKubeStatelessScript(input *DeploymentIn) (string, error) { diff --git a/app/pipeline/convert/utils.go b/app/pipeline/convert/utils.go index b05f41c..2fbde9a 100644 --- a/app/pipeline/convert/utils.go +++ b/app/pipeline/convert/utils.go @@ -30,14 +30,6 @@ func getBuildVolumeMount(in *pipeline.RunnerContext) *pipeline.VolumeMount { } } -func getDeployVolumeMount(in *pipeline.RunnerContext) *pipeline.VolumeMount { - return &pipeline.VolumeMount{ - ID: getDeploymentWorkspaceVolumeId(in), - Path: wsDeployVolumePath, - Readonly: false, - } -} - // var replacer func replaceEnvVars(input string, vars map[string]*types.Variable) string { var builder strings.Builder diff --git a/app/pipeline/runner/engine/kubernetes/tokube.go b/app/pipeline/runner/engine/kubernetes/tokube.go index 252831e..d5dcb55 100644 --- a/app/pipeline/runner/engine/kubernetes/tokube.go +++ b/app/pipeline/runner/engine/kubernetes/tokube.go @@ -235,15 +235,13 @@ func toVolumeMounts(s *pipeline.Step) []v1.VolumeMount { }) } - // Add ConfigFileMount volumes + // Add ConfigFileMount volumes (mounts ConfigMap files to specified path) for _, cfm := range s.ConfigFileMounts { - var items []v1.KeyToPath - for _, key := range cfm.Keys { - items = append(items, v1.KeyToPath{ - Key: key, - Path: key, // Use key as filename - }) - } + volumeMounts = append(volumeMounts, v1.VolumeMount{ + Name: "configfiles", + MountPath: cfm.Path, + ReadOnly: true, + }) } return volumeMounts From 17df1ca660a789fe0a46ab782f34c0ef395d75c7 Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 10:09:49 +0100 Subject: [PATCH 16/17] Handle volume watch when resizing --- app/pipeline/convert/const.go | 2 +- plugins/builder/deployer/logger.go | 2 +- .../builder/deployer/operator_statefull.go | 37 ++++++++++++++----- plugins/builder/scripts/cloudness-utils.sh | 3 +- scripts/install/cloudness-runner-rbac.yaml | 18 +++++---- scripts/install/install.sh | 2 +- 6 files changed, 42 insertions(+), 22 deletions(-) diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 3393db0..8d10842 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,7 +22,7 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.22" + return "cloudnessio/builder:1.0.24" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) diff --git a/plugins/builder/deployer/logger.go b/plugins/builder/deployer/logger.go index ec8b300..621293b 100644 --- a/plugins/builder/deployer/logger.go +++ b/plugins/builder/deployer/logger.go @@ -15,7 +15,7 @@ const ( colorRed = "\033[1;31m" colorGreen = "\033[1;32m" colorYellow = "\033[1;33m" - colorBlue = "\033[0;34m" + colorBlue = "\033[38;2;40;153;245m" colorReset = "\033[0m" ) diff --git a/plugins/builder/deployer/operator_statefull.go b/plugins/builder/deployer/operator_statefull.go index 370d005..3febf34 100644 --- a/plugins/builder/deployer/operator_statefull.go +++ b/plugins/builder/deployer/operator_statefull.go @@ -196,7 +196,7 @@ func (k *StatefulOperator) waitForPVC(ctx context.Context, name string) error { } defer watcher.Stop() - k.log.Info("Waiting for volume '%s'...", name) + k.log.Info("Waiting for volume...", name) for { select { @@ -232,15 +232,11 @@ func (k *StatefulOperator) isPVCReady(pvc *corev1.PersistentVolumeClaim) bool { return true } - // WaitForFirstConsumer - consider ready (will bind when pod schedules) + // For Pending PVCs, check if they're waiting for first consumer if pvc.Status.Phase == corev1.ClaimPending { - if pvc.Spec.StorageClassName != nil { - // Check for WaitForFirstConsumer annotation - if ann := pvc.Annotations; ann != nil { - if ann["volume.kubernetes.io/selected-node"] != "" { - return true - } - } + // Check events to see if it's WaitForFirstConsumer + if k.hasWaitForFirstConsumerEvent(pvc.Name) { + return true } } @@ -254,3 +250,26 @@ func (k *StatefulOperator) isPVCReady(pvc *corev1.PersistentVolumeClaim) bool { return false } + +// hasWaitForFirstConsumerEvent checks if the PVC has a WaitForFirstConsumer event +func (k *StatefulOperator) hasWaitForFirstConsumerEvent(pvcName string) bool { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + events, err := k.clientset.CoreV1().Events(k.config.AppNamespace).List(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("involvedObject.kind=PersistentVolumeClaim,involvedObject.name=%s", pvcName), + }) + if err != nil { + k.log.Debug("Failed to get events for PVC %s: %v", pvcName, err) + return false + } + + // Check if any event has WaitForFirstConsumer reason + for _, event := range events.Items { + if event.Reason == "WaitForFirstConsumer" { + return true + } + } + + return false +} diff --git a/plugins/builder/scripts/cloudness-utils.sh b/plugins/builder/scripts/cloudness-utils.sh index a5f0bee..071ee46 100644 --- a/plugins/builder/scripts/cloudness-utils.sh +++ b/plugins/builder/scripts/cloudness-utils.sh @@ -8,7 +8,7 @@ readonly CLOUDNESS_RED='\033[1;31m' readonly CLOUDNESS_GREEN='\033[1;32m' readonly CLOUDNESS_YELLOW='\033[1;33m' -readonly CLOUDNESS_BLUE='\033[0;34m' +readonly CLOUDNESS_BLUE='\033[38;2;40;153;245m' readonly CLOUDNESS_NC='\033[0m' # ============================================================================== @@ -42,7 +42,6 @@ log_debug() { } print_section() { - printf "\n" printf "${CLOUDNESS_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CLOUDNESS_NC}\n" printf "${CLOUDNESS_BLUE} %s${CLOUDNESS_NC}\n" "$1" printf "${CLOUDNESS_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CLOUDNESS_NC}\n" diff --git a/scripts/install/cloudness-runner-rbac.yaml b/scripts/install/cloudness-runner-rbac.yaml index e9b78cd..f807065 100644 --- a/scripts/install/cloudness-runner-rbac.yaml +++ b/scripts/install/cloudness-runner-rbac.yaml @@ -4,20 +4,22 @@ metadata: name: cloudness-runner-role namespace: cloudness rules: - - apiGroups: [''] # '' indicates core apiGroup (don't remove) - resources: ['namespaces','serviceaccounts','persistentvolumeclaims','events'] - verbs: ["get", "list", "create", "patch", "delete"] + - apiGroups: [""] # '' indicates core apiGroup (don't remove) + resources: + ["namespaces", "serviceaccounts", "persistentvolumeclaims", "events"] + verbs: ["get", "list", "create", "patch", "delete", "watch"] - apiGroups: [""] - resources: ["pods", "services", "endpoints", "configmaps", "secrets"] + resources: ["pods", "services", "endpoints", "configmaps", "secrets"] verbs: ["get", "list", "create", "patch", "delete"] - - apiGroups: ['apps'] # '' indicates core apiGroup (don't remove) - resources: ['statefulsets', 'deployments', 'replicasets','controllerrevisions'] + - apiGroups: ["apps"] # '' indicates core apiGroup (don't remove) + resources: + ["statefulsets", "deployments", "replicasets", "controllerrevisions"] verbs: ["get", "list", "create", "patch", "watch", "delete"] - apiGroups: ["autoscaling"] resources: ["horizontalpodautoscalers"] verbs: ["get", "list", "create", "patch", "delete"] - apiGroups: ["rbac.authorization.k8s.io"] - resources: ["roles","rolebindings"] + resources: ["roles", "rolebindings"] verbs: ["get", "list", "create", "patch", "delete"] - apiGroups: ["gateway.networking.k8s.io"] resources: ["httproutes"] @@ -43,4 +45,4 @@ subjects: roleRef: kind: ClusterRole name: cloudness-runner-role - apiGroup: rbac.authorization.k8s.io \ No newline at end of file + apiGroup: rbac.authorization.k8s.io diff --git a/scripts/install/install.sh b/scripts/install/install.sh index 9f0126b..ba4d9a3 100755 --- a/scripts/install/install.sh +++ b/scripts/install/install.sh @@ -9,7 +9,7 @@ set -e RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' -BLUE='\033[0;34m' +BLUE='\033[38;2;40;153;245m' NC='\033[0m' # No Color # Configuration From 0f2c786de2d03b07941c1879d50a1eade4abd51b Mon Sep 17 00:00:00 2001 From: KArtHiK Date: Thu, 1 Jan 2026 10:14:44 +0100 Subject: [PATCH 17/17] rename builder plugin to helper --- .../{_build-builder.yml => _build-helper.yml} | 14 +++++++------- ...{cloudness-builder.yml => cloudness-helper.yml} | 8 ++++---- .github/workflows/cloudness-release.yml | 8 ++++---- .github/workflows/pr-validation.yml | 13 ------------- app/pipeline/convert/const.go | 4 ++-- plugins/builder/readme.md | 3 --- plugins/{builder => helper}/Dockerfile | 0 plugins/{builder => helper}/deployer/config.go | 0 plugins/{builder => helper}/deployer/deployer.go | 0 plugins/{builder => helper}/deployer/go.mod | 2 +- plugins/{builder => helper}/deployer/go.sum | 0 plugins/{builder => helper}/deployer/kubectl.go | 0 plugins/{builder => helper}/deployer/logger.go | 0 plugins/{builder => helper}/deployer/main.go | 0 plugins/{builder => helper}/deployer/operator.go | 0 .../{builder => helper}/deployer/operator_base.go | 0 .../deployer/operator_statefull.go | 0 .../deployer/operator_stateless.go | 0 plugins/helper/readme.md | 3 +++ .../{builder => helper}/scripts/build-script.sh | 0 .../{builder => helper}/scripts/cloudness-utils.sh | 0 .../{builder => helper}/scripts/deploy-script.sh | 0 plugins/{builder => helper}/scripts/init-script.sh | 0 runbooks/dev/loacalbuilder.md | 6 +++--- 24 files changed, 24 insertions(+), 37 deletions(-) rename .github/workflows/{_build-builder.yml => _build-helper.yml} (88%) rename .github/workflows/{cloudness-builder.yml => cloudness-helper.yml} (78%) delete mode 100644 plugins/builder/readme.md rename plugins/{builder => helper}/Dockerfile (100%) rename plugins/{builder => helper}/deployer/config.go (100%) rename plugins/{builder => helper}/deployer/deployer.go (100%) rename plugins/{builder => helper}/deployer/go.mod (97%) rename plugins/{builder => helper}/deployer/go.sum (100%) rename plugins/{builder => helper}/deployer/kubectl.go (100%) rename plugins/{builder => helper}/deployer/logger.go (100%) rename plugins/{builder => helper}/deployer/main.go (100%) rename plugins/{builder => helper}/deployer/operator.go (100%) rename plugins/{builder => helper}/deployer/operator_base.go (100%) rename plugins/{builder => helper}/deployer/operator_statefull.go (100%) rename plugins/{builder => helper}/deployer/operator_stateless.go (100%) create mode 100644 plugins/helper/readme.md rename plugins/{builder => helper}/scripts/build-script.sh (100%) rename plugins/{builder => helper}/scripts/cloudness-utils.sh (100%) rename plugins/{builder => helper}/scripts/deploy-script.sh (100%) rename plugins/{builder => helper}/scripts/init-script.sh (100%) diff --git a/.github/workflows/_build-builder.yml b/.github/workflows/_build-helper.yml similarity index 88% rename from .github/workflows/_build-builder.yml rename to .github/workflows/_build-helper.yml index 20bbcd5..6ff10df 100644 --- a/.github/workflows/_build-builder.yml +++ b/.github/workflows/_build-helper.yml @@ -1,4 +1,4 @@ -name: Build and Push Builder (Reusable) +name: Build and Push Helper (Reusable) on: workflow_call: @@ -46,13 +46,13 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Builder + - name: Extract metadata (tags, labels) for Helper id: meta uses: docker/metadata-action@v5 with: images: | - ghcr.io/${{ github.repository }}/builder - ${{ secrets.DOCKERHUB_USERNAME }}/builder + ghcr.io/${{ github.repository }}/helper + ${{ secrets.DOCKERHUB_USERNAME }}/helper tags: | # on git tag push, create a tag with the version number (e.g., v1.2.3) type=ref,event=tag @@ -61,11 +61,11 @@ jobs: # create a tag with the git sha for every push type=sha - - name: Build and push Builder Plugin + - name: Build and push Helper Plugin uses: docker/build-push-action@v5 with: - context: ./plugins/builder - file: ./plugins/builder/Dockerfile + context: ./plugins/helper + file: ./plugins/helper/Dockerfile push: ${{ inputs.push-images }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/cloudness-builder.yml b/.github/workflows/cloudness-helper.yml similarity index 78% rename from .github/workflows/cloudness-builder.yml rename to .github/workflows/cloudness-helper.yml index a7b41d9..8cc318c 100644 --- a/.github/workflows/cloudness-builder.yml +++ b/.github/workflows/cloudness-helper.yml @@ -1,4 +1,4 @@ -name: Plugin - Builder +name: Plugin - Helper on: # push: @@ -15,12 +15,12 @@ env: IMAGE_NAME: ${{ github.repository }} jobs: - build-cloudness-builder: - name: Builder Plugin + build-cloudness-helper: + name: Helper Plugin permissions: contents: read packages: write - uses: ./.github/workflows/_build-builder.yml + uses: ./.github/workflows/_build-helper.yml secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/cloudness-release.yml b/.github/workflows/cloudness-release.yml index c55b5e3..f01223a 100644 --- a/.github/workflows/cloudness-release.yml +++ b/.github/workflows/cloudness-release.yml @@ -24,12 +24,12 @@ jobs: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - build-cloudness-builder: - name: Builder Plugin + build-cloudness-helper: + name: Helper Plugin permissions: contents: read packages: write - uses: ./.github/workflows/_build-builder.yml + uses: ./.github/workflows/_build-helper.yml with: enable-cache: true secrets: @@ -38,7 +38,7 @@ jobs: upload-scripts: name: Upload Scripts - needs: [build-cloudness-app, build-cloudness-builder] + needs: [build-cloudness-app, build-cloudness-helper] permissions: contents: read uses: ./.github/workflows/_upload-scripts.yml diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index b91ce3f..79ee880 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -18,16 +18,3 @@ jobs: secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - - validate-builder: - name: Validate Builder - permissions: - contents: read - packages: write - uses: ./.github/workflows/_build-builder.yml - with: - enable-cache: true - push-images: false - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/app/pipeline/convert/const.go b/app/pipeline/convert/const.go index 8d10842..b2a29dd 100644 --- a/app/pipeline/convert/const.go +++ b/app/pipeline/convert/const.go @@ -22,8 +22,8 @@ var ( func getBuilderImage() string { ver := version.Version if ver.Major == 0 && ver.Minor == 0 && ver.Patch == 0 { - return "cloudnessio/builder:1.0.24" + return "cloudnessio/helper:latest" } // Use semver String() which includes prerelease (e.g., "0.1.0-alpha.1") - return fmt.Sprintf("cloudnessio/builder:v%s", ver.String()) + return fmt.Sprintf("cloudnessio/helper:v%s", ver.String()) } diff --git a/plugins/builder/readme.md b/plugins/builder/readme.md deleted file mode 100644 index 9c0069e..0000000 --- a/plugins/builder/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -to build builder - -sudo docker build . -t cloudnessio/builder:51 --build-arg TARGETPLATFORM="'linux/amd64'" diff --git a/plugins/builder/Dockerfile b/plugins/helper/Dockerfile similarity index 100% rename from plugins/builder/Dockerfile rename to plugins/helper/Dockerfile diff --git a/plugins/builder/deployer/config.go b/plugins/helper/deployer/config.go similarity index 100% rename from plugins/builder/deployer/config.go rename to plugins/helper/deployer/config.go diff --git a/plugins/builder/deployer/deployer.go b/plugins/helper/deployer/deployer.go similarity index 100% rename from plugins/builder/deployer/deployer.go rename to plugins/helper/deployer/deployer.go diff --git a/plugins/builder/deployer/go.mod b/plugins/helper/deployer/go.mod similarity index 97% rename from plugins/builder/deployer/go.mod rename to plugins/helper/deployer/go.mod index 1053251..8b354ed 100644 --- a/plugins/builder/deployer/go.mod +++ b/plugins/helper/deployer/go.mod @@ -1,4 +1,4 @@ -module github.com/cloudness-io/cloudness/plugins/builder/deployer +module github.com/cloudness-io/cloudness/plugins/helper/deployer go 1.25 diff --git a/plugins/builder/deployer/go.sum b/plugins/helper/deployer/go.sum similarity index 100% rename from plugins/builder/deployer/go.sum rename to plugins/helper/deployer/go.sum diff --git a/plugins/builder/deployer/kubectl.go b/plugins/helper/deployer/kubectl.go similarity index 100% rename from plugins/builder/deployer/kubectl.go rename to plugins/helper/deployer/kubectl.go diff --git a/plugins/builder/deployer/logger.go b/plugins/helper/deployer/logger.go similarity index 100% rename from plugins/builder/deployer/logger.go rename to plugins/helper/deployer/logger.go diff --git a/plugins/builder/deployer/main.go b/plugins/helper/deployer/main.go similarity index 100% rename from plugins/builder/deployer/main.go rename to plugins/helper/deployer/main.go diff --git a/plugins/builder/deployer/operator.go b/plugins/helper/deployer/operator.go similarity index 100% rename from plugins/builder/deployer/operator.go rename to plugins/helper/deployer/operator.go diff --git a/plugins/builder/deployer/operator_base.go b/plugins/helper/deployer/operator_base.go similarity index 100% rename from plugins/builder/deployer/operator_base.go rename to plugins/helper/deployer/operator_base.go diff --git a/plugins/builder/deployer/operator_statefull.go b/plugins/helper/deployer/operator_statefull.go similarity index 100% rename from plugins/builder/deployer/operator_statefull.go rename to plugins/helper/deployer/operator_statefull.go diff --git a/plugins/builder/deployer/operator_stateless.go b/plugins/helper/deployer/operator_stateless.go similarity index 100% rename from plugins/builder/deployer/operator_stateless.go rename to plugins/helper/deployer/operator_stateless.go diff --git a/plugins/helper/readme.md b/plugins/helper/readme.md new file mode 100644 index 0000000..95d30ff --- /dev/null +++ b/plugins/helper/readme.md @@ -0,0 +1,3 @@ +to build helper + +sudo docker build . -t cloudnessio/helper:51 --build-arg TARGETPLATFORM="'linux/amd64'" diff --git a/plugins/builder/scripts/build-script.sh b/plugins/helper/scripts/build-script.sh similarity index 100% rename from plugins/builder/scripts/build-script.sh rename to plugins/helper/scripts/build-script.sh diff --git a/plugins/builder/scripts/cloudness-utils.sh b/plugins/helper/scripts/cloudness-utils.sh similarity index 100% rename from plugins/builder/scripts/cloudness-utils.sh rename to plugins/helper/scripts/cloudness-utils.sh diff --git a/plugins/builder/scripts/deploy-script.sh b/plugins/helper/scripts/deploy-script.sh similarity index 100% rename from plugins/builder/scripts/deploy-script.sh rename to plugins/helper/scripts/deploy-script.sh diff --git a/plugins/builder/scripts/init-script.sh b/plugins/helper/scripts/init-script.sh similarity index 100% rename from plugins/builder/scripts/init-script.sh rename to plugins/helper/scripts/init-script.sh diff --git a/runbooks/dev/loacalbuilder.md b/runbooks/dev/loacalbuilder.md index 5b35e5c..da3573d 100644 --- a/runbooks/dev/loacalbuilder.md +++ b/runbooks/dev/loacalbuilder.md @@ -2,9 +2,9 @@ ```bash # Run from plugins directory -cd plugins/builder +cd plugins/helper export IMAGE_TAG="1.0.0" && \ - docker build -f Dockerfile -t cloudnessio/builder:${IMAGE_TAG} . && \ - sudo docker save cloudnessio/builder:${IMAGE_TAG} | \ + docker build -f Dockerfile -t cloudnessio/helper:${IMAGE_TAG} . && \ + sudo docker save cloudnessio/helper:${IMAGE_TAG} | \ sudo ctr -a /run/k3s/containerd/containerd.sock -n=k8s.io images import - ```