mirror of https://github.com/portainer/portainer
fix(k8s) cleaning up namespace access policies when removing users orteams from endpoint or endpoint group EE-718 (#5184)
* fix(k8s) cleaning up namespace access policies when removing users or teams from endpoint or endpoint group EE-718 * fix(k8s) minor code cleanup EE-718 Co-authored-by: Simon Meng <simon.meng@portainer.io>pull/5203/head
parent
2170ad49ef
commit
6b759438b8
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/portainer/portainer/api/http/client"
|
"github.com/portainer/portainer/api/http/client"
|
||||||
"github.com/portainer/portainer/api/http/proxy"
|
"github.com/portainer/portainer/api/http/proxy"
|
||||||
kubeproxy "github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
kubeproxy "github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
||||||
|
"github.com/portainer/portainer/api/internal/authorization"
|
||||||
"github.com/portainer/portainer/api/internal/edge"
|
"github.com/portainer/portainer/api/internal/edge"
|
||||||
"github.com/portainer/portainer/api/internal/snapshot"
|
"github.com/portainer/portainer/api/internal/snapshot"
|
||||||
"github.com/portainer/portainer/api/jwt"
|
"github.com/portainer/portainer/api/jwt"
|
||||||
|
@ -389,6 +390,9 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
||||||
}
|
}
|
||||||
snapshotService.Start()
|
snapshotService.Start()
|
||||||
|
|
||||||
|
authorizationService := authorization.NewService(dataStore)
|
||||||
|
authorizationService.K8sClientFactory = kubernetesClientFactory
|
||||||
|
|
||||||
swarmStackManager, err := initSwarmStackManager(*flags.Assets, *flags.Data, digitalSignatureService, fileService, reverseTunnelService)
|
swarmStackManager, err := initSwarmStackManager(*flags.Assets, *flags.Data, digitalSignatureService, fileService, reverseTunnelService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed initializing swarm stack manager: %v", err)
|
log.Fatalf("failed initializing swarm stack manager: %v", err)
|
||||||
|
@ -461,6 +465,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &http.Server{
|
return &http.Server{
|
||||||
|
AuthorizationService: authorizationService,
|
||||||
ReverseTunnelService: reverseTunnelService,
|
ReverseTunnelService: reverseTunnelService,
|
||||||
Status: applicationStatus,
|
Status: applicationStatus,
|
||||||
BindAddress: *flags.Addr,
|
BindAddress: *flags.Addr,
|
||||||
|
|
|
@ -109,12 +109,33 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAuthorizations := false
|
||||||
if payload.UserAccessPolicies != nil && !reflect.DeepEqual(payload.UserAccessPolicies, endpointGroup.UserAccessPolicies) {
|
if payload.UserAccessPolicies != nil && !reflect.DeepEqual(payload.UserAccessPolicies, endpointGroup.UserAccessPolicies) {
|
||||||
endpointGroup.UserAccessPolicies = payload.UserAccessPolicies
|
endpointGroup.UserAccessPolicies = payload.UserAccessPolicies
|
||||||
|
updateAuthorizations = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.TeamAccessPolicies != nil && !reflect.DeepEqual(payload.TeamAccessPolicies, endpointGroup.TeamAccessPolicies) {
|
if payload.TeamAccessPolicies != nil && !reflect.DeepEqual(payload.TeamAccessPolicies, endpointGroup.TeamAccessPolicies) {
|
||||||
endpointGroup.TeamAccessPolicies = payload.TeamAccessPolicies
|
endpointGroup.TeamAccessPolicies = payload.TeamAccessPolicies
|
||||||
|
updateAuthorizations = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if updateAuthorizations {
|
||||||
|
endpoints, err := handler.DataStore.Endpoint().Endpoints()
|
||||||
|
if err != nil {
|
||||||
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve endpoints from the database", err}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
if endpoint.GroupID == endpointGroup.ID {
|
||||||
|
if endpoint.Type == portainer.KubernetesLocalEnvironment || endpoint.Type == portainer.AgentOnKubernetesEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment {
|
||||||
|
err = handler.AuthorizationService.CleanNAPWithOverridePolicies(&endpoint, endpointGroup)
|
||||||
|
if err != nil {
|
||||||
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update user authorizations", err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.DataStore.EndpointGroup().UpdateEndpointGroup(endpointGroup.ID, endpointGroup)
|
err = handler.DataStore.EndpointGroup().UpdateEndpointGroup(endpointGroup.ID, endpointGroup)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package endpointgroups
|
package endpointgroups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/portainer/portainer/api/internal/authorization"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
// Handler is the HTTP handler used to handle endpoint group operations.
|
// Handler is the HTTP handler used to handle endpoint group operations.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
*mux.Router
|
*mux.Router
|
||||||
|
AuthorizationService *authorization.Service
|
||||||
DataStore portainer.DataStore
|
DataStore portainer.DataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,11 +155,14 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
|
||||||
endpoint.Kubernetes = *payload.Kubernetes
|
endpoint.Kubernetes = *payload.Kubernetes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAuthorizations := false
|
||||||
if payload.UserAccessPolicies != nil && !reflect.DeepEqual(payload.UserAccessPolicies, endpoint.UserAccessPolicies) {
|
if payload.UserAccessPolicies != nil && !reflect.DeepEqual(payload.UserAccessPolicies, endpoint.UserAccessPolicies) {
|
||||||
|
updateAuthorizations = true
|
||||||
endpoint.UserAccessPolicies = payload.UserAccessPolicies
|
endpoint.UserAccessPolicies = payload.UserAccessPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.TeamAccessPolicies != nil && !reflect.DeepEqual(payload.TeamAccessPolicies, endpoint.TeamAccessPolicies) {
|
if payload.TeamAccessPolicies != nil && !reflect.DeepEqual(payload.TeamAccessPolicies, endpoint.TeamAccessPolicies) {
|
||||||
|
updateAuthorizations = true
|
||||||
endpoint.TeamAccessPolicies = payload.TeamAccessPolicies
|
endpoint.TeamAccessPolicies = payload.TeamAccessPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +255,15 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if updateAuthorizations {
|
||||||
|
if endpoint.Type == portainer.KubernetesLocalEnvironment || endpoint.Type == portainer.AgentOnKubernetesEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment {
|
||||||
|
err = handler.AuthorizationService.CleanNAPWithOverridePolicies(endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update user authorizations", err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint)
|
err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist endpoint changes inside the database", err}
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist endpoint changes inside the database", err}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/http/proxy"
|
"github.com/portainer/portainer/api/http/proxy"
|
||||||
"github.com/portainer/portainer/api/http/security"
|
"github.com/portainer/portainer/api/http/security"
|
||||||
|
"github.com/portainer/portainer/api/internal/authorization"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ type Handler struct {
|
||||||
ReverseTunnelService portainer.ReverseTunnelService
|
ReverseTunnelService portainer.ReverseTunnelService
|
||||||
SnapshotService portainer.SnapshotService
|
SnapshotService portainer.SnapshotService
|
||||||
ComposeStackManager portainer.ComposeStackManager
|
ComposeStackManager portainer.ComposeStackManager
|
||||||
|
AuthorizationService *authorization.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandler creates a handler to manage endpoint operations.
|
// NewHandler creates a handler to manage endpoint operations.
|
||||||
|
|
|
@ -45,11 +45,13 @@ import (
|
||||||
"github.com/portainer/portainer/api/http/proxy"
|
"github.com/portainer/portainer/api/http/proxy"
|
||||||
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
||||||
"github.com/portainer/portainer/api/http/security"
|
"github.com/portainer/portainer/api/http/security"
|
||||||
|
"github.com/portainer/portainer/api/internal/authorization"
|
||||||
"github.com/portainer/portainer/api/kubernetes/cli"
|
"github.com/portainer/portainer/api/kubernetes/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server implements the portainer.Server interface
|
// Server implements the portainer.Server interface
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
AuthorizationService *authorization.Service
|
||||||
BindAddress string
|
BindAddress string
|
||||||
AssetsPath string
|
AssetsPath string
|
||||||
Status *portainer.Status
|
Status *portainer.Status
|
||||||
|
@ -135,6 +137,7 @@ func (server *Server) Start() error {
|
||||||
endpointHandler.SnapshotService = server.SnapshotService
|
endpointHandler.SnapshotService = server.SnapshotService
|
||||||
endpointHandler.ReverseTunnelService = server.ReverseTunnelService
|
endpointHandler.ReverseTunnelService = server.ReverseTunnelService
|
||||||
endpointHandler.ComposeStackManager = server.ComposeStackManager
|
endpointHandler.ComposeStackManager = server.ComposeStackManager
|
||||||
|
endpointHandler.AuthorizationService = server.AuthorizationService
|
||||||
|
|
||||||
var endpointEdgeHandler = endpointedge.NewHandler(requestBouncer)
|
var endpointEdgeHandler = endpointedge.NewHandler(requestBouncer)
|
||||||
endpointEdgeHandler.DataStore = server.DataStore
|
endpointEdgeHandler.DataStore = server.DataStore
|
||||||
|
@ -142,6 +145,7 @@ func (server *Server) Start() error {
|
||||||
endpointEdgeHandler.ReverseTunnelService = server.ReverseTunnelService
|
endpointEdgeHandler.ReverseTunnelService = server.ReverseTunnelService
|
||||||
|
|
||||||
var endpointGroupHandler = endpointgroups.NewHandler(requestBouncer)
|
var endpointGroupHandler = endpointgroups.NewHandler(requestBouncer)
|
||||||
|
endpointGroupHandler.AuthorizationService = server.AuthorizationService
|
||||||
endpointGroupHandler.DataStore = server.DataStore
|
endpointGroupHandler.DataStore = server.DataStore
|
||||||
|
|
||||||
var endpointProxyHandler = endpointproxy.NewHandler(requestBouncer)
|
var endpointProxyHandler = endpointproxy.NewHandler(requestBouncer)
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package authorization
|
package authorization
|
||||||
|
|
||||||
import "github.com/portainer/portainer/api"
|
import (
|
||||||
|
"github.com/portainer/portainer/api"
|
||||||
|
"github.com/portainer/portainer/api/kubernetes/cli"
|
||||||
|
)
|
||||||
|
|
||||||
// Service represents a service used to
|
// Service represents a service used to
|
||||||
// update authorizations associated to a user or team.
|
// update authorizations associated to a user or team.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
dataStore portainer.DataStore
|
dataStore portainer.DataStore
|
||||||
|
K8sClientFactory *cli.ClientFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService returns a point to a new Service instance.
|
// NewService returns a point to a new Service instance.
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
package authorization
|
||||||
|
|
||||||
|
import portainer "github.com/portainer/portainer/api"
|
||||||
|
|
||||||
|
// CleanNAPWithOverridePolicies Clean Namespace Access Policies with override policies
|
||||||
|
func (service *Service) CleanNAPWithOverridePolicies(
|
||||||
|
endpoint *portainer.Endpoint,
|
||||||
|
endpointGroup *portainer.EndpointGroup,
|
||||||
|
) error {
|
||||||
|
kubecli, err := service.K8sClientFactory.GetKubeClient(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
accessPolicies, err := kubecli.GetNamespaceAccessPolicies()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hasChange := false
|
||||||
|
|
||||||
|
for namespace, policy := range accessPolicies {
|
||||||
|
for teamID := range policy.TeamAccessPolicies {
|
||||||
|
access, err := service.getTeamEndpointAccessWithPolicies(teamID, endpoint, endpointGroup)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !access {
|
||||||
|
delete(accessPolicies[namespace].TeamAccessPolicies, teamID)
|
||||||
|
hasChange = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for userID := range policy.UserAccessPolicies {
|
||||||
|
access, err := service.getUserEndpointAccessWithPolicies(userID, endpoint, endpointGroup)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !access {
|
||||||
|
delete(accessPolicies[namespace].UserAccessPolicies, userID)
|
||||||
|
hasChange = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasChange {
|
||||||
|
err = kubecli.UpdateNamespaceAccessPolicies(accessPolicies)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *Service) getUserEndpointAccessWithPolicies(
|
||||||
|
userID portainer.UserID,
|
||||||
|
endpoint *portainer.Endpoint,
|
||||||
|
endpointGroup *portainer.EndpointGroup,
|
||||||
|
) (bool, error) {
|
||||||
|
memberships, err := service.dataStore.TeamMembership().TeamMembershipsByUserID(userID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if endpointGroup == nil {
|
||||||
|
endpointGroup, err = service.dataStore.EndpointGroup().EndpointGroup(endpoint.GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if userAccess(userID, endpoint.UserAccessPolicies, endpoint.TeamAccessPolicies, memberships) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if userAccess(userID, endpointGroup.UserAccessPolicies, endpointGroup.TeamAccessPolicies, memberships) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func userAccess(
|
||||||
|
userID portainer.UserID,
|
||||||
|
userAccessPolicies portainer.UserAccessPolicies,
|
||||||
|
teamAccessPolicies portainer.TeamAccessPolicies,
|
||||||
|
memberships []portainer.TeamMembership,
|
||||||
|
) bool {
|
||||||
|
if _, ok := userAccessPolicies[userID]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, membership := range memberships {
|
||||||
|
if _, ok := teamAccessPolicies[membership.TeamID]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *Service) getTeamEndpointAccessWithPolicies(
|
||||||
|
teamID portainer.TeamID,
|
||||||
|
endpoint *portainer.Endpoint,
|
||||||
|
endpointGroup *portainer.EndpointGroup,
|
||||||
|
) (bool, error) {
|
||||||
|
if endpointGroup == nil {
|
||||||
|
var err error
|
||||||
|
endpointGroup, err = service.dataStore.EndpointGroup().EndpointGroup(endpoint.GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if teamAccess(teamID, endpoint.TeamAccessPolicies) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if teamAccess(teamID, endpointGroup.TeamAccessPolicies) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func teamAccess(
|
||||||
|
teamID portainer.TeamID,
|
||||||
|
teamAccessPolicies portainer.TeamAccessPolicies,
|
||||||
|
) bool {
|
||||||
|
_, ok := teamAccessPolicies[teamID];
|
||||||
|
return ok
|
||||||
|
}
|
|
@ -9,12 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
accessPolicies struct {
|
namespaceAccessPolicies map[string]portainer.K8sNamespaceAccessPolicy
|
||||||
UserAccessPolicies portainer.UserAccessPolicies `json:"UserAccessPolicies"`
|
|
||||||
TeamAccessPolicies portainer.TeamAccessPolicies `json:"TeamAccessPolicies"`
|
|
||||||
}
|
|
||||||
|
|
||||||
namespaceAccessPolicies map[string]accessPolicies
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (kcl *KubeClient) setupNamespaceAccesses(userID int, teamIDs []int, serviceAccountName string) error {
|
func (kcl *KubeClient) setupNamespaceAccesses(userID int, teamIDs []int, serviceAccountName string) error {
|
||||||
|
@ -69,7 +64,7 @@ func (kcl *KubeClient) setupNamespaceAccesses(userID int, teamIDs []int, service
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasUserAccessToNamespace(userID int, teamIDs []int, policies accessPolicies) bool {
|
func hasUserAccessToNamespace(userID int, teamIDs []int, policies portainer.K8sNamespaceAccessPolicy) bool {
|
||||||
_, userAccess := policies.UserAccessPolicies[portainer.UserID(userID)]
|
_, userAccess := policies.UserAccessPolicies[portainer.UserID(userID)]
|
||||||
if userAccess {
|
if userAccess {
|
||||||
return true
|
return true
|
||||||
|
@ -84,3 +79,50 @@ func hasUserAccessToNamespace(userID int, teamIDs []int, policies accessPolicies
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNamespaceAccessPolicies gets the namespace access policies
|
||||||
|
// from config maps in the portainer namespace
|
||||||
|
func (kcl *KubeClient) GetNamespaceAccessPolicies() (map[string]portainer.K8sNamespaceAccessPolicy, error) {
|
||||||
|
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(portainerConfigMapName, metav1.GetOptions{})
|
||||||
|
if k8serrors.IsNotFound(err) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
accessData := configMap.Data[portainerConfigMapAccessPoliciesKey]
|
||||||
|
|
||||||
|
var policies map[string]portainer.K8sNamespaceAccessPolicy
|
||||||
|
err = json.Unmarshal([]byte(accessData), &policies)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return policies, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNamespaceAccessPolicies updates the namespace access policies
|
||||||
|
func (kcl *KubeClient) UpdateNamespaceAccessPolicies(accessPolicies map[string]portainer.K8sNamespaceAccessPolicy) error {
|
||||||
|
data, err := json.Marshal(accessPolicies)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(portainerConfigMapName, metav1.GetOptions{})
|
||||||
|
if k8serrors.IsNotFound(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configMap.Data[portainerConfigMapAccessPoliciesKey] = string(data)
|
||||||
|
_, err = kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Update(configMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -392,6 +392,11 @@ type (
|
||||||
// JobType represents a job type
|
// JobType represents a job type
|
||||||
JobType int
|
JobType int
|
||||||
|
|
||||||
|
K8sNamespaceAccessPolicy struct {
|
||||||
|
UserAccessPolicies UserAccessPolicies `json:"UserAccessPolicies"`
|
||||||
|
TeamAccessPolicies TeamAccessPolicies `json:"TeamAccessPolicies"`
|
||||||
|
}
|
||||||
|
|
||||||
// KubernetesData contains all the Kubernetes related endpoint information
|
// KubernetesData contains all the Kubernetes related endpoint information
|
||||||
KubernetesData struct {
|
KubernetesData struct {
|
||||||
Snapshots []KubernetesSnapshot `json:"Snapshots"`
|
Snapshots []KubernetesSnapshot `json:"Snapshots"`
|
||||||
|
@ -1160,6 +1165,8 @@ type (
|
||||||
SetupUserServiceAccount(userID int, teamIDs []int) error
|
SetupUserServiceAccount(userID int, teamIDs []int) error
|
||||||
GetServiceAccountBearerToken(userID int) (string, error)
|
GetServiceAccountBearerToken(userID int) (string, error)
|
||||||
StartExecProcess(namespace, podName, containerName string, command []string, stdin io.Reader, stdout io.Writer) error
|
StartExecProcess(namespace, podName, containerName string, command []string, stdin io.Reader, stdout io.Writer) error
|
||||||
|
GetNamespaceAccessPolicies() (map[string]K8sNamespaceAccessPolicy, error)
|
||||||
|
UpdateNamespaceAccessPolicies(accessPolicies map[string]K8sNamespaceAccessPolicy) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubernetesDeployer represents a service to deploy a manifest inside a Kubernetes endpoint
|
// KubernetesDeployer represents a service to deploy a manifest inside a Kubernetes endpoint
|
||||||
|
|
Loading…
Reference in New Issue