6 Commits

4 changed files with 22 additions and 39 deletions

View File

@@ -11,44 +11,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# 1. Checkout source code
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
# 2. Setup Go environment
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.24.5' go-version: '1.24.5'
# 3. Build binary with Version injected
- name: Build binary - name: Build binary
run: | run: |
VERSION=${GITEA_REF_NAME} VERSION=${GITEA_REF_NAME}
echo "Building version $VERSION" echo "Building version $VERSION"
go mod tidy go mod tidy
go build -ldflags "-s -w -X main.Version=$VERSION" -o lab-ca . go build -ldflags "-s -w -X main.Version=$VERSION" -o lab-ca .
# 4. Install the tea CLI
- name: Install tea CLI
run: go install code.gitea.io/tea@latest
# 5. Authenticate tea CLI
- name: Login to Gitea
run: |
tea login add --name ci --url $GITEA_URL --token $GITEA_TOKEN
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_URL: ${{ secrets.GITEA_URL }}
# 6. Create or update release
- name: Create or update release
run: |
tea release create $GITEA_REF_NAME \
--title "$GITEA_REF_NAME" \
--note "Automated release for $GITEA_REF_NAME" || \
echo "Release already exists, skipping create."
# 7. Upload binary to the release
- name: Upload binary
run: tea release upload $GITEA_REF_NAME lab-ca

View File

@@ -1,5 +1,7 @@
# Lab CA # Lab CA
[![Build Status](https://gitea.koszewscy.waw.pl/slawek/lab-ca/actions/workflows/release.yml/badge.svg)](https://gitea.koszewscy.waw.pl/slawek/lab-ca/actions?workflow=release.yml)
This repository contains a simple CLI tool for managing a Certificate Authority (CA). This repository contains a simple CLI tool for managing a Certificate Authority (CA).
It is designed to be easy to use and provides a basic set of CA features: It is designed to be easy to use and provides a basic set of CA features:
@@ -86,7 +88,7 @@ lab-ca list --revoked
Issue a new certificate from the command line: Issue a new certificate from the command line:
```bash ```bash
lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <period>] [--san <SAN> ...] [--overwrite] [--dry-run] [--verbose] lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <period>] [--san <SAN> ...] [--dry-run] [--verbose]
``` ```
- `--name` (required): Name for the certificate and key files (used as subject if `--subject` is omitted) - `--name` (required): Name for the certificate and key files (used as subject if `--subject` is omitted)
@@ -94,7 +96,6 @@ lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <pe
- `--type`: Certificate type: `client`, `server`, `code-signing`, `email` (comma-separated for multiple usages; default: `server`) - `--type`: Certificate type: `client`, `server`, `code-signing`, `email` (comma-separated for multiple usages; default: `server`)
- `--validity`: Validity period (e.g. `2y`, `6m`, `30d`; default: `1y`) - `--validity`: Validity period (e.g. `2y`, `6m`, `30d`; default: `1y`)
- `--san`: Subject Alternative Name (repeatable; e.g. `dns:example.com`, `ip:1.2.3.4`, `email:user@example.com`) - `--san`: Subject Alternative Name (repeatable; e.g. `dns:example.com`, `ip:1.2.3.4`, `email:user@example.com`)
- `--overwrite`: Allow overwriting existing files
- `--dry-run`: Validate and show what would be created, but do not write files - `--dry-run`: Validate and show what would be created, but do not write files
- `--verbose`: Print detailed information - `--verbose`: Print detailed information
@@ -105,7 +106,7 @@ lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <pe
Provision multiple certificates from a batch file (HCL): Provision multiple certificates from a batch file (HCL):
```bash ```bash
lab-ca provision --file <certificates.hcl> [--overwrite] [--verbose] lab-ca provision --file <certificates.hcl> [--verbose]
``` ```
#### Example HCL Provisioning File #### Example HCL Provisioning File
@@ -223,13 +224,9 @@ See `examples/example-certificates.hcl` for a more advanced provisioning file wi
## Building the Tool ## Building the Tool
The repository includes a `build.sh` script to build the CLI tool. It updates the version in `version.go` and builds the binary. The repository includes a `Makefile` to build the CLI tool. It automatically determines the version from Git tags and builds the binary.
To ignore changes made to `version.go` in Git, you can run: To build the tool, run the `make` command. The binary will be created as `build/lab-ca`.
```bash
git update-index --assume-unchanged version.go
```
--- ---

14
ca.go
View File

@@ -460,9 +460,19 @@ func issueSingleCertificate(def CertificateDefinition, i int, n int) (bool, erro
return false, fmt.Errorf("certificate name must be specified and contain only letters, numbers, dash, or underscore") return false, fmt.Errorf("certificate name must be specified and contain only letters, numbers, dash, or underscore")
} }
// Check if the certificate is in database, fail if it is. // Check if the certificate is in database, skip if it already exists and is valid.
if caState.FindByName(def.Name, false) != nil { if caState.FindByName(def.Name, false) != nil {
return false, fmt.Errorf("certificate %s already exists and is valid", def.Name) if !dryRun {
fmt.Printf("skipped (already exists).\n")
} else {
msg := fmt.Sprintf("Certificate '%s' already exists and is valid (would skip).", def.Name)
if n > 1 {
fmt.Printf("[%d/%d] %s\n", i+1, n, msg)
} else {
fmt.Printf("%s\n", msg)
}
}
return false, nil
} }
// Initialize Subject if not specified // Initialize Subject if not specified

View File

@@ -71,10 +71,13 @@ func main() {
os.Exit(1) os.Exit(1)
} }
for _, certDef := range caState.Certificates { for _, certDef := range caState.Certificates {
if certDef.RevokedAt != "" { if certDef.RevokedAt != "" && !listRevoked {
continue continue
} }
fmt.Printf("Certificate %s\n", certDef.Name) fmt.Printf("Certificate %s\n", certDef.Name)
if certDef.RevokedAt != "" {
fmt.Printf("\tStatus: REVOKED (at %s)\n", certDef.RevokedAt)
}
fmt.Printf("\tSubject: %s\n\tType: %s\n\tIssued at: %s\n", fmt.Printf("\tSubject: %s\n\tType: %s\n\tIssued at: %s\n",
certDef.Subject, certDef.Type, certDef.Issued) certDef.Subject, certDef.Type, certDef.Issued)
} }