Files
portainer/api/http/handler/gitops/sources/get.go
T
2026-05-18 18:01:36 -03:00

113 lines
3.2 KiB
Go

package sources
import (
"net/http"
portainer "github.com/portainer/portainer/api"
gittypes "github.com/portainer/portainer/api/git/types"
ce "github.com/portainer/portainer/api/gitops/workflows"
"github.com/portainer/portainer/api/http/security"
httperror "github.com/portainer/portainer/pkg/libhttp/error"
"github.com/portainer/portainer/pkg/libhttp/request"
"github.com/portainer/portainer/pkg/libhttp/response"
)
type connectionInfo struct {
ReferenceName string `json:"referenceName"`
ConfigFilePath string `json:"configFilePath"`
TLSSkipVerify bool `json:"tlsSkipVerify"`
Authentication bool `json:"authentication,omitempty"`
}
type autoUpdateInfo struct {
Mechanism string `json:"mechanism,omitempty"`
FetchInterval string `json:"fetchInterval,omitempty"`
}
// SourceDetail extends Source with connection settings and linked workflows.
type SourceDetail struct {
Source
Connection *connectionInfo `json:"connection,omitempty"`
AutoUpdate *autoUpdateInfo `json:"autoUpdate,omitempty"`
Workflows []ce.Workflow `json:"workflows"`
}
// @id GitOpsSourceGet
// @summary Get a GitOps source by ID
// @description Returns a single GitOps source with its connection settings and linked workflows.
// @description **Access policy**: admin
// @tags gitops
// @security ApiKeyAuth
// @security jwt
// @produce json
// @param id path string true "Source ID"
// @success 200 {object} SourceDetail
// @failure 403 "Access denied"
// @failure 404 "Source not found"
// @failure 500 "Server error"
// @router /gitops/sources/{id} [get]
func (h *Handler) getSource(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
id, err := request.RetrieveRouteVariableValue(r, "id")
if err != nil {
return httperror.BadRequest("Invalid source ID", err)
}
securityContext, err := security.RetrieveRestrictedRequestContext(r)
if err != nil {
return httperror.InternalServerError("Unable to retrieve info from request context", err)
}
workflows, err := ce.FetchWorkflows(r.Context(), h.dataStore, h.gitService, h.k8sFactory, securityContext, nil)
if err != nil {
return httperror.InternalServerError("Unable to retrieve workflows", err)
}
byID := workflowsBySourceID(workflows)
wfs, ok := byID[id]
if !ok || len(wfs) == 0 || wfs[0].GitConfig == nil {
return httperror.NotFound("Source not found", nil)
}
url := wfs[0].GitConfig.URL
detail := SourceDetail{
Source: buildSource(id, url, wfs),
Connection: buildConnectionInfo(wfs[0].GitConfig),
AutoUpdate: buildAutoUpdateInfo(wfs[0].AutoUpdate),
Workflows: redactWorkflowCredentials(wfs),
}
return response.JSON(w, detail)
}
func buildConnectionInfo(cfg *gittypes.RepoConfig) *connectionInfo {
if cfg == nil {
return nil
}
return &connectionInfo{
ReferenceName: cfg.ReferenceName,
ConfigFilePath: cfg.ConfigFilePath,
TLSSkipVerify: cfg.TLSSkipVerify,
Authentication: cfg.Authentication != nil,
}
}
func buildAutoUpdateInfo(autoUpdate *portainer.AutoUpdateSettings) *autoUpdateInfo {
if autoUpdate == nil {
return nil
}
switch {
case autoUpdate.Interval != "":
return &autoUpdateInfo{
Mechanism: "Interval",
FetchInterval: autoUpdate.Interval,
}
case autoUpdate.Webhook != "":
return &autoUpdateInfo{
Mechanism: "Webhook",
}
default:
return nil
}
}