67 lines
2.2 KiB
Go
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
|
|
})
|
|
}
|