Skip to content

Commit 3cfee0f

Browse files
committed
add ols cli
1 parent f568cd6 commit 3cfee0f

47 files changed

Lines changed: 8214 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
15+
- name: Setup Go
16+
uses: actions/setup-go@v5
17+
with:
18+
go-version: "1.22"
19+
20+
- name: Download dependencies
21+
run: go mod download
22+
23+
- name: Vet
24+
run: go vet ./...
25+
26+
- name: Test
27+
run: go test ./...

.github/workflows/release.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
goarch: [amd64, arm64]
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Go
25+
uses: actions/setup-go@v5
26+
with:
27+
go-version: "1.22"
28+
29+
- name: Build binary and tar.gz
30+
shell: bash
31+
run: |
32+
set -euo pipefail
33+
mkdir -p dist
34+
GOOS=linux GOARCH=${{ matrix.goarch }} CGO_ENABLED=0 \
35+
go build -trimpath -ldflags "-s -w" -o "dist/ols-linux-${{ matrix.goarch }}" ./cmd/ols
36+
chmod +x "dist/ols-linux-${{ matrix.goarch }}"
37+
cp "dist/ols-linux-${{ matrix.goarch }}" dist/ols
38+
tar -C dist -czf "dist/ols-linux-${{ matrix.goarch }}.tar.gz" ols
39+
rm -f dist/ols
40+
41+
- name: Upload artifact
42+
uses: actions/upload-artifact@v4
43+
with:
44+
name: ols-linux-${{ matrix.goarch }}
45+
path: |
46+
dist/ols-linux-${{ matrix.goarch }}
47+
dist/ols-linux-${{ matrix.goarch }}.tar.gz
48+
if-no-files-found: error
49+
50+
publish:
51+
needs: build
52+
runs-on: ubuntu-latest
53+
if: startsWith(github.ref, 'refs/tags/v')
54+
55+
steps:
56+
- name: Download build artifacts
57+
uses: actions/download-artifact@v4
58+
with:
59+
pattern: ols-linux-*
60+
path: dist
61+
merge-multiple: true
62+
63+
- name: Generate checksums
64+
shell: bash
65+
run: |
66+
set -euo pipefail
67+
cd dist
68+
sha256sum ols-linux-* > checksums.txt
69+
70+
- name: Publish GitHub Release
71+
uses: softprops/action-gh-release@v2
72+
with:
73+
files: |
74+
dist/ols-linux-amd64
75+
dist/ols-linux-amd64.tar.gz
76+
dist/ols-linux-arm64
77+
dist/ols-linux-arm64.tar.gz
78+
dist/checksums.txt
79+
generate_release_notes: true
80+
env:
81+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# OLS CLI
2+
3+
![ols-cli](https://socialify.git.ci/Code-Egg/ols-cli/image?custom_description=A+CLI+tool+for+managing+OpenLiteSpeed+and+WordPress.&description=1&language=1&logo=https%3A%2F%2Fopenlitespeed.org%2Fwp-content%2Fuploads%2F2018%2F05%2Fopenlitespeed-logo-1.png&theme=Dark)
4+
5+
[![CI Status](https://github.com/Code-Egg/ols-cli/workflows/ci/badge.svg)](https://github.com/Code-Egg/ols-cli/actions/)
6+
[![Release Status](https://github.com/Code-Egg/ols-cli/workflows/release/badge.svg)](https://github.com/Code-Egg/ols-cli/actions/workflows/release.yml)
7+
[![Go](https://img.shields.io/badge/Go-1.22+-00ADD8?logo=go&logoColor=white)](https://go.dev/)
8+
[![Release](https://img.shields.io/github/v/release/Code-Egg/ols-cli?display_name=tag)](https://github.com/Code-Egg/ols-cli/releases)
9+
10+
[![Ubuntu](https://img.shields.io/badge/OS-Ubuntu-E95420?logo=ubuntu&logoColor=white)](https://ubuntu.com/)
11+
[![CentOS](https://img.shields.io/badge/OS-CentOS-262577?logo=centos&logoColor=white)](https://www.centos.org/)
12+
[![CPU amd64](https://img.shields.io/badge/CPU-amd64_(x86__64)-5C2D91?logo=amd&logoColor=white)](https://en.wikipedia.org/wiki/X86-64)
13+
[![CPU arm64](https://img.shields.io/badge/CPU-arm64_(aarch64)-0091BD?logo=arm&logoColor=white)](https://en.wikipedia.org/wiki/AArch64)
14+
15+
## Installation
16+
17+
Use the one-line installer to install ols cli binary:
18+
19+
```bash
20+
bash <(curl -fsSL https://raw.githubusercontent.com/Code-Egg/ols-cli/master/install_olscli.sh)
21+
```
22+
23+
### Install runtime once
24+
25+
Install OpenLiteSpeed, PHP, Database.
26+
27+
```bash
28+
sudo ols install
29+
```
30+
31+
## Usage
32+
33+
### Create a wordprss site
34+
35+
```bash
36+
sudo ols site create example.com --wp
37+
```
38+
39+
### Create a site with WordPress + Let's Encrypt
40+
41+
```bash
42+
sudo ols site create example.com --wp --le
43+
```
44+
45+
### Update a site to a target PHP version
46+
47+
```bash
48+
sudo ols site update example.com --php85
49+
```
50+
51+
### Update CLI binary to latest release
52+
53+
```bash
54+
sudo ols update
55+
```
56+
57+
### Security
58+
59+
#### Enable OWASP + reCAPTCHA and add security headers on a site
60+
61+
```bash
62+
sudo ols site update example.com --enable-owasp --enable-recaptcha --hsts
63+
```
64+
65+
#### Enable namespace
66+
67+
```bash
68+
sudo ols site update example.com --enable-ns
69+
```
70+
71+
72+
### Control
73+
74+
#### Show site information
75+
76+
```bash
77+
ols site info example.com
78+
```
79+
80+
#### Show OpenLiteSpeed virtual host config
81+
82+
```bash
83+
ols site show example.com
84+
```
85+
86+
#### List managed sites
87+
88+
```bash
89+
ols site list
90+
```
91+
92+
### Preview mode
93+
94+
```bash
95+
ols --dry-run site create example.com --wp --le --php85 --enable-owasp --hsts --enable-ns
96+
ols --dry-run site update example.com --enable-recaptcha --disable-owasp --disable-ns --le
97+
ols --dry-run site info example.com
98+
ols --dry-run site show example.com
99+
ols --dry-run site list
100+
ols --dry-run update
101+
```
102+
103+
## Command overview
104+
105+
The ols commands:
106+
107+
```bash
108+
ols (command) [options]
109+
```
110+
111+
| Command | Purpose | Options |
112+
| --- | --- | --- |
113+
| `install` | Install/align OpenLiteSpeed runtime and related packages | `--php81` `--php82` `--php83` `--php84` `--php85` `--database` `--config` `--http-port` `--https-port` `--ssl-cert` `--ssl-key` `--no-listeners` |
114+
| `site` | Manage sites (`create`, `update`, `enable`, `disable`, `info`, `show`, `list`, `delete`) | `--wp` `--le` `--php81` `--php82` `--php83` `--php84` `--php85` `--enable-owasp` `--disable-owasp` `--enable-recaptcha` `--disable-recaptcha` `--enable-ns` `--disable-ns` `--hsts` `--keep-db` |
115+
| `update` | Update installed `ols` binary to latest GitHub release for current platform | |
116+
117+
Global options (apply to all commands): `--dry-run`, `--color`
118+
119+
120+
### site
121+
```bash
122+
ols site (command) [options]
123+
```
124+
125+
| Subcommand | Purpose | Options |
126+
| --- | --- | --- |
127+
| `create` | Create a new site/vhost | `--wp` `--le` `--php81` `--php82` `--php83` `--php84` `--php85` `--enable-owasp` `--disable-owasp` `--enable-recaptcha` `--disable-recaptcha` `--enable-ns` `--disable-ns` `--hsts` |
128+
| `update` | Update an existing site (PHP target optional when only WordPress/security/LE flags are used) | optional `--wp`, optional `--le`, optional PHP target: `--php81` `--php82` `--php83` `--php84` `--php85`, or security flags: `--enable-owasp` `--disable-owasp` `--enable-recaptcha` `--disable-recaptcha` `--enable-ns` `--disable-ns` `--hsts` |
129+
| `enable` | Enable site from server-level | |
130+
| `disable` | Disable site from server-level | |
131+
| `info` | Show site metadata and detected status | |
132+
| `show` | Print OLS virtual host config | |
133+
| `list` | List managed sites discovered from OLS vhost directory | |
134+
| `delete` | Remove site config/files and optionally keep DB | `--keep-db` |
135+
136+
137+
## Development
138+
139+
### Build locally
140+
141+
```bash
142+
go build -o ols ./cmd/ols
143+
```
144+
145+
### Run tests
146+
147+
```bash
148+
go test ./...
149+
```
150+
151+
For verbose output:
152+
153+
```bash
154+
go test -v ./...
155+
```
156+
157+
158+
## FAQ
159+
160+
#### Custom the default config file
161+
Use config file defaults (recommended for first-run bootstrap):
162+
163+
```bash
164+
sudo mkdir -p /etc/ols-cli
165+
sudo cp docs/install.example.json /etc/ols-cli/install.json
166+
sudo ols install
167+
```
168+
169+
`install.json` also supports:
170+
- `owasp_crs_version` (for example, `"4.21.0"`) for OWASP CRS setup during `ols install`
171+
- `vh_recaptcha_type` and `vh_recaptcha_reg_conn_limit` (defaults: `1` and `500`) used when enabling vhost reCAPTCHA via `site create/update --enable-recaptcha`
172+
173+
By default, `ols install` prepares server-level security blocks as:
174+
- `module mod_security` with `ls_enabled 0`
175+
- `lsrecaptcha` with `enabled 1` and `type 0`
176+
- `namespace` with `1`
177+
178+
Override config values with flags when needed:
179+
180+
```bash
181+
sudo ols install --config /etc/ols-cli/install.json --php85 --database mysql --http-port 80 --https-port 443
182+
sudo ols install --no-listeners
183+
```

cmd/ols/main.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/ols/ols-cli/internal/cli"
8+
)
9+
10+
func main() {
11+
if err := cli.NewRootCmd().Execute(); err != nil {
12+
fmt.Fprintln(os.Stderr, err.Error())
13+
os.Exit(1)
14+
}
15+
}

docs/ARCHITECTURE.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# OLS CLI Architecture
2+
3+
This document defines the initial architecture for `ols`, a security-focused CLI for OpenLiteSpeed + WordPress lifecycle management.
4+
5+
## Goals
6+
7+
- Linux server support for Ubuntu, Debian, and CentOS-family distributions.
8+
- Predictable, testable automation for:
9+
- `ols site create <domain> --wp [--le]`
10+
- `ols site update <domain> --phpXX`
11+
- Strong error handling with stable error codes.
12+
- Beautiful and readable console output.
13+
- No code copy from WordOps/ols1clk; behavior-inspired design only.
14+
15+
## Language Choice
16+
17+
- Core CLI: Go
18+
- Single static binary deployment
19+
- Strong typing and robust test tooling
20+
- Good fit for privileged server automation
21+
- Installer channels:
22+
- apt (Debian/Ubuntu package)
23+
- npm (binary bootstrap/downloader package)
24+
25+
## High-Level Layout
26+
27+
```text
28+
cmd/ols/main.go # binary entrypoint
29+
internal/cli/ # Cobra command graph
30+
internal/platform/ # OS detection + package manager logic
31+
internal/service/ # business workflows (site create/update)
32+
internal/runner/ # command execution abstraction
33+
internal/ui/ # styled console output
34+
internal/apperr/ # structured application errors
35+
scripts/install.sh # bash bootstrap installer
36+
```
37+
38+
## Security Baseline
39+
40+
- Validate and sanitize all user inputs (domain, php switch flags).
41+
- Explicit command execution through a small runner abstraction.
42+
- Prefer non-shell invocation (`exec.CommandContext`) to avoid shell injection.
43+
- Fail fast with actionable errors and no silent fallback.
44+
- Dry-run support to preview privileged operations.
45+
46+
## Testing Strategy
47+
48+
- Unit tests for:
49+
- domain validation
50+
n - distro detection parser
51+
- php flag selection
52+
- package manager command generation
53+
- Command behavior tests with fake runner (no real package installs).
54+
- CI gate: `go test ./...` must pass before release artifacts.
55+
56+
## Delivery Strategy
57+
58+
- Release pipeline builds Linux binaries for `amd64` and `arm64`.
59+
- `scripts/install.sh` downloads and verifies release binary.
60+
- apt package and npm package act as distribution channels to install the same signed binary.

docs/install.example.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"php_version": "85",
3+
"database": "mariadb",
4+
"configure_listeners": true,
5+
"http_port": 80,
6+
"https_port": 443,
7+
"ssl_cert_file": "/usr/local/lsws/admin/conf/webadmin.crt",
8+
"ssl_key_file": "/usr/local/lsws/admin/conf/webadmin.key",
9+
"owasp_crs_version": "4.21.0",
10+
"vh_recaptcha_type": 1,
11+
"vh_recaptcha_reg_conn_limit": 500
12+
}

0 commit comments

Comments
 (0)