Metadata-Version: 2.4
Name: ikctl
Version: 1.0.13
Summary: CLI tool for deploying software to remote and local servers via SSH/SFTP.
Project-URL: Repository, https://github.com/3nueves/ikctl
Author-email: David Moya Lopez <3nueves@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.13
Requires-Dist: envyaml
Requires-Dist: paramiko>=3.0
Requires-Dist: pyaml
Description-Content-Type: text/markdown

# ikctl — Install Kit Control

CLI tool to deploy and execute bash scripts ("kits") on remote servers via SSH/SFTP or on the local machine.

## How it works

A **kit** is a folder containing bash scripts and an `ikctl.yaml` manifest. ikctl uploads the scripts to the remote server via SFTP and executes them over SSH. Everything is driven by a configuration file at `~/.ikctl/config` that defines one or more **contexts** (sets of servers, kits path and secrets).

```
~/.ikctl/config          ← main config: contexts, active context
~/kits/
  ikctl.yaml             ← index of available kits
  config.yaml            ← server groups
  show-date/
    ikctl.yaml           ← kit manifest (uploads + pipeline)
    date.sh              ← the actual script
```

## Requirements

- Python 3.13+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip

## Installation

**From PyPI:**
```bash
pip install ikctl
# or with uv:
uv tool install ikctl
```

**From source:**
```bash
git clone <repo>
cd ikctl
uv sync
uv run ikctl --version
```

## Initial setup

On first run, ikctl creates `~/.ikctl/` and `~/kits/` automatically and prompts for confirmation. To skip the prompt:

```bash
ikctl --list context   # triggers bootstrap if config is missing
```

Or create the config manually:

```yaml
# ~/.ikctl/config
context: remote
contexts:
  remote:
    path_kits: ~/kits
    path_servers: ~/kits
    path_secrets: ~/.passwords/password
    mode: remote
    timeout_connect: 30.0
    timeout_exec: 120.0
  local:
    path_kits: ~/kits
    path_servers: ~/kits
    path_secrets: ~/.passwords/password
    mode: local
```

## Server config

```yaml
# ~/kits/config.yaml
servers:
  - name: web
    user: ubuntu
    hosts: [10.0.0.10, 10.0.0.11]
    port: 22
    pkey: ~/.ssh/id_ed25519
  - name: db
    user: root
    hosts: [10.0.0.20]
    port: 22
    password: $PASSWORD
```

Passwords in YAML can reference environment variables (`$PASSWORD`). Set them before running:

```bash
export PASSWORD="your-password"
```

## Kit structure

```yaml
# ~/kits/show-date/ikctl.yaml
kits:
  uploads:
    - date.sh        # files to upload to the remote server
  pipeline:
    - date.sh        # scripts to execute (in order)
```

Register the kit in the index:

```yaml
# ~/kits/ikctl.yaml
kits:
  - show-date/ikctl.yaml
  - install-docker/ikctl.yaml
```

## Usage

```
ikctl [-h] [-l {kits,servers,context,mode}] [-i INSTALL] [-n NAME]
      [-p [PARAMETER ...]] [-s {sudo}] [-c CONTEXT] [-m {local,remote}]
      [-v] [--dry-run] [--timeout-connect FLOAT] [--timeout-exec FLOAT]
      [--parallel-workers N]
```

### List

```bash
ikctl --list kits       # available kits in the active context
ikctl --list servers    # configured server groups
ikctl --list context    # contexts, active context and paths
ikctl --list mode       # current execution mode
```

### Switch context

```bash
ikctl --context production
```

### Run a kit

```bash
# Remote (default)
ikctl --install show-date --name web

# With parameters passed to the script
ikctl --install deploy --name web -p v1.2.3

# With sudo
ikctl --install install-docker --name web --sudo sudo

# Local machine (no SSH)
ikctl --install show-date --mode local
```

### Preview without executing

`--dry-run` shows exactly what would be uploaded and executed, without opening any SSH connection:

```bash
ikctl --install deploy --name web -p v1.2.3 --sudo sudo --dry-run
```

Output:
```
[DRY RUN] Host: 10.0.0.10
[DRY RUN] UPLOAD: ~/kits/deploy/deploy.sh → .ikctl/deploy/deploy.sh
[DRY RUN] EXEC: echo *** | sudo -S bash deploy.sh v1.2.3
```

### Parallel execution

When a server group has multiple hosts, ikctl runs them concurrently:

```bash
ikctl --install show-date --name web --parallel-workers 4
```

Output includes per-host prefix and a final summary:

```
[10.0.0.10] UPLOAD: ...
[10.0.0.11] UPLOAD: ...
2 hosts OK, 0 hosts FAILED
```

### Timeouts

```bash
# Override SSH connection timeout (default 30s)
ikctl --install show-date --name web --timeout-connect 60

# Override local execution timeout (default 120s)
ikctl --install build --mode local --timeout-exec 300
```

Timeouts can also be set per context in `~/.ikctl/config` (`timeout_connect`, `timeout_exec`). CLI values take precedence over config values.

## SSH authentication

ikctl supports all standard SSH authentication methods:

| Method | Config key |
|--------|-----------|
| Ed25519 / ECDSA / RSA key | `pkey: ~/.ssh/id_ed25519` |
| Password | `password: $PASSWORD` |
| SSH agent | enabled by default |
| Jump host (ProxyCommand) | configured in SSHOptions |

## License

Apache License 2.0 — see [LICENSE](LICENSE) for details.
