Files
nadir-agent/internal/modules/system/hostname.go
T
urania 0e041fac5e
build-and-release / release (push) Failing after 2m1s
fix: .minisign for signed releases
2026-06-22 20:03:27 +02:00

67 lines
2.2 KiB
Go

package system
import (
"context"
"regexp"
"strings"
"nadir/internal/oscmd"
"github.com/danielgtaylor/huma/v2"
)
// hostnameRe matches RFC-1123 labels joined by dots, max 253 chars total. Anchored
// so a leading "-" can't be read as a hostnamectl flag and shell metacharacters
// can't survive — same pattern the other modules use (CLAUDE.md §5).
var hostnameRe = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}))*$`)
type HostnameBody struct {
Hostname string `json:"hostname" example:"server01" doc:"System hostname"`
}
type GetHostnameOutput struct{ Body HostnameBody }
type SetHostnameInput struct{ Body HostnameBody }
func registerHostname(api huma.API) {
huma.Register(api, huma.Operation{
OperationID: "system-get-hostname",
Method: "GET",
Path: "/api/system/hostname",
Summary: "Get system hostname",
Description: "Returns the current hostname as reported by hostnamectl.",
Tags: []string{tagSystem},
Metadata: op("read"),
Errors: readErrors,
}, func(ctx context.Context, _ *struct{}) (*GetHostnameOutput, error) {
name, err := oscmd.Run("hostnamectl", "hostname")
if err != nil {
return nil, huma.Error500InternalServerError("hostnamectl failed", err)
}
return &GetHostnameOutput{Body: HostnameBody{Hostname: name}}, nil
})
huma.Register(api, huma.Operation{
OperationID: "system-set-hostname",
Method: "POST",
Path: "/api/system/hostname",
Summary: "Set system hostname",
Description: "Sets the static hostname via hostnamectl, which owns " +
"/etc/hostname and manages the static/pretty/transient names.",
Tags: []string{tagSystem},
Metadata: op("write"),
Errors: writeErrors,
}, func(ctx context.Context, in *SetHostnameInput) (*oscmd.StatusOutput, error) {
name := strings.TrimSpace(in.Body.Hostname)
if name == "" {
return nil, huma.Error400BadRequest("empty hostname")
}
if len(name) > 253 || !hostnameRe.MatchString(name) {
return nil, huma.Error400BadRequest("invalid hostname: " + name)
}
if _, err := oscmd.Run("hostnamectl", "set-hostname", "--", name); err != nil {
return nil, huma.Error500InternalServerError("hostnamectl failed", err)
}
return oscmd.OK(), nil
})
}