Documentation
¶
Overview ¶
Package api provides HTTP API handlers and server implementation for the krkn-operator. It includes endpoints for authentication, target management, scenario execution, and user management.
Index ¶
- Constants
- Variables
- func GetJWTSecretName() string
- func ValidateValueAgainstSchema(key string, value interface{}, schemaJSON string) error
- type ActiveRunsOverviewResponse
- type AddGroupMemberRequest
- type AddGroupMemberResponse
- type ChangePasswordRequest
- type ChangePasswordResponse
- type ClusterJobStatusResponse
- type ClusterPermissionSet
- type ClustersResponse
- type CreateTargetRequest
- type CreateTargetResponse
- type CreateUserGroupRequest
- type CreateUserGroupResponse
- type CreateUserRequest
- type CreateUserResponse
- type DeleteUserGroupResponse
- type DeleteUserResponse
- type ErrorResponse
- type FileMount
- type GlobalsRequest
- type GlobalsResponse
- type Handler
- func (h *Handler) AddGroupMember(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ChangePassword(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CreateTarget(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CreateUserGroup(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteScenarioRun(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteScenarioRunComplete(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteSingleJob(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteTarget(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteUser(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteUserGroup(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetActiveRunsOverview(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetClusters(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetNodes(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetProviderConfigByUUID(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetScenarioRunLogs(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetScenarioRunStatus(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetSingleJob(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetTarget(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetTargetByUUID(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetUserGroup(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GroupsRouter(w http.ResponseWriter, r *http.Request)
- func (h *Handler) HealthCheck(w http.ResponseWriter, r *http.Request)
- func (h *Handler) IsRegistered(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListGroupMembers(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListProviders(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListScenarioRuns(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListTargets(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListUserGroups(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListUsers(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Login(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostProviderConfig(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostScenarioDetail(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostScenarioGlobals(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostScenarioRun(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostScenarios(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PostTarget(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ProviderConfigHandler(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ProvidersRouter(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Register(w http.ResponseWriter, r *http.Request)
- func (h *Handler) RemoveGroupMember(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ScenariosRunRouter(w http.ResponseWriter, r *http.Request)
- func (h *Handler) TargetsCRUDRouter(w http.ResponseWriter, r *http.Request)
- func (h *Handler) TargetsHandler(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateProviderConfigValues(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateProviderStatus(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateTarget(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateUserGroup(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UsersRouter(w http.ResponseWriter, r *http.Request)
- type InputFieldResponse
- type IsRegisteredResponse
- type JobStatusResponse
- type JobsListResponse
- type ListGroupMembersResponse
- type ListProvidersResponse
- type ListTargetsResponse
- type ListUserGroupsResponse
- type ListUsersResponse
- type LoginRequest
- type LoginResponse
- type NodesResponse
- type ProviderConfigUpdateRequest
- type ProviderConfigUpdateResponse
- type ProviderResponse
- type RegisterRequest
- type RegisterResponse
- type RemoveGroupMemberResponse
- type ScenarioDetailResponse
- type ScenarioRunCreateResponse
- type ScenarioRunListItem
- type ScenarioRunListResponse
- type ScenarioRunRequest
- type ScenarioRunResponse
- type ScenarioRunStatusResponse
- type ScenarioTag
- type ScenariosRequest
- type ScenariosResponse
- type Server
- type TargetJobResult
- type TargetResponse
- type UpdateProviderStatusRequest
- type UpdateProviderStatusResponse
- type UpdateTargetRequest
- type UpdateUserGroupRequest
- type UpdateUserGroupResponse
- type UpdateUserRequest
- type UpdateUserResponse
- type UserGroupResponse
- type UserResponse
Constants ¶
const ( // AdminRoleLabel is the label used to identify admin users AdminRoleLabel = "krkn.krkn-chaos.dev/role" // UserAccountLabel is the label used to identify user account CRDs UserAccountLabel = "krkn.krkn-chaos.dev/user-account" // JWTSecretKey is the key in the JWT secret JWTSecretKey = "jwt-secret" // DefaultJWTSecretName is the default name of the secret containing the JWT signing key // Can be overridden via JWT_SECRET_NAME environment variable DefaultJWTSecretName = "krkn-operator-jwt-secret" // #nosec G101 -- This is a default name, not credentials; actual secret is stored in Kubernetes Secret with random generated value )
const ( // APIVersion is the current API version APIVersion = "v1" // APIBasePath is the base path for all API endpoints APIBasePath = "/api/" + APIVersion )
API version constants When bumping API version, only change APIVersion constant
const ( AuthBasePath = APIBasePath + "/auth" AuthIsRegistered = AuthBasePath + "/is-registered" AuthRegister = AuthBasePath + "/register" AuthLogin = AuthBasePath + "/login" AuthRefresh = AuthBasePath + "/refresh" AuthLogout = AuthBasePath + "/logout" )
Authentication endpoints
const ( HealthPath = APIBasePath + "/health" ClustersPath = APIBasePath + "/clusters" NodesPath = APIBasePath + "/nodes" )
Core resource endpoints
const ( ScenariosPath = APIBasePath + "/scenarios" ScenariosDetailPath = ScenariosPath + "/detail" ScenariosGlobalsPath = ScenariosPath + "/globals" ScenariosRunPath = ScenariosPath + "/run" ScenariosRunJobsPath = ScenariosRunPath + "/jobs" )
Scenarios endpoints
const ( DashboardPath = APIBasePath + "/dashboard" DashboardActiveRunsPath = DashboardPath + "/active-runs" )
Dashboard endpoints
const ( UsersPath = APIBasePath + "/users" GroupsPath = APIBasePath + "/groups" )
User management endpoints
const ( ProvidersPath = APIBasePath + "/providers" ProviderConfigPath = APIBasePath + "/provider-config" )
Provider endpoints
const ( OperatorPath = APIBasePath + "/operator" OperatorTargetsPath = OperatorPath + "/targets" )
Operator configuration endpoints
const (
TargetsPath = APIBasePath + "/targets"
)
Legacy targets endpoints (deprecated, use OperatorTargetsPath)
Variables ¶
var ( // TokenDuration is how long JWT tokens remain valid // Can be configured via JWT_EXPIRY_HOURS environment variable (default: 24 hours) TokenDuration = getTokenDuration() )
Functions ¶
func GetJWTSecretName ¶
func GetJWTSecretName() string
GetJWTSecretName returns the JWT secret name from environment or default
func ValidateValueAgainstSchema ¶
ValidateValueAgainstSchema validates a single value against typing.InputField schema The schema is a JSON array of typing.InputField objects
Types ¶
type ActiveRunsOverviewResponse ¶
type ActiveRunsOverviewResponse struct {
// TotalActiveRuns is the total number of scenario runs in Running state
TotalActiveRuns int `json:"totalActiveRuns"`
// TotalClusters is the total number of unique clusters with active runs
TotalClusters int `json:"totalClusters"`
// ClusterRuns is a map of cluster name to list of scenario run names running on that cluster
ClusterRuns map[string][]string `json:"clusterRuns"`
}
ActiveRunsOverviewResponse represents the response for GET /api/v1/dashboard/active-runs It provides an overview of currently running scenario runs
type AddGroupMemberRequest ¶
type AddGroupMemberRequest struct {
// UserID is the email address of the user to add (required)
UserID string `json:"userId"`
}
AddGroupMemberRequest represents the request body for POST /api/v1/groups/:groupName/members
type AddGroupMemberResponse ¶
type AddGroupMemberResponse struct {
// Message contains a success message
Message string `json:"message"`
// UserID is the added user's email
UserID string `json:"userId"`
// GroupName is the group name
GroupName string `json:"groupName"`
}
AddGroupMemberResponse represents the response for POST /api/v1/groups/:groupName/members
type ChangePasswordRequest ¶
type ChangePasswordRequest struct {
// CurrentPassword is the user's current password (required when changing own password)
CurrentPassword string `json:"currentPassword,omitempty"`
// NewPassword is the new password (required)
NewPassword string `json:"newPassword"`
}
ChangePasswordRequest represents the request body for PATCH /api/v1/users/:userId/password
type ChangePasswordResponse ¶
type ChangePasswordResponse struct {
// Message contains a success message
Message string `json:"message"`
}
ChangePasswordResponse represents the response for PATCH /api/v1/users/:userId/password
type ClusterJobStatusResponse ¶
type ClusterJobStatusResponse struct {
// ProviderName is the name of the provider that owns this cluster
ProviderName string `json:"providerName"`
// ClusterName is the name of the target cluster
ClusterName string `json:"clusterName"`
// JobID is the unique identifier for this job
JobID string `json:"jobId"`
// PodName is the name of the pod running the scenario
PodName string `json:"podName,omitempty"`
// Phase is the current phase of the job
Phase string `json:"phase"`
// StartTime is when the job started
StartTime *time.Time `json:"startTime,omitempty"`
// CompletionTime is when the job completed
CompletionTime *time.Time `json:"completionTime,omitempty"`
// Message contains additional information about the job status
Message string `json:"message,omitempty"`
// RetryCount is the number of times this job has been retried
RetryCount int `json:"retryCount,omitempty"`
// MaxRetries is the maximum number of retries allowed
MaxRetries int `json:"maxRetries,omitempty"`
// CancelRequested indicates if cancellation was requested
CancelRequested bool `json:"cancelRequested,omitempty"`
// FailureReason contains the categorized failure reason
FailureReason string `json:"failureReason,omitempty"`
}
ClusterJobStatusResponse represents the status of a job for a specific cluster
type ClusterPermissionSet ¶
type ClusterPermissionSet struct {
// Actions is the list of allowed actions: "view", "run", "cancel"
Actions []string `json:"actions"`
}
ClusterPermissionSet defines the actions allowed on a cluster
type ClustersResponse ¶
type ClustersResponse struct {
// TargetData contains a map of operator-name to list of cluster targets
TargetData map[string][]krknv1alpha1.ClusterTarget `json:"targetData"`
// Status represents the current state of the request (pending, completed)
Status string `json:"status"`
}
ClustersResponse represents the response for GET /clusters endpoint
type CreateTargetRequest ¶
type CreateTargetRequest struct {
// ClusterName is the name of the target cluster (required)
ClusterName string `json:"clusterName"`
// ClusterAPIURL is the Kubernetes API server URL (optional if kubeconfig provided)
ClusterAPIURL string `json:"clusterAPIURL,omitempty"`
// SecretType specifies the authentication method: "kubeconfig", "token", or "credentials"
SecretType string `json:"secretType"`
// CABundle is the base64-encoded CA certificate bundle (optional)
CABundle string `json:"caBundle,omitempty"`
// Kubeconfig (base64-encoded) - for SecretType="kubeconfig"
Kubeconfig string `json:"kubeconfig,omitempty"`
// Token - for SecretType="token"
Token string `json:"token,omitempty"`
// Username - for SecretType="credentials"
Username string `json:"username,omitempty"`
// Password - for SecretType="credentials"
Password string `json:"password,omitempty"`
}
CreateTargetRequest represents the request body for POST /api/v1/targets
type CreateTargetResponse ¶
type CreateTargetResponse struct {
// UUID is the unique identifier for the created target
UUID string `json:"uuid"`
// Message contains additional information
Message string `json:"message,omitempty"`
}
CreateTargetResponse represents the response for POST /api/v1/targets
type CreateUserGroupRequest ¶
type CreateUserGroupRequest struct {
// Name is the group name (required)
Name string `json:"name"`
// Description is the group description (optional)
Description string `json:"description,omitempty"`
// ClusterPermissions is a map of clusterAPIURL to permitted actions (required, min 1)
ClusterPermissions map[string]ClusterPermissionSet `json:"clusterPermissions"`
// DiscoveryUUID is the optional UUID of a KrknTargetRequest to delete after group creation
DiscoveryUUID string `json:"discoveryUuid,omitempty"`
}
CreateUserGroupRequest represents the request body for POST /api/v1/groups
type CreateUserGroupResponse ¶
type CreateUserGroupResponse struct {
// Message contains a success message
Message string `json:"message"`
// Name is the created group's name
Name string `json:"name"`
}
CreateUserGroupResponse represents the response for POST /api/v1/groups
type CreateUserRequest ¶
type CreateUserRequest struct {
// UserID is the email address of the user (required)
UserID string `json:"userId"`
// Password is the plaintext password (required, min 8 characters)
Password string `json:"password"`
// Name is the first name of the user (required)
Name string `json:"name"`
// Surname is the last name of the user (required)
Surname string `json:"surname"`
// Organization is the user's organization (optional)
Organization string `json:"organization,omitempty"`
// Role is either "user" or "admin" (required)
Role string `json:"role"`
}
CreateUserRequest represents the request body for POST /api/v1/users
type CreateUserResponse ¶
type CreateUserResponse struct {
// Message contains a success message
Message string `json:"message"`
// UserID is the created user's email
UserID string `json:"userId"`
// Role is the user's role
Role string `json:"role"`
}
CreateUserResponse represents the response for POST /api/v1/users
type DeleteUserGroupResponse ¶
type DeleteUserGroupResponse struct {
// Message contains a success message
Message string `json:"message"`
}
DeleteUserGroupResponse represents the response for DELETE /api/v1/groups/:groupName
type DeleteUserResponse ¶
type DeleteUserResponse struct {
// Message contains a success message
Message string `json:"message"`
}
DeleteUserResponse represents the response for DELETE /api/v1/users/:userId
type ErrorResponse ¶
ErrorResponse represents an error response
type FileMount ¶
type FileMount struct {
// Name is the file name
Name string `json:"name"`
// Content is the base64-encoded file content
Content string `json:"content"`
// MountPath is the absolute path where the file should be mounted
MountPath string `json:"mountPath"`
}
FileMount represents a file to be mounted in the scenario pod
type GlobalsRequest ¶
type GlobalsRequest struct {
ScenariosRequest
// ScenarioNames is the list of scenario names to get global environments for
ScenarioNames []string `json:"scenarioNames"`
}
GlobalsRequest represents the request body for POST /scenarios/globals
type GlobalsResponse ¶
type GlobalsResponse struct {
// Globals is a map of scenario name to global environment details
Globals map[string]ScenarioDetailResponse `json:"globals"`
}
GlobalsResponse represents the response for POST /scenarios/globals endpoint
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler contains the dependencies for API handlers
func NewHandler ¶
func NewHandler(client client.Client, clientset kubernetes.Interface, namespace string, grpcServerAddr string) *Handler
NewHandler creates a new Handler
func (*Handler) AddGroupMember ¶
func (h *Handler) AddGroupMember(w http.ResponseWriter, r *http.Request)
AddGroupMember handles POST /api/v1/groups/:groupName/members Adds a user to a group by adding label (admin only)
func (*Handler) ChangePassword ¶
func (h *Handler) ChangePassword(w http.ResponseWriter, r *http.Request)
ChangePassword handles PATCH /api/v1/users/:userID/password Changes user password (admin can change any password, users can change own password)
func (*Handler) CreateTarget ¶
func (h *Handler) CreateTarget(w http.ResponseWriter, r *http.Request)
CreateTarget handles POST /api/v1/operator/targets Creates a new KrknOperatorTarget CR with a generated UUID and associated Secret
func (*Handler) CreateUser ¶
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request)
CreateUser handles POST /api/v1/users Creates a new user (admin only)
func (*Handler) CreateUserGroup ¶
func (h *Handler) CreateUserGroup(w http.ResponseWriter, r *http.Request)
CreateUserGroup handles POST /api/v1/groups Creates a new user group (admin only)
func (*Handler) DeleteScenarioRun ¶
func (h *Handler) DeleteScenarioRun(w http.ResponseWriter, r *http.Request)
DeleteScenarioRun handles DELETE /api/v1/scenarios/run/{jobID} endpoint It stops and deletes a running job
func (*Handler) DeleteScenarioRunComplete ¶
func (h *Handler) DeleteScenarioRunComplete(w http.ResponseWriter, r *http.Request)
DeleteScenarioRunComplete handles DELETE /api/v1/scenarios/run/{scenarioRunName} It deletes the entire KrknScenarioRun CR (all jobs)
func (*Handler) DeleteSingleJob ¶
func (h *Handler) DeleteSingleJob(w http.ResponseWriter, r *http.Request)
DeleteSingleJob handles DELETE /api/v1/scenarios/run/jobs/{jobID} It cancels a single job by setting CancelRequested flag and deleting the pod
func (*Handler) DeleteTarget ¶
func (h *Handler) DeleteTarget(w http.ResponseWriter, r *http.Request)
DeleteTarget handles DELETE /api/v1/operator/targets/{uuid} Deletes a KrknOperatorTarget and its associated Secret
func (*Handler) DeleteUser ¶
func (h *Handler) DeleteUser(w http.ResponseWriter, r *http.Request)
DeleteUser handles DELETE /api/v1/users/:userID Deletes a user (admin only, cannot delete self, cannot delete last admin)
func (*Handler) DeleteUserGroup ¶
func (h *Handler) DeleteUserGroup(w http.ResponseWriter, r *http.Request)
DeleteUserGroup handles DELETE /api/v1/groups/:groupName Deletes a user group (admin only)
func (*Handler) GetActiveRunsOverview ¶
func (h *Handler) GetActiveRunsOverview(w http.ResponseWriter, r *http.Request)
GetActiveRunsOverview handles GET /api/v1/dashboard/active-runs endpoint It returns an overview of currently running scenario runs Accessible to all authenticated users - all users see all active runs (global dashboard)
func (*Handler) GetClusters ¶
func (h *Handler) GetClusters(w http.ResponseWriter, r *http.Request)
GetClusters handles GET /api/v1/clusters endpoint It fetches the KrknTargetRequest CR by the provided ID and returns the target data
func (*Handler) GetNodes ¶
func (h *Handler) GetNodes(w http.ResponseWriter, r *http.Request)
GetNodes handles GET /api/v1/nodes endpoint Supports both new and legacy parameter formats: - New: ?targetUUID=<uuid> - Legacy: ?id=<targetRequestId>&cluster-name=<clusterName>
func (*Handler) GetProviderConfigByUUID ¶
func (h *Handler) GetProviderConfigByUUID(w http.ResponseWriter, r *http.Request)
GetProviderConfigByUUID handles GET /api/v1/provider-config/{uuid} endpoint Returns 100 Continue when pending, 200 OK with config_data when Completed
func (*Handler) GetScenarioRunLogs ¶
func (h *Handler) GetScenarioRunLogs(w http.ResponseWriter, r *http.Request)
GetScenarioRunLogs handles GET /api/v1/scenarios/run/{scenarioRunName}/jobs/{jobID}/logs endpoint It streams the stdout/stderr logs of a running or completed job via WebSocket
func (*Handler) GetScenarioRunStatus ¶
func (h *Handler) GetScenarioRunStatus(w http.ResponseWriter, r *http.Request)
GetScenarioRunStatus handles GET /api/v1/scenarios/run/{scenarioRunName} endpoint It returns the current status of a scenario run
func (*Handler) GetSingleJob ¶
func (h *Handler) GetSingleJob(w http.ResponseWriter, r *http.Request)
GetSingleJob handles GET /api/v1/scenarios/run/jobs/{jobID} It returns the status of a single job by jobID (jobID is unique across all scenario runs)
func (*Handler) GetTarget ¶
func (h *Handler) GetTarget(w http.ResponseWriter, r *http.Request)
GetTarget handles GET /api/v1/operator/targets/{uuid} Returns a single KrknOperatorTarget by UUID
func (*Handler) GetTargetByUUID ¶
func (h *Handler) GetTargetByUUID(w http.ResponseWriter, r *http.Request)
GetTargetByUUID handles GET /api/v1/targets/{uuid} endpoint (legacy - checks KrknTargetRequest status) This endpoint checks the status of a KrknTargetRequest CR created by krkn-operator-acm
func (*Handler) GetUser ¶
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request)
GetUser handles GET /api/v1/users/:userID Returns a single user by email (admin or self)
func (*Handler) GetUserGroup ¶
func (h *Handler) GetUserGroup(w http.ResponseWriter, r *http.Request)
GetUserGroup handles GET /api/v1/groups/:groupName Returns a single user group (admin only)
func (*Handler) GroupsRouter ¶
func (h *Handler) GroupsRouter(w http.ResponseWriter, r *http.Request)
GroupsRouter routes requests to /api/v1/groups endpoints
func (*Handler) HealthCheck ¶
func (h *Handler) HealthCheck(w http.ResponseWriter, r *http.Request)
HealthCheck handles GET /api/v1/health endpoint
func (*Handler) IsRegistered ¶
func (h *Handler) IsRegistered(w http.ResponseWriter, r *http.Request)
IsRegistered handles GET /auth/is-registered Returns whether at least one admin user is registered in the system
func (*Handler) ListGroupMembers ¶
func (h *Handler) ListGroupMembers(w http.ResponseWriter, r *http.Request)
ListGroupMembers handles GET /api/v1/groups/:groupName/members Lists all members of a group (admin only)
func (*Handler) ListProviders ¶
func (h *Handler) ListProviders(w http.ResponseWriter, r *http.Request)
ListProviders handles GET /api/v1/providers endpoint Returns a list of all KrknOperatorTargetProvider resources
func (*Handler) ListScenarioRuns ¶
func (h *Handler) ListScenarioRuns(w http.ResponseWriter, r *http.Request)
ListScenarioRuns handles GET /api/v1/scenarios/run endpoint It returns a list of all scenario runs (KrknScenarioRun CRs)
func (*Handler) ListTargets ¶
func (h *Handler) ListTargets(w http.ResponseWriter, r *http.Request)
ListTargets handles GET /api/v1/operator/targets Returns a list of all KrknOperatorTarget CRs
func (*Handler) ListUserGroups ¶
func (h *Handler) ListUserGroups(w http.ResponseWriter, r *http.Request)
ListUserGroups handles GET /api/v1/groups Lists all user groups (admin only)
func (*Handler) ListUsers ¶
func (h *Handler) ListUsers(w http.ResponseWriter, r *http.Request)
ListUsers handles GET /api/v1/users Lists all users with filtering and pagination (admin only)
func (*Handler) Login ¶
func (h *Handler) Login(w http.ResponseWriter, r *http.Request)
Login handles POST /auth/login Authenticates a user and returns a JWT token
func (*Handler) PostProviderConfig ¶
func (h *Handler) PostProviderConfig(w http.ResponseWriter, r *http.Request)
PostProviderConfig handles POST /api/v1/provider-config endpoint Creates a new KrknOperatorTargetProviderConfig CR and returns the UUID
func (*Handler) PostScenarioDetail ¶
func (h *Handler) PostScenarioDetail(w http.ResponseWriter, r *http.Request)
PostScenarioDetail handles POST /api/v1/scenarios/detail/{scenario_name} endpoint It returns detailed information about a specific scenario including input fields
func (*Handler) PostScenarioGlobals ¶
func (h *Handler) PostScenarioGlobals(w http.ResponseWriter, r *http.Request)
PostScenarioGlobals handles POST /api/v1/scenarios/globals/{scenario_name} endpoint It returns global environment fields for a specific scenario
func (*Handler) PostScenarioRun ¶
func (h *Handler) PostScenarioRun(w http.ResponseWriter, r *http.Request)
func (*Handler) PostScenarios ¶
func (h *Handler) PostScenarios(w http.ResponseWriter, r *http.Request)
PostScenarios handles POST /api/v1/scenarios endpoint It returns the list of available krkn scenarios from quay.io or a private registry
func (*Handler) PostTarget ¶
func (h *Handler) PostTarget(w http.ResponseWriter, r *http.Request)
PostTarget handles POST /api/v1/targets endpoint (legacy - creates KrknTargetRequest) This endpoint triggers the krkn-operator-acm to discover and return target clusters
func (*Handler) ProviderConfigHandler ¶
func (h *Handler) ProviderConfigHandler(w http.ResponseWriter, r *http.Request)
ProviderConfigHandler handles both GET /api/v1/provider-config/{UUID} and POST /api/v1/provider-config endpoints It routes to the appropriate handler based on the HTTP method and path
func (*Handler) ProvidersRouter ¶
func (h *Handler) ProvidersRouter(w http.ResponseWriter, r *http.Request)
ProvidersRouter routes provider-related requests
func (*Handler) Register ¶
func (h *Handler) Register(w http.ResponseWriter, r *http.Request)
Register handles POST /auth/register Registers the FIRST admin user only. After that, use POST /api/v1/users (admin only).
func (*Handler) RemoveGroupMember ¶
func (h *Handler) RemoveGroupMember(w http.ResponseWriter, r *http.Request)
RemoveGroupMember handles DELETE /api/v1/groups/:groupName/members/:userId Removes a user from a group by removing label (admin only)
func (*Handler) ScenariosRunRouter ¶
func (h *Handler) ScenariosRunRouter(w http.ResponseWriter, r *http.Request)
func (*Handler) TargetsCRUDRouter ¶
func (h *Handler) TargetsCRUDRouter(w http.ResponseWriter, r *http.Request)
TargetsCRUDRouter routes requests to /api/v1/operator/targets endpoints
func (*Handler) TargetsHandler ¶
func (h *Handler) TargetsHandler(w http.ResponseWriter, r *http.Request)
TargetsHandler handles both GET /api/v1/targets/{UUID} and POST /api/v1/targets endpoints It routes to the appropriate handler based on the HTTP method
func (*Handler) UpdateProviderConfigValues ¶
func (h *Handler) UpdateProviderConfigValues(w http.ResponseWriter, r *http.Request)
UpdateProviderConfigValues handles POST /api/v1/provider-config/{uuid} Updates a provider's ConfigMap with validated configuration values
func (*Handler) UpdateProviderStatus ¶
func (h *Handler) UpdateProviderStatus(w http.ResponseWriter, r *http.Request)
UpdateProviderStatus handles PATCH /api/v1/providers/{name} endpoint Activates or deactivates a provider
func (*Handler) UpdateTarget ¶
func (h *Handler) UpdateTarget(w http.ResponseWriter, r *http.Request)
UpdateTarget handles PUT /api/v1/operator/targets/{uuid} Updates an existing KrknOperatorTarget (overwrites the Secret kubeconfig)
func (*Handler) UpdateUser ¶
func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request)
UpdateUser handles PATCH /api/v1/users/:userID Updates user profile (admin can update all fields, users can only update own profile)
func (*Handler) UpdateUserGroup ¶
func (h *Handler) UpdateUserGroup(w http.ResponseWriter, r *http.Request)
UpdateUserGroup handles PATCH /api/v1/groups/:groupName Updates a user group (admin only)
func (*Handler) UsersRouter ¶
func (h *Handler) UsersRouter(w http.ResponseWriter, r *http.Request)
UsersRouter routes requests to /api/v1/users endpoints
type InputFieldResponse ¶
type InputFieldResponse struct {
Name *string `json:"name"`
ShortDescription *string `json:"short_description,omitempty"`
Description *string `json:"description,omitempty"`
Variable *string `json:"variable"`
Type string `json:"type"` // String representation instead of int64 enum
Default *string `json:"default,omitempty"`
Validator *string `json:"validator,omitempty"`
ValidationMessage *string `json:"validation_message,omitempty"`
Separator *string `json:"separator,omitempty"`
AllowedValues *string `json:"allowed_values,omitempty"`
Required bool `json:"required,omitempty"`
MountPath *string `json:"mount_path,omitempty"`
Requires *string `json:"requires,omitempty"`
MutuallyExcludes *string `json:"mutually_excludes,omitempty"`
Secret bool `json:"secret,omitempty"`
}
InputFieldResponse represents a scenario input field with Type as string This is a wrapper around krknctl typing.InputField to ensure Type is serialized as string
type IsRegisteredResponse ¶
type IsRegisteredResponse struct {
// Registered indicates if at least one admin user exists
Registered bool `json:"registered"`
}
IsRegisteredResponse represents the response for GET /auth/is-registered
type JobStatusResponse ¶
type JobStatusResponse struct {
// JobID is the unique job identifier
JobID string `json:"jobId"`
// ClusterName is the target cluster name
ClusterName string `json:"clusterName"`
// ScenarioName is the scenario name
ScenarioName string `json:"scenarioName"`
// Status is the current job status (Pending, Running, Succeeded, Failed, Stopped)
Status string `json:"status"`
// PodName is the Kubernetes pod name
PodName string `json:"podName"`
// StartTime is when the job started (optional)
StartTime *time.Time `json:"startTime,omitempty"`
// CompletionTime is when the job completed (optional)
CompletionTime *time.Time `json:"completionTime,omitempty"`
// Message is additional status message or error details (optional)
Message string `json:"message,omitempty"`
}
JobStatusResponse represents the response for GET /scenarios/run/{jobId}
type JobsListResponse ¶
type JobsListResponse struct {
// Jobs is the array of job status objects
Jobs []JobStatusResponse `json:"jobs"`
}
JobsListResponse represents the response for GET /scenarios/run
type ListGroupMembersResponse ¶
type ListGroupMembersResponse struct {
// Members is the array of user objects in this group
Members []UserResponse `json:"members"`
// Total is the total number of members
Total int `json:"total"`
// GroupName is the group name
GroupName string `json:"groupName"`
}
ListGroupMembersResponse represents the response for GET /api/v1/groups/:groupName/members
type ListProvidersResponse ¶
type ListProvidersResponse struct {
// Providers is the list of registered providers
Providers []ProviderResponse `json:"providers"`
}
ListProvidersResponse is the response for GET /api/v1/providers
type ListTargetsResponse ¶
type ListTargetsResponse struct {
// Targets is the array of target objects
Targets []TargetResponse `json:"targets"`
}
ListTargetsResponse represents the response for GET /api/v1/targets
type ListUserGroupsResponse ¶
type ListUserGroupsResponse struct {
// Groups is the array of user group objects
Groups []UserGroupResponse `json:"groups"`
// Total is the total number of groups
Total int `json:"total"`
}
ListUserGroupsResponse represents the response for GET /api/v1/groups
type ListUsersResponse ¶
type ListUsersResponse struct {
// Users is the array of user objects
Users []UserResponse `json:"users"`
// Total is the total number of users matching the filter
Total int `json:"total"`
// Page is the current page number
Page int `json:"page"`
// Limit is the number of items per page
Limit int `json:"limit"`
}
ListUsersResponse represents the response for GET /api/v1/users
type LoginRequest ¶
type LoginRequest struct {
// UserID is the email address of the user (required)
UserID string `json:"userId"`
// Password is the plaintext password (required)
Password string `json:"password"`
}
LoginRequest represents the request body for POST /auth/login
type LoginResponse ¶
type LoginResponse struct {
// Token is the JWT authentication token
Token string `json:"token"`
// ExpiresAt is the token expiration timestamp
ExpiresAt string `json:"expiresAt"`
// UserID is the authenticated user's email
UserID string `json:"userId"`
// Role is the user's role
Role string `json:"role"`
// Name is the user's first name
Name string `json:"name"`
// Surname is the user's last name
Surname string `json:"surname"`
}
LoginResponse represents the response for POST /auth/login
type NodesResponse ¶
type NodesResponse struct {
// Nodes contains the list of node names in the cluster
Nodes []string `json:"nodes"`
}
NodesResponse represents the response for GET /nodes endpoint
type ProviderConfigUpdateRequest ¶
type ProviderConfigUpdateRequest struct {
// ProviderName is the name of the provider whose config to update
ProviderName string `json:"provider_name"`
// Values is a map of configuration keys to values (all values are strings)
Values map[string]string `json:"values"`
}
ProviderConfigUpdateRequest is the request body for POST /api/v1/provider-config/{uuid}
type ProviderConfigUpdateResponse ¶
type ProviderConfigUpdateResponse struct {
// Message contains a success message
Message string `json:"message"`
// UpdatedFields is the list of fields that were updated
UpdatedFields []string `json:"updatedFields,omitempty"`
}
ProviderConfigUpdateResponse is the response for successful config updates
type ProviderResponse ¶
type ProviderResponse struct {
// Name is the operator name
Name string `json:"name"`
// Active indicates if the provider is active
Active bool `json:"active"`
// LastHeartbeat is the timestamp of the last heartbeat
LastHeartbeat *metav1.Time `json:"lastHeartbeat,omitempty"`
}
ProviderResponse represents a single provider in the list
type RegisterRequest ¶
type RegisterRequest struct {
// UserID is the email address of the user (required)
UserID string `json:"userId"`
// Password is the plaintext password (required, min 8 characters)
Password string `json:"password"`
// Name is the first name of the user (required)
Name string `json:"name"`
// Surname is the last name of the user (required)
Surname string `json:"surname"`
// Organization is the user's organization (optional)
Organization string `json:"organization,omitempty"`
// Role is either "user" or "admin" (required)
Role string `json:"role"`
}
RegisterRequest represents the request body for POST /auth/register
type RegisterResponse ¶
type RegisterResponse struct {
// Message contains a success message
Message string `json:"message"`
// UserID is the registered user's email
UserID string `json:"userId"`
// Role is the user's role
Role string `json:"role"`
}
RegisterResponse represents the response for POST /auth/register
type RemoveGroupMemberResponse ¶
type RemoveGroupMemberResponse struct {
// Message contains a success message
Message string `json:"message"`
}
RemoveGroupMemberResponse represents the response for DELETE /api/v1/groups/:groupName/members/:userId
type ScenarioDetailResponse ¶
type ScenarioDetailResponse struct {
Name string `json:"name"`
Digest *string `json:"digest,omitempty"`
Size *int64 `json:"size,omitempty"`
LastModified *time.Time `json:"last_modified,omitempty"`
Title string `json:"title"`
Description string `json:"description"`
Fields []InputFieldResponse `json:"fields"`
}
ScenarioDetailResponse represents the response for POST /scenarios/detail/{scenario_name} This wraps krknctl models.ScenarioDetail to ensure Type fields are strings
type ScenarioRunCreateResponse ¶
type ScenarioRunCreateResponse struct {
// ScenarioRunName is the name of the created KrknScenarioRun CR
ScenarioRunName string `json:"scenarioRunName"`
// TargetClusters is a map of provider-name to list of cluster names
TargetClusters map[string][]string `json:"targetClusters"`
// TotalTargets is the total number of target clusters
TotalTargets int `json:"totalTargets"`
// OwnerUserID is the email address of the user who created this scenario run
OwnerUserID string `json:"ownerUserId,omitempty"`
}
ScenarioRunCreateResponse represents the response for POST /scenarios/run (new CRD-based approach)
type ScenarioRunListItem ¶
type ScenarioRunListItem struct {
// ScenarioRunName is the name of the KrknScenarioRun CR
ScenarioRunName string `json:"scenarioRunName"`
// ScenarioName is the name of the scenario being executed
ScenarioName string `json:"scenarioName"`
// Phase is the overall phase of the scenario run
Phase string `json:"phase"`
// TotalTargets is the total number of target clusters
TotalTargets int `json:"totalTargets"`
// SuccessfulJobs is the number of successfully completed jobs
SuccessfulJobs int `json:"successfulJobs"`
// FailedJobs is the number of failed jobs
FailedJobs int `json:"failedJobs"`
// RunningJobs is the number of currently running jobs
RunningJobs int `json:"runningJobs"`
// CreatedAt is the creation timestamp
CreatedAt time.Time `json:"createdAt"`
// OwnerUserID is the email address of the user who created this scenario run
OwnerUserID string `json:"ownerUserId,omitempty"`
}
ScenarioRunListItem represents a single scenario run in the list view
type ScenarioRunListResponse ¶
type ScenarioRunListResponse struct {
// ScenarioRuns is the list of scenario runs
ScenarioRuns []ScenarioRunListItem `json:"scenarioRuns"`
}
ScenarioRunListResponse represents the response for GET /scenarios/run
type ScenarioRunRequest ¶
type ScenarioRunRequest struct {
// TargetRequestID is the UUID of the KrknTargetRequest (required)
TargetRequestID string `json:"targetRequestId"`
// TargetClusters is a map of provider-name to list of cluster names
// Example: {"krkn-operator": ["cluster1", "cluster2"], "krkn-operator-acm": ["cluster3"]}
TargetClusters map[string][]string `json:"targetClusters"`
// ScenarioImage is the container image to run
ScenarioImage string `json:"scenarioImage"`
// ScenarioName is the name of the scenario being executed
ScenarioName string `json:"scenarioName"`
// KubeconfigPath is the path where kubeconfig should be mounted (optional, default: /home/krkn/.kube/config)
KubeconfigPath string `json:"kubeconfigPath,omitempty"`
// Environment is a map of environment variables to pass to the container (optional)
Environment map[string]string `json:"environment,omitempty"`
// Files is an array of file objects to mount in the container (optional)
Files []FileMount `json:"files,omitempty"`
// Private registry configuration (optional)
ScenariosRequest
}
ScenarioRunRequest represents the request body for POST /scenarios/run
type ScenarioRunResponse ¶
type ScenarioRunResponse struct {
// Jobs is the array of job results for each target
Jobs []TargetJobResult `json:"jobs"`
// TotalTargets is the total number of targets requested
TotalTargets int `json:"totalTargets"`
// SuccessfulJobs is the number of jobs created successfully
SuccessfulJobs int `json:"successfulJobs"`
// FailedJobs is the number of jobs that failed to create
FailedJobs int `json:"failedJobs"`
}
ScenarioRunResponse represents the response for POST /scenarios/run
type ScenarioRunStatusResponse ¶
type ScenarioRunStatusResponse struct {
// ScenarioRunName is the name of the KrknScenarioRun CR
ScenarioRunName string `json:"scenarioRunName"`
// Phase is the overall phase of the scenario run
Phase string `json:"phase"`
// TotalTargets is the total number of target clusters
TotalTargets int `json:"totalTargets"`
// SuccessfulJobs is the number of successfully completed jobs
SuccessfulJobs int `json:"successfulJobs"`
// FailedJobs is the number of failed jobs
FailedJobs int `json:"failedJobs"`
// RunningJobs is the number of currently running jobs
RunningJobs int `json:"runningJobs"`
// ClusterJobs contains the status of each cluster job
ClusterJobs []ClusterJobStatusResponse `json:"clusterJobs"`
// OwnerUserID is the email address of the user who created this scenario run
OwnerUserID string `json:"ownerUserId,omitempty"`
}
ScenarioRunStatusResponse represents the response for GET /scenarios/run/{scenarioRunName} (new CRD-based approach)
type ScenarioTag ¶
type ScenarioTag struct {
// Name is the scenario tag/version name
Name string `json:"name"`
// Digest is the image digest (optional)
Digest *string `json:"digest,omitempty"`
// Size is the image size in bytes (optional)
Size *int64 `json:"size,omitempty"`
// LastModified is when the scenario was last updated (optional)
LastModified *time.Time `json:"lastModified,omitempty"`
}
ScenarioTag represents a scenario available in the registry
type ScenariosRequest ¶
type ScenariosRequest struct {
// Username for private registry authentication (optional)
Username *string `json:"username,omitempty"`
// Password for private registry authentication (optional)
Password *string `json:"password,omitempty"`
// Token for private registry authentication (optional, alternative to username/password)
Token *string `json:"token,omitempty"`
// RegistryURL is the private registry URL (required if using private registry)
RegistryURL string `json:"registryUrl,omitempty"`
// ScenarioRepository is the scenario repository name (required if using private registry)
ScenarioRepository string `json:"scenarioRepository,omitempty"`
// SkipTLS skips TLS verification for private registry
SkipTLS bool `json:"skipTls,omitempty"`
// Insecure allows insecure connections to private registry
Insecure bool `json:"insecure,omitempty"`
}
ScenariosRequest represents the optional request body for POST /scenarios If provided, uses private registry; if nil/empty, defaults to quay.io
type ScenariosResponse ¶
type ScenariosResponse struct {
// Scenarios contains the list of available scenario tags
Scenarios []ScenarioTag `json:"scenarios"`
}
ScenariosResponse represents the response for POST /scenarios endpoint
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server represents the REST API server
func NewServer ¶
func NewServer(port int, client client.Client, clientset kubernetes.Interface, namespace string, grpcServerAddr string) *Server
NewServer creates a new API server
type TargetJobResult ¶
type TargetJobResult struct {
// ClusterName is the name of the target cluster
ClusterName string `json:"clusterName"`
// JobID is the unique job identifier
JobID string `json:"jobId"`
// Status is the initial job status (usually "Pending" or "Failed")
Status string `json:"status"`
// PodName is the Kubernetes pod name
PodName string `json:"podName"`
// Success indicates if the job was created successfully
Success bool `json:"success"`
// Error contains error message if Success is false
Error string `json:"error,omitempty"`
}
TargetJobResult represents the result of creating a job for a specific target
type TargetResponse ¶
type TargetResponse struct {
// UUID is the unique identifier
UUID string `json:"uuid"`
// ClusterName is the name of the target cluster
ClusterName string `json:"clusterName"`
// ClusterAPIURL is the Kubernetes API server URL
ClusterAPIURL string `json:"clusterAPIURL"`
// SecretType is the authentication method
SecretType string `json:"secretType"`
// Ready indicates if the target is ready
Ready bool `json:"ready"`
// CreatedAt is the creation timestamp
CreatedAt *time.Time `json:"createdAt,omitempty"`
}
TargetResponse represents a single target in responses
type UpdateProviderStatusRequest ¶
type UpdateProviderStatusRequest struct {
// Active sets the provider active status
Active bool `json:"active"`
}
UpdateProviderStatusRequest is the request body for PATCH /api/v1/providers/{name}
type UpdateProviderStatusResponse ¶
type UpdateProviderStatusResponse struct {
// Message contains a success message
Message string `json:"message"`
// Name is the provider name
Name string `json:"name"`
// Active is the new active status
Active bool `json:"active"`
}
UpdateProviderStatusResponse is the response for successful provider status updates
type UpdateTargetRequest ¶
type UpdateTargetRequest struct {
CreateTargetRequest
}
UpdateTargetRequest represents the request body for PUT /api/v1/targets/{uuid}
type UpdateUserGroupRequest ¶
type UpdateUserGroupRequest struct {
// Description is the group description (optional)
Description *string `json:"description,omitempty"`
// ClusterPermissions is a map of clusterAPIURL to permitted actions (optional)
ClusterPermissions map[string]ClusterPermissionSet `json:"clusterPermissions,omitempty"`
// DiscoveryUUID is the optional UUID of a KrknTargetRequest to delete after group update
DiscoveryUUID string `json:"discoveryUuid,omitempty"`
}
UpdateUserGroupRequest represents the request body for PATCH /api/v1/groups/:groupName
type UpdateUserGroupResponse ¶
type UpdateUserGroupResponse struct {
// Message contains a success message
Message string `json:"message"`
// Group is the updated group object
Group UserGroupResponse `json:"group"`
}
UpdateUserGroupResponse represents the response for PATCH /api/v1/groups/:groupName
type UpdateUserRequest ¶
type UpdateUserRequest struct {
// Name is the first name (optional)
Name *string `json:"name,omitempty"`
// Surname is the last name (optional)
Surname *string `json:"surname,omitempty"`
// Organization is the user's organization (optional)
Organization *string `json:"organization,omitempty"`
// Role is either "user" or "admin" (admin only, optional)
Role *string `json:"role,omitempty"`
// Active indicates if the user account is active (admin only, optional)
Active *bool `json:"active,omitempty"`
}
UpdateUserRequest represents the request body for PATCH /api/v1/users/:userId
type UpdateUserResponse ¶
type UpdateUserResponse struct {
// Message contains a success message
Message string `json:"message"`
// User is the updated user object
User UserResponse `json:"user"`
}
UpdateUserResponse represents the response for PATCH /api/v1/users/:userId
type UserGroupResponse ¶
type UserGroupResponse struct {
// Name is the group name
Name string `json:"name"`
// Description is the group description (optional)
Description string `json:"description,omitempty"`
// ClusterPermissions is a map of clusterAPIURL to permitted actions
ClusterPermissions map[string]ClusterPermissionSet `json:"clusterPermissions"`
// MemberCount is the number of users in this group (calculated dynamically)
MemberCount int `json:"memberCount"`
// CreatedAt is when the group was created
CreatedAt *time.Time `json:"createdAt,omitempty"`
}
UserGroupResponse represents a user group in API responses
type UserResponse ¶
type UserResponse struct {
// UserID is the email address of the user
UserID string `json:"userId"`
// Name is the first name of the user
Name string `json:"name"`
// Surname is the last name of the user
Surname string `json:"surname"`
// Organization is the user's organization (optional)
Organization string `json:"organization,omitempty"`
// Role is either "user" or "admin"
Role string `json:"role"`
// Active indicates if the user account is active
Active bool `json:"active"`
// Created is when the user was created
Created *time.Time `json:"created,omitempty"`
// LastLogin is when the user last logged in
LastLogin *time.Time `json:"lastLogin,omitempty"`
}
UserResponse represents a user in API responses (no password)