mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
refactor(k8s): namespace core logic (#12142)
Co-authored-by: testA113 <aliharriss1995@gmail.com> Co-authored-by: Anthony Lapenna <anthony.lapenna@portainer.io> Co-authored-by: James Carppe <85850129+jamescarppe@users.noreply.github.com> Co-authored-by: Ali <83188384+testA113@users.noreply.github.com>
This commit is contained in:
parent
da010f3d08
commit
ea228c3d6d
276 changed files with 9241 additions and 3361 deletions
95
api/kubernetes/cli/resource_quota.go
Normal file
95
api/kubernetes/cli/resource_quota.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/rs/zerolog/log"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// GetResourceQuotas gets all resource quotas in the current k8s environment(endpoint).
|
||||
// if the user is an admin, all resource quotas in all namespaces are fetched.
|
||||
// otherwise, namespaces the non-admin user has access to will be used to filter the resource quotas.
|
||||
func (kcl *KubeClient) GetResourceQuotas(namespace string) (*[]corev1.ResourceQuota, error) {
|
||||
if kcl.IsKubeAdmin {
|
||||
return kcl.fetchResourceQuotas(namespace)
|
||||
}
|
||||
return kcl.fetchResourceQuotasForNonAdmin(namespace)
|
||||
}
|
||||
|
||||
// fetchResourceQuotasForNonAdmin gets the resource quotas in the current k8s environment(endpoint) for a non-admin user.
|
||||
// the role of the user must have read access to the resource quotas in the defined namespaces.
|
||||
func (kcl *KubeClient) fetchResourceQuotasForNonAdmin(namespace string) (*[]corev1.ResourceQuota, error) {
|
||||
log.Debug().Msgf("Fetching resource quotas for non-admin user: %v", kcl.NonAdminNamespaces)
|
||||
|
||||
if len(kcl.NonAdminNamespaces) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
resourceQuotas, err := kcl.fetchResourceQuotas(namespace)
|
||||
if err != nil && !k8serrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonAdminNamespaceSet := kcl.buildNonAdminNamespacesMap()
|
||||
results := []corev1.ResourceQuota{}
|
||||
for _, resourceQuota := range *resourceQuotas {
|
||||
if _, exists := nonAdminNamespaceSet[resourceQuota.Namespace]; exists {
|
||||
results = append(results, resourceQuota)
|
||||
}
|
||||
}
|
||||
|
||||
return &results, nil
|
||||
}
|
||||
|
||||
func (kcl *KubeClient) fetchResourceQuotas(namespace string) (*[]corev1.ResourceQuota, error) {
|
||||
resourceQuotas, err := kcl.cli.CoreV1().ResourceQuotas(namespace).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occured, failed to list resource quotas for the admin user: %w", err)
|
||||
}
|
||||
|
||||
return &resourceQuotas.Items, nil
|
||||
}
|
||||
|
||||
// GetPortainerResourceQuota gets the resource quota for the portainer namespace.
|
||||
// The resource quota is prefixed with "portainer-rq-".
|
||||
func (kcl *KubeClient) GetPortainerResourceQuota(namespace string) (*corev1.ResourceQuota, error) {
|
||||
return kcl.cli.CoreV1().ResourceQuotas(namespace).Get(context.TODO(), "portainer-rq-"+namespace, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
// GetResourceQuota gets a resource quota in a specific namespace.
|
||||
func (kcl *KubeClient) GetResourceQuota(namespace, resourceQuota string) (*corev1.ResourceQuota, error) {
|
||||
return kcl.cli.CoreV1().ResourceQuotas(namespace).Get(context.TODO(), resourceQuota, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
// UpdateNamespacesWithResourceQuotas updates the namespaces with the resource quotas.
|
||||
// The resource quotas are matched with the namespaces by name.
|
||||
func (kcl *KubeClient) UpdateNamespacesWithResourceQuotas(namespaces map[string]portainer.K8sNamespaceInfo, resourceQuotas []corev1.ResourceQuota) []portainer.K8sNamespaceInfo {
|
||||
namespacesWithQuota := map[string]portainer.K8sNamespaceInfo{}
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
resourceQuota := kcl.GetResourceQuotaFromNamespace(namespace, resourceQuotas)
|
||||
if resourceQuota != nil {
|
||||
namespace.ResourceQuota = resourceQuota
|
||||
}
|
||||
|
||||
namespacesWithQuota[namespace.Name] = namespace
|
||||
}
|
||||
|
||||
return kcl.ConvertNamespaceMapToSlice(namespacesWithQuota)
|
||||
}
|
||||
|
||||
// GetResourceQuotaFromNamespace gets the resource quota in a specific namespace where the resource quota's name is prefixed with "portainer-rq-".
|
||||
func (kcl *KubeClient) GetResourceQuotaFromNamespace(namespace portainer.K8sNamespaceInfo, resourceQuotas []corev1.ResourceQuota) *corev1.ResourceQuota {
|
||||
for _, resourceQuota := range resourceQuotas {
|
||||
if resourceQuota.ObjectMeta.Namespace == namespace.Name && resourceQuota.ObjectMeta.Name == "portainer-rq-"+namespace.Name {
|
||||
return &resourceQuota
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue