├── .gitattributes ├── .github └── workflows │ └── jekyll-gh-pages.yml ├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── LICENSE ├── Makefile ├── README.md ├── docs ├── .gitignore ├── .ruby-version ├── Gemfile ├── _config.yml ├── _includes │ ├── footer_custom.html │ ├── head.html │ ├── head_custom.html │ ├── mermaid_config.js │ ├── nav_footer_custom.html │ └── seo_custom.html ├── _sass │ └── custom │ │ └── custom.scss ├── assets │ ├── brand │ │ ├── kubert-ai-assistant-favicon-16x16.png │ │ ├── kubert-ai-assistant-favicon-32x32.png │ │ ├── kubert-ai-assistant-favicon.ico │ │ ├── kubert-ai-assistant-logo-1080x1080-optimized.png │ │ ├── kubert-ai-assistant-logo-1080x1080-transparent-optimized.png │ │ ├── kubert-ai-assistant-logo-1080x1080-transparent.png │ │ ├── kubert-ai-assistant-logo-1080x1080.png │ │ ├── kubert-ai-assistant-logo-180x180.png │ │ ├── kubert-ai-assistant-logo-192x192.png │ │ ├── kubert-ai-assistant-logo-512x512.png │ │ ├── kubert-ai-assistant-logo-540x540-transparent-optimized.png │ │ └── kubert-ai-assistant-logo-540x540-transparent.png.png │ ├── css │ │ └── asciinema-player.css │ ├── images │ │ ├── azure-vm │ │ │ ├── 10_delete_public_ip.png │ │ │ ├── 11_auto-shutdown.png │ │ │ ├── 12_create-vm.png │ │ │ ├── 13_deploying.png │ │ │ ├── 14_done-deployment.png │ │ │ ├── 15_host.png │ │ │ ├── 16_set-rdp-port.png │ │ │ ├── 17_enter-port.png │ │ │ ├── 18_port-set.png │ │ │ ├── 19_set-inbound-rule.png │ │ │ ├── 1_azure-home.png │ │ │ ├── 20_my-ip-rule.png │ │ │ ├── 21_new-rule.png │ │ │ ├── 22_download-rdp-file.png │ │ │ ├── 23_remote-desktop.png │ │ │ ├── 24_updated-port.png │ │ │ ├── 25_logged-in.png │ │ │ ├── 2_azure-vm-home.png │ │ │ ├── 3_create-vm.png │ │ │ ├── 4_create-resource-group.png │ │ │ ├── 5_define_host_name.png │ │ │ ├── 6_security_and_image.png │ │ │ ├── 7_size_cpu_ram.png │ │ │ ├── 8_account_port.png │ │ │ └── 9_disks.png │ │ ├── coverage-report.png │ │ ├── favicon.ico │ │ ├── kubert-logo.png │ │ ├── namespace-status.png │ │ └── windows │ │ │ ├── start-search.png │ │ │ ├── turn-on-hyper-v.png │ │ │ └── turn-on-wsl.png │ ├── js │ │ ├── asciinema-player.min.js │ │ └── zzzz-search-data.json │ ├── terminal │ │ ├── build-kcov-image.cast │ │ ├── helm-tests.cast │ │ ├── lint-chart.cast │ │ ├── make-cleanup-mac.cast │ │ ├── make-coverage.cast │ │ ├── make-deploy-mac.cast │ │ ├── make-list.cast │ │ ├── make-tests-integration-one-file.cast │ │ ├── make-tests-integration.cast │ │ ├── make-tests-one-file-one-test.cast │ │ ├── make-tests-one-file.cast │ │ ├── make-tests.cast │ │ └── template-chart.cast │ └── video │ │ ├── Kubert_AI_Assistant_Lite_Demo.mp4 │ │ ├── kubert-agent-hello-world.mp4 │ │ ├── memory-hog.mp4 │ │ ├── ollama-installation-kubert-ai-config.mp4 │ │ └── open-browser.mov ├── azure.md ├── index.md ├── installation.md ├── ollama.md ├── sitemap.xml ├── testing.md ├── usage.md ├── usage_ollama_and_kubert.md ├── usage_window_setup_dev.md └── wsl.md ├── kind-config.yaml ├── manifests ├── calico │ └── deploy.yaml ├── chart │ ├── Chart.yaml │ ├── charts │ │ └── common-2.20.5.tgz │ ├── templates │ │ ├── _helpers.tpl │ │ ├── clusterrole.yaml │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ ├── networkpolicy.yaml │ │ ├── role.yaml │ │ ├── service.yaml │ │ ├── serviceaccount.yaml │ │ └── test.yaml │ └── values.yaml ├── kubert-assistant │ ├── agent-repo-values.yaml │ ├── command-runner-values.yaml │ ├── gateway-values.yaml │ ├── lobe-chat-values.yaml │ └── plugin-repo-values.yaml ├── nginx-ingress-controller │ └── deploy.yaml └── test-deployment │ └── memory-hog.yaml ├── scripts ├── cleanup.sh ├── deploy.sh ├── hello.sh ├── utils.sh ├── validate-tools.sh └── variables.sh └── tests ├── integration ├── kind-config.yaml ├── test_create_kind_cluster.bats └── test_deploy_application.bats ├── support └── Dockerfile └── unit ├── test_cluster.bats ├── test_command.bats ├── test_deploy_functions.bats ├── test_hosts_file.bats ├── test_logs.bats └── test_wait_functions.bats /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/jekyll-gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Jekyll site to Pages 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | paths: 7 | - "docs/**" 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | concurrency: 20 | group: "pages" 21 | cancel-in-progress: true 22 | 23 | jobs: 24 | # Build job 25 | build: 26 | runs-on: ubuntu-latest 27 | defaults: 28 | run: 29 | working-directory: docs 30 | steps: 31 | - name: Checkout 32 | uses: actions/checkout@v4.1.7 33 | - name: Setup Ruby 34 | uses: ruby/setup-ruby@v1 35 | with: 36 | bundler-cache: true 37 | cache-version: 0 38 | working-directory: '${{ github.workspace }}/docs' 39 | - name: Setup Pages 40 | uses: actions/configure-pages@v5 41 | - name: Build with Jekyll 42 | run: bundle exec jekyll build 43 | env: 44 | JEKYLL_ENV: production 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v3.0.1 47 | with: 48 | path: "docs/_site/" 49 | 50 | # Deployment job 51 | deploy: 52 | environment: 53 | name: github-pages 54 | url: ${{ steps.deployment.outputs.page_url }} 55 | runs-on: ubuntu-latest 56 | needs: build 57 | steps: 58 | - name: Deploy to GitHub Pages 59 | id: deployment 60 | uses: actions/deploy-pages@v4.0.5 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output.log 2 | 3 | # test coverage 4 | coverage/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/bats"] 2 | path = tests/bats 3 | url = https://github.com/bats-core/bats-core.git 4 | [submodule "tests/test_helper/bats-support"] 5 | path = tests/test_helper/bats-support 6 | url = https://github.com/bats-core/bats-support.git 7 | [submodule "tests/test_helper/bats-assert"] 8 | path = tests/test_helper/bats-assert 9 | url = https://github.com/bats-core/bats-assert.git 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Ollama", 4 | "Qwen" 5 | ] 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Kubert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for running Bats tests and generating coverage with kcov 2 | # 3 | # Copyright 2024 Kubert 4 | 5 | # Use bash as the shell 6 | SHELL := /bin/bash 7 | 8 | # Shell command 9 | SHELL_CMD := /bin/bash 10 | 11 | # Directories 12 | TESTS_DIR := tests 13 | UNIT_TESTS_DIR := $(TESTS_DIR)/unit 14 | INTEGRATION_TESTS_DIR := $(TESTS_DIR)/integration 15 | SCRIPTS_DIR := scripts 16 | COVERAGE_DIR := coverage 17 | BATS_LIBS_DIR := $(TESTS_DIR)/test_helper 18 | BATS_DIR := $(TESTS_DIR)/bats 19 | BATS := $(BATS_DIR)/bin/bats 20 | DOCKER_IMAGE_NAME ?= kubert_kcov 21 | CHART_PATH := manifests/chart 22 | 23 | # Unit test file to run, use like this: make tests TEST_FILE=tests/unit/test_specific.bats 24 | # If not specified, runs all tests in the UNIT_TESTS_DIR. 25 | TEST_FILE ?= $(UNIT_TESTS_DIR) 26 | 27 | # Pattern to filter tests, use like this: make tests TEST_PATTERN="specific test" 28 | # Leave empty to run all tests within the TEST_FILE or UNIT_TESTS_DIR. 29 | TEST_PATTERN ?= 30 | 31 | # Integration test file to run, use like this: make tests TEST_FILE=tests/integration/test_specific.bats 32 | # If not specified, runs all tests in the INTEGRATION_TESTS_DIR. 33 | INTEGRATION_TEST_FILE ?= $(INTEGRATION_TESTS_DIR) 34 | 35 | # Pattern to filter tests, use like this: make tests INTEGRATION_TEST_PATTERN="specific test" 36 | # Leave empty to run all tests within the TEST_FILE or INTEGRATION_TEST_FILE. 37 | INTEGRATION_TEST_PATTERN ?= 38 | 39 | # Docker security options 40 | DOCKER_SECURITY_OPTS ?= --security-opt seccomp=unconfined 41 | 42 | # Docker run command 43 | DOCKER_RUN_CMD := docker run --rm $(DOCKER_SECURITY_OPTS) \ 44 | -v "$(shell pwd):/source" 45 | 46 | # kcov command, change to "kcov" if not using Docker 47 | KCOV := $(DOCKER_RUN_CMD) $(DOCKER_IMAGE_NAME) kcov 48 | 49 | # Paths to include/exclude in coverage 50 | EXCLUDE_PATH := "/source/$(BATS_LIBS_DIR),/source/$(BATS_DIR)" 51 | 52 | # Verbose mode (set VERBOSE=1 to enable) 53 | ifeq ($(VERBOSE),1) 54 | Q := 55 | else 56 | Q := @ 57 | endif 58 | 59 | # Help target to display available commands 60 | .PHONY: help 61 | help: 62 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) 63 | 64 | # Build custom Docker image 65 | .PHONY: build-docker 66 | build-kcov-image: ## Build kcov image with additional tools 67 | $(Q)command -v docker >/dev/null 2>&1 || { echo >&2 "Docker is not installed. Aborting."; exit 1; } 68 | $(Q)docker build -t $(DOCKER_IMAGE_NAME) ./tests/support 69 | 70 | # Target for running tests 71 | .PHONY: tests 72 | tests: ## Run bats and tests 73 | $(Q)if [ -z "$(TEST_PATTERN)" ]; then \ 74 | BATS_LIB_PATH=$(BATS_LIBS_DIR) $(BATS) $(TEST_FILE); \ 75 | else \ 76 | BATS_LIB_PATH=$(BATS_LIBS_DIR) $(BATS) -f "$(TEST_PATTERN)" $(TEST_FILE); \ 77 | fi 78 | 79 | # Target for running integration tests 80 | .PHONY: integration-tests 81 | integration-tests: ## Run bats integration tests 82 | $(Q)if [ -z "$(INTEGRATION_TEST_PATTERN)" ]; then \ 83 | BATS_LIB_PATH=$(BATS_LIBS_DIR) $(BATS) -p -t $(INTEGRATION_TEST_FILE); \ 84 | else \ 85 | BATS_LIB_PATH=$(BATS_LIBS_DIR) $(BATS) -p -t -f "$(INTEGRATION_TEST_PATTERN)" $(INTEGRATION_TEST_FILE); \ 86 | fi 87 | 88 | # Target for running tests with kcov 89 | .PHONY: coverage 90 | coverage: ## Run kcov and tests 91 | $(Q)$(KCOV) --exclude-path=$(EXCLUDE_PATH) /source/$(COVERAGE_DIR) /source/$(BATS) /source/$(TEST_FILE) 92 | 93 | # Clean up coverage directory 94 | .PHONY: clean-build 95 | clean-build: ## Remove coverage dir and kcov image 96 | $(Q)rm -rf $(COVERAGE_DIR) 97 | $(Q)docker rmi $(DOCKER_IMAGE_NAME) || true 98 | 99 | # Validate and deploy scripts 100 | .PHONY: deploy 101 | deploy: ## Deploy kind cluster with Kubert AI Assistant Lite 102 | $(Q)LOG_TO_TERMINAL=true $(SCRIPTS_DIR)/deploy.sh 103 | 104 | # Deploy Kubert Assistant components using Helm 105 | .PHONY: deploy-kubert-assistant 106 | deploy-kubert-assistant: ## Deploy Kubert Assistant components using Helm 107 | $(Q) LOG_TO_TERMINAL=true && \ 108 | source $(SCRIPTS_DIR)/utils.sh && \ 109 | source $(SCRIPTS_DIR)/variables.sh && \ 110 | deploy_kubert_assistant "$${CHART_PATH}" "$${HELM_NAMESPACE}" "$${KIND_CLUSTER_NAME}" "$${KUBERT_COMPONENTS[@]}" 111 | 112 | # Deploy Kubert Assistant components using Helm 113 | .PHONY: cleanup-kubert-assistant 114 | cleanup-kubert-assistant: ## Uninstall deployed Kubert Assistant components with Helm 115 | $(Q) LOG_TO_TERMINAL=true && \ 116 | source $(SCRIPTS_DIR)/utils.sh && \ 117 | source $(SCRIPTS_DIR)/variables.sh && \ 118 | uninstall_kubert_assistant "$${HELM_NAMESPACE}" "$${KUBERT_COMPONENTS[@]}" 119 | 120 | # Cleanup scripts 121 | .PHONY: cleanup 122 | cleanup: ## Clean up kind cluster and hosts file 123 | $(Q)LOG_TO_TERMINAL=true $(SCRIPTS_DIR)/cleanup.sh 124 | 125 | # Dependency check for development 126 | check-deps-dev: ## Check for required dependencies for development 127 | @command -v docker >/dev/null 2>&1 || { echo >&2 "Docker is not installed. Aborting."; exit 1; } 128 | @docker info >/dev/null 2>&1 || { echo >&2 "Docker is not running or not accessible. Aborting."; exit 1; } 129 | @command -v kind >/dev/null 2>&1 || { echo >&2 "kind is not installed. Aborting."; exit 1; } 130 | @command -v kubectl >/dev/null 2>&1 || { echo >&2 "Kubectl is not installed. Aborting."; exit 1; } 131 | @command -v helm >/dev/null 2>&1 || { echo >&2 "Helm is not installed. Aborting."; exit 1; } 132 | @command -v jq >/dev/null 2>&1 || { echo >&2 "jq is not installed. Aborting."; exit 1; } 133 | @[ -x "$(BATS)" ] || { echo >&2 "Bats is not installed or not executable. Aborting."; exit 1; } 134 | @echo "All development dependencies are installed." 135 | 136 | # Dependency check for deployment 137 | .PHONY: check-deps-deploy 138 | check-deps-deploy: ## Check for required dependencies for deployment 139 | $(Q)command -v docker >/dev/null 2>&1 || { echo >&2 "Docker is not installed. Aborting."; exit 1; } 140 | @docker info >/dev/null 2>&1 || { echo >&2 "Docker is not running or not accessible. Aborting."; exit 1; } 141 | $(Q)command -v kind >/dev/null 2>&1 || { echo >&2 "kind is not installed. Aborting."; exit 1; } 142 | $(Q)command -v kubectl >/dev/null 2>&1 || { echo >&2 "Kubectl is not installed. Aborting."; exit 1; } 143 | $(Q)command -v helm >/dev/null 2>&1 || { echo >&2 "Helm is not installed. Aborting."; exit 1; } 144 | $(Q)command -v jq >/dev/null 2>&1 || { echo >&2 "jq is not installed. Aborting."; exit 1; } 145 | $(Q)echo "All deployment dependencies are installed." 146 | 147 | # Lint the Helm chart 148 | .PHONY: lint 149 | lint-chart: ## Lint the Helm chart 150 | helm lint $(CHART_PATH) 151 | 152 | # Template the Helm chart 153 | .PHONY: template 154 | template-chart: ## Template the Helm chart 155 | helm template --debug $(CHART_PATH) 156 | 157 | # Helm test target 158 | .PHONY: helm-test 159 | helm-test: ## Run Helm tests 160 | $(Q) LOG_TO_TERMINAL=true source $(SCRIPTS_DIR)/variables.sh && \ 161 | for component in "$${KUBERT_COMPONENTS[@]}"; do \ 162 | IFS=":" read -r release_name values_file <<< "$$component"; \ 163 | helm test "$$release_name" -n "$$HELM_NAMESPACE"; \ 164 | done -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubert AI Assistant Lite Project 2 | 3 | Kubert AI Assistant Lite is an open-source project designed to deploy a lightweight version of Kubert Assistant in a local kind (Kubernetes in Docker) cluster. This version includes a single AI agent, the Kubectl Agent, which can execute `kubectl` commands within the cluster. 4 | 5 | Additional documentation can be found here -> [Documentation](https://translucentcomputing.github.io/kubert-assistant-lite/) 6 | 7 | Setup video -> [Video](https://translucentcomputing.github.io/kubert-assistant-lite/usage.html#kubert-ai-assistant-setup) 8 | 9 | ## Table of Contents 10 | 11 | - [Kubert AI Assistant Lite Project](#kubert-ai-assistant-lite-project) 12 | - [Table of Contents](#table-of-contents) 13 | - [Introduction](#introduction) 14 | - [Features](#features) 15 | - [Prerequisites](#prerequisites) 16 | - [Installation](#installation) 17 | - [Usage](#usage) 18 | - [Deploy the Kubernetes Cluster and Application](#deploy-the-kubernetes-cluster-and-application) 19 | - [Scripts](#scripts) 20 | - [Helm Configuration](#helm-configuration) 21 | - [Makefile Targets](#makefile-targets) 22 | - [Testing](#testing) 23 | - [Running Tests](#running-tests) 24 | - [Unit Tests](#unit-tests) 25 | - [Integration Tests](#integration-tests) 26 | - [Test Coverage with kcov](#test-coverage-with-kcov) 27 | - [Contributing](#contributing) 28 | - [License](#license) 29 | - [Acknowledgments](#acknowledgments) 30 | 31 | ## Introduction 32 | 33 | Kubert Assistant is a DevOps productivity tool designed to simplify the management of workloads within a Kubernetes cluster. It provides a suite of capabilities that allow DevOps teams to automate, monitor, and manage their Kubernetes environments more efficiently. 34 | 35 | Kubert AI Assistant Lite provides an easy way to set up a local Kubernetes environment using kind and deploys a minimal version of the Kubert Assistant platform. This project is ideal for testing and development purposes, offering the core functionalities of Kubert Assistant with a focus on the Kubectl Agent. 36 | 37 | ## Features 38 | 39 | - Deploys a local kind cluster. 40 | - Includes a Kubectl Agent for executing `kubectl` commands. 41 | - Utilizes Helm charts for easy deployment and management. 42 | - Lightweight and easy to set up for local testing and development. 43 | 44 | ## Prerequisites 45 | 46 | Before you begin, ensure you have the following installed on your system: 47 | 48 | - [Docker](https://docs.docker.com/get-docker/) 49 | - [kind](https://kind.sigs.k8s.io/) 50 | - [Helm](https://helm.sh/docs/intro/install/) 51 | - [Kubectl](https://kubernetes.io/docs/tasks/tools/) 52 | - [jq](https://stedolan.github.io/jq/) 53 | - [Make](https://www.gnu.org/software/make/) 54 | - [OpenAI API Key](https://platform.openai.com/docs/api-reference/authentication) or [Anthropic API Key](https://console.anthropic.com/docs/authentication) (for AI capabilities) 55 | 56 | 57 | ## Installation 58 | 59 | 1. Clone the Repository 60 | 61 | ```bash 62 | git clone https://github.com/TranslucentComputing/kubert-assistant-lite.git 63 | cd kubert-assistant-lite 64 | ``` 65 | 66 | 2. For testing initialize BATS submodules 67 | 68 | ```bash 69 | git submodule update --init --recursive 70 | ``` 71 | 72 | ## Usage 73 | 74 | ### Deploy the Kubernetes Cluster and Application 75 | 76 | The deployment process is automated using a Makefile. To deploy the kind cluster and the Kubert AI Assistant Lite application, run: 77 | 78 | ```bash 79 | make deploy 80 | ``` 81 | 82 | This will execute the deploy.sh script which sets up the kind cluster and deploys the application using Helm. 83 | 84 | ## Scripts 85 | 86 | - `deploy.sh`: Deploys the kind cluster and the Kubert AI Assistant Lite application. 87 | - `utils.sh`: Contains utility functions used across the scripts. 88 | - `hello.sh`: Greetings and deployment description. 89 | - `validate-tools.sh`: Validates the installation of required tools. 90 | - `variables.sh`: Contains variables used in the deployment script. 91 | - `cleanup.sh`: Cleans up resources after deployment by deleting the kind cluster and updating the hosts file. 92 | 93 | ## Helm Configuration 94 | 95 | Configuration files are located in the manifests/kubert-assistant/ directory. You can customize the deployment by modifying these Helm values files: 96 | 97 | - `gateway-values.yaml` 98 | - `agent-repo-values.yaml` 99 | - `command-runner-values.yaml` 100 | - `lobe-chat-values.yaml` 101 | - `plugin-repo-values.yaml` 102 | 103 | ## Makefile Targets 104 | 105 | - `help`: Displays available commands. 106 | - `build-kcov-image`: Builds the Docker image for kcov used for test coverage. 107 | - `tests`: Runs unit tests. 108 | - `integration-tests`: Runs integration tests. 109 | - `coverage`: Runs tests with kcov for coverage. 110 | - `clean-build`: Cleans up the coverage directory and Docker image. 111 | - `deploy`: Deploys the kind cluster and Kubert AI Assistant Lite application. 112 | - `deploy-kubert-assistant`: Deploys Kubert Assistant components using Helm. 113 | - `cleanup-kubert-assistant`: Uninstall deployed Kubert Assistant components with Helm 114 | - `cleanup`: Cleans up the kind cluster and hosts file. 115 | - `check-deps-dev`: Checks for required dev dependencies. 116 | - `check-deps-deploy`: Checks for required deployment dependencies. 117 | - `lint-chart`: Lints the Helm chart. 118 | - `template-chart`: Templates the Helm chart. 119 | - `helm-test`: Execute Helm tests 120 | 121 | ## Testing 122 | 123 | BATS is a testing framework for Bash scripts that provides a simple way to test and validate shell scripts. It is used in this project to ensure the reliability and correctness of shell scripts and command-line operations. BATS tests are written in a plain text format, making them easy to read and understand. 124 | 125 | ### Running Tests 126 | 127 | #### Unit Tests 128 | 129 | To run the BATS unit tests: 130 | 131 | ```bash 132 | make tests 133 | ``` 134 | 135 | #### Integration Tests 136 | 137 | To run the BATS integration tests: 138 | 139 | ```bash 140 | make integration-tests 141 | ``` 142 | 143 | To run specific integration test: 144 | 145 | ```bash 146 | make integration-tests INTEGRATION_TEST_FILE=tests/integration/test_deploy_application.bats 147 | ``` 148 | 149 | ### Test Coverage with kcov 150 | 151 | To run the tests with kcov for coverage, follow these steps: 152 | 153 | 1. Build the kcov Docker image: 154 | 155 | ```bash 156 | make build-kcov-image 157 | ``` 158 | 159 | 2. Run the coverage target: 160 | 161 | ```bash 162 | make coverage 163 | ``` 164 | 165 | This will execute the tests and generate coverage reports in coverage folder using kcov. 166 | 167 | ## Contributing 168 | 169 | We welcome contributions from the community! To contribute, please follow these steps: 170 | 171 | 1. Fork the repository. 172 | 2. Create a new branch: git checkout -b feature/YourFeatureName. 173 | 3. Make your changes and commit them: git commit -m 'Add some feature'. 174 | 4. Push to the branch: git push origin feature/YourFeatureName. 175 | 5. Open a pull request. 176 | 177 | ## License 178 | 179 | This project is licensed under the terms of the `LICENSE` file. 180 | 181 | ## Acknowledgments 182 | 183 | Thank you to all contributors and the open-source community for making this project possible. 184 | Special thanks to the authors of the tools and libraries used in this project. 185 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | .jekyll-cache 4 | .jekyll-metadata 5 | vendor 6 | Gemfile.lock -------------------------------------------------------------------------------- /docs/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.3.1 2 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "jekyll", "~> 4.3.3" 3 | gem "just-the-docs" 4 | gem 'base64' 5 | gem 'csv' # Required for Ruby 3.4.0+ 6 | gem 'webrick' # Required for Ruby 3.0.0+ 7 | gem 'faraday-retry' # If using Faraday v2.0+ 8 | 9 | # If you have any plugins, put them here! 10 | group :jekyll_plugins do 11 | gem "jekyll-feed", "~> 0.12" 12 | end 13 | 14 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem 15 | # and associated library. 16 | platforms :mingw, :x64_mingw, :mswin, :jruby do 17 | gem "tzinfo", ">= 1", "< 3" 18 | gem "tzinfo-data" 19 | end 20 | 21 | # Performance-booster for watching directories on Windows 22 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] 23 | 24 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem 25 | # do not have a Java counterpart. 26 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] 27 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: Kubert AI Assistant Lite 2 | name: Kubert Lite 3 | email: patryk@translucentcomputing.com 4 | description: >- 5 | Kubert AI Assistant Lite is a productivity system for DevOps. 6 | It combines the GenAI with Kubernetes to provide out-of-the-box 7 | solutions for optimizing DevOps work. 8 | baseurl: "/kubert-assistant-lite" # Repository name 9 | url: "https://translucentcomputing.github.io" 10 | twitter_username: kubertai 11 | github_username: patrykattc 12 | logo: "/assets/images/kubert-logo.png" 13 | favicon_ico: "/assets/images/favicon.ico" 14 | search_enabled: true 15 | search: 16 | # Split pages into sections that can be searched individually 17 | # Supports 1 - 6, default: 2 18 | heading_level: 2 19 | # Maximum amount of previews per search result 20 | # Default: 3 21 | previews: 3 22 | # Maximum amount of words to display before a matched word in the preview 23 | # Default: 5 24 | preview_words_before: 5 25 | # Maximum amount of words to display after a matched word in the preview 26 | # Default: 10 27 | preview_words_after: 10 28 | # Set the search token separator 29 | # Default: /[\s\-/]+/ 30 | # Example: enable support for hyphenated search words 31 | tokenizer_separator: /[\s/]+/ 32 | # Display the relative url in search results 33 | # Supports true (default) or false 34 | rel_url: true 35 | # Enable or disable the search button that appears in the bottom right corner of every page 36 | # Supports true or false (default) 37 | button: false 38 | # Focus the search input by pressing `ctrl + focus_shortcut_key` (or `cmd + focus_shortcut_key` on macOS) 39 | focus_shortcut_key: 'k' 40 | 41 | # Footer last edited timestamp 42 | last_edit_timestamp: true 43 | last_edit_time_format: "%b %e %Y at %I:%M %p" 44 | 45 | # Footer "Edit this page on GitHub" link text 46 | gh_edit_link: true 47 | gh_edit_link_text: "Edit this page on GitHub." 48 | gh_edit_repository: "https://github.com/TranslucentComputing/kubert-assistant-lite" 49 | gh_edit_branch: "main" 50 | gh_edit_view_mode: "tree" 51 | 52 | # Google Analytics Tracking (optional) 53 | ga_tracking: G-Q7QDCP3CE4 54 | ga_tracking_anonymize_ip: true 55 | 56 | mermaid: 57 | version: "10.9.1" 58 | 59 | # Build settings 60 | theme: just-the-docs 61 | plugins: 62 | - jekyll-feed 63 | 64 | # Aux links for the upper right navigation 65 | aux_links: 66 | "Kubert AI Assistant Lite GitHub": 67 | - "https://github.com/TranslucentComputing/kubert-assistant-lite" 68 | 69 | # Makes Aux links open in a new tab. Default is false 70 | aux_links_new_tab: true -------------------------------------------------------------------------------- /docs/_includes/footer_custom.html: -------------------------------------------------------------------------------- 1 |

2 | Copyright © 2024 Kubert. Distributed by an MIT license. 3 |

-------------------------------------------------------------------------------- /docs/_includes/head.html: -------------------------------------------------------------------------------- 1 | {%- comment -%} 2 | Include as: {%- include head.html -%} 3 | Depends on: site.ga_tracking, site.ga_tracking_anonymize_ip, 4 | site.search_enabled, site.static_files, site.favicon_ico. 5 | Results in: HTML for the head element. 6 | Includes: 7 | css/activation.scss.liquid, head_custom.html. 8 | Overwrites: 9 | ga_tracking_ids, ga_property, file, favicon. 10 | Should not be cached, because included files depend on page. 11 | {%- endcomment -%} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | {% if site.ga_tracking != nil %} 26 | {% assign ga_tracking_ids = site.ga_tracking | split: "," %} 27 | 28 | 37 | {% endif %} 38 | 39 | {% if site.search_enabled != false %} 40 | 41 | {% endif %} 42 | 43 | 44 | 45 | 46 | 47 | {% include_cached favicon.html %} 48 | 49 | {% include head_custom.html %} 50 | 51 | {% include seo_custom.html %} 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/_includes/head_custom.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_includes/mermaid_config.js: -------------------------------------------------------------------------------- 1 | { 2 | theme: "light", 3 | securityLevel: "loose", 4 | displayMode: "compact" 5 | } -------------------------------------------------------------------------------- /docs/_includes/nav_footer_custom.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_includes/seo_custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% assign page_title = page.k_seo.title | default: page.title %} 4 | {{ page_title }} 5 | 6 | {% assign social_page_title = page.k_seo.social_title | default: page_title %} 7 | 8 | 9 | 10 | {% if page.author.name %} 11 | 12 | {% endif %} 13 | 14 | {% assign description = page.k_seo.description | default: page.description %} 15 | 16 | 17 | 18 | 19 | {% assign base_url = site.url | append: '/kubert-assistant-lite' %} 20 | {% if site.url %} 21 | 22 | 23 | {% endif %} 24 | 25 | {% if site.title %} 26 | 27 | {% endif %} 28 | 29 | {% if page.k_seo.image %} 30 | 31 | {% if page.k_seo.image.height %} 32 | 33 | {% endif %} 34 | {% if page.k_seo.image.width %} 35 | 36 | {% endif %} 37 | {% if page.k_seo.image.alt %} 38 | 39 | {% endif %} 40 | {% endif %} 41 | 42 | {% if page.date %} 43 | 44 | 45 | {% else %} 46 | 47 | {% endif %} 48 | 49 | 50 | {% if page.k_seo.image %} 51 | 52 | 53 | {% else %} 54 | 55 | {% endif %} 56 | 57 | {% if page.k_seo.image.alt %} 58 | 59 | {% endif %} 60 | 61 | {% if social_page_title %} 62 | 63 | {% endif %} 64 | 65 | {% if site.twitter %} 66 | 67 | 68 | {% if page.k_seo.author.twitter %} 69 | 70 | {% endif %} 71 | {% endif %} 72 | 73 | {% if site.facebook %} 74 | {% if site.facebook.admins %} 75 | 76 | {% endif %} 77 | 78 | {% if site.facebook.publisher %} 79 | 80 | {% endif %} 81 | 82 | {% if site.facebook.app_id %} 83 | 84 | {% endif %} 85 | {% endif %} 86 | 87 | 101 | 102 | -------------------------------------------------------------------------------- /docs/_sass/custom/custom.scss: -------------------------------------------------------------------------------- 1 | .video-container { 2 | position: relative; 3 | width: 100%; 4 | padding-bottom: 56.25%; /* Aspect ratio of 16:9 (9/16 = 0.5625) */ 5 | height: 0; 6 | overflow: hidden; 7 | } 8 | 9 | .video-container video { 10 | position: absolute; 11 | top: 0; 12 | left: 0; 13 | width: 100%; 14 | height: 100%; 15 | } 16 | 17 | .video-container iframe { 18 | position: absolute; 19 | top: 0; 20 | left: 0; 21 | width: 100%; 22 | height: 100%; 23 | border: 0; 24 | } -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-favicon-16x16.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-favicon-32x32.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-favicon.ico -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-1080x1080-optimized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-1080x1080-optimized.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-1080x1080-transparent-optimized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-1080x1080-transparent-optimized.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-1080x1080-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-1080x1080-transparent.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-1080x1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-1080x1080.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-180x180.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-192x192.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-512x512.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-540x540-transparent-optimized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-540x540-transparent-optimized.png -------------------------------------------------------------------------------- /docs/assets/brand/kubert-ai-assistant-logo-540x540-transparent.png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/brand/kubert-ai-assistant-logo-540x540-transparent.png.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/10_delete_public_ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/10_delete_public_ip.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/11_auto-shutdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/11_auto-shutdown.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/12_create-vm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/12_create-vm.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/13_deploying.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/13_deploying.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/14_done-deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/14_done-deployment.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/15_host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/15_host.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/16_set-rdp-port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/16_set-rdp-port.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/17_enter-port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/17_enter-port.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/18_port-set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/18_port-set.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/19_set-inbound-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/19_set-inbound-rule.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/1_azure-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/1_azure-home.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/20_my-ip-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/20_my-ip-rule.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/21_new-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/21_new-rule.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/22_download-rdp-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/22_download-rdp-file.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/23_remote-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/23_remote-desktop.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/24_updated-port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/24_updated-port.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/25_logged-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/25_logged-in.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/2_azure-vm-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/2_azure-vm-home.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/3_create-vm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/3_create-vm.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/4_create-resource-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/4_create-resource-group.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/5_define_host_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/5_define_host_name.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/6_security_and_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/6_security_and_image.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/7_size_cpu_ram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/7_size_cpu_ram.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/8_account_port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/8_account_port.png -------------------------------------------------------------------------------- /docs/assets/images/azure-vm/9_disks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/azure-vm/9_disks.png -------------------------------------------------------------------------------- /docs/assets/images/coverage-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/coverage-report.png -------------------------------------------------------------------------------- /docs/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/favicon.ico -------------------------------------------------------------------------------- /docs/assets/images/kubert-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/kubert-logo.png -------------------------------------------------------------------------------- /docs/assets/images/namespace-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/namespace-status.png -------------------------------------------------------------------------------- /docs/assets/images/windows/start-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/windows/start-search.png -------------------------------------------------------------------------------- /docs/assets/images/windows/turn-on-hyper-v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/windows/turn-on-hyper-v.png -------------------------------------------------------------------------------- /docs/assets/images/windows/turn-on-wsl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/images/windows/turn-on-wsl.png -------------------------------------------------------------------------------- /docs/assets/js/zzzz-search-data.json: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /assets/js/search-data.json 3 | --- 4 | { 5 | {%- assign i = 0 -%} 6 | {%- assign pages_array = "" | split: "" -%} 7 | {%- assign pages_array = pages_array | push: site.html_pages -%} 8 | {%- if site.just_the_docs.collections -%} 9 | {%- for collection_entry in site.just_the_docs.collections -%} 10 | {%- assign collection_key = collection_entry[0] -%} 11 | {%- assign collection_value = collection_entry[1] -%} 12 | {%- assign collection = site[collection_key] -%} 13 | {%- if collection_value.search_exclude != true -%} 14 | {%- assign pages_array = pages_array | push: collection -%} 15 | {%- endif -%} 16 | {%- endfor -%} 17 | {%- endif -%} 18 | {%- for pages in pages_array -%} 19 | {%- for page in pages -%} 20 | {%- if page.title and page.search_exclude != true -%} 21 | {%- assign page_content = page.content -%} 22 | {%- assign heading_level = site.search.heading_level | default: 2 -%} 23 | {%- for j in (2..heading_level) -%} 24 | {%- assign tag = '' -%} 32 | {%- assign title = titleAndContent[0] | replace_first: '>', '

' | split: '

' -%} 33 | {%- assign title = title[1] | strip_html -%} 34 | {%- assign content = titleAndContent[1] -%} 35 | {%- assign url = page.url -%} 36 | {%- if title == page.title and parts[0] == '' -%} 37 | {%- assign title_found = true -%} 38 | {%- else -%} 39 | {%- assign id = titleAndContent[0] -%} 40 | {%- assign id = id | split: 'id="' -%} 41 | {%- if id.size == 2 -%} 42 | {%- assign id = id[1] -%} 43 | {%- assign id = id | split: '"' -%} 44 | {%- assign id = id[0] -%} 45 | {%- capture url -%}{{ url | append: '#' | append: id }}{%- endcapture -%} 46 | {%- endif -%} 47 | {%- endif -%} 48 | {%- unless i == 0 -%},{%- endunless -%} 49 | "{{ i }}": { 50 | "doc": {{ page.title | jsonify }}, 51 | "title": {{ title | jsonify }}, 52 | "content": {{ content | replace: '"] 24 | [5.545042, "o", "\u001b[?2004l\r\r\n"] 25 | [5.553171, "o", "\u001b]2;make helm-test\u0007\u001b]1;make\u0007"] 26 | [5.553214, "o", "\u001b]133;C;\r\u0007"] 27 | [12.357598, "o", "NAME: command-runner\r\nLAST DEPLOYED: Sat Aug 3 07:20:40 2024\r\nNAMESPACE: kubert-assistant\r\nSTATUS: deployed\r\nREVISION: 1\r\nTEST SUITE: command-runner-kubert-assistant-workload-test-connection\r\nLast Started: Sat Aug 3 07:24:50 2024\r\nLast Completed: Sat Aug 3 07:24:56 2024\r\nPhase: Succeeded\r\n"] 28 | [12.421405, "o", "NAME: agent-repo\r\nLAST DEPLOYED: Sat Aug 3 07:20:40 2024\r\nNAMESPACE: kubert-assistant\r\nSTATUS: deployed\r\nREVISION: 1\r\nTEST SUITE: None\r\n"] 29 | [12.468782, "o", "NAME: plugin-repo\r\nLAST DEPLOYED: Sat Aug 3 07:20:40 2024\r\nNAMESPACE: kubert-assistant\r\nSTATUS: deployed\r\nREVISION: 1\r\nTEST SUITE: None\r\n"] 30 | [12.51235, "o", "NAME: gateway\r\nLAST DEPLOYED: Sat Aug 3 07:20:41 2024\r\nNAMESPACE: kubert-assistant\r\nSTATUS: deployed\r\nREVISION: 1\r\nTEST SUITE: None\r\n"] 31 | [12.569741, "o", "NAME: lobechat\r\nLAST DEPLOYED: Sat Aug 3 07:20:41 2024\r\nNAMESPACE: kubert-assistant\r\nSTATUS: deployed\r\nREVISION: 1\r\nTEST SUITE: None\r\n"] 32 | [12.571144, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 33 | [12.679651, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 34 | [12.681701, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 35 | [12.681784, "o", "\u001b]133;D;0\u0007"] 36 | [12.683389, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 37 | [12.693052, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 38 | [12.693128, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 39 | [15.714226, "o", "\u001b[?2004l\r\r\n"] 40 | -------------------------------------------------------------------------------- /docs/assets/terminal/lint-chart.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 44, "timestamp": 1722683799, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.111661, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 3 | [0.1121, "o", "\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 4 | [0.766899, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 5 | [0.868339, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 6 | [0.869968, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 7 | [0.870098, "o", "\u001b]133;D;0\u0007"] 8 | [0.874486, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 9 | [0.88634, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 10 | [0.886423, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 11 | [0.906595, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 12 | [2.572652, "o", "m"] 13 | [2.575687, "o", "\bm\u001b[90make\u001b[39m\b\b\b"] 14 | [2.706752, "o", "\bm\u001b[39ma"] 15 | [2.820511, "o", "\u001b[39mk"] 16 | [3.152259, "o", "\u001b[39me"] 17 | [3.540311, "o", " "] 18 | [3.543536, "o", "\u001b[90mcoverage\u001b[39m\u001b[8D"] 19 | [4.07692, "o", "\u001b[39ml\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \b\b\b\b\b\b\b"] 20 | [4.080107, "o", "\u001b[90mint-chart\u001b[39m\u001b[9D"] 21 | [4.27027, "o", "\u001b[39mi"] 22 | [4.418951, "o", "\u001b[39mn"] 23 | [5.584551, "o", "\u001b[39mt\u001b[39m-\u001b[39mc\u001b[39mh\u001b[39ma\u001b[39mr\u001b[39mt"] 24 | [6.155476, "o", "\u001b[?1l\u001b>\u001b[?2004l"] 25 | [6.155737, "o", "\r\r\n"] 26 | [6.164141, "o", "\u001b]2;make lint-chart\u0007\u001b]1;make\u0007"] 27 | [6.164204, "o", "\u001b]133;C;\r\u0007"] 28 | [6.181623, "o", "helm lint manifests/chart\r\n"] 29 | [6.236186, "o", "==> Linting manifests/chart\r\n\r\n1 chart(s) linted, 0 chart(s) failed\r\n"] 30 | [6.237166, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 31 | [6.333244, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 32 | [6.335064, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 33 | [6.335112, "o", "\u001b]133;D;0\u0007"] 34 | [6.336689, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 35 | [6.346392, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 36 | [6.346464, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 37 | [8.867849, "o", "\u001b[?2004l\r\r\n"] 38 | -------------------------------------------------------------------------------- /docs/assets/terminal/make-cleanup-mac.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 167, "height": 45, "timestamp": 1722610317, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [2.183254, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 3 | [2.445038, "o", "\u001b]2;patrykattc@Patryks-MacBook-Pro:~/projects/git/kubert-assistant-lite\u0007"] 4 | [2.445391, "o", "\u001b]1;..ssistant-lite\u0007"] 5 | [2.45147, "o", "\u001b]7;file://Patryks-MacBook-Pro.local/Users/patrykattc/projects/git/kubert-assistant-lite\u001b\\"] 6 | [2.453349, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[K"] 7 | [2.453533, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 8 | [2.58262, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] 9 | [4.066769, "o", "m"] 10 | [4.219875, "o", "\bma"] 11 | [4.376931, "o", "k"] 12 | [4.465005, "o", "e"] 13 | [4.647347, "o", " "] 14 | [4.963685, "o", "c"] 15 | [5.097384, "o", "l"] 16 | [5.525404, "o", "e"] 17 | [5.693303, "o", "a"] 18 | [5.815114, "o", "n"] 19 | [6.161226, "o", "u"] 20 | [6.315051, "o", "p"] 21 | [7.335266, "o", "\u001b[?1l\u001b>"] 22 | [7.3353, "o", "\u001b[?2004l\r\r\n"] 23 | [7.336075, "o", "\u001b]2;make cleanup\u0007\u001b]1;make\u0007"] 24 | [7.744802, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: Validating required tools...\u001b[0m\r\n"] 25 | [7.750981, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: kind is installed.\u001b[0m\r\n"] 26 | [7.756568, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: kubectl is installed.\u001b[0m\r\n"] 27 | [7.765572, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: helm is installed.\u001b[0m\r\n"] 28 | [7.771811, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: jq is installed.\u001b[0m\r\n"] 29 | [7.782165, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: All required tools are installed. You are ready to proceed!\u001b[0m\r\n"] 30 | [7.788239, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: Starting cleanup process...\u001b[0m\r\n"] 31 | [7.910504, "o", "\u001b[0;32m2024-08-02 10:52:05 [INFO]: Deleting kind cluster kubert-cluster...\u001b[0m\r\n"] 32 | [7.948696, "o", "Deleting cluster \"kubert-cluster\" ...\r\n"] 33 | [10.806227, "o", "Deleted nodes: [\"kubert-cluster-control-plane\"]\r\n"] 34 | [10.815412, "o", "\u001b[0;32m2024-08-02 10:52:08 [INFO]: Cleaning up hosts file entries...\u001b[0m\r\n"] 35 | [10.854347, "o", "\u001b[0;32m2024-08-02 10:52:08 [INFO]: Cleaning up /etc/hosts file...\u001b[0m\r\n"] 36 | [10.906736, "o", "Password:"] 37 | [14.489117, "o", "\r\n"] 38 | [14.785301, "o", "\u001b[0;32m2024-08-02 10:52:12 [INFO]: Removed 10.1.1.75 kubert-assistant.lan from /etc/hosts\u001b[0m\r\n"] 39 | [14.831711, "o", "\u001b[0;32m2024-08-02 10:52:12 [INFO]: Removed 10.1.1.75 kubert-agent.lan from /etc/hosts\u001b[0m\r\n"] 40 | [14.881216, "o", "\u001b[0;32m2024-08-02 10:52:12 [INFO]: Removed 10.1.1.75 kubert-plugin.lan from /etc/hosts\u001b[0m\r\n"] 41 | [14.932174, "o", "\u001b[0;32m2024-08-02 10:52:12 [INFO]: Removed 10.1.1.75 kubert-plugin-gateway.lan from /etc/hosts\u001b[0m\r\n"] 42 | [14.975068, "o", "grep: /proc/version: No such file or directory\r\n"] 43 | [15.068704, "o", "\u001b[0;32m2024-08-02 10:52:12 [INFO]: Cleanup process completed successfully.\u001b[0m\r\n"] 44 | [15.069713, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 45 | [15.340786, "o", "\u001b]2;patrykattc@Patryks-MacBook-Pro:~/projects/git/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 46 | [15.347489, "o", "\u001b]7;file://Patryks-MacBook-Pro.local/Users/patrykattc/projects/git/kubert-assistant-lite\u001b\\"] 47 | [15.34932, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] 48 | [15.349511, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 49 | [19.114894, "o", "\u001b[?2004l\r\r\n"] 50 | -------------------------------------------------------------------------------- /docs/assets/terminal/make-list.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 40, "timestamp": 1722625742, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.132128, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 3 | [0.132658, "o", "\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 4 | [0.787775, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 5 | [0.891362, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 6 | [0.893376, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 7 | [0.893454, "o", "\u001b]133;D;0\u0007"] 8 | [0.897797, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 9 | [0.910312, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 10 | [0.910444, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 11 | [0.933514, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 12 | [2.079989, "o", "m"] 13 | [2.083011, "o", "\bm\u001b[90make deploy\u001b[39m\u001b[10D"] 14 | [2.151302, "o", "\bm\u001b[39ma"] 15 | [2.265167, "o", "\u001b[39mk"] 16 | [2.353699, "o", "\u001b[39me"] 17 | [2.998081, "o", "\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \b\b\b\b\b\b\b"] 18 | [2.998573, "o", "\u001b[?1l\u001b>\u001b[?2004l\r\r\n"] 19 | [3.007774, "o", "\u001b]2;make\u0007\u001b]1;make\u0007"] 20 | [3.007932, "o", "\u001b]133;C;\r\u0007"] 21 | [3.03142, "o", "\u001b[36mbuild-kcov-image \u001b[0m Build kcov image with additional tools\r\n\u001b[36mtests \u001b[0m Run bats and tests\r\n"] 22 | [3.031534, "o", "\u001b[36mintegration-tests \u001b[0m Run bats integration tests\r\n\u001b[36mcoverage \u001b[0m Run kcov and tests\r\n\u001b[36mclean-build \u001b[0m Remove coverage dir and kcov image\r\n\u001b[36mdeploy \u001b[0m Deploy kind cluster with Kubert AI Assistant Lite\r\n\u001b[36mdeploy-kubert-assistant \u001b[0m Deploy Kubert Assistant components using Helm\r\n\u001b[36mcleanup-kubert-assistant \u001b[0m Uninstall deployed Kubert Assistant components with Helm\r\n\u001b[36mcleanup \u001b[0m Clean up kind cluster and hosts file\r\n"] 23 | [3.031599, "o", "\u001b[36mcheck-deps-dev \u001b[0m Check for required dependencies for development\r\n\u001b[36mcheck-deps-deploy \u001b[0m Check for required dependencies for deployment\r\n"] 24 | [3.03162, "o", "\u001b[36mlint-chart \u001b[0m Lint the Helm chart\r\n\u001b[36mtemplate-chart \u001b[0m Template the Helm chart\r\n"] 25 | [3.031723, "o", "\u001b[36mhelm-test \u001b[0m Run Helm tests\r\n"] 26 | [3.032165, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 27 | [3.14505, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 28 | [3.147056, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 29 | [3.147116, "o", "\u001b]133;D;0\u0007"] 30 | [3.148762, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 31 | [3.158886, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 32 | [3.158948, "o", "\u001b[?1h\u001b="] 33 | [3.15899, "o", "\u001b[?2004h"] 34 | [4.756026, "o", "\u001b[?2004l\r\r\n"] 35 | -------------------------------------------------------------------------------- /docs/assets/terminal/make-tests-integration.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 40, "timestamp": 1722626461, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.122815, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 3 | [0.773314, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 4 | [0.883508, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 5 | [0.885455, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 6 | [0.885543, "o", "\u001b]133;D;0\u0007"] 7 | [0.889833, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 8 | [0.902344, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 9 | [0.902506, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 10 | [0.926005, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 11 | [2.430321, "o", "m"] 12 | [2.433405, "o", "\bm\u001b[90make tests TEST_FILE=tests/unit/test_wait_functions.bats TEST_PATTERN=\"wait_for_nodes should succeed when all nodes are ready\"\u001b[39m\u001b[125D"] 13 | [2.561007, "o", "\bm\u001b[39ma"] 14 | [2.683143, "o", "\u001b[39mk"] 15 | [2.75052, "o", "\u001b[39me"] 16 | [3.043124, "o", "\u001b[39m "] 17 | [3.349697, "o", "\u001b[39mi\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[120D"] 18 | [3.352388, "o", "\u001b[90mntegration-tests\u001b[39m\u001b[16D"] 19 | [4.384632, "o", "\u001b[39mn\u001b[39mt\u001b[39me\u001b[39mg\u001b[39mr\u001b[39ma\u001b[39mt\u001b[39mi\u001b[39mo\u001b[39mn\u001b[39m-\u001b[39mt\u001b[39me\u001b[39ms\u001b[39mt\u001b[39ms"] 20 | [4.907772, "o", "\u001b[?1l\u001b>\u001b[?2004l"] 21 | [4.907838, "o", "\r\r\n"] 22 | [4.916574, "o", "\u001b]2;make integration-tests\u0007\u001b]1;make\u0007"] 23 | [4.916806, "o", "\u001b]133;C;\r\u0007"] 24 | [5.07708, "o", "1..3\r\n"] 25 | [5.171338, "o", "# Setting up integration test for create_kind_cluster...\r\n"] 26 | [5.171673, "o", "# Running create_kind_cluster function...\r\n"] 27 | [5.260888, "o", "# kind cluster creation step completed.\r\n"] 28 | [5.364014, "o", "# Checking if the kind cluster was created...\r\n"] 29 | [5.398548, "o", "# kind cluster verification step completed.\r\n"] 30 | [5.398617, "o", "# Checking if nodes are present...\r\n"] 31 | [5.480007, "o", "# Nodes verification completed.\r\n"] 32 | [5.5609, "o", "# Checking if the namespace is created...\r\n"] 33 | [5.638406, "o", "# Namespace verification completed.\r\n"] 34 | [5.642055, "o", "# Cleaning up by deleting the kind cluster...\r\n"] 35 | [7.366557, "o", "# Cleanup step completed.\r\n"] 36 | [7.366955, "o", "# Integration test for create_kind_cluster completed.\r\n"] 37 | [7.369337, "o", "ok 1 create_kind_cluster should create a kind cluster\r\n"] 38 | [7.49654, "o", "# Setting up integration test for deploy_application...\r\n"] 39 | [39.245576, "o", "kubectl coredns configmap output (before update): .:53 {\r\n"] 40 | [39.245616, "o", " errors\r\n health {\r\n lameduck 5s\r\n }\r\n"] 41 | [39.245821, "o", " ready\r\n kubernetes cluster.local in-addr.arpa ip6.arpa {\r\n pods insecure\r\n fallthrough in-addr.arpa ip6.arpa\r\n ttl 30\r\n }\r\n prometheus :9153\r\n forward . /etc/resolv.conf {\r\n"] 42 | [39.245848, "o", " max_concurrent 1000\r\n }\r\n cache 30\r\n loop\r\n"] 43 | [39.245949, "o", " reload\r\n loadbalance\r\n}\r\n"] 44 | [39.698379, "o", "kubectl coredns configmap output (after update): .:53 {\r\n hosts {\r\n"] 45 | [39.698491, "o", " 192.168.86.32 kubert-assistant.lan\r\n 192.168.86.32 kubert-agent.lan\r\n 192.168.86.32 kubert-plugin.lan\r\n 192.168.86.32 kubert-plugin-gateway.lan\r\n fallthrough\r\n"] 46 | [39.698503, "o", " }\r\n"] 47 | [39.698579, "o", " errors\r\n health {\r\n lameduck 5s\r\n"] 48 | [39.698668, "o", " }\r\n ready\r\n kubernetes cluster.local in-addr.arpa ip6.arpa {\r\n pods insecure\r\n"] 49 | [39.698727, "o", " fallthrough in-addr.arpa ip6.arpa\r\n ttl 30\r\n }\r\n"] 50 | [39.698774, "o", " prometheus :9153\r\n forward . /etc/resolv.conf {\r\n"] 51 | [39.698795, "o", " max_concurrent 1000\r\n"] 52 | [39.698845, "o", " }\r\n cache 30\r\n loop\r\n"] 53 | [39.698891, "o", " reload\r\n loadbalance\r\n"] 54 | [39.698942, "o", "}\r\n2024-08-02 15:21:41 [INFO]: CoreDNS ConfigMap updated successfully.\r\n"] 55 | [39.698964, "o", "2024-08-02 15:21:41 [INFO]: Restarting CoreDNS pods...\r\n"] 56 | [39.698997, "o", "2024-08-02 15:21:41 [INFO]: CoreDNS pods restarted successfully.\r\n"] 57 | [39.703481, "o", "\r\n"] 58 | [39.707662, "o", "\r\n"] 59 | [39.71179, "o", "\r\n"] 60 | [39.718914, "o", "# Cleaning up by deleting the kind cluster...\r\n"] 61 | [40.157862, "o", "# Cleanup step completed.\r\n"] 62 | [40.158143, "o", "# Integration test for deploy_application completed.\r\n"] 63 | [40.160701, "o", "ok 2 update_coredns_config should update CoreDNS ConfigMap with host IP and local domains\r\n"] 64 | [40.233209, "o", "# Setting up integration test for deploy_application...\r\n"] 65 | [71.609364, "o", "# Deploying the echo server application...\r\n"] 66 | [72.463263, "o", "# Echo server application deployment step completed.\r\n"] 67 | [72.463375, "o", "# Checking if the namespace is created...\r\n"] 68 | [72.539123, "o", "# Namespace verification completed.\r\n"] 69 | [72.539249, "o", "# Checking if echo server pod is running in the namespace...\r\n"] 70 | [72.611156, "o", "# Echo server pod verification completed.\r\n"] 71 | [72.611286, "o", "# Checking if echo server service is running in the namespace...\r\n"] 72 | [72.684217, "o", "# Echo server service verification completed.\r\n"] 73 | [72.684375, "o", "# Cleaning up the echo server deployment...\r\n"] 74 | [72.763028, "o", "# Echo server deployment cleanup step completed.\r\n"] 75 | [72.767007, "o", "# Cleaning up by deleting the kind cluster...\r\n"] 76 | [73.246812, "o", "# Cleanup step completed.\r\n"] 77 | [73.247048, "o", "# Integration test for deploy_application completed.\r\n"] 78 | [73.252189, "o", "ok 3 deploy_application should deploy the echo server\r\n"] 79 | [73.275199, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 80 | [73.398282, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 81 | [73.400344, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 82 | [73.400403, "o", "\u001b]133;D;0\u0007"] 83 | [73.402013, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 84 | [73.412119, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 85 | [73.4122, "o", "\u001b[?1h\u001b="] 86 | [73.412238, "o", "\u001b[?2004h"] 87 | [76.503649, "o", "\u001b[?2004l\r\r\n"] 88 | -------------------------------------------------------------------------------- /docs/assets/terminal/make-tests-one-file-one-test.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 40, "timestamp": 1722625872, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.115587, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 3 | [0.116195, "o", "\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 4 | [0.771272, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 5 | [0.873654, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 6 | [0.875351, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 7 | [0.875421, "o", "\u001b]133;D;0\u0007"] 8 | [0.879631, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 9 | [0.891485, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 10 | [0.891576, "o", "\u001b[?1h\u001b="] 11 | [0.891586, "o", "\u001b[?2004h"] 12 | [0.91317, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 13 | [1.572331, "o", "m"] 14 | [1.575125, "o", "\bm\u001b[90make tests TEST_FILE=tests/unit/test_wait_functions.bats\u001b[39m\u001b[55D"] 15 | [1.616297, "o", "\bm\u001b[39ma"] 16 | [1.737921, "o", "\u001b[39mk"] 17 | [1.828787, "o", "\u001b[39me"] 18 | [3.30308, "o", "\u001b[39m \u001b[39mt\u001b[39me\u001b[39ms\u001b[39mt\u001b[39ms\u001b[39m \u001b[39mT\u001b[39mE\u001b[39mS\u001b[39mT\u001b[39m_\u001b[39mF\u001b[39mI\u001b[39mL\u001b[39mE\u001b[39m=\u001b[39mt\u001b[39me\u001b[39ms\u001b[39mt\u001b[39ms\u001b[39m/\u001b[39mu\u001b[39mn\u001b[39mi\u001b[39mt\u001b[39m/\u001b[39mt\u001b[39me\u001b[39ms\u001b[39mt\u001b[39m_\u001b[39mw\u001b[39ma\u001b[39mi\u001b[39mt\u001b[39m_\u001b[39mf\u001b[39mu\u001b[39mn\u001b[39mc\u001b[39mt\u001b[39mi\u001b[39mo\u001b[39mn\u001b[39ms\u001b[39m.\u001b[39mb\u001b[39ma\u001b[39mt\u001b[39ms"] 19 | [3.886564, "o", " "] 20 | [3.889745, "o", "\u001b[90mTEST_PATTERN=\"wait_for_nodes should succeed when all nodes are ready\"\u001b[39m\u001b[69D"] 21 | [5.224566, "o", "\u001b[39mT\u001b[39mE\u001b[39mS\u001b[39mT\u001b[39m_\u001b[39mP\u001b[39mA\u001b[39mT\u001b[39mT\u001b[39mE\u001b[39mR\u001b[39mN\u001b[39m=\u001b[39m\"\u001b[39mw\u001b[39ma\u001b[39mi\u001b[39mt\u001b[39m_\u001b[39mf\u001b[39mo\u001b[39mr\u001b[39m_\u001b[39mn\u001b[39mo\u001b[39md\u001b[39me\u001b[39ms\u001b[39m \u001b[39ms\u001b[39mh\u001b[39mo\u001b[39mu\u001b[39ml\u001b[39md\u001b[39m \u001b[39ms\u001b[39mu\u001b[39mc\u001b[39mc\u001b[39me\u001b[39me\u001b[39md\u001b[39m \u001b[39mw\u001b[39mh\u001b[39me\u001b[39mn\u001b[39m \u001b[39ma\u001b[39ml\u001b[39ml\u001b[39m \u001b[39mn\u001b[39mo\u001b[39md\u001b[39me\u001b[39ms\u001b[39m \u001b[39ma\u001b[39mr\u001b[39me\u001b[39m \u001b[39mr\u001b[39me\u001b[39ma\u001b[39md\u001b[39my\u001b[39m\""] 22 | [6.090281, "o", "\u001b[?1l\u001b>"] 23 | [6.090704, "o", "\u001b[?2004l\r\r\n"] 24 | [6.100093, "o", "\u001b]2;make tests TEST_FILE=tests/unit/test_wait_functions.bats \u0007\u001b]1;make\u0007"] 25 | [6.100253, "o", "\u001b]133;C;\r\u0007"] 26 | [6.349136, "o", "\u001b[34;1mtest_wait_functions.bats\r\n\u001b[0m\u001b[1G wait_for_nodes should succeed when all nodes are ready\u001b[K\u001b[269G1/1\u001b[2G"] 27 | [6.571699, "o", "\u001b[1G ✓ wait_for_nodes should succeed when all nodes are ready\u001b[K\r\n\u001b[0m\u001b[32;1m\r\n1 test, 0 failures\r\n\u001b[0m\r\n"] 28 | [6.575666, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 29 | [6.680014, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 30 | [6.682077, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 31 | [6.682141, "o", "\u001b]133;D;0\u0007"] 32 | [6.683639, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 33 | [6.693415, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 34 | [6.693489, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 35 | [8.029421, "o", "\u001b[?2004l\r\r\n"] 36 | -------------------------------------------------------------------------------- /docs/assets/terminal/make-tests-one-file.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 40, "timestamp": 1722625846, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.116336, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 3 | [0.763271, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 4 | [0.868063, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 5 | [0.870067, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 6 | [0.87018, "o", "\u001b]133;D;0\u0007"] 7 | [0.874247, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 8 | [0.887304, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 9 | [0.887424, "o", "\u001b[?1h\u001b="] 10 | [0.887441, "o", "\u001b[?2004h"] 11 | [0.911066, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 12 | [1.665531, "o", "asciinema rec make-tests-one-file.cast"] 13 | [1.938286, "o", "\u001b[38Drm\u001b[11P\u001b[25C \u001b[11D"] 14 | [2.817133, "o", "\u001b[27Dmake tests TEST_FILE=tests/unit/test_wait_functions.bats"] 15 | [5.324806, "o", "\u001b[?1l\u001b>\u001b[?2004l\r\r\n"] 16 | [5.332731, "o", "\u001b]2;make tests TEST_FILE=tests/unit/test_wait_functions.bats\u0007\u001b]1;make\u0007"] 17 | [5.332773, "o", "\u001b]133;C;\r\u0007"] 18 | [5.577574, "o", "\u001b[34;1mtest_wait_functions.bats\r\n\u001b[0m\u001b[1G wait_for_nodes should succeed when all nodes are ready\u001b[K\u001b[269G1/9\u001b[2G"] 19 | [5.810491, "o", "\u001b[1G ✓ wait_for_nodes should succeed when all nodes are ready\u001b[K\r\n\u001b[0m\u001b[1G wait_for_nodes should fail when not all nodes are ready within timeout\u001b[K\u001b[269G2/9\u001b[2G"] 20 | [6.585894, "o", "\u001b[1G ✓ wait_for_nodes should fail when not all nodes are ready within timeout\u001b[K\r\n\u001b[0m\u001b[1G wait_for_nginx_ingress should succeed when all pods are ready\u001b[K\u001b[269G3/9\u001b[2G"] 21 | [6.848105, "o", "\u001b[1G ✓ wait_for_nginx_ingress should succeed when all pods are ready\u001b[K\r\n\u001b[0m\u001b[1G wait_for_nginx_ingress should fail when not all pods are ready within timeout\u001b[K\u001b[269G4/9\u001b[2G"] 22 | [7.62692, "o", "\u001b[1G ✓ wait_for_nginx_ingress should fail when not all pods are ready within timeout\u001b[K\r\n\u001b[0m\u001b[1G wait_for_ingress_ready should succeed when all ingresses have an address\u001b[K\u001b[269G5/9\u001b[2G"] 23 | [7.876436, "o", "\u001b[1G ✓ wait_for_ingress_ready should succeed when all ingresses have an address\u001b[K\r\n\u001b[0m\u001b[1G wait_for_ingress_ready should fail when not all ingresses have an address within timeout\u001b[K\u001b[269G6/9\u001b[2G"] 24 | [8.649741, "o", "\u001b[1G ✓ wait_for_ingress_ready should fail when not all ingresses have an address within timeout\u001b[K\r\n\u001b[0m\u001b[1G wait_for_service should succeed when the service is available immediately\u001b[K\u001b[269G7/9\u001b[2G"] 25 | [8.906901, "o", "\u001b[1G ✓ wait_for_service should succeed when the service is available immediately\u001b[K\r\n\u001b[0m\u001b[1G wait_for_service should fail when the service is not available within timeout\u001b[K\u001b[269G8/9\u001b[2G"] 26 | [11.188105, "o", "\u001b[1G ✓ wait_for_service should fail when the service is not available within timeout\u001b[K\r\n\u001b[0m\u001b[1G wait_for_service should succeed when the service becomes available after a delay\u001b[K\u001b[269G9/9\u001b[2G"] 27 | [12.467669, "o", "\u001b[1G ✓ wait_for_service should succeed when the service becomes available after a delay\u001b[K\r\n\u001b[0m\u001b[32;1m\r\n9 tests, 0 failures\r\n\u001b[0m\r\n"] 28 | [12.472685, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 29 | [12.576918, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 30 | [12.578742, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 31 | [12.57882, "o", "\u001b]133;D;0\u0007"] 32 | [12.580295, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 33 | [12.590697, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 34 | [12.590826, "o", "\u001b[?1h\u001b=\u001b[?2004h"] 35 | [14.092824, "o", "\u001b[?2004l\r\r\n"] 36 | -------------------------------------------------------------------------------- /docs/assets/terminal/template-chart.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 272, "height": 44, "timestamp": 1722683851, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.112367, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1337;ShellIntegrationVersion=14;shell=zsh\u0007"] 3 | [0.752396, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 4 | [0.848571, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 5 | [0.850314, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 6 | [0.850399, "o", "\u001b]133;D;0\u0007"] 7 | [0.854492, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 8 | [0.867035, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b]133;B\u0007\u001b[K"] 9 | [0.867121, "o", "\u001b[?1h\u001b="] 10 | [0.867131, "o", "\u001b[?2004h"] 11 | [0.886974, "o", "\r\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 12 | [2.551571, "o", "m"] 13 | [2.553988, "o", "\bm\u001b[90make lint-chart\u001b[39m\u001b[14D"] 14 | [2.660515, "o", "\bm\u001b[39ma"] 15 | [2.792285, "o", "\u001b[39mk"] 16 | [2.913289, "o", "\u001b[39me"] 17 | [3.098727, "o", "\u001b[39m "] 18 | [3.326238, "o", "\u001b[39mt\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[9D"] 19 | [3.328903, "o", "\u001b[90mests TEST_FILE=tests/unit/test_wait_functions.bats TEST_PATTERN=\"wait_for_nodes should succeed when all nodes are ready\"\u001b[39m\u001b[120D"] 20 | [3.482548, "o", "\u001b[39me"] 21 | [4.437992, "o", "\u001b[39mm\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[118D"] 22 | [4.441328, "o", "\u001b[90mplate-chart\u001b[39m\u001b[11D"] 23 | [5.584878, "o", "\u001b[39mp\u001b[39ml\u001b[39ma\u001b[39mt\u001b[39me\u001b[39m-\u001b[39mc\u001b[39mh\u001b[39ma\u001b[39mr\u001b[39mt"] 24 | [6.259932, "o", "\u001b[?1l\u001b>"] 25 | [6.260115, "o", "\u001b[?2004l\r\r\n"] 26 | [6.268474, "o", "\u001b]2;make template-chart\u0007\u001b]1;make\u0007"] 27 | [6.268528, "o", "\u001b]133;C;\r\u0007"] 28 | [6.284922, "o", "helm template --debug manifests/chart\r\n"] 29 | [6.323906, "o", "install.go:214: [debug] Original chart version: \"\"\r\n"] 30 | [6.323928, "o", "install.go:231: [debug] CHART PATH: /Users/patrykattc/work/git/GitHub/kubert-assistant-lite/manifests/chart\r\n\r\n"] 31 | [6.331242, "o", "---\r\n# Source: kubert-assistant-workload/templates/networkpolicy.yaml\r\nkind: NetworkPolicy\r\napiVersion: networking.k8s.io/v1\r\nmetadata:\r\n name: release-name-kubert-assistant-workload\r\n namespace: \"default\"\r\n labels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/managed-by: Helm\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n app.kubernetes.io/version: 1.0.0\r\n helm.sh/chart: kubert-assistant-workload-1.0.0\r\nspec:\r\n podSelector:\r\n matchLabels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/name: kubert-assistant-workload \r\n policyTypes:\r\n - Ingress\r\n - Egress\r\n egress:\r\n # Allow dns resolution\r\n - ports:\r\n - port: 53\r\n protocol: UDP\r\n - port: 53\r\n protocol: TCP\r\n # Allow outbound connections to other cluster pods\r\n - ports:\r\n - port: \r\n - port: 8080\r\n to:\r\n - podSelector:\r\n matchLabels:\r\n app.kubernetes.io/instance: release-name\r\n "] 32 | [6.331342, "o", " app.kubernetes.io/name: kubert-assistant-workload\r\n ingress:\r\n - ports:\r\n - port: \r\n - port: 8080\r\n---\r\n# Source: kubert-assistant-workload/templates/serviceaccount.yaml\r\napiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n name: release-name-kubert-assistant-workload\r\n namespace: \"default\"\r\n labels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/managed-by: Helm\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n app.kubernetes.io/version: 1.0.0\r\n helm.sh/chart: kubert-assistant-workload-1.0.0\r\nautomountServiceAccountToken: true\r\n---\r\n# Source: kubert-assistant-workload/templates/service.yaml\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n name: release-name-kubert-assistant-workload\r\n namespace: \"default\"\r\n labels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/managed-by: Helm\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n app.kubernetes.io/version: 1.0.0\r\n helm.sh/chart: kubert-assistant-workload-1.0.0\r\nspec:\r\n"] 33 | [6.331404, "o", " type: ClusterIP\r\n sessionAffinity: None\r\n ports:\r\n - name: http\r\n port: 8080\r\n protocol: TCP\r\n targetPort: http\r\n nodePort: null\r\n selector:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n---\r\n# Source: kubert-assistant-workload/templates/deployment.yaml\r\napiVersion: apps/v1\r\nkind: Deployment\r\nmetadata:\r\n name: release-name-kubert-assistant-workload\r\n namespace: \"default\"\r\n labels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/managed-by: Helm\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n app.kubernetes.io/version: 1.0.0\r\n helm.sh/chart: kubert-assistant-workload-1.0.0\r\n annotations:\r\nspec:\r\n strategy:\r\n rollingUpdate: {}\r\n type: RollingUpdate\r\n replicas: 1\r\n selector:\r\n matchLabels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/name: kubert-assistant-workload \r\n template:\r\n metadata:\r\n labels:\r\n app.kubernetes.io/instance: rel"] 34 | [6.331474, "o", "ease-name\r\n app.kubernetes.io/managed-by: Helm\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n app.kubernetes.io/version: 1.0.0\r\n helm.sh/chart: kubert-assistant-workload-1.0.0\r\n annotations: \r\n spec:\r\n automountServiceAccountToken: false\r\n serviceAccountName: release-name-kubert-assistant-workload\r\n affinity:\r\n podAffinity:\r\n \r\n podAntiAffinity:\r\n preferredDuringSchedulingIgnoredDuringExecution:\r\n - podAffinityTerm:\r\n labelSelector:\r\n matchLabels:\r\n app.kubernetes.io/instance: release-name\r\n app.kubernetes.io/name: kubert-assistant-workload\r\n topologyKey: kubernetes.io/hostname\r\n weight: 1\r\n nodeAffinity:\r\n \r\n containers:\r\n - name: \"workload\"\r\n image: replace:replace\r\n imagePullPolicy: \"IfNotPresent\"\r\n ports:\r\n - name: http\r\n conta"] 35 | [6.331487, "o", "inerPort: \r\n env:\r\n"] 36 | [6.332524, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 37 | [6.432062, "o", "\u001b]2;patrykattc@patryksacstudio:~/work/git/GitHub/kubert-assistant-lite\u0007\u001b]1;..ssistant-lite\u0007"] 38 | [6.433991, "o", "\u001b]7;file://patryksacstudio.lan/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u001b\\"] 39 | [6.434057, "o", "\u001b]133;D;0\u0007"] 40 | [6.435676, "o", "\u001b]1337;RemoteHost=patrykattc@patryksacstudio.lan\u0007\u001b]1337;CurrentDir=/Users/patrykattc/work/git/GitHub/kubert-assistant-lite\u0007"] 41 | [6.445582, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b]133;A\u0007\u001b[01;32m➜ \u001b[36mkubert-assistant-lite\u001b[00m \u001b[01;34mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[00m \u001b]133;B\u0007\u001b[K"] 42 | [6.445634, "o", "\u001b[?1h\u001b="] 43 | [6.445657, "o", "\u001b[?2004h"] 44 | [9.362302, "o", "\u001b[?2004l\r\r\n"] 45 | -------------------------------------------------------------------------------- /docs/assets/video/Kubert_AI_Assistant_Lite_Demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/video/Kubert_AI_Assistant_Lite_Demo.mp4 -------------------------------------------------------------------------------- /docs/assets/video/kubert-agent-hello-world.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/video/kubert-agent-hello-world.mp4 -------------------------------------------------------------------------------- /docs/assets/video/memory-hog.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/video/memory-hog.mp4 -------------------------------------------------------------------------------- /docs/assets/video/ollama-installation-kubert-ai-config.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/video/ollama-installation-kubert-ai-config.mp4 -------------------------------------------------------------------------------- /docs/assets/video/open-browser.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/docs/assets/video/open-browser.mov -------------------------------------------------------------------------------- /docs/azure.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Azure Windows VM 4 | description: "Learn how to deploy a Windows 10 Pro VM on Microsoft Azure with our complete guide. Set up a scalable, secure environment for development and testing. Includes Kubert AI Assistant Lite setup." 5 | parent: Installation 6 | nav_order: 2 7 | nav_fold: false 8 | k_seo: 9 | title: "Azure VM Windows 10 Pro Deployment: A Complete Guide" 10 | --- 11 | 12 | # Azure VM Windows 10 Pro Deployment: A Complete Guide 13 | 14 | Deploying a Windows Virtual Machine (VM) on Microsoft Azure allows you to create a scalable and flexible environment for development, testing, or any other business needs. Azure provides a cloud-based platform where you can easily deploy and manage Windows VMs, taking advantage of the power and security of Microsoft's infrastructure. This document will guide you through the process of deploying a Windows 10 Pro VM on Azure, from the initial setup to accessing the VM remotely. 15 | 16 | **Note:** While you can select other versions of Windows, including Windows 11 Pro, this guide focuses on Windows 10 Pro to support the deployment of Kubert AI Assistant Lite for developers, who mostly use Windows 10 Pro on their personal development PCs. 17 | 18 | ## Prerequisites 19 | 20 | Before you begin, ensure you have the following: 21 | 22 | - **Azure Subscription**: An active Azure subscription is required. If you don’t have one, you can sign up for a free account at the [Azure portal](https://azure.microsoft.com/en-ca/){:target="_blank"}. 23 | 24 | ## Step 1: Sign in to the Azure Portal 25 | 26 | 1. Open your web browser and go to the Azure Portal. 27 | 2. Sign in with your Microsoft account. 28 | 29 | [![Azure home](/kubert-assistant-lite/assets/images/azure-vm/1_azure-home.png)](/kubert-assistant-lite/assets/images/azure-vm/1_azure-home.png) 30 | 31 | ## Step 2: Create a Virtual Machine 32 | 33 | 1. Navigate to the "Virtual Machine" section in the Azure Portal. 34 | [![Azure VM Home](/kubert-assistant-lite/assets/images/azure-vm/2_azure-vm-home.png)](/kubert-assistant-lite/assets/images/azure-vm/2_azure-vm-home.png) 35 | 2. Click "Create" and select "Azure virtual machine". 36 | [![Create VM](/kubert-assistant-lite/assets/images/azure-vm/3_create-vm.png)](/kubert-assistant-lite/assets/images/azure-vm/3_create-vm.png) 37 | 38 | ## Step 3: Configure the VM 39 | 40 | 1. Start by creating a new, click "Create a resource". 41 | [![Create Resource](/kubert-assistant-lite/assets/images/azure-vm/4_create-resource-group.png)](/kubert-assistant-lite/assets/images/azure-vm/4_create-resource-group.png) 42 | 43 | `Note`-> **Benefits of Using a Resource Group for Cleanup**: 44 | - **Centralized Management**: A resource group allows you to manage all related resources as a single unit. This means that all components related to your VM (e.g., virtual network, public IP address, network interface, storage accounts) are organized under one resource group. 45 | - **Simplified Deletion**: If you no longer need the VM and its associated resources, you can delete the entire resource group in one action. This ensures that no orphaned resources are left behind, which can otherwise incur unnecessary costs. 46 | - **Cost Management**: By grouping related resources together, you can more easily track the costs associated with a specific project or environment. When you're done with the project, deleting the resource group removes all associated costs. 47 | - **Isolation**: Resource groups help isolate environments, especially in cases where you might have multiple projects or environments (e.g., development, testing, production). This reduces the risk of accidentally deleting or modifying resources that are unrelated to your current task. 48 | 2. Enter the host name and choose the region where you want to deploy the VM. 49 | [![Host Name](/kubert-assistant-lite/assets/images/azure-vm/5_define_host_name.png)](/kubert-assistant-lite/assets/images/azure-vm/5_define_host_name.png) 50 | 3. Select image and security type. 51 | [![Image Name](/kubert-assistant-lite/assets/images/azure-vm/6_security_and_image.png)](/kubert-assistant-lite/assets/images/azure-vm/6_security_and_image.png) 52 | 53 | `Note`-> For the security type, select "Standard" to support nested virtualization, more on that in the size section. We selected the Windows 10 Pro image and chose "Run with Azure Spot discount." There is no expectation for this VM, which is used for development and testing, to run for a long time uninterrupted. Therefore, using the spot discount can significantly reduce costs. 54 | 4. Select the size. 55 | [![Size](/kubert-assistant-lite/assets/images/azure-vm/7_size_cpu_ram.png)](/kubert-assistant-lite/assets/images/azure-vm/7_size_cpu_ram.png) 56 | 57 | `Note`-> We plan to run Windows Subsystem for Linux (WSL) within the VM, it's crucial to select a VM size that supports nested virtualization. Nested virtualization allows you to run a virtual machine inside another virtual machine, which is necessary for WSL. 58 | 59 | [What is Nested Virtualization](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/nested-virtualization){:target="_blank"} 60 | 61 | Not all Azure VM sizes support nested virtualization. Typically, VMs in the Dv3, Ev3, and newer series (like Dv4 or Ev4) support this feature. Ensure you select a VM size from a CPU family that offers nested virtualization support. 62 | List of CPU families that support nested virtualization can be found [here](https://learn.microsoft.com/en-us/azure/virtual-machines/acu){:target="_blank"}. 63 | 64 | Information about the CPU family used in this deployment can be found [here](https://learn.microsoft.com/en-us/azure/virtual-machines/ev3-esv3-series){:target="_blank"}. 65 | 5. Account and inbound ports. 66 | [![Size](/kubert-assistant-lite/assets/images/azure-vm/8_account_port.png)](/kubert-assistant-lite/assets/images/azure-vm/8_account_port.png) 67 | 68 | `Note`-> Enter the username and password that will be used to log into Windows 10 pro. Disable the "Public inbound ports". The specific inbound ports will be configured once the VM has been deployed. Accept the licensing and click "Next: Disks >" to continue the configuration. 69 | 6. Disks 70 | [![Size](/kubert-assistant-lite/assets/images/azure-vm/9_disks.png)](/kubert-assistant-lite/assets/images/azure-vm/9_disks.png) 71 | 72 | `Note`-> No updates are required in this section, click on the "Next: Networking >" to continue the configuration. 73 | 7. Networking 74 | [![Size](/kubert-assistant-lite/assets/images/azure-vm/10_delete_public_ip.png)](/kubert-assistant-lite/assets/images/azure-vm/10_delete_public_ip.png) 75 | 76 | `Note`-> Check of the "Delete public IP and NIC when VM is deleted" to help with resource cleanup once the VM has been deleted. Click on the "Next: Management ->" to continue the configuration. 77 | 8. Auto-shutdown 78 | [![Auto Shutdown](/kubert-assistant-lite/assets/images/azure-vm/11_auto-shutdown.png)](/kubert-assistant-lite/assets/images/azure-vm/11_auto-shutdown.png) 79 | 80 | `Note`-> Don't leave you VM running, enable the auto-shutdown and the time and timezone, to shutdown the VM automatically. We will stop the configuration here, click on "Review + create". For advance use case continue the configuration to the monitoring section. 81 | 9. Trigger deployment. 82 | [![Start VM creation](/kubert-assistant-lite/assets/images/azure-vm/12_create-vm.png)](/kubert-assistant-lite/assets/images/azure-vm/12_create-vm.png.png) 83 | 84 | `Note`-> Review the configuration and click "Create" to start the deployment. 85 | 10. Deploying 86 | [![Deploying](/kubert-assistant-lite/assets/images/azure-vm/13_deploying.png)](/kubert-assistant-lite/assets/images/azure-vm/13_deploying.png) 87 | 11. Deployment completed, go to the resource. 88 | [![Deployed](/kubert-assistant-lite/assets/images/azure-vm/14_done-deployment.png)](/kubert-assistant-lite/assets/images/azure-vm/14_done-deployment.png) 89 | 12. Deployed host 90 | [![Host](/kubert-assistant-lite/assets/images/azure-vm/15_host.png)](/kubert-assistant-lite/assets/images/azure-vm/15_host.png) 91 | 13. Set RDP port 92 | [![Set RDP Port](/kubert-assistant-lite/assets/images/azure-vm/16_set-rdp-port.png)](/kubert-assistant-lite/assets/images/azure-vm/16_set-rdp-port.png) 93 | 94 | `Note`-> Go to the "Operations" section, then "Run command", select the "SetRDPPort" 95 | 14. Enter the RDP port and execute the script. 96 | [![Enter RDP Port](/kubert-assistant-lite/assets/images/azure-vm/17_enter-port.png)](/kubert-assistant-lite/assets/images/azure-vm/17_enter-port.png) 97 | 15. RDP port updated 98 | [![RDP Port Set](/kubert-assistant-lite/assets/images/azure-vm/18_port-set.png)](/kubert-assistant-lite/assets/images/azure-vm/18_port-set.png) 99 | 16. Set inbound networking rule 100 | [![Inbound Rule](/kubert-assistant-lite/assets/images/azure-vm/19_set-inbound-rule.png)](/kubert-assistant-lite/assets/images/azure-vm/19_set-inbound-rule.png) 101 | 102 | `Note`-> Go to the "Networking" section, then "Networking settings", click "Create port rule" and select "inbound port rule" 103 | 17. Configure "My IP address" security rule 104 | [![My IP Rule](/kubert-assistant-lite/assets/images/azure-vm/20_my-ip-rule.png)](/kubert-assistant-lite/assets/images/azure-vm/20_my-ip-rule.png) 105 | 106 | `Note`-> For the source, select "My IP address"; it will auto-populate the Source IP with your IP address. For the "Destination port ranges," add the RDP port used in the previous step. The protocol should be TCP, and provide a description for clarity. 107 | 18. Download RDP file 108 | [![Download RDP File](/kubert-assistant-lite/assets/images/azure-vm/22_download-rdp-file.png)](/kubert-assistant-lite/assets/images/azure-vm/22_download-rdp-file.png) 109 | 110 | ## Step 4: Remote Desktop 111 | 112 | 1. Edit the downloaded RDP file. 113 | [![RDP config](/kubert-assistant-lite/assets/images/azure-vm/23_remote-desktop.png)](/kubert-assistant-lite/assets/images/azure-vm/23_remote-desktop.png) 114 | 115 | 2. Update the port. 116 | [![Updated RDP config](/kubert-assistant-lite/assets/images/azure-vm/24_updated-port.png)](/kubert-assistant-lite/assets/images/azure-vm/24_updated-port.png) 117 | 118 | 3. Start remote desktop and log into Windows. 119 | [![windows](/kubert-assistant-lite/assets/images/azure-vm/25_logged-in.png)](/kubert-assistant-lite/assets/images/azure-vm/25_logged-in.png) 120 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Installation 4 | description: "Step-by-step instructions to install and set up Kubert AI Assistant Lite on your local machine. Ensure Docker, kind, Helm, Kubectl, and other essential tools are ready for a smooth installation." 5 | nav_nabled: true 6 | has_children: true 7 | has_toc: false 8 | nav_fold: false 9 | k_seo: 10 | title: "Kubert AI Assistant Lite Installation Guide" 11 | --- 12 | 13 | # Kubert Lite Installation Guide 14 | 15 | This guide provides step-by-step instructions to install and set up Kubert AI Assistant Lite on your local machine. 16 | 17 | ## Prerequisites 18 | 19 | Before proceeding with the installation, ensure you have the following software installed: 20 | 21 | - [Docker](https://docs.docker.com/get-docker/){:target="_blank"} 22 | - [kind](https://kind.sigs.k8s.io/){:target="_blank"} 23 | - [Helm](https://helm.sh/docs/intro/install/){:target="_blank"} 24 | - [Kubectl](https://kubernetes.io/docs/tasks/tools/){:target="_blank"} 25 | - [jq](https://stedolan.github.io/jq/){:target="_blank"} 26 | - [Make](https://www.gnu.org/software/make/){:target="_blank"} 27 | - [OpenAI API Key](https://platform.openai.com/docs/api-reference/authentication){:target="_blank"} or [Anthropic API Key](https://console.anthropic.com/docs/authentication){:target="_blank"} (for AI capabilities) 28 | 29 | Ensure that these tools are properly installed and accessible from your command line. 30 | 31 | ## Setting up API Keys 32 | 33 | To enable the AI capabilities of Kubert AI Assistant Lite, you need to set up an API key from either OpenAI or Anthropic. Follow these steps to obtain and configure your API key: 34 | 35 | ### OpenAI API Key 36 | 37 | 1. Sign up for an account at [OpenAI](https://platform.openai.com/signup/){:target="_blank"} if you don't have one already. 38 | 2. Navigate to the [API Keys](https://platform.openai.com/account/api-keys){:target="_blank"} section in your OpenAI account dashboard. 39 | 3. Click on the "Create new secret key" button to generate a new API key. 40 | 4. Copy the generated API key and store it securely. 41 | 42 | ### Anthropic API Key 43 | 44 | 1. Sign up for an account at [Anthropic](https://console.anthropic.com/login){:target="_blank"} if you don't have one already. 45 | 2. Navigate to the [API Keys](https://console.anthropic.com/settings/keys){:target="_blank"} section in your Anthropic account dashboard. 46 | 3. Click on the "Create Key" button to generate a new API key. 47 | 4. Copy the generated API key and store it securely. 48 | 49 | ### Groq API Key 50 | 51 | 1. Sign up for an account at [groqcloud](https://console.groq.com/login){:target="_blank"} if you don't have one already. 52 | 2. Navigate to the [API Keys](https://console.groq.com/keys){:target="_blank"} section in your groqcloud account dashboard. 53 | 3. Click on teh "Create Key" button to generate a new API key. 54 | 4. Copy the generated API key and store it securely. 55 | 56 | ### Google AI API key 57 | 58 | 1. Sign up for an account at [AI Studio](https://ai.google.dev/aistudio){:target="_blank"} if you don't have one already. 59 | 2. Click on teh "Get API Key" to navigate to the API keys section. 60 | 3. Click on teh "Create Key" button to generate a new API key. 61 | 4. Copy the generated API key and store it securely. 62 | 63 | Once you have obtained your API key, you will need to provide it during the installation process. 64 | 65 | ## Installation Steps 66 | 67 | Follow these steps to install and set up Kubert AI Assistant Lite: 68 | 69 | 1. **Clone the repository** 70 | 71 | Open a terminal and run: 72 | 73 | ```bash 74 | git clone https://github.com/TranslucentComputing/kubert-assistant-lite.git 75 | cd kubert-assistant-lite 76 | ``` 77 | 78 | 2. **(Optional) Initialize Git submodules for testing** 79 | 80 | If you plan to run tests, initialize the BATS submodules: 81 | 82 | ```bash 83 | git submodule update --init --recursive 84 | ``` 85 | 86 | 3. **Check deployment dependencies.** 87 | 88 | ```bash 89 | make check-deps-deploy 90 | ``` 91 | 92 | 4. **Deploy the kind Cluster and Application** 93 | 94 | Use the Makefile to deploy: 95 | 96 | ```bash 97 | make deploy 98 | ``` 99 | 100 | This command will set up the kind cluster and deploy the application using Helm. During the deployment `OPENAI_API_KEY` will be requested as well as the system password to update `/etc/hosts` file with the local domains. For Windows users the user admin password is required to update `c:\Windows\System32\Drivers\etc\hosts`. 101 | 102 | 5. **Open browser to [http://kubert-assistant.lan/](http://kubert-assistant.lan/){:target="_blank"}** 103 | 104 |
105 | 109 |
110 | 111 | ## Cleaning Up 112 | 113 | To clean up and delete the kind cluster and the Kubert AI Assistant Lite components, run the following command: 114 | 115 | ```bash 116 | make cleanup 117 | ``` 118 | 119 | This command will remove the kind cluster and all the associated resources, bringing your environment back to its initial state. 120 | 121 | ## Terminal Deployment 122 | 123 | ### Make Deploy 124 | 125 | #### Mac Version 126 | 127 | Example running `make deploy` in iTerminal on a Mac. 128 | 129 |
130 | 135 | 136 | ### Make Cleanup 137 | 138 | #### Mac Version 139 | 140 | Example running `make cleanup` in iTerminal on a Mac. 141 | 142 |
143 | 148 | -------------------------------------------------------------------------------- /docs/ollama.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Ollama 4 | description: "Complete guide to Ollama installation with step-by-step instructions for macOS and Windows. Install Ollama on your local system easily today!" 5 | parent: Installation 6 | nav_order: 1 7 | nav_fold: false 8 | k_seo: 9 | title: "Ollama Installation for macOS, Linux, and Windows" 10 | --- 11 | 12 | # Ollama Installation for macOS, Linux, and Windows 13 | 14 | Full Ollama installation instruction can be found at [Ollama](https://ollama.com){:target="_blank"}. 15 | Bellow you have links to the macOS and Windows installation binaries, download and install. 16 | 17 | ### Installation macOS 18 | 19 | [Download](https://ollama.com/download/Ollama-darwin.zip){:target="_blank"} 20 | 21 | ### Installation Windows 22 | 23 | [Download](https://ollama.com/download/OllamaSetup.exe){:target="_blank"} 24 | 25 | ### Installation Linux 26 | 27 | ```bash 28 | curl -fsSL https://ollama.com/install.sh | sh 29 | ``` 30 | 31 | [Manual install instructions](https://github.com/ollama/ollama/blob/main/docs/linux.md){:target="_blank"} 32 | 33 | ## Ollama Server Configuration Guide 34 | 35 | These instructions go over how to configure the Ollama server using environment variables on macOS, Linux, and Windows. 36 | 37 | Additional info can be found [Ollama FAQ](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-do-i-configure-ollama-server){:target="_blank"} 38 | 39 | ### Configuration macOS 40 | 41 | If Ollama is run as a macOS application, environment variables should be set using `launchctl`. 42 | 43 | #### Steps 44 | 45 | 1. Open the Terminal application. 46 | 2. For each environment variable you need to set, use the following command: 47 | 48 | ```bash 49 | launchctl setenv OLLAMA_HOST "0.0.0.0" 50 | launchctl setenv OLLAMA_ORIGINS "*" 51 | ``` 52 | 53 | 3. After setting the environment variables, restart the Ollama application for the changes to take effect. 54 | 55 | ### Configuration Linux 56 | 57 | If Ollama is run as a systemd service, environment variables should be set using `systemctl`. 58 | 59 | #### Steps 60 | 61 | 1. Open a terminal and edit the systemd service for Ollama by running: 62 | 63 | ```bash 64 | sudo systemctl edit ollama.service 65 | ``` 66 | 67 | This will open an editor. 68 | 69 | 2. Under the `[Service]` section, add a line for each environment variable: 70 | 71 | ```ini 72 | [Service] 73 | Environment="OLLAMA_HOST=0.0.0.0" 74 | Environment="OLLAMA_ORIGINS=*" 75 | ``` 76 | 77 | 3. Save the file and exit the editor. 78 | 79 | 4. Reload the systemd daemon to apply the changes: 80 | 81 | ```bash 82 | sudo systemctl daemon-reload 83 | ``` 84 | 85 | 5. Restart the Ollama service: 86 | 87 | ```bash 88 | sudo systemctl restart ollama 89 | ``` 90 | 91 | ### Configuration Windows 92 | 93 | On Windows, Ollama inherits your user and system environment variables. 94 | 95 | #### Steps 96 | 97 | 1. Quit Ollama by right-clicking the Ollama icon in the taskbar and selecting "Quit". 98 | 2. Open the **Settings** (Windows 11) or **Control Panel** (Windows 10) application. 99 | 3. Search for "environment variables" and select **Edit environment variables for your account**. 100 | 4. In the Environment Variables window, edit or create a new variable for your user account: 101 | - Variable Name: `OLLAMA_HOST` 102 | - Variable Value: `0.0.0.0` 103 | 5. Create a new variable for `OLLAMA_ORIGINS` with value `"*"` 104 | 6. Click **OK** or **Apply** to save your changes. 105 | 7. Restart the Ollama application from the Windows Start menu. 106 | 107 | ## Models 108 | 109 | There are several models we suggest to install. Starting with the main model, LLama3.1. Open a terminal and execute: 110 | 111 | ```bash 112 | ollama pull llama3.1:latest 113 | ``` 114 | 115 | The other models we suggest are: 116 | 117 | | Model | Parameters | Size | Download | Why? | 118 | | ------------------ | ---------- | ----- | -----------------------------------------------------| ----------------------------------------------------- | 119 | | Llama 3.1 | 405B | 231GB | `ollama pull llama3.1:405b` | If you have the space and want full Llama experience. | 120 | | Gemma 2 | 2B | 1.6GB | `ollama pull gemma2:2b` | Good for testing Google SLM | 121 | | Mistral | 7B | 4.1GB | `ollama pull mistral` | SLM with good performance. | 122 | | Code Llama | 7B | 3.8GB | `ollama pull codellama` | Use text prompts to generate and discuss code. | 123 | | Qwen 2 | 7.62B | 4.4GB | `ollama pull qwen2:latest` | LLM with good performance. | 124 | | Qwen 2 Math | 72B | 47GB | `ollama pull incept5/qwen2-math-72b-instruct:latest` | Specialized math LLM built upon the Qwen2 LLM. | 125 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | sitemap: 4 | exclude: 'yes' 5 | --- 6 | 7 | 8 | {% assign base_url = site.url | append: '/kubert-assistant-lite' %} 9 | {% for post in site.posts %} 10 | {% unless post.published == false %} 11 | 12 | {{ base_url }}{{ post.url }} 13 | {% if post.sitemap.lastmod %} 14 | {{ post.sitemap.lastmod | date: "%Y-%m-%d" }} 15 | {% elsif post.date %} 16 | {{ post.date | date_to_xmlschema }} 17 | {% else %} 18 | {{ site.time | date_to_xmlschema }} 19 | {% endif %} 20 | {% if post.sitemap.changefreq %} 21 | {{ post.sitemap.changefreq }} 22 | {% else %} 23 | monthly 24 | {% endif %} 25 | {% if post.sitemap.priority %} 26 | {{ post.sitemap.priority }} 27 | {% else %} 28 | 0.5 29 | {% endif %} 30 | 31 | {% endunless %} 32 | {% endfor %} 33 | {% for page in site.pages %} 34 | {% assign file_extension = page.path | split: '.' | last %} 35 | {% unless page.sitemap.exclude == "yes" or page.name == "feed.xml" or page.path contains ".js" or page.path contains ".xml" or page.path contains ".css" or page.path contains ".json" or page.path contains ".scss" %} 36 | 37 | {{ base_url }}{{ page.url | remove: "index.html" }} 38 | {% if page.sitemap.lastmod %} 39 | {{ page.sitemap.lastmod | date: "%Y-%m-%d" }} 40 | {% elsif page.date %} 41 | {{ page.date | date_to_xmlschema }} 42 | {% else %} 43 | {{ site.time | date_to_xmlschema }} 44 | {% endif %} 45 | {% if page.sitemap.changefreq %} 46 | {{ page.sitemap.changefreq }} 47 | {% else %} 48 | monthly 49 | {% endif %} 50 | {% if page.sitemap.priority %} 51 | {{ page.sitemap.priority }} 52 | {% else %} 53 | 0.5 54 | {% endif %} 55 | 56 | {% endunless %} 57 | {% endfor %} 58 | -------------------------------------------------------------------------------- /docs/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Testing 4 | nav_nabled: true 5 | k_seo: 6 | title: "Kubert Lite Testing Guide: Unit and Integration Testing with BATS, kcov, and Helm Linter" 7 | --- 8 | 9 | # **Kubert Lite Testing Guide:** Unit and Integration Testing with BATS, kcov, and Helm Linter 10 | 11 | Testing is an essential part of ensuring the reliability and correctness of the Kubert AI Assistant Lite project. This section outlines the testing strategy, tools used, and how to run the tests for the project. 12 | 13 | ## Testing Philosophy 14 | 15 | At Kubert AI Assistant Lite, we believe in the importance of thorough testing to maintain code quality, prevent regressions, and ensure a smooth user experience. We follow a comprehensive testing approach that includes: 16 | 17 | - **Unit Testing**: We write unit tests to verify the behavior of individual components and functions in isolation. Unit tests help catch bugs early and provide a safety net for refactoring and making changes to the codebase. 18 | 19 | - **Integration Testing**: Integration tests focus on the interaction between different components of the system. These tests ensure that the components work together seamlessly and produce the expected results when combined. 20 | 21 | - **Continuous Integration**: We have set up continuous integration (CI) pipelines that automatically run the test suite on each commit or pull request. This helps catch any issues early in the development process and maintains the stability of the main branch. - #TODO 22 | 23 | By following this testing philosophy, we aim to deliver a robust and reliable product to our users. 24 | 25 | ## Testing Tools 26 | 27 | The following tools are used for testing in the Kubert AI Assistant Lite project: 28 | 29 | - **BATS (Bash Automated Testing System)**: A testing framework for Bash scripts that provides a simple way to verify the behavior of shell scripts. 30 | - **bats-support**: A library of helper functions for writing BATS tests, making them easier to read and maintain. 31 | - **bats-assert**: An assertion library for BATS, providing convenient functions for making assertions in tests. 32 | - **kcov**: A code coverage tool for Bash scripts, providing insights into which parts of the scripts are executed during testing. 33 | - **Helm Linter**: Checks if the the helm chart used for the Kubert AI Assistant Lite components has issues. 34 | - **Helm Test**: After Helm chart deployment, Helm tests are executed to validate the deployment. 35 | 36 | ## Test Structure 37 | 38 | The tests are organized into unit tests and integration tests: 39 | 40 | - **Unit Tests**: These tests focus on individual functions and scripts, verifying their behavior in isolation. The unit tests are located in the tests/unit directory. 41 | - **Integration Tests**: These tests focus on the interaction between components, ensuring they work together as expected. Integration tests are located in the tests/integration directory. 42 | 43 | ## Running Tests 44 | 45 | To run the tests, ensure you have the necessary dependencies installed and the project environment set up correctly. 46 | 47 | ### Unit Tests 48 | 49 | Unit tests verify individual components of the project: 50 | 51 | ```bash 52 | make tests 53 | ``` 54 | 55 | This command runs all unit tests located in the tests/unit directory. 56 | 57 |
58 | 63 | 64 | To run a single unit test file: 65 | 66 | ```bash 67 | make tests TEST_FILE=tests/unit/test_wait_functions.bats 68 | ``` 69 | 70 |
71 | 76 | 77 | To run a single test in a unit test file: 78 | 79 | ```bash 80 | make tests TEST_FILE=tests/unit/test_wait_functions.bats TEST_PATTERN="wait_for_nodes should succeed when all nodes are ready" 81 | ``` 82 | 83 |
84 | 89 | 90 | ### Integration Tests 91 | 92 | Integration tests verify the interaction between components: 93 | 94 | ```bash 95 | make integration-tests 96 | ``` 97 | 98 |
99 | 104 | 105 | This command runs all integration tests located in the tests/integration directory. 106 | 107 | To run a specific integration test, use the following command: 108 | 109 | ```bash 110 | make integration-tests INTEGRATION_TEST_FILE=tests/integration/test_deploy_application.bats 111 | ``` 112 | 113 |
114 | 119 | 120 | ## Test Coverage 121 | 122 | To run tests with coverage and generate coverage reports using kcov, follow these steps: 123 | 124 | 1. Build the kcov Docker image: 125 | 126 | ```bash 127 | make build-kcov-image 128 | ``` 129 | 130 |
131 | 136 | 137 | 2. Run the coverage target: 138 | 139 | ```bash 140 | make coverage 141 | ``` 142 | 143 |
144 | 149 | 150 | This command will execute the tests and generate coverage reports in the coverage directory using kcov. To view the coverage open the index.html file in the coverage directory in a browser. 151 | 152 | ```bash 153 | open coverage/index.html 154 | ``` 155 | 156 | !["Coverage Report"](/kubert-assistant-lite/assets/images/coverage-report.png "Coverage Report") 157 | 158 | ## Helm Testing 159 | 160 | Local Helm chart, `manifests/chart`, is used to deploy the different Kubert AI Assistant Lite component. Use a linter for a quick check: 161 | 162 | ```bash 163 | make lint-chart 164 | ``` 165 |
166 | 171 | 172 | Using Helm template, we can have a quick view at the Helm templates in the chart: 173 | 174 | ```bash 175 | make template-chart 176 | ``` 177 | 178 |
179 | 184 | 185 | Once the system has been deployed, we can execute Helm tests with: 186 | 187 | ```bash 188 | make helm-test 189 | ``` 190 | 191 |
192 | 197 | 198 | ## Conclusion 199 | 200 | Testing is a crucial aspect of the Kubert AI Assistant Lite project, ensuring its reliability, stability, and correctness. By following the testing guidelines, writing comprehensive unit tests, running integration tests, and utilizing continuous integration, we aim to deliver a robust and well-tested product to our users. 201 | 202 | We encourage all contributors to prioritize testing and to follow the best practices outlined in this guide when working on the project. Together, we can maintain the quality and integrity of Kubert AI Assistant Lite. 203 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Usage 4 | description: "Watch Kubert usage videos, including AI Assistant setup, Kubernetes cluster queries, diagnosing resource issues, Ollama installation, and Windows 10 Pro setup for developers." 5 | nav_nabled: true 6 | has_children: true 7 | toc: true 8 | sitemap: 9 | priority: 0.7 10 | changefreq: 'weekly' 11 | k_seo: 12 | title: "Kubert Lite Usage Videos: Guide for Setup, Querying, and Troubleshooting" 13 | --- 14 | 15 | # Kubert Lite Usage Videos: Guide for Setup, Querying, and Troubleshooting 16 | {: .no_toc } 17 | 18 | ## Table of contents 19 | {: .no_toc .text-delta } 20 | 21 | 1. TOC 22 | {:toc} 23 | 24 | ## Kubert AI Assistant Setup 25 | 26 | Below is a demonstration video that guides you through the setup and usage of Kubert AI Assistant Lite. Watch as we cover the deployment process, features, and key interactions with the AI Assistant. 27 | 28 |
29 | 33 |
34 | ## Querying the Kubernetes Cluster with Kubert AI Agent 35 | 36 | In this video, you'll learn how to use the Kubert AI Agent to efficiently query your Kubernetes cluster using natural language prompts. We'll demonstrate both basic and advanced use cases, showing how these prompts are seamlessly transformed into `kubectl` commands to simplify cluster management. 37 | 38 |
39 | 43 |
44 | 45 | ## Diagnosing and Fixing Resource Misconfigurations 46 | 47 | This video demonstrates how to identify and resolve resource misconfigurations in Kubernetes using the Kubectl AI Agent. Watch as we deploy a problematic manifest, diagnose an Out of Memory (OOM) error, and use AI-generated commands to dynamically adjust resource limits, showcasing the power of AI-driven automation. 48 | 49 | The memory hog yaml can be found [HERE](https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/main/manifests/test-deployment/memory-hog.yaml){:target="_blank"} 50 | 51 |
52 | 56 |
-------------------------------------------------------------------------------- /docs/usage_ollama_and_kubert.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "Ollama & Kubert Lite" 4 | description: "Learn how to install Ollama, set up Kubert AI Assistant Lite, and configure it within the Kubert UI for seamless AI-powered Kubernetes management. Follow this guide for an effortless setup." 5 | parent: Usage 6 | nav_order: 1 7 | nav_fold: false 8 | k_seo: 9 | title: "Installing Ollama and Configuring Kubert AI Assistant Lite Video" 10 | --- 11 | 12 | # Installing Ollama and Configuring Kubert AI Assistant Lite Video 13 | 14 | In this video, we walk you through the process of installing Ollama, deploying Kubert AI Assistant Lite, and configuring Ollama within the Kubert UI settings. This comprehensive guide is perfect for anyone looking to integrate AI-powered tools into their Kubernetes environment seamlessly. 15 | 16 | Once, you've installed Ollama and configured the environment variables, pull the models from the Ollama library. 17 | 18 | Additional information is available in [Ollama Installation Guide](ollama.html). 19 | 20 |
21 | 25 |
26 | -------------------------------------------------------------------------------- /docs/usage_window_setup_dev.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "Windows Setup For Devs" 4 | description: "Set up a development environment on Windows 10 Pro by enabling Hyper-V, configuring WSL 2, and installing Ubuntu, Docker, VS Code, and Ollama for an optimized workflow." 5 | parent: Usage 6 | nav_order: 1 7 | nav_fold: false 8 | k_seo: 9 | title: "Windows 10 Pro Setup for Developers Video" 10 | --- 11 | 12 | # Windows 10 Pro Setup for Developers Video 13 | 14 | Follow along as we transform a fresh Windows 10 Pro installation into a powerful development environment. In this step-by-step guide, we’ll enable Hyper-V, configure WSL 2, install Ubuntu, Docker, Visual Studio Code, and Ollama. Whether you're setting up a new machine or optimizing your current setup, this video provides everything you need to get started with a robust and AI-enhanced workflow. Perfect for developers at any level! 15 | 16 |
17 | 18 |
-------------------------------------------------------------------------------- /docs/wsl.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: WSL Setup 4 | description: "Learn how to set up WSL in Windows 10 Pro and discover why it's essential for developers who need a Linux environment within Windows. Run Linux tools and apps seamlessly with WSL 2." 5 | parent: Installation 6 | nav_order: 3 7 | nav_fold: false 8 | k_seo: 9 | title: "WSL Setup in Windows 10 Pro" 10 | --- 11 | 12 | # WSL Setup in Windows 10 Pro 13 | ## Why Should You Care? 14 | 15 | For developers who need a Linux environment but prefer or are required to work within Windows, WSL offers a powerful solution. By using WSL 2 with Hyper-V and, if necessary, nested virtualization, you can enjoy the benefits of a full Linux experience directly on your Windows machine, with minimal overhead and without needing to reboot or manage a dual-boot setup. 16 | 17 | ## What is WSL? 18 | 19 | Windows Subsystem for Linux (WSL) is a compatibility layer for running Linux binary executables natively on Windows. WSL enables developers to use a Linux environment directly within Windows without the need for a dual-boot setup or using a full virtual machine. With WSL, you can run Linux command-line tools, utilities, and applications alongside your Windows applications, providing a seamless development experience. 20 | 21 | **There are two versions of WSL**: 22 | 23 | - **WSL 1**: Uses a translation layer to map Linux system calls to Windows system calls. 24 | - **WSL 2**: Introduces a full Linux kernel running in a lightweight virtual machine (VM), offering increased compatibility and performance, especially for file system operations. 25 | 26 | [Comparing WSL Versions](https://learn.microsoft.com/en-us/windows/wsl/compare-versions){:target="_blank"} 27 | 28 | ## Why Hyper-V is Needed 29 | 30 | Hyper-V is a crucial component for running WSL 2. Unlike WSL 1, which does not require Hyper-V, WSL 2 operates within a virtualized environment powered by Hyper-V. This allows WSL 2 to leverage a real Linux kernel, leading to improved system call compatibility and faster file I/O performance. Hyper-V ensures that the Linux kernel runs in an isolated, secure, and efficient environment on top of Windows. 31 | 32 | - **Virtualization**: Hyper-V is a Type 1 hypervisor that enables hardware virtualization, allowing the Linux kernel to run directly on the machine's hardware through a lightweight VM. This setup is essential for the full functionality of WSL 2. 33 | 34 | [Introduction to Hyper-V on Windows](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/about/){:target="_blank"} 35 | 36 | ### The Role of Nested Virtualization 37 | 38 | If you're running WSL inside a virtual machine, you may need nested virtualization. Nested virtualization allows you to enable Hyper-V within a virtual machine, effectively letting you run virtualized environments (like WSL 2) inside another virtualized environment. 39 | 40 | - **Nested Virtualization**: This is required if you're working within a virtualized development environment, such as a Windows 10 VM running on a hypervisor like VMware or Azure. With nested virtualization, you can enable Hyper-V inside the VM, allowing you to install and run WSL 2. 41 | 42 | [Nested Virtualization](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/nested-virtualization){:target="_blank"} 43 | 44 | ## Enable Hyper-V 45 | 46 | In the start search, search for "Turn Windows features on or off". 47 | 48 | [![Search](/kubert-assistant-lite/assets/images/windows/start-search.png)](/kubert-assistant-lite/assets/images/windows/start-search.png) 49 | 50 | [![Hyper-v](/kubert-assistant-lite/assets/images/windows/turn-on-hyper-v.png)](/kubert-assistant-lite/assets/images/windows/turn-on-hyper-v.png) 51 | 52 | Restart the PC. 53 | 54 | ## Enable WSL 55 | 56 | Search for the "Turn Windows features on or off", and this time enable "Virtual Machine Platform" and "Windows Subsystem for Linux" 57 | 58 | [![WSL](/kubert-assistant-lite/assets/images/windows/turn-on-wsl.png)](/kubert-assistant-lite/assets/images/windows/wsl.png) 59 | 60 | Restart the PC. 61 | 62 | ## Configure WSL 63 | 64 | Once WSl has been enabled in Windows it is good to check the status of it. 65 | 66 | Check WSL status: 67 | 68 | ```bash 69 | wsl --status 70 | ``` 71 | 72 | Depending on you Windows setting you might have to run WSL update. 73 | 74 | Let's update it: 75 | 76 | ```bash 77 | wsl --update 78 | ``` 79 | 80 | There are several Linux distribution available. 81 | To list available Linux distributions: 82 | 83 | ```bash 84 | wsl --list --online 85 | ``` 86 | 87 | Here is an example of the available distributions. 88 | 89 | ```bash 90 | NAME FRIENDLY NAME 91 | Ubuntu Ubuntu 92 | Debian Debian GNU/Linux 93 | kali-linux Kali Linux Rolling 94 | Ubuntu-18.04 Ubuntu 18.04 LTS 95 | Ubuntu-20.04 Ubuntu 20.04 LTS 96 | Ubuntu-22.04 Ubuntu 22.04 LTS 97 | Ubuntu-24.04 Ubuntu 24.04 LTS 98 | OracleLinux_7_9 Oracle Linux 7.9 99 | OracleLinux_8_7 Oracle Linux 8.7 100 | OracleLinux_9_1 Oracle Linux 9.1 101 | openSUSE-Leap-15.6 openSUSE Leap 15.6 102 | SUSE-Linux-Enterprise-15-SP5 SUSE Linux Enterprise 15 SP5 103 | SUSE-Linux-Enterprise-15-SP6 SUSE Linux Enterprise 15 SP6 104 | openSUSE-Tumbleweed openSUSE Tumbleweed 105 | ``` 106 | 107 | For our dev deployments we install Ubuntu distribution: 108 | 109 | ```bash 110 | wsl --install -d Ubuntu 111 | ``` 112 | 113 | For SecOps work we use `kali-linux`. 114 | 115 | ## Configure Linux 116 | 117 | Here is the minimal Linux package install that is required by Kubert. 118 | 119 | ```bash 120 | sudo apt install net-tools jq make 121 | ``` 122 | 123 | Let's break it down: 124 | 125 | - **sudo**: This command runs the following commands with superuser (root) privileges. It's required for installing software packages on the system since these actions require administrative rights. 126 | - **apt**: This is the package management command-line tool in Ubuntu. It stands for "Advanced Package Tool" and is used to handle the installation, updating, and removal of software packages. 127 | - **install**: This is a subcommand of apt that tells the package manager to install the specified packages. 128 | - **net-tools**: This package provides various networking tools like ifconfig, netstat, route, arp, etc. These tools are often used to configure network interfaces, check network connections, and manage the routing table. 129 | - **jq**: This is a lightweight and flexible command-line JSON processor. It allows you to parse, filter, and manipulate JSON data in a powerful and easy-to-use way. 130 | - **make**: This is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles. It's commonly used in software development for compiling and linking programs. 131 | 132 | ### Docker WSL 133 | 134 | Docker WSL refers to the integration of Docker with the WSL. This setup allows you to run Docker containers directly within a WSL environment, which can be particularly beneficial for developers working on a Windows machine but needing a Linux-based environment for their Docker workloads. 135 | 136 | The Docker WSL installation instruction can be found at [Docker Desktop](https://docs.docker.com/desktop/wsl/){:target="_blank"}. 137 | 138 | ### kind 139 | 140 | kind (short for Kubernetes IN Docker) is a tool that allows you to run local Kubernetes clusters using Docker container "nodes." It's particularly useful for development, testing, and CI/CD workflows. 141 | 142 | To install kind in a WSL environment, follow these commands: 143 | 144 | ```bash 145 | # Check for system architecture and download the kind Binary 146 | [ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64 147 | # Make the kind Binary Executable 148 | chmod +x ./kind 149 | # Move kind to /usr/local/bin, a directory that's included in your system's PATH. This allows you to run kind from anywhere in your terminal without specifying its full path. 150 | sudo mv ./kind /usr/local/bin/kind 151 | ``` 152 | 153 | ### Helm 154 | 155 | Helm is a package manager for Kubernetes, similar to how apt or yum works for Linux. It helps you define, install, and manage Kubernetes applications. Helm uses a packaging format called "charts," which are collections of files that describe a related set of Kubernetes resources. Helm simplifies the deployment process, making it easier to manage complex Kubernetes applications with many resources. 156 | 157 | To install Helm in a WSL environment, follow these commands: 158 | 159 | ```bash 160 | # Download the install shell script 161 | curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 162 | # Allow the shell script to Run 163 | chmod 700 get_helm.sh 164 | # Install Helm 165 | ./get_helm.sh 166 | # Remove the script after install 167 | rm get_helm.sh 168 | ``` 169 | 170 | ## Visual Studio Code 171 | 172 | Visual Studio Code (VS Code) is a powerful and lightweight code editor developed by Microsoft. It’s highly popular among developers for its rich set of features, extensive extensions marketplace, and support for multiple programming languages. To enhance development in a WSL environment, you can install the WSL extension, allowing you to seamlessly work on projects within your WSL distributions directly from VS Code. 173 | 174 | The VS Code WSL installation instruction can be found at [VS Code](https://code.visualstudio.com/docs/remote/wsl){:target="_blank"} 175 | -------------------------------------------------------------------------------- /kind-config.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | networking: 4 | # The default CNI will not be installed 5 | disableDefaultCNI: true 6 | # Only IPv4 7 | ipFamily: ipv4 8 | # 512 IP's for pods 9 | podSubnet: "10.10.0.0/23" 10 | # 256 IP's for services 11 | serviceSubnet: "10.20.0.0/24" 12 | nodes: 13 | - role: control-plane 14 | # Node label used by Ingress controller nodeSelector 15 | kubeadmConfigPatches: 16 | - | 17 | kind: InitConfiguration 18 | nodeRegistration: 19 | kubeletExtraArgs: 20 | node-labels: "ingress-ready=true" 21 | extraPortMappings: 22 | - containerPort: 80 23 | hostPort: 80 24 | protocol: TCP 25 | -------------------------------------------------------------------------------- /manifests/chart/charts/common-2.20.5.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TranslucentComputing/kubert-assistant-lite/3d7421646259e037dd34887a0766db5f4bc99a62/manifests/chart/charts/common-2.20.5.tgz -------------------------------------------------------------------------------- /manifests/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Create the name of the service account to use 3 | */}} 4 | {{- define "workload.serviceAccountName" -}} 5 | {{- if .Values.serviceAccount.create -}} 6 | {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} 7 | {{- else -}} 8 | {{ default "default" .Values.serviceAccount.name }} 9 | {{- end -}} 10 | {{- end -}} 11 | 12 | {{/* 13 | Return the proper image name 14 | */}} 15 | {{- define "workload.image" -}} 16 | {{- include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) -}} 17 | {{- end -}} 18 | -------------------------------------------------------------------------------- /manifests/chart/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | 2 | {{- if .Values.rbac.create_cluster -}} 3 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 4 | kind: ClusterRole 5 | metadata: 6 | name: {{ include "common.names.fullname" . }} 7 | namespace: {{ include "common.names.namespace" . | quote }} 8 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 9 | {{- if .Values.commonAnnotations }} 10 | annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} 11 | {{- end }} 12 | rules: 13 | {{- if .Values.rbac.rules_cluster }} 14 | {{- include "common.tplvalues.render" ( dict "value" .Values.rbac.rules_cluster "context" $ ) | nindent 2 }} 15 | {{- end }} 16 | --- 17 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 18 | kind: ClusterRoleBinding 19 | metadata: 20 | name: {{ include "common.names.fullname" . }} 21 | namespace: {{ include "common.names.namespace" . | quote }} 22 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 23 | {{- if .Values.commonAnnotations }} 24 | annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} 25 | {{- end }} 26 | subjects: 27 | - kind: ServiceAccount 28 | name: {{ include "workload.serviceAccountName" . }} 29 | namespace: {{ include "common.names.namespace" . | quote }} 30 | roleRef: 31 | kind: ClusterRole 32 | name: {{ include "common.names.fullname" . }} 33 | apiGroup: rbac.authorization.k8s.io 34 | {{- end -}} -------------------------------------------------------------------------------- /manifests/chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "common.names.fullname" . }} 5 | namespace: {{ include "common.names.namespace" . | quote }} 6 | {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.image "chart" .Chart ) ) }} 7 | {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} 8 | labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} 9 | annotations: 10 | {{- if .Values.commonAnnotations }} 11 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 12 | {{- end }} 13 | {{- if .Values.deploymentAnnotations }} 14 | {{- include "common.tplvalues.render" ( dict "value" .Values.deploymentAnnotations "context" $ ) | nindent 4 }} 15 | {{- end }} 16 | spec: 17 | {{- if .Values.updateStrategy }} 18 | strategy: {{- toYaml .Values.updateStrategy | nindent 4 }} 19 | {{- end }} 20 | replicas: {{ .Values.replicaCount }} 21 | {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels $versionLabel ) "context" . ) }} 22 | selector: 23 | matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} 24 | template: 25 | metadata: 26 | labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} 27 | annotations: 28 | {{- if .Values.podAnnotations }} 29 | {{- include "common.tplvalues.render" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} 30 | {{- end }} 31 | spec: 32 | {{- include "common.images.pullSecrets" (dict "images" (list .Values.image)) }} 33 | automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} 34 | {{- if .Values.hostAliases }} 35 | hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} 36 | {{- end }} 37 | {{- if .Values.terminationGracePeriodSeconds }} 38 | terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} 39 | {{- end }} 40 | serviceAccountName: {{ include "workload.serviceAccountName" . }} 41 | {{- if .Values.podSecurityContext.enabled }} 42 | securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} 43 | {{- end }} 44 | {{- if .Values.nodeSelector }} 45 | nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} 46 | {{- end }} 47 | {{- if .Values.tolerations }} 48 | tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} 49 | {{- end }} 50 | {{- if .Values.topologySpreadConstraints }} 51 | topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} 52 | {{- end }} 53 | {{- if .Values.affinity }} 54 | affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} 55 | {{- else }} 56 | affinity: 57 | podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} 58 | podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} 59 | nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} 60 | {{- end }} 61 | containers: 62 | - name: "workload" 63 | image: {{ include "common.images.image" (dict "imageRoot" .Values.image) }} 64 | imagePullPolicy: {{ .Values.image.pullPolicy | quote }} 65 | {{- if .Values.containerSecurityContext.enabled }} 66 | securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} 67 | {{- end }} 68 | ports: 69 | - name: http 70 | containerPort: {{ .Values.containerPortHttp }} 71 | {{- range .Values.extraContainerPorts}} 72 | - name: {{ .name }} 73 | containerPort: {{ .port }} 74 | {{- end }} 75 | env: 76 | {{- if .Values.extraEnvVars }} 77 | {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} 78 | {{- end }} 79 | {{- if or .Values.extraEnvVarsCM .Values.extraEnvVarsSecret .Values.extraEnvVarsSecrets }} 80 | envFrom: 81 | {{- if .Values.extraEnvVarsCM }} 82 | - configMapRef: 83 | name: {{ .Values.extraEnvVarsCM }} 84 | {{- end }} 85 | {{- if .Values.extraEnvVarsSecret }} 86 | - secretRef: 87 | name: {{ .Values.extraEnvVarsSecret }} 88 | {{- end }} 89 | {{- range .Values.extraEnvVarsSecrets }} 90 | - secretRef: 91 | name: {{ . }} 92 | {{- end }} 93 | {{- end }} 94 | {{- if .Values.resources }} 95 | resources: {{- toYaml .Values.resources | nindent 12 }} 96 | {{- end }} 97 | {{- if .Values.livenessProbe }} 98 | livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.livenessProbe "context" $) | nindent 12 }} 99 | {{- end }} 100 | {{- if .Values.readinessProbe }} 101 | readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.readinessProbe "context" $) | nindent 12 }} 102 | {{- end }} 103 | {{- if .Values.extraVolumeMounts }} 104 | volumeMounts: 105 | {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} 106 | {{- end }} 107 | {{- if .Values.extraVolumes }} 108 | volumes: 109 | {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} 110 | {{- end }} -------------------------------------------------------------------------------- /manifests/chart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} 3 | kind: Ingress 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ include "common.names.namespace" . | quote }} 7 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 8 | annotations: 9 | {{- if .Values.commonAnnotations }} 10 | {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} 11 | {{- end }} 12 | {{- if .Values.ingress.extraAnnotations }} 13 | {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraAnnotations "context" $) | nindent 4 }} 14 | {{- end }} 15 | nginx.ingress.kubernetes.io/enable-cors: "true" 16 | nginx.ingress.kubernetes.io/cors-allow-methods: "*" 17 | nginx.ingress.kubernetes.io/cors-allow-origin: "http://{{ .Values.ingress.hostname }}" 18 | {{- if .Values.ingress.corsAllowedOrigins }} 19 | nginx.ingress.kubernetes.io/cors-allow-origin: "{{ .Values.ingress.corsAllowedOrigins | join "," }}" 20 | {{- end }} 21 | nginx.ingress.kubernetes.io/cors-allow-credentials: "true" 22 | {{- if .Values.ingress.corsAllowedHeaders }} 23 | nginx.ingress.kubernetes.io/cors-allow-headers: "{{ .Values.ingress.corsAllowedHeaders | join "," }}" 24 | {{- end }} 25 | nginx.ingress.kubernetes.io/configuration-snippet: | 26 | more_clear_headers "Server"; 27 | more_clear_headers "X-Powered-By"; 28 | more_set_headers "X-Xss-Protection: 1; mode=block"; 29 | more_set_headers "X-Content-Type-Options: nosniff"; 30 | more_set_headers "X-Permitted-Cross-Domain-Policies: none"; 31 | more_set_headers "Referrer-Policy: no-referrer"; 32 | {{- if .Values.ingress.frameAncestors }} 33 | more_set_headers "Content-Security-Policy: frame-ancestors {{ .Values.ingress.frameAncestors | join " " }}"; 34 | {{- else }} 35 | more_set_headers "X-Frame-Options SAMEORIGIN"; 36 | {{- end }} 37 | spec: 38 | {{- if and .Values.ingress.className (eq "true" (include "common.ingress.supportsIngressClassname" .)) }} 39 | ingressClassName: {{ .Values.ingress.className | quote }} 40 | {{- end }} 41 | rules: 42 | - host: {{ .Values.ingress.hostname | quote }} 43 | http: 44 | paths: 45 | - path: {{ .Values.ingress.path }} 46 | pathType: Prefix 47 | backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} 48 | {{- end }} 49 | -------------------------------------------------------------------------------- /manifests/chart/templates/networkpolicy.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.networkPolicy.enabled }} 2 | kind: NetworkPolicy 3 | apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ include "common.names.namespace" . | quote }} 7 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 8 | {{- if .Values.commonAnnotations }} 9 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} 13 | podSelector: 14 | matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} 15 | policyTypes: 16 | - Ingress 17 | - Egress 18 | egress: 19 | # Allow dns resolution 20 | - ports: 21 | - port: 53 22 | protocol: UDP 23 | - port: 53 24 | protocol: TCP 25 | # Allow outbound connections to other cluster pods 26 | - ports: 27 | - port: {{ .Values.containerPortHttp }} 28 | - port: {{ .Values.service.ports.http }} 29 | to: 30 | - podSelector: 31 | matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} 32 | {{- if .Values.networkPolicy.extraEgress }} 33 | {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} 34 | {{- end }} 35 | ingress: 36 | - ports: 37 | - port: {{ .Values.containerPortHttp }} 38 | - port: {{ .Values.service.ports.http }} 39 | {{- if not .Values.networkPolicy.allowExternal }} 40 | from: 41 | - podSelector: 42 | matchLabels: 43 | {{ include "common.names.fullname" . }}-client: "true" 44 | {{- if .Values.networkPolicy.ingressNSMatchLabels }} 45 | - namespaceSelector: 46 | matchLabels: 47 | {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} 48 | {{ $key | quote }}: {{ $value | quote }} 49 | {{- end }} 50 | {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} 51 | podSelector: 52 | matchLabels: 53 | {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} 54 | {{ $key | quote }}: {{ $value | quote }} 55 | {{- end }} 56 | {{- end }} 57 | {{- end }} 58 | {{- end }} 59 | {{- if .Values.networkPolicy.extraIngress }} 60 | {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /manifests/chart/templates/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create -}} 2 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 3 | kind: Role 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ include "common.names.namespace" . | quote }} 7 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 8 | {{- if .Values.commonAnnotations }} 9 | annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} 10 | {{- end }} 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - "pods" 16 | verbs: 17 | - "get" # Permission to get pod information 18 | - "list" # Permission to list pods 19 | - "watch" # Permission to watch for changes to pods 20 | - apiGroups: 21 | - "" 22 | resources: 23 | - "pods/log" 24 | verbs: 25 | - "get" # Permission to get logs from pods 26 | - apiGroups: 27 | - "" 28 | resources: 29 | - "pods/exec" 30 | verbs: 31 | - "create" # Permission to execute commands in a pod (troubleshooting) 32 | - "get" # Permission to retrieve necessary information for exec session 33 | {{- if .Values.rbac.rules }} 34 | {{- include "common.tplvalues.render" ( dict "value" .Values.rbac.rules "context" $ ) | nindent 2 }} 35 | {{- end }} 36 | --- 37 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 38 | kind: RoleBinding 39 | metadata: 40 | name: {{ include "common.names.fullname" . }} 41 | namespace: {{ include "common.names.namespace" . | quote }} 42 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 43 | {{- if .Values.commonAnnotations }} 44 | annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} 45 | {{- end }} 46 | subjects: 47 | - kind: ServiceAccount 48 | name: {{ include "workload.serviceAccountName" . }} 49 | namespace: {{ include "common.names.namespace" . | quote }} 50 | roleRef: 51 | kind: Role 52 | name: {{ include "common.names.fullname" . }} 53 | apiGroup: rbac.authorization.k8s.io 54 | {{- end -}} -------------------------------------------------------------------------------- /manifests/chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "common.names.fullname" . }} 5 | namespace: {{ include "common.names.namespace" . | quote }} 6 | {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.image "chart" .Chart ) ) }} 7 | {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} 8 | labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} 9 | {{- if or .Values.service.annotations .Values.commonAnnotations }} 10 | {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }} 11 | annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} 12 | {{- end }} 13 | spec: 14 | type: {{ .Values.service.type }} 15 | {{- if .Values.service.sessionAffinity }} 16 | sessionAffinity: {{ .Values.service.sessionAffinity }} 17 | {{- end }} 18 | {{- if .Values.service.sessionAffinityConfig }} 19 | sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} 20 | {{- end }} 21 | {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} 22 | clusterIP: {{ .Values.service.clusterIP }} 23 | {{- end }} 24 | {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} 25 | externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} 26 | {{- end }} 27 | {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerSourceRanges)) }} 28 | loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }} 29 | {{- end }} 30 | {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} 31 | loadBalancerIP: {{ .Values.service.loadBalancerIP }} 32 | {{- end }} 33 | ports: 34 | - name: http 35 | port: {{ .Values.service.ports.http }} 36 | protocol: TCP 37 | targetPort: http 38 | {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.http))) }} 39 | nodePort: {{ .Values.service.nodePorts.http }} 40 | {{- else if eq .Values.service.type "ClusterIP" }} 41 | nodePort: null 42 | {{- end }} 43 | {{- if .Values.service.extraPorts }} 44 | {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} 45 | {{- end }} 46 | {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels ) "context" . ) }} 47 | selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} 48 | -------------------------------------------------------------------------------- /manifests/chart/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "workload.serviceAccountName" . }} 6 | namespace: {{ include "common.names.namespace" . | quote }} 7 | labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} 8 | {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} 9 | {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} 10 | annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} 11 | {{- end }} 12 | automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} 13 | {{- end -}} -------------------------------------------------------------------------------- /manifests/chart/templates/test.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.test.enabled }} 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: "{{ include "common.names.fullname" . }}-test-connection" 6 | namespace: {{ include "common.names.namespace" . | quote }} 7 | {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.image "chart" .Chart ) ) }} 8 | {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} 9 | labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} 10 | annotations: 11 | "helm.sh/hook": test 12 | spec: 13 | template: 14 | metadata: 15 | labels: 16 | {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 8 }} 17 | spec: 18 | {{- if .Values.test.container }} 19 | containers: 20 | {{- include "common.tplvalues.render" (dict "value" .Values.test.container "context" $) | trim | nindent 8 }} 21 | {{- end }} 22 | restartPolicy: Never 23 | backoffLimit: 1 24 | {{- end }} -------------------------------------------------------------------------------- /manifests/kubert-assistant/agent-repo-values.yaml: -------------------------------------------------------------------------------- 1 | # Deployment config 2 | 3 | ## Image from Kubert Images public docker repo 4 | image: 5 | repository: northamerica-northeast2-docker.pkg.dev/tcinc-dev/kubert-images/agent-repo 6 | tag: 6ac4178 7 | 8 | ## Container Http port 9 | containerPortHttp: 8080 10 | 11 | ## Additional port used for probes 12 | extraContainerPorts: 13 | - name: health 14 | port: 8081 15 | 16 | ## Resource allocation for the main container 17 | resources: 18 | limits: 19 | cpu: 80m 20 | memory: 128Mi 21 | requests: 22 | cpu: 50m 23 | memory: 64Mi 24 | 25 | ## Additional mounts 26 | extraVolumeMounts: |- 27 | - name: cache-volume 28 | mountPath: /var/cache/nginx 29 | 30 | ## Additional volumes 31 | extraVolumes: |- 32 | - name: cache-volume 33 | emptyDir: {} 34 | 35 | ## Probes 36 | livenessProbe: 37 | httpGet: 38 | path: /healthz 39 | port: 8081 40 | initialDelaySeconds: 10 41 | periodSeconds: 10 42 | readinessProbe: 43 | httpGet: 44 | path: /ready 45 | port: 8081 46 | initialDelaySeconds: 5 47 | periodSeconds: 10 48 | 49 | ## Pod security context 50 | podSecurityContext: 51 | enabled: true 52 | fsGroup: 101 53 | runAsGroup: 101 54 | runAsUser: 101 55 | 56 | ## Container security context 57 | containerSecurityContext: 58 | allowPrivilegeEscalation: false 59 | capabilities: 60 | drop: 61 | - ALL 62 | enabled: true 63 | readOnlyRootFilesystem: true 64 | runAsNonRoot: true 65 | 66 | # Ingress config 67 | ingress: 68 | enabled: true 69 | className: nginx 70 | corsAllowedOrigins: 71 | - http://kubert-assistant.lan 72 | - http://kubert-agent.lan 73 | hostname: kubert-agent.lan 74 | -------------------------------------------------------------------------------- /manifests/kubert-assistant/command-runner-values.yaml: -------------------------------------------------------------------------------- 1 | # Deployment config 2 | 3 | ## Automatically mount token to the pod after it has been created 4 | automountServiceAccountToken: true 5 | 6 | ## Image from Kubert Images public docker repo 7 | image: 8 | pullPolicy: IfNotPresent 9 | repository: northamerica-northeast2-docker.pkg.dev/tcinc-dev/kubert-images/command-runner 10 | tag: 12b08ac 11 | 12 | ## Container Http port 13 | containerPortHttp: 3000 14 | 15 | ## Resource allocation for the main container 16 | resources: 17 | limits: 18 | cpu: 300m 19 | memory: 728Mi 20 | requests: 21 | cpu: 200m 22 | memory: 128Mi 23 | 24 | ## Environment variables 25 | extraEnvVars: 26 | - name: HOST 27 | value: 0.0.0.0 28 | - name: LOG_LEVEL 29 | value: debug 30 | - name: LOG_PATH 31 | value: logging.json 32 | 33 | ## Probes 34 | livenessProbe: {} 35 | readinessProbe: {} 36 | 37 | ## Pod security context 38 | podSecurityContext: 39 | enabled: true 40 | fsGroup: 10000 41 | fsGroupChangePolicy: Always 42 | supplementalGroups: [] 43 | sysctls: [] 44 | 45 | ## Container security context 46 | containerSecurityContext: 47 | allowPrivilegeEscalation: false 48 | capabilities: 49 | drop: 50 | - ALL 51 | enabled: true 52 | privileged: false 53 | runAsNonRoot: true 54 | runAsUser: 10001 55 | seLinuxOptions: null 56 | seccompProfile: 57 | type: RuntimeDefault 58 | 59 | # RBAC for the command runner 60 | rbac: 61 | create: true 62 | create_cluster: true 63 | rules: [] 64 | rules_cluster: 65 | - apiGroups: 66 | - '*' 67 | resources: 68 | - '*' 69 | verbs: 70 | - get 71 | - list 72 | - create 73 | - update 74 | - patch 75 | - delete 76 | 77 | # Network policy config 78 | networkPolicy: 79 | enabled: false 80 | 81 | # Test config 82 | test: 83 | enabled: true 84 | container: 85 | - name: curl 86 | image: "curlimages/curl" 87 | env: 88 | - name: "HOST" 89 | value: |- 90 | {{ include "common.names.fullname" . }}:{{ .Values.service.ports.http }} 91 | command: 92 | - sh 93 | - -c 94 | - > 95 | response=$(curl -s -o /dev/stderr -w "%{http_code}" -X POST -d '{"command": "kubectl get pods"}' -H "Content-Type: application/json" $HOST/command/kubectl); 96 | if [ $response -ne 200 ]; then exit 1; fi -------------------------------------------------------------------------------- /manifests/kubert-assistant/gateway-values.yaml: -------------------------------------------------------------------------------- 1 | # Deployment config 2 | image: 3 | repository: northamerica-northeast2-docker.pkg.dev/tcinc-dev/kubert-images/plugin-gateway 4 | tag: ed74444 5 | 6 | ## Container Http port 7 | containerPortHttp: 3000 8 | 9 | ## Resource allocation for the main container 10 | resources: 11 | limits: 12 | cpu: 100m 13 | memory: 512Mi 14 | requests: 15 | cpu: 50m 16 | memory: 128Mi 17 | 18 | ## Environment variables 19 | extraEnvVars: 20 | - name: BASE_URL_KUBECTL 21 | value: http://command-runner-kubert-assistant-workload.kubert-assistant.svc.cluster.local:8080/command/kubectl 22 | - name: LOG_LEVEL 23 | value: debug 24 | - name: PROBE_PORT 25 | value: "3200" 26 | 27 | ## Probes 28 | livenessProbe: 29 | failureThreshold: 3 30 | httpGet: 31 | path: /live 32 | port: 3200 33 | initialDelaySeconds: 10 34 | periodSeconds: 30 35 | successThreshold: 1 36 | timeoutSeconds: 5 37 | readinessProbe: 38 | failureThreshold: 1 39 | httpGet: 40 | path: /ready 41 | port: 3200 42 | initialDelaySeconds: 5 43 | periodSeconds: 5 44 | successThreshold: 1 45 | timeoutSeconds: 5 46 | 47 | ## Pod security context 48 | podSecurityContext: 49 | enabled: true 50 | fsGroup: 1001 51 | runAsGroup: 1001 52 | runAsNonRoot: true 53 | runAsUser: 1001 54 | 55 | ## Container security context 56 | containerSecurityContext: 57 | allowPrivilegeEscalation: false 58 | capabilities: 59 | drop: 60 | - ALL 61 | enabled: true 62 | privileged: false 63 | readOnlyRootFilesystem: false 64 | runAsNonRoot: true 65 | runAsUser: 1001 66 | 67 | # RBAC for the gateway 68 | rbac: 69 | create: true 70 | 71 | # Network policy config 72 | networkPolicy: 73 | enabled: false 74 | 75 | # Ingress config 76 | ingress: 77 | enabled: true 78 | className: nginx 79 | corsAllowedHeaders: 80 | - x-lobe-chat-auth 81 | - x-lobe-plugin-settings 82 | - x-lobe-trace 83 | - content-type 84 | corsAllowedOrigins: 85 | - http://kubert-plugin-gateway.lan 86 | - http://kubert-assistant.lan 87 | frameAncestors: 88 | - self 89 | - http://kubert-assistant.lan 90 | hostname: kubert-plugin-gateway.lan 91 | -------------------------------------------------------------------------------- /manifests/kubert-assistant/lobe-chat-values.yaml: -------------------------------------------------------------------------------- 1 | # Deployment config 2 | 3 | ## Image for Lobe Chat 4 | image: 5 | pullPolicy: IfNotPresent 6 | repository: lobehub/lobe-chat 7 | tag: v1.12.14 8 | 9 | ## Container Http port 10 | containerPortHttp: 3210 11 | 12 | ## Environment variables 13 | extraEnvVars: 14 | - name: OPENAI_API_KEY 15 | value: "" 16 | - name: ANTHROPIC_API_KEY 17 | value: "" 18 | - name: GROQ_API_KEY 19 | value: "" 20 | - name: GOOGLE_API_KEY 21 | value: "" 22 | - name: PERPLEXITY_API_KEY 23 | value: "" 24 | - name: OLLAMA_PROXY_URL 25 | value: "http://kubert-ollama.lan:11434" 26 | - name: OLLAMA_MODEL_LIST 27 | value: "llama3.1" 28 | - name: DEFAULT_AGENT_CONFIG 29 | value: model=gpt-4o;tts.sttLocale=en-US;inputTemplate="Hello;I am a Kubert assistant;" 30 | - name: AGENTS_INDEX_URL 31 | value: http://kubert-agent.lan 32 | - name: PLUGINS_INDEX_URL 33 | value: http://kubert-plugin.lan 34 | - name: ACCESS_CODES 35 | value: kubert 36 | 37 | 38 | ## Resource allocation for the main container 39 | resources: 40 | limits: 41 | cpu: 150m 42 | memory: 256Mi 43 | requests: 44 | cpu: 50m 45 | memory: 128Mi 46 | 47 | ## Probes 48 | livenessProbe: {} 49 | readinessProbe: {} 50 | 51 | ## Pod security context 52 | podSecurityContext: 53 | enabled: true 54 | fsGroup: 1001 55 | runAsGroup: 1001 56 | runAsNonRoot: true 57 | runAsUser: 1001 58 | 59 | ## Container security context 60 | containerSecurityContext: 61 | allowPrivilegeEscalation: false 62 | capabilities: 63 | drop: 64 | - ALL 65 | enabled: true 66 | privileged: false 67 | readOnlyRootFilesystem: false 68 | runAsNonRoot: true 69 | runAsUser: 1001 70 | 71 | # Network policy config 72 | networkPolicy: 73 | enabled: false 74 | 75 | # RBAC config 76 | rbac: 77 | create: true 78 | 79 | # Ingress config 80 | ingress: 81 | enabled: true 82 | className: nginx 83 | corsAllowedOrigins: 84 | - http://kubert-assistant.lan 85 | extraAnnotations: | 86 | nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" 87 | nginx.ingress.kubernetes.io/proxy-buffers-number: "8" 88 | nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "24k" 89 | hostname: kubert-assistant.lan 90 | path: / 91 | 92 | 93 | -------------------------------------------------------------------------------- /manifests/kubert-assistant/plugin-repo-values.yaml: -------------------------------------------------------------------------------- 1 | # Deployment config 2 | 3 | ## Image from Kubert Images public docker repo 4 | image: 5 | repository: northamerica-northeast2-docker.pkg.dev/tcinc-dev/kubert-images/plugin-repo 6 | tag: 6bc7c45 7 | 8 | ## Container Http port 9 | containerPortHttp: 8080 10 | 11 | ## Additional port used for probes 12 | extraContainerPorts: 13 | - name: health 14 | port: 8081 15 | 16 | ## Resource allocation for the main container 17 | resources: 18 | limits: 19 | cpu: 80m 20 | memory: 128Mi 21 | requests: 22 | cpu: 50m 23 | memory: 64Mi 24 | 25 | ## Additional mounts 26 | extraVolumeMounts: |- 27 | - name: cache-volume 28 | mountPath: /var/cache/nginx 29 | 30 | ## Additional volumes 31 | extraVolumes: |- 32 | - name: cache-volume 33 | emptyDir: {} 34 | 35 | ## Probes 36 | livenessProbe: 37 | httpGet: 38 | path: /healthz 39 | port: 8081 40 | initialDelaySeconds: 10 41 | periodSeconds: 10 42 | readinessProbe: 43 | httpGet: 44 | path: /ready 45 | port: 8081 46 | initialDelaySeconds: 5 47 | periodSeconds: 10 48 | 49 | ## Pod security context 50 | podSecurityContext: 51 | enabled: true 52 | fsGroup: 101 53 | runAsGroup: 101 54 | runAsUser: 101 55 | 56 | ## Container security context 57 | containerSecurityContext: 58 | allowPrivilegeEscalation: false 59 | capabilities: 60 | drop: 61 | - ALL 62 | enabled: true 63 | readOnlyRootFilesystem: true 64 | runAsNonRoot: true 65 | 66 | # Ingress config 67 | ingress: 68 | enabled: true 69 | className: nginx 70 | corsAllowedOrigins: 71 | - http://kubert-assistant.lan 72 | - http://kubert-plugin.lan 73 | hostname: kubert-plugin.lan 74 | -------------------------------------------------------------------------------- /manifests/test-deployment/memory-hog.yaml: -------------------------------------------------------------------------------- 1 | # This YAML manifest defines a Kubernetes Deployment that simulates a resource misconfiguration scenario. 2 | # The deployment uses the stress-ng tool to intentionally exceed its memory limits, demonstrating how Kubernetes handles Out of Memory (OOM) conditions. 3 | # This example is useful for educational purposes, illustrating the importance of proper resource configuration in a Kubernetes environment. 4 | 5 | apiVersion: apps/v1 6 | kind: Deployment 7 | metadata: 8 | name: memory-hog 9 | labels: 10 | app: memory-hog 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app: memory-hog 16 | template: 17 | metadata: 18 | labels: 19 | app: memory-hog 20 | spec: 21 | automountServiceAccountToken: false 22 | containers: 23 | - name: memory-hog 24 | # Using a lightweight image that includes the stress-ng tool to simulate memory usage 25 | image: ghcr.io/colinianking/stress-ng 26 | resources: 27 | # Requests are the minimum resources required for scheduling the pod 28 | requests: 29 | memory: "32Mi" # Requesting a small amount of memory 30 | cpu: "100m" # Requesting a small amount of CPU 31 | # Limits are the maximum resources the pod can consume 32 | limits: 33 | memory: "32Mi" # Limiting memory to 32Mi, likely to cause an OOM error when exceeded 34 | cpu: "100m" # Limiting CPU to 100m 35 | command: 36 | # Using stress-ng to allocate 64Mi of memory, intentionally exceeding the limit 37 | - "sh" 38 | - "-c" 39 | - "echo 'Starting memory hog'; stress-ng --vm 1 --vm-bytes 64M --vm-hang 0 --timeout 60s; tail -f /dev/null" 40 | -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | # Script Name: cleanup.sh 5 | # Description: This script cleans up the Kubert AI Assistant Lite application by 6 | # removing the kind Kubernetes cluster and cleaning up the hosts file. 7 | # 8 | # Usage: ./cleanup.sh 9 | # 10 | # Copyright © 2024 Kubert 11 | # ----------------------------------------------------------------------------- 12 | 13 | # Bash safeties: exit on error, no unset variables, pipelines can't hide errors 14 | set -o errexit 15 | set -o nounset 16 | set -o pipefail 17 | 18 | # Source the utils.sh and variables.sh scripts to use their functions and variables 19 | BASE_DIR="$(dirname "$0")" 20 | 21 | # shellcheck disable=SC1091 22 | source "$BASE_DIR/utils.sh" 23 | # shellcheck disable=SC1091 24 | source "$BASE_DIR/variables.sh" 25 | 26 | # Validate that necessary tools are installed 27 | ./scripts/validate-tools.sh 28 | 29 | # Main cleanup script 30 | log "INFO" "Starting cleanup process..." 31 | 32 | # Remove the kind cluster 33 | if kind get clusters | grep -q "$KIND_CLUSTER_NAME"; then 34 | log "INFO" "Deleting kind cluster $KIND_CLUSTER_NAME..." 35 | kind delete cluster --name "$KIND_CLUSTER_NAME" 36 | else 37 | log "INFO" "kind cluster $KIND_CLUSTER_NAME does not exist. Skipping deletion." 38 | fi 39 | 40 | # Clean up hosts file entries 41 | log "INFO" "Cleaning up hosts file entries..." 42 | clean_up_hosts_file "${HOSTS_ENTRIES[@]}" 43 | 44 | log "INFO" "Cleanup process completed successfully." 45 | -------------------------------------------------------------------------------- /scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | # Script Name: deploy.sh 5 | # Description: This script deploys the Kubert AI Assistant Lite application in a kind Kubernetes cluster. 6 | # 7 | # Usage: ./deploy.sh 8 | # 9 | # Copyright © 2024 Kubert 10 | # ----------------------------------------------------------------------------- 11 | 12 | # Bash safeties: exit on error, no unset variables, pipelines can't hide errors 13 | set -o errexit 14 | set -o nounset 15 | set -o pipefail 16 | 17 | # Source the utils.sh and variables.sh scripts to use their functions and variables 18 | BASE_DIR="$(dirname "$0")" 19 | 20 | # shellcheck disable=SC1091 21 | source "${BASE_DIR}/utils.sh" 22 | # shellcheck disable=SC1091 23 | source "${BASE_DIR}/variables.sh" 24 | 25 | # Source and execute the hello.sh script for greetings and explanation 26 | # shellcheck disable=SC1091 27 | source "${BASE_DIR}/hello.sh" 28 | 29 | # Validate that necessary tools are installed 30 | ./scripts/validate-tools.sh 31 | 32 | # Main deployment script 33 | log "INFO" "Starting deployment process..." 34 | 35 | # Check if the kind cluster already exists 36 | if kind get clusters | grep -q "${KIND_CLUSTER_NAME}"; then 37 | log "INFO" "kind cluster ${KIND_CLUSTER_NAME} already exists. Skipping creation." 38 | else 39 | create_kind_cluster "${KIND_CLUSTER_NAME}" "${KIND_CONFIG}" 40 | fi 41 | 42 | # Deploy Calico for network policies 43 | deploy_calico "${CALICO_YAML}" 44 | 45 | # Wait for all nodes to be ready 46 | wait_for_nodes 47 | 48 | # Deploy NGINX Ingress Controller 49 | deploy_nginx_ingress "${NGINX_INGRESS_CONTROLLER_YAML}" 50 | 51 | # Wait for NGINX Ingress Controller pods to be ready 52 | wait_for_nginx_ingress 53 | 54 | # Update hosts file for local testing 55 | update_hosts_file "${KIND_CLUSTER_NAME}" "${HOSTS_ENTRIES[@]}" 56 | 57 | # Update CoreDNS ConfigMap with host IP and local domains 58 | update_coredns_config "${HOSTS_ENTRIES[@]}" 59 | 60 | # Deploy Kubert Assistant components using the new function 61 | deploy_kubert_assistant "${CHART_PATH}" "${HELM_NAMESPACE}" "${KIND_CLUSTER_NAME}" "${KUBERT_COMPONENTS[@]}" 62 | 63 | # Wait for the ingresses to have an address 64 | wait_for_ingress_ready "${HELM_NAMESPACE}" 65 | 66 | # Check if the application is accessible 67 | wait_for_service "http://kubert-assistant.lan" 68 | 69 | log "INFO" "Deployment process completed successfully." 70 | log "INFO" "You can now access Kubert Assistant at http://kubert-assistant.lan" 71 | log "INFO" "The access code to use is 'kubert'." -------------------------------------------------------------------------------- /scripts/hello.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | # Script Name: hello.sh 5 | # Description: This script prints a welcome message and displays the product name in ASCII art. 6 | # 7 | # Usage: ./hello.sh 8 | # 9 | # Copyright © 2024 Kubert 10 | # ----------------------------------------------------------------------------- 11 | 12 | # Source the utils.sh script to use the log function 13 | BASE_DIR="$(dirname "$0")" 14 | # shellcheck disable=SC1091 15 | source "$BASE_DIR/utils.sh" 16 | 17 | # Print welcome message 18 | log "INFO" "Hello! Welcome to the deployment of the Kubert AI Assistant Lite application." 19 | 20 | # Display the product name in ASCII art with spaces before and after 21 | log "INFO" "" 22 | log "INFO" "" 23 | ascii_art=$(cat << "EOF" 24 | ██╗ ██╗██╗ ██╗██████╗ ███████╗██████╗ ████████╗ █████╗ ███████╗███████╗██╗███████╗████████╗ █████╗ ███╗ ██╗████████╗ 25 | ██║ ██╔╝██║ ██║██╔══██╗██╔════╝██╔══██╗╚══██╔══╝ ██╔══██╗██╔════╝██╔════╝██║██╔════╝╚══██╔══╝██╔══██╗████╗ ██║╚══██╔══╝ 26 | █████╔╝ ██║ ██║██████╔╝█████╗ ██████╔╝ ██║ ███████║███████╗███████╗██║███████╗ ██║ ███████║██╔██╗ ██║ ██║ 27 | ██╔═██╗ ██║ ██║██╔══██╗██╔══╝ ██╔══██╗ ██║ ██╔══██║╚════██║╚════██║██║╚════██║ ██║ ██╔══██║██║╚██╗██║ ██║ 28 | ██║ ██╗╚██████╔╝██████╔╝███████╗██║ ██║ ██║ ██║ ██║███████║███████║██║███████║ ██║ ██║ ██║██║ ╚████║ ██║ 29 | ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ 30 | EOF 31 | ) 32 | while IFS= read -r line; do 33 | log "INFO" "$line" 34 | done <<< "$ascii_art" 35 | log "INFO" "" 36 | log "INFO" "" 37 | 38 | # Print deployment process explanation 39 | log "INFO" "We are about to start the deployment process which includes the following steps:" 40 | log "INFO" "1. Check if the kind Kubernetes cluster exists or create a new one." 41 | log "INFO" "2. Deploy Calico for network policies." 42 | log "INFO" "3. Wait for all Kubernetes nodes to be ready." 43 | log "INFO" "4. Deploy the NGINX Ingress Controller." 44 | log "INFO" "5. Wait for the NGINX Ingress Controller pods to be ready." 45 | log "INFO" "6. Update the hosts file for local deployment." 46 | log "INFO" "7. Update the CoreDNS hosts." 47 | log "INFO" "8. Deploy the Kubert AI Assistant Lite application." 48 | 49 | # Prompt user to press any button to continue 50 | read -n 1 -s -r -p $'\nPress any key to continue...\n' 51 | -------------------------------------------------------------------------------- /scripts/validate-tools.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | # Script Name: validate-tools.sh 5 | # Description: This script checks if the necessary tools (kind, kubectl, helm, jq) 6 | # are installed on the system. If any tool is missing, it provides 7 | # instructions for installing the missing tool. 8 | # 9 | # Usage: ./validate-tools.sh 10 | # 11 | # Copyright © 2024 Kubert 12 | # ----------------------------------------------------------------------------- 13 | 14 | # Bash safeties: exit on error, no unset variables, pipelines can't hide errors 15 | set -o errexit 16 | set -o nounset 17 | set -o pipefail 18 | 19 | # Source the utils.sh script to use its functions 20 | 21 | BASE_DIR="$(dirname "$0")" 22 | 23 | # shellcheck disable=SC1091 24 | source "$BASE_DIR/utils.sh" 25 | 26 | # Tools and their installation instructions 27 | 28 | # shellcheck disable=SC2034 29 | TOOLS=("kind" "kubectl" "helm" "jq") 30 | # shellcheck disable=SC2034 31 | INSTRUCTIONS=( 32 | "Visit https://kind.sigs.k8s.io/docs/user/quick-start/#installation to install kind." 33 | "Visit https://kubernetes.io/docs/tasks/tools/ to install kubectl." 34 | "Visit https://helm.sh/docs/intro/install/ to install Helm." 35 | "Install jq by running: sudo apt-get install jq (Debian/Ubuntu) or brew install jq (macOS)." 36 | ) 37 | 38 | # Validate the required tools 39 | log "INFO" "Validating required tools..." 40 | check_command TOOLS INSTRUCTIONS 41 | log "INFO" "All required tools are installed. You are ready to proceed!" -------------------------------------------------------------------------------- /scripts/variables.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | # Script Name: variables.sh 5 | # Description: This file contains all the variables used in the deployment script. 6 | # 7 | # Copyright © 2024 Kubert 8 | # ----------------------------------------------------------------------------- 9 | 10 | #shellcheck disable=SC2034 11 | 12 | # kind cluaster vars 13 | KIND_CLUSTER_NAME="kubert-cluster" 14 | KIND_CONFIG="kind-config.yaml" 15 | 16 | # Manifests 17 | NGINX_INGRESS_CONTROLLER_YAML="manifests/nginx-ingress-controller/deploy.yaml" 18 | CALICO_YAML="manifests/calico/deploy.yaml" 19 | KUBERT_COMPONENTS=( 20 | "command-runner:manifests/kubert-assistant/command-runner-values.yaml" 21 | "agent-repo:manifests/kubert-assistant/agent-repo-values.yaml" 22 | "plugin-repo:manifests/kubert-assistant/plugin-repo-values.yaml" 23 | "gateway:manifests/kubert-assistant/gateway-values.yaml" 24 | "lobechat:manifests/kubert-assistant/lobe-chat-values.yaml" 25 | ) 26 | 27 | # Helm vars 28 | HELM_NAMESPACE="kubert-assistant" 29 | CHART_PATH="manifests/chart" 30 | 31 | # Hosts entries for the applications 32 | HOSTS_ENTRIES=( 33 | "kubert-assistant.lan" 34 | "kubert-agent.lan" 35 | "kubert-plugin.lan" 36 | "kubert-plugin-gateway.lan" 37 | "kubert-ollama.lan" 38 | ) -------------------------------------------------------------------------------- /tests/integration/kind-config.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | networking: 4 | # Only IPv4 5 | ipFamily: ipv4 6 | # 512 IP's for pods 7 | podSubnet: "10.10.0.0/23" 8 | # 256 IP's for services 9 | serviceSubnet: "10.20.0.0/24" 10 | nodes: 11 | - role: control-plane 12 | # Node label used by Ingress controller nodeSelector 13 | kubeadmConfigPatches: 14 | - | 15 | kind: InitConfiguration 16 | nodeRegistration: 17 | kubeletExtraArgs: 18 | node-labels: "ingress-ready=true" 19 | extraPortMappings: 20 | - containerPort: 80 21 | hostPort: 80 22 | protocol: TCP 23 | -------------------------------------------------------------------------------- /tests/integration/test_create_kind_cluster.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | source "$BASE_DIR/../../scripts/variables.sh" 11 | 12 | # Define a temporary log file for testing 13 | TEMP_LOG_FILE=$(mktemp) 14 | export LOG_FILE="$TEMP_LOG_FILE" 15 | 16 | echo "# Setting up integration test for create_kind_cluster..." >&3 17 | } 18 | 19 | teardown() { 20 | # Clean up the temporary log file after tests 21 | rm -f "$TEMP_LOG_FILE" 22 | 23 | # Clean up the kind cluster 24 | echo "# Cleaning up by deleting the kind cluster..." >&3 25 | kind delete cluster --name "$KIND_CLUSTER_NAME" >&3 || true 26 | echo "# Cleanup step completed." >&3 27 | 28 | echo "# Integration test for create_kind_cluster completed." >&3 29 | } 30 | 31 | @test "create_kind_cluster should create a kind cluster" { 32 | # Step 1: Run the function to create a kind cluster 33 | echo "# Running create_kind_cluster function..." >&3 34 | run create_kind_cluster "$KIND_CLUSTER_NAME" "tests/integration/kind-config.yaml" 35 | assert_success "create_kind_cluster function should succeed" 36 | echo "# kind cluster creation step completed." >&3 37 | 38 | # Wait for the nodes to be ready 39 | wait_for_nodes 40 | 41 | # Step 2: Check that the kind cluster was created 42 | echo "# Checking if the kind cluster was created..." >&3 43 | run kind get clusters 44 | assert_output --partial "$KIND_CLUSTER_NAME" "kind cluster should be listed" 45 | echo "# kind cluster verification step completed." >&3 46 | 47 | # Check nodes 48 | echo "# Checking if nodes are present..." >&3 49 | run kubectl get nodes 50 | assert_success "Nodes should be present in the cluster" 51 | echo "# Nodes verification completed." >&3 52 | 53 | # Check namespaces 54 | run kubectl create namespace testing 55 | echo "# Checking if the namespace is created..." >&3 56 | run kubectl get namespace testing 57 | assert_success "Namespace should be present" 58 | echo "# Namespace verification completed." >&3 59 | } 60 | -------------------------------------------------------------------------------- /tests/integration/test_deploy_application.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | source "$BASE_DIR/../../scripts/variables.sh" 11 | 12 | # Define a temporary log file for testing 13 | TEMP_LOG_FILE=$(mktemp) 14 | export LOG_FILE="$TEMP_LOG_FILE" 15 | 16 | echo "# Setting up integration test for deploy_application..." >&3 17 | 18 | # Create a kind cluster for the test 19 | create_kind_cluster "$KIND_CLUSTER_NAME" "tests/integration/kind-config.yaml" 20 | 21 | # Wait for the nodes to be ready 22 | wait_for_nodes 23 | } 24 | 25 | teardown() { 26 | # Clean up the temporary log file after tests 27 | rm -f "$TEMP_LOG_FILE" 28 | 29 | # Clean up the kind cluster 30 | echo "# Cleaning up by deleting the kind cluster..." >&3 31 | kind delete cluster --name "$KIND_CLUSTER_NAME" >&3 || true 32 | echo "# Cleanup step completed." >&3 33 | 34 | echo "# Integration test for deploy_application completed." >&3 35 | } 36 | 37 | @test "update_coredns_config should update CoreDNS ConfigMap with host IP and local domains" { 38 | # Ensure get_host_ip returns a valid IP address 39 | host_ip=$(get_host_ip) 40 | [ -n "$host_ip" ] 41 | 42 | kubectl_output=$(kubectl get configmap coredns -n kube-system -o jsonpath='{.data.Corefile}') 43 | echo "kubectl coredns configmap output (before update): $kubectl_output" >&3 44 | 45 | # Run the update_coredns_config function 46 | run update_coredns_config "${HOSTS_ENTRIES[@]}" 47 | assert_success 48 | run tail -n 3 "$LOG_FILE" 49 | assert_output --partial "[INFO]: CoreDNS ConfigMap updated successfully." 50 | assert_output --partial "[INFO]: Restarting CoreDNS pods..." 51 | assert_output --partial "[INFO]: CoreDNS pods restarted successfully." 52 | 53 | kubectl_output=$(kubectl get configmap coredns -n kube-system -o jsonpath='{.data.Corefile}') 54 | echo "kubectl coredns configmap output (after update): $kubectl_output" >&3 55 | 56 | for domain in "${HOSTS_ENTRIES[@]}"; do 57 | echo "$output" >&3 58 | run grep -q "$host_ip $domain" <<< "$kubectl_output" 59 | assert_success "CoreDNS ConfigMap should contain the entry for $domain" 60 | done 61 | } 62 | 63 | @test "deploy_application should deploy the echo server" { 64 | local repo_name="ealenn" 65 | local repo_url="https://ealenn.github.io/charts" 66 | local release_name="echo-server" 67 | local chart_name="ealenn/echo-server" 68 | local namespace="echo-server-ns" 69 | 70 | # Deploy the echo server using Helm 71 | echo "# Deploying the echo server application..." >&3 72 | run deploy_application "$repo_name" "$repo_url" "$release_name" "$chart_name" "$namespace" 73 | assert_success "deploy_application function should succeed" 74 | echo "# Echo server application deployment step completed." >&3 75 | 76 | # Verify that the namespace is created 77 | echo "# Checking if the namespace is created..." >&3 78 | run kubectl get namespace "$namespace" 79 | assert_success "Namespace should be present" 80 | echo "# Namespace verification completed." >&3 81 | 82 | # Verify that the echo server pod is running 83 | echo "# Checking if echo server pod is running in the namespace..." >&3 84 | run kubectl get pods --namespace "$namespace" 85 | assert_success "Echo server pod should be running in the namespace" 86 | echo "# Echo server pod verification completed." >&3 87 | 88 | # Verify the echo server service 89 | echo "# Checking if echo server service is running in the namespace..." >&3 90 | run kubectl get svc --namespace "$namespace" 91 | assert_success "Echo server service should be running in the namespace" 92 | echo "# Echo server service verification completed." >&3 93 | 94 | # Clean up the echo server deployment 95 | echo "# Cleaning up the echo server deployment..." >&3 96 | run helm uninstall "$release_name" --namespace "$namespace" 97 | assert_success "Echo server uninstallation should succeed" 98 | echo "# Echo server deployment cleanup step completed." >&3 99 | } -------------------------------------------------------------------------------- /tests/support/Dockerfile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------- 2 | # Dockerfile for Building kcov with Additional Tools 3 | # 4 | # Description: 5 | # This Dockerfile builds a Docker image based on the latest kcov image and 6 | # installs additional tools such as jq and curl. This image is used to run 7 | # tests and generate coverage reports for shell scripts. 8 | # 9 | # Usage: 10 | # docker build -t my_kcov . 11 | # 12 | # Base Image: 13 | # kcov/kcov:latest 14 | # 15 | # Maintainer: 16 | # Kubert 17 | # ----------------------------------------------------------------------------- 18 | 19 | # Use the latest kcov image as the base image 20 | FROM kcov/kcov:latest 21 | 22 | # Install additional tools (jq and curl) 23 | # Using && and a single RUN layer to minimize the number of layers 24 | RUN apt-get update && \ 25 | apt-get install -y jq curl && \ 26 | rm -rf /var/lib/apt/lists/* 27 | -------------------------------------------------------------------------------- /tests/unit/test_cluster.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | 11 | # Define a temporary log file for testing 12 | TEMP_LOG_FILE=$(mktemp) 13 | export LOG_FILE="$TEMP_LOG_FILE" 14 | 15 | # Create a temporary directory for mocks 16 | MOCK_DIR=$(mktemp -d) 17 | export PATH="$MOCK_DIR:$PATH" 18 | 19 | # Create mock commands 20 | echo -e "#!/usr/bin/env bash\necho 'kind create cluster --name \$1 --config \$2'" > "$MOCK_DIR/kind" 21 | chmod +x "$MOCK_DIR/kind" 22 | echo -e "#!/usr/bin/env bash\nif [ \$1 = 'repo' ]; then echo 'helm repo \$2 \$3'; elif [ \$1 = 'install' ]; then echo 'helm install \$2 \$3'; fi" > "$MOCK_DIR/helm" 23 | chmod +x "$MOCK_DIR/helm" 24 | } 25 | 26 | teardown() { 27 | # Clean up the temporary log file and mock directory after tests 28 | rm -f "$TEMP_LOG_FILE" 29 | rm -rf "$MOCK_DIR" 30 | } 31 | 32 | # Mock kind and helm commands for create_kind_cluster and deploy_application tests 33 | setup_mock_kind() { 34 | echo -e "#!/usr/bin/env bash\necho 'kind create cluster --name $1 --config $2'" > "$MOCK_DIR/kind" 35 | chmod +x "$MOCK_DIR/kind" 36 | } 37 | 38 | setup_mock_helm() { 39 | echo -e "#!/usr/bin/env bash\nif [ \$1 = 'repo' ]; then echo 'helm repo $2 $3'; elif [ \$1 = 'install' ]; then echo 'helm install $2 $3'; fi" > "$MOCK_DIR/helm" 40 | chmod +x "$MOCK_DIR/helm" 41 | } 42 | 43 | @test "create_kind_cluster should log and call kind command" { 44 | setup_mock_kind "test-cluster" "test-config.yaml" 45 | run create_kind_cluster "test-cluster" "test-config.yaml" 46 | assert_success 47 | run tail -n 2 "$TEMP_LOG_FILE" 48 | assert_output --partial "[INFO]: Creating kind cluster named test-cluster..." 49 | assert_output --partial "[INFO]: kind cluster test-cluster created successfully." 50 | } 51 | 52 | @test "deploy_application should log and call helm commands" { 53 | setup_mock_helm "repo" "add" "https://example.com/helm-charts" 54 | run deploy_application "test-repo" "https://example.com/helm-charts" "test-release" "test-chart" "test-assistant" 55 | assert_success 56 | run tail -n 4 "$TEMP_LOG_FILE" 57 | assert_output --partial "[INFO]: Deploying Kubert AI Assistant Lite application using Helm..." 58 | assert_output --partial "[INFO]: Kubert AI Assistant Lite application deployed successfully." 59 | } 60 | 61 | # Mock for kubectl 62 | setup_mock_kubectl() { 63 | # Mock kubectl get configmap command 64 | echo -e "#!/usr/bin/env bash\n\ 65 | if [[ \$* == *'get configmap coredns -n kube-system -o jsonpath={.data.Corefile}'* ]]; then\n\ 66 | echo '.:53 {\nerrors\nhealth { lameduck 5s }\nready\nkubernetes cluster.local in-addr.arpa ip6.arpa {\npods insecure\nfallthrough in-addr.arpa ip6.arpa\nttl 30\n}\nprometheus :9153\nforward . /etc/resolv.conf { max_concurrent 1000 }\ncache 30\nloop\nreload\nloadbalance\n}'\n\ 67 | fi" > "$MOCK_DIR/kubectl_get" 68 | 69 | # Mock kubectl patch configmap command 70 | echo -e "#!/usr/bin/env bash\n\ 71 | if [[ \$* == *'patch configmap coredns -n kube-system --type merge -p'* ]]; then\n\ 72 | echo 'configmap/coredns patched'\n\ 73 | fi" > "$MOCK_DIR/kubectl_patch" 74 | 75 | # Mock kubectl rollout restart deployment command 76 | echo -e "#!/usr/bin/env bash\n\ 77 | if [[ \$* == *'rollout restart deployment coredns -n kube-system'* ]]; then\n\ 78 | echo 'deployment.apps/coredns restarted'\n\ 79 | fi" > "$MOCK_DIR/kubectl_restart" 80 | 81 | chmod +x "$MOCK_DIR/kubectl_get" 82 | chmod +x "$MOCK_DIR/kubectl_patch" 83 | chmod +x "$MOCK_DIR/kubectl_restart" 84 | 85 | # Create a wrapper script to call the appropriate mock based on arguments 86 | echo -e "#!/usr/bin/env bash\n\ 87 | if [[ \$* == *'get configmap coredns -n kube-system -o jsonpath={.data.Corefile}'* ]]; then\n\ 88 | $MOCK_DIR/kubectl_get \"\$@\"\n\ 89 | elif [[ \$* == *'patch configmap coredns -n kube-system --type merge -p'* ]]; then\n\ 90 | $MOCK_DIR/kubectl_patch \"\$@\"\n\ 91 | elif [[ \$* == *'rollout restart deployment coredns -n kube-system'* ]]; then\n\ 92 | $MOCK_DIR/kubectl_restart \"\$@\"\n\ 93 | else\n\ 94 | echo \"Unexpected kubectl command: \$*\" >&2\n\ 95 | exit 1\n\ 96 | fi" > "$MOCK_DIR/kubectl" 97 | 98 | chmod +x "$MOCK_DIR/kubectl" 99 | } 100 | 101 | @test "update_coredns_config should update CoreDNS ConfigMap with host IP and local domains" { 102 | setup_mock_kubectl 103 | 104 | # Mock get_host_ip to return a fixed IP address 105 | echo -e "#!/usr/bin/env bash\nget_host_ip() {\n echo '192.168.0.1'\n}" > "$MOCK_DIR/get_host_ip" 106 | chmod +x "$MOCK_DIR/get_host_ip" 107 | source "$MOCK_DIR/get_host_ip" 108 | 109 | local_domains=("kubert-assistant.lan" "kubert-agent.lan" "kubert-plugin.lan" "kubert-plugin-gateway.lan") 110 | run update_coredns_config "${local_domains[@]}" 111 | assert_success 112 | run tail -n 2 "$TEMP_LOG_FILE" 113 | assert_output --partial "[INFO]: Restarting CoreDNS pods..." 114 | assert_output --partial "[INFO]: CoreDNS pods restarted successfully." 115 | } -------------------------------------------------------------------------------- /tests/unit/test_command.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | 11 | # Define a temporary log file for testing 12 | TEMP_LOG_FILE=$(mktemp) 13 | export LOG_FILE="$TEMP_LOG_FILE" 14 | } 15 | 16 | teardown() { 17 | # Clean up the temporary log file 18 | rm -f "$TEMP_LOG_FILE" 19 | } 20 | 21 | TOOLS=("ls" "echo") 22 | INSTRUCTIONS=("Command ls should be installed." "Command echo should be installed.") 23 | 24 | @test "check_command should succeed for existing commands" { 25 | run check_command TOOLS INSTRUCTIONS 26 | assert_success 27 | } 28 | 29 | @test "check_command should fail for non-existing commands" { 30 | NON_EXISTING_TOOLS=("nonexistingcommand") 31 | NON_EXISTING_INSTRUCTIONS=("Non-existing command should be installed.") 32 | 33 | run check_command NON_EXISTING_TOOLS NON_EXISTING_INSTRUCTIONS 34 | assert_failure 35 | run tail -n 1 "$TEMP_LOG_FILE" 36 | assert_output --partial "[ERROR]: nonexistingcommand is not installed." 37 | } 38 | 39 | @test "check_command should succeed for existing commands without instructions" { 40 | run check_command TOOLS 41 | assert_success 42 | } 43 | 44 | @test "check_command should fail for non-existing commands without instructions" { 45 | NON_EXISTING_TOOLS=("nonexistingcommand") 46 | 47 | run check_command NON_EXISTING_TOOLS 48 | assert_failure 49 | run tail -n 1 "$TEMP_LOG_FILE" 50 | assert_output --partial "[ERROR]: nonexistingcommand is not installed." 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/test_hosts_file.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | 11 | # Define a temporary log file for testing 12 | TEMP_LOG_FILE=$(mktemp) 13 | export LOG_FILE="$TEMP_LOG_FILE" 14 | 15 | # Create a temporary directory for mocks 16 | MOCK_DIR=$(mktemp -d) 17 | export PATH="$MOCK_DIR:$PATH" 18 | 19 | # Create a mock /etc/hosts file 20 | MOCK_HOSTS_FILE=$(mktemp) 21 | export HOSTS_FILE_PATH="$MOCK_HOSTS_FILE" 22 | 23 | # Create a mock sudo command 24 | echo -e "#!/usr/bin/env bash\n\$@" > "$MOCK_DIR/sudo" 25 | chmod +x "$MOCK_DIR/sudo" 26 | 27 | # Mock get_host_ip to return a fixed IP address 28 | echo -e "#!/usr/bin/env bash\nget_host_ip() {\n echo '192.168.0.1'\n}" > "$MOCK_DIR/get_host_ip" 29 | chmod +x "$MOCK_DIR/get_host_ip" 30 | source "$MOCK_DIR/get_host_ip" 31 | 32 | # Detect the platform 33 | PLATFORM=$(uname -s) 34 | if grep -qi microsoft /proc/version &> /dev/null; then 35 | PLATFORM="WSL" 36 | fi 37 | 38 | # Platform-specific mocks 39 | case "$PLATFORM" in 40 | "Darwin") 41 | # Mock macOS specific commands to prevent actual execution 42 | echo -e "#!/usr/bin/env bash\necho 'Flushed DNS cache'" > "$MOCK_DIR/dscacheutil" 43 | echo -e "#!/usr/bin/env bash\necho 'No matching processes belonging to you were found'" > "$MOCK_DIR/killall" 44 | chmod +x "$MOCK_DIR/dscacheutil" "$MOCK_DIR/killall" 45 | ;; 46 | "Linux"|"WSL") 47 | # Mock Linux/WSL specific commands 48 | if [[ "$PLATFORM" == "WSL" ]]; then 49 | echo -e "#!/usr/bin/env bash\necho 'Windows hosts file updated'" > "$MOCK_DIR/powershell.exe" 50 | chmod +x "$MOCK_DIR/powershell.exe" 51 | else 52 | echo -e "#!/usr/bin/env bash\necho 'Flushed DNS cache using resolvectl'" > "$MOCK_DIR/resolvectl" 53 | chmod +x "$MOCK_DIR/resolvectl" 54 | fi 55 | ;; 56 | *) 57 | echo "Unsupported platform: $PLATFORM" 58 | exit 1 59 | ;; 60 | esac 61 | } 62 | 63 | teardown() { 64 | # Clean up the temporary log file and mock directory after tests 65 | rm -f "$TEMP_LOG_FILE" 66 | rm -rf "$MOCK_DIR" 67 | rm -f "$MOCK_HOSTS_FILE" 68 | } 69 | 70 | @test "update_hosts_file should add new entries to the hosts file" { 71 | export NON_INTERACTIVE=true 72 | update_hosts_file "test-cluster" "kubert-assistant.lan" "kubert-agent.lan" 73 | run cat "$MOCK_HOSTS_FILE" 74 | assert_output --partial "192.168.0.1 kubert-assistant.lan" 75 | assert_output --partial "192.168.0.1 kubert-agent.lan" 76 | run tail -n 4 "$TEMP_LOG_FILE" 77 | assert_output --partial "[INFO]: Added 192.168.0.1 kubert-assistant.lan to $MOCK_HOSTS_FILE" 78 | assert_output --partial "[INFO]: Added 192.168.0.1 kubert-agent.lan to $MOCK_HOSTS_FILE" 79 | } 80 | 81 | @test "update_hosts_file should not duplicate existing entries" { 82 | echo "192.168.0.1 kubert-assistant.lan" >> "$MOCK_HOSTS_FILE" 83 | export NON_INTERACTIVE=true 84 | update_hosts_file "test-cluster" "kubert-assistant.lan" "kubert-agent.lan" 85 | run grep -c "192.168.0.1 kubert-assistant.lan" "$MOCK_HOSTS_FILE" 86 | assert_output "1" 87 | run cat "$MOCK_HOSTS_FILE" 88 | assert_output --partial "192.168.0.1 kubert-assistant.lan" 89 | assert_output --partial "192.168.0.1 kubert-agent.lan" 90 | run tail -n 4 "$TEMP_LOG_FILE" 91 | assert_output --partial "[INFO]: 192.168.0.1 kubert-assistant.lan already exists in $MOCK_HOSTS_FILE" 92 | assert_output --partial "[INFO]: Added 192.168.0.1 kubert-agent.lan to $MOCK_HOSTS_FILE" 93 | } 94 | 95 | @test "update_hosts_file should log an error if unable to update the hosts file" { 96 | export NON_INTERACTIVE=true 97 | # Override the function to simulate failure 98 | update_hosts_file() { 99 | log "ERROR" "Failed to update the hosts file." 100 | return 1 101 | } 102 | run update_hosts_file "test-cluster" "kubert-assistant.lan" 103 | assert_failure 104 | run tail -n 1 "$TEMP_LOG_FILE" 105 | assert_output --partial "[ERROR]: Failed to update the hosts file." 106 | } 107 | 108 | # Test for user response "yes" 109 | @test "update_hosts_file should proceed when user responds 'yes'" { 110 | (echo yes) | update_hosts_file "test-cluster" "kubert-assistant.lan" 111 | run cat "$MOCK_HOSTS_FILE" 112 | assert_output --partial "192.168.0.1 kubert-assistant.lan" 113 | run tail -n 2 "$TEMP_LOG_FILE" 114 | assert_output --partial "[INFO]: Added 192.168.0.1 kubert-assistant.lan to $MOCK_HOSTS_FILE" 115 | } 116 | 117 | # Test for user response "no" 118 | @test "update_hosts_file should not proceed when user responds 'no'" { 119 | (echo no) | update_hosts_file "test-cluster" "kubert-assistant.lan" 120 | run cat "$MOCK_HOSTS_FILE" 121 | refute_output --partial "192.168.0.1 kubert-assistant.lan" 122 | run tail -n 1 "$TEMP_LOG_FILE" 123 | assert_output --partial "[INFO]: Aborted updating the hosts file." 124 | } 125 | 126 | @test "clean_up_hosts_file should remove entries from the hosts file" { 127 | echo "192.168.0.1 kubert-assistant.lan" >> "$MOCK_HOSTS_FILE" 128 | echo "192.168.0.1 kubert-agent.lan" >> "$MOCK_HOSTS_FILE" 129 | entries_to_remove=("kubert-assistant.lan" "kubert-agent.lan") 130 | clean_up_hosts_file "${entries_to_remove[@]}" 131 | run cat "$MOCK_HOSTS_FILE" 132 | refute_output --partial "192.168.0.1 kubert-assistant.lan" 133 | refute_output --partial "192.168.0.1 kubert-agent.lan" 134 | run tail -n 4 "$TEMP_LOG_FILE" 135 | assert_output --partial "[INFO]: Removed 192.168.0.1 kubert-assistant.lan from $MOCK_HOSTS_FILE" 136 | assert_output --partial "[INFO]: Removed 192.168.0.1 kubert-agent.lan from $MOCK_HOSTS_FILE" 137 | } 138 | -------------------------------------------------------------------------------- /tests/unit/test_logs.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load '../test_helper/bats-support/load' 4 | load '../test_helper/bats-assert/load' 5 | 6 | setup() { 7 | # Ensure relative paths are resolved correctly. 8 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 9 | source "$BASE_DIR/../../scripts/utils.sh" 10 | 11 | # Define a temporary log file for testing 12 | TEMP_LOG_FILE=$(mktemp) 13 | export LOG_FILE="$TEMP_LOG_FILE" 14 | } 15 | 16 | teardown() { 17 | # Clean up the temporary log file 18 | rm -f "$TEMP_LOG_FILE" 19 | } 20 | 21 | # Function to verify the date format in log messages 22 | verify_date_format() { 23 | local log_entry=$1 24 | if [[ $log_entry =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2} ]]; then 25 | return 0 26 | else 27 | echo "Log entry does not contain valid date format: $log_entry" 28 | return 1 29 | fi 30 | } 31 | 32 | @test "log should output with default INFO level" { 33 | log "Test message" 34 | run tail -n 1 "$TEMP_LOG_FILE" 35 | assert_output --partial "[INFO]: Test message" 36 | } 37 | 38 | @test "log should output ERROR level" { 39 | log "ERROR" "Error message" 40 | run tail -n 1 "$TEMP_LOG_FILE" 41 | assert_output --partial "[ERROR]: Error message" 42 | } 43 | 44 | @test "log should output WARN level" { 45 | log "WARN" "Warning message" 46 | run tail -n 1 "$TEMP_LOG_FILE" 47 | assert_output --partial "[WARN]: Warning message" 48 | } 49 | 50 | @test "log should output DEBUG level" { 51 | log "DEBUG" "Debug message" 52 | run tail -n 1 "$TEMP_LOG_FILE" 53 | assert_output --partial "[DEBUG]: Debug message" 54 | } 55 | 56 | @test "log should output INFO level with valid date format" { 57 | log "Test message" 58 | run tail -n 1 "$TEMP_LOG_FILE" 59 | assert_output --partial "[INFO]: Test message" 60 | verify_date_format "$output" 61 | } 62 | 63 | @test "error_exit should log an error message and exit" { 64 | run error_exit "Sample error" 65 | assert_failure 66 | run tail -n 1 "$TEMP_LOG_FILE" 67 | assert_output --partial "[ERROR]: Sample error" 68 | } 69 | 70 | @test "log should omit timestamp in test mode" { 71 | export LOG_TEST_MODE=true 72 | log "Test mode message" 73 | run tail -n 1 "$TEMP_LOG_FILE" 74 | assert_output --partial "[INFO]: Test mode message" 75 | [[ ! "$output" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2} ]] 76 | unset LOG_TEST_MODE 77 | } 78 | 79 | @test "log should create log file if it does not exist" { 80 | NEW_TEMP_LOG_FILE=$(mktemp) 81 | rm -f "$NEW_TEMP_LOG_FILE" 82 | export LOG_FILE="$NEW_TEMP_LOG_FILE" 83 | 84 | log "INFO" "Creating a new log file" 85 | [ -f "$NEW_TEMP_LOG_FILE" ] 86 | run tail -n 1 "$NEW_TEMP_LOG_FILE" 87 | assert_output --partial "[INFO]: Creating a new log file" 88 | verify_date_format "$output" 89 | rm -f "$NEW_TEMP_LOG_FILE" 90 | } 91 | 92 | # Test for log_to_terminal enabled 93 | @test "log should print to terminal when log_to_terminal is enabled" { 94 | export LOG_TO_TERMINAL=true 95 | log "INFO" "Message to terminal" 96 | run tail -n 1 "$TEMP_LOG_FILE" 97 | assert_output --partial "[INFO]: Message to terminal" 98 | 99 | run echo "Message to terminal" # Check terminal output 100 | assert_output --partial "Message to terminal" 101 | } 102 | 103 | # Tests for color output 104 | @test "log should output colored INFO level" { 105 | export LOG_TO_TERMINAL=true 106 | run log "INFO" "Colored info message" 107 | assert_output --partial $'\033[0;32m' 108 | assert_output --partial "Colored info message" 109 | unset LOG_TO_TERMINAL 110 | } 111 | 112 | @test "log should output colored ERROR level" { 113 | export LOG_TO_TERMINAL=true 114 | run log "ERROR" "Colored error message" 115 | assert_output --partial $'\033[0;31m' 116 | assert_output --partial "Colored error message" 117 | unset LOG_TO_TERMINAL 118 | } 119 | 120 | @test "log should output colored WARN level" { 121 | export LOG_TO_TERMINAL=true 122 | run log "WARN" "Colored warning message" 123 | assert_output --partial $'\033[0;33m' 124 | assert_output --partial "Colored warning message" 125 | unset LOG_TO_TERMINAL 126 | } 127 | 128 | @test "log should output colored DEBUG level" { 129 | export LOG_TO_TERMINAL=true 130 | run log "DEBUG" "Colored debug message" 131 | assert_output --partial $'\033[0;34m' 132 | assert_output --partial "Colored debug message" 133 | unset LOG_TO_TERMINAL 134 | } -------------------------------------------------------------------------------- /tests/unit/test_wait_functions.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | # Load test helpers 4 | load '../test_helper/bats-support/load' 5 | load '../test_helper/bats-assert/load' 6 | 7 | setup() { 8 | # Ensure relative paths are resolved correctly. 9 | BASE_DIR="$(dirname "$BATS_TEST_FILENAME")" 10 | source "$BASE_DIR/../../scripts/utils.sh" 11 | 12 | # Define a temporary log file for testing 13 | TEMP_LOG_FILE=$(mktemp) 14 | export LOG_FILE="$TEMP_LOG_FILE" 15 | 16 | # Create a temporary directory for mocks 17 | MOCK_DIR=$(mktemp -d) 18 | export PATH="$MOCK_DIR:$PATH" 19 | 20 | # Create a temporary file for CURL_OUTPUT 21 | CURL_OUTPUT_FILE=$(mktemp) 22 | export CURL_OUTPUT_FILE 23 | 24 | # Initial mock kubectl to handle different cases 25 | cat << 'EOF' > "$MOCK_DIR/kubectl" 26 | #!/usr/bin/env bash 27 | case "$1 $2" in 28 | "get nodes") 29 | if [ -n "$KUBECTL_OUTPUT" ]; then 30 | echo "$KUBECTL_OUTPUT" 31 | else 32 | echo "Error: KUBECTL_OUTPUT not set" >&3 33 | exit 1 34 | fi 35 | ;; 36 | "get pods") 37 | if [ "$7" = "-o" ] && [ "$8" = "jsonpath={.items[*].status.containerStatuses[*].ready}" ]; then 38 | if [ -n "$KUBECTL_PODS_READY_OUTPUT" ]; then 39 | echo -e "$KUBECTL_PODS_READY_OUTPUT" 40 | else 41 | echo "Error: KUBECTL_PODS_READY_OUTPUT not set" >&3 42 | exit 1 43 | fi 44 | else 45 | if [ -n "$KUBECTL_PODS_OUTPUT" ]; then 46 | echo -e "$KUBECTL_PODS_OUTPUT" 47 | else 48 | echo "Error: KUBECTL_PODS_OUTPUT not set" >&3 49 | exit 1 50 | fi 51 | fi 52 | ;; 53 | "get ingress") 54 | if [ "$5" = "--no-headers" ] && [ "$7" = "custom-columns=:metadata.name" ]; then 55 | if [ -n "$KUBECTL_INGRESS_LIST" ]; then 56 | echo -e "$KUBECTL_INGRESS_LIST" 57 | else 58 | echo "Error: KUBECTL_INGRESS_LIST not set" >&3 59 | exit 1 60 | fi 61 | elif [ "$6" = "-o" ] && [ "$7" = "jsonpath={.status.loadBalancer.ingress[0].hostname}" ]; then 62 | if [ "$5" = "ingress1" ] && [ -n "$KUBECTL_INGRESS1_HOSTNAME" ]; then 63 | echo -e "$KUBECTL_INGRESS1_HOSTNAME" 64 | elif [ "$5" = "ingress2" ] && [ -n "$KUBECTL_INGRESS2_HOSTNAME" ]; then 65 | echo -e "$KUBECTL_INGRESS2_HOSTNAME" 66 | else 67 | echo "" 68 | fi 69 | elif [ "$6" = "-o" ] && [ "$7" = "jsonpath={.status.loadBalancer.ingress[0].ip}" ]; then 70 | if [ "$5" = "ingress1" ] && [ -n "$KUBECTL_INGRESS1_IP" ]; then 71 | echo -e "$KUBECTL_INGRESS1_IP" 72 | elif [ "$5" = "ingress2" ] && [ -n "$KUBECTL_INGRESS2_IP" ]; then 73 | echo -e "$KUBECTL_INGRESS2_IP" 74 | else 75 | echo "" 76 | fi 77 | else 78 | echo "Error: Unsupported kubectl command" >&3 79 | exit 1 80 | fi 81 | ;; 82 | *) 83 | echo "kubectl $@" 84 | ;; 85 | esac 86 | EOF 87 | chmod +x "$MOCK_DIR/kubectl" 88 | 89 | # Mock curl command for testing wait_for_service 90 | cat << 'EOF' > "$MOCK_DIR/curl" 91 | #!/usr/bin/env bash 92 | if [[ "$1" == "--fail" && "$2" == "--silent" && "$3" == "--head" ]]; then 93 | if [[ -s "$CURL_OUTPUT_FILE" ]]; then 94 | cat "$CURL_OUTPUT_FILE" 95 | exit 0 96 | else 97 | exit 1 98 | fi 99 | else 100 | echo "curl $@" 101 | exit 0 102 | fi 103 | EOF 104 | chmod +x "$MOCK_DIR/curl" 105 | } 106 | 107 | teardown() { 108 | # Clean up the temporary log file and mock directory after tests 109 | rm -f "$TEMP_LOG_FILE" 110 | rm -rf "$MOCK_DIR" 111 | rm -f "$CURL_OUTPUT_FILE" 112 | } 113 | 114 | @test "wait_for_nodes should succeed when all nodes are ready" { 115 | export KUBECTL_OUTPUT="node1 Ready\nnode2 Ready" 116 | run wait_for_nodes 1 0.5 117 | assert_success 118 | run tail -n 1 "$TEMP_LOG_FILE" 119 | assert_output --partial "[INFO]: All Kind nodes are ready!" 120 | } 121 | 122 | @test "wait_for_nodes should fail when not all nodes are ready within timeout" { 123 | export KUBECTL_OUTPUT="node1 NotReady\nnode2 NotReady" 124 | run wait_for_nodes 1 0.5 125 | assert_failure 126 | run tail -n 1 "$TEMP_LOG_FILE" 127 | assert_output --partial "[ERROR]: Timeout reached. Kind nodes are not ready after 1 seconds." 128 | } 129 | 130 | @test "wait_for_nginx_ingress should succeed when all pods are ready" { 131 | export KUBECTL_PODS_READY_OUTPUT="true true" 132 | export KUBECTL_PODS_OUTPUT="pod1 Ready\npod2 Ready" 133 | run wait_for_nginx_ingress 1 0.5 134 | assert_success 135 | 136 | run tail -n 1 "$TEMP_LOG_FILE" 137 | assert_output --partial "[INFO]: All Nginx Ingress Controller pods are ready!" 138 | } 139 | 140 | @test "wait_for_nginx_ingress should fail when not all pods are ready within timeout" { 141 | export KUBECTL_PODS_READY_OUTPUT="false false" 142 | export KUBECTL_PODS_OUTPUT="pod1 NotReady\npod2 NotReady" 143 | run wait_for_nginx_ingress 1 0.5 144 | assert_failure 145 | run tail -n 1 "$TEMP_LOG_FILE" 146 | assert_output --partial "[ERROR]: Timeout reached. Nginx Ingress Controller pods are not ready after 1 seconds." 147 | } 148 | 149 | @test "wait_for_ingress_ready should succeed when all ingresses have an address" { 150 | export KUBECTL_INGRESS_LIST="ingress1\ningress2" 151 | export KUBECTL_INGRESS1_HOSTNAME="localhost" 152 | export KUBECTL_INGRESS2_HOSTNAME="localhost" 153 | run wait_for_ingress_ready "default" 1 0.5 154 | assert_success 155 | run tail -n 1 "$TEMP_LOG_FILE" 156 | assert_output --partial "[INFO]: All ingresses in namespace default are ready with an address." 157 | } 158 | 159 | @test "wait_for_ingress_ready should fail when not all ingresses have an address within timeout" { 160 | export KUBECTL_INGRESS_LIST="ingress1\ningress2" 161 | export KUBECTL_INGRESS1_HOSTNAME="" 162 | export KUBECTL_INGRESS1_IP="" 163 | export KUBECTL_INGRESS2_HOSTNAME="localhost" 164 | run wait_for_ingress_ready "default" 1 0.5 165 | tail -n 50 "$TEMP_LOG_FILE" 166 | assert_failure 167 | run tail -n 1 "$TEMP_LOG_FILE" 168 | assert_output --partial "[ERROR]: Timeout reached. Not all ingresses in namespace default have an address." 169 | } 170 | 171 | @test "wait_for_service should succeed when the service is available immediately" { 172 | echo "HTTP/1.1 200 OK" > "$CURL_OUTPUT_FILE" # Simulate immediate availability 173 | 174 | run wait_for_service "http://example.com" 1 0.5 175 | assert_success 176 | 177 | run tail -n 1 "$TEMP_LOG_FILE" 178 | assert_output --partial "[INFO]: Service is available at http://example.com" 179 | } 180 | 181 | @test "wait_for_service should fail when the service is not available within timeout" { 182 | echo -n "" > "$CURL_OUTPUT_FILE" # Simulate unavailability 183 | 184 | run wait_for_service "http://example.com" 3 1 185 | assert_failure 186 | 187 | run tail -n 1 "$TEMP_LOG_FILE" 188 | assert_output --partial "[ERROR]: Service at http://example.com did not become available after" 189 | } 190 | 191 | @test "wait_for_service should succeed when the service becomes available after a delay" { 192 | echo -n "" > "$CURL_OUTPUT_FILE" # Start with no response 193 | 194 | # Set a delay for when the CURL_OUTPUT should be available 195 | ( 196 | sleep 1 # Simulates the service becoming available after 1 second 197 | echo "HTTP/1.1 200 OK" > "$CURL_OUTPUT_FILE" 198 | ) & 199 | 200 | # Ensure we wait for the background process 201 | run wait_for_service "http://example.com" 5 0.5 202 | wait # Wait for all background processes to finish 203 | 204 | assert_success 205 | 206 | run tail -n 1 "$TEMP_LOG_FILE" 207 | assert_output --partial "[INFO]: Service is available at http://example.com" 208 | } --------------------------------------------------------------------------------