mirror of https://github.com/portainer/portainer
fix showing namespaces for standard user (#7917)
parent
446febb0f6
commit
a550bfaedb
|
@ -62,6 +62,7 @@ func NewHandler(bouncer *security.RequestBouncer, authorizationService *authoriz
|
||||||
endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.updateKubernetesNamespace)).Methods(http.MethodPut)
|
endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.updateKubernetesNamespace)).Methods(http.MethodPut)
|
||||||
endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.getKubernetesNamespaces)).Methods(http.MethodGet)
|
endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.getKubernetesNamespaces)).Methods(http.MethodGet)
|
||||||
endpointRouter.Path("/namespace/{namespace}").Handler(httperror.LoggerHandler(h.deleteKubernetesNamespaces)).Methods(http.MethodDelete)
|
endpointRouter.Path("/namespace/{namespace}").Handler(httperror.LoggerHandler(h.deleteKubernetesNamespaces)).Methods(http.MethodDelete)
|
||||||
|
endpointRouter.Path("/namespaces/{namespace}").Handler(httperror.LoggerHandler(h.getKubernetesNamespace)).Methods(http.MethodGet)
|
||||||
|
|
||||||
// namespaces
|
// namespaces
|
||||||
// in the future this piece of code might be in another package (or a few different packages - namespaces/namespace?)
|
// in the future this piece of code might be in another package (or a few different packages - namespaces/namespace?)
|
||||||
|
|
|
@ -40,6 +40,43 @@ func (handler *Handler) getKubernetesNamespaces(w http.ResponseWriter, r *http.R
|
||||||
return response.JSON(w, namespaces)
|
return response.JSON(w, namespaces)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (handler *Handler) getKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||||
|
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||||
|
if err != nil {
|
||||||
|
return httperror.BadRequest(
|
||||||
|
"Invalid environment identifier route variable",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
||||||
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
||||||
|
)
|
||||||
|
if !ok {
|
||||||
|
return httperror.InternalServerError(
|
||||||
|
"Failed to lookup KubeClient",
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns, err := request.RetrieveRouteVariableValue(r, "namespace")
|
||||||
|
if err != nil {
|
||||||
|
return httperror.BadRequest(
|
||||||
|
"Invalid namespace identifier route variable",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
namespace, err := cli.GetNamespace(ns)
|
||||||
|
if err != nil {
|
||||||
|
return httperror.InternalServerError(
|
||||||
|
"Unable to retrieve namespace",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.JSON(w, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -44,6 +44,21 @@ func (kcl *KubeClient) GetNamespaces() (map[string]portainer.K8sNamespaceInfo, e
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNamespace gets the namespace in the current k8s environment(endpoint).
|
||||||
|
func (kcl *KubeClient) GetNamespace(name string) (portainer.K8sNamespaceInfo, error) {
|
||||||
|
namespace, err := kcl.cli.CoreV1().Namespaces().Get(context.TODO(), name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return portainer.K8sNamespaceInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := portainer.K8sNamespaceInfo{
|
||||||
|
IsSystem: isSystemNamespace(*namespace),
|
||||||
|
IsDefault: namespace.Name == defaultNamespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateIngress creates a new ingress in a given namespace in a k8s endpoint.
|
// CreateIngress creates a new ingress in a given namespace in a k8s endpoint.
|
||||||
func (kcl *KubeClient) CreateNamespace(info models.K8sNamespaceDetails) error {
|
func (kcl *KubeClient) CreateNamespace(info models.K8sNamespaceDetails) error {
|
||||||
client := kcl.cli.CoreV1().Namespaces()
|
client := kcl.cli.CoreV1().Namespaces()
|
||||||
|
|
|
@ -1357,6 +1357,7 @@ type (
|
||||||
CreateNamespace(info models.K8sNamespaceDetails) error
|
CreateNamespace(info models.K8sNamespaceDetails) error
|
||||||
UpdateNamespace(info models.K8sNamespaceDetails) error
|
UpdateNamespace(info models.K8sNamespaceDetails) error
|
||||||
GetNamespaces() (map[string]K8sNamespaceInfo, error)
|
GetNamespaces() (map[string]K8sNamespaceInfo, error)
|
||||||
|
GetNamespace(string) (K8sNamespaceInfo, error)
|
||||||
DeleteNamespace(namespace string) error
|
DeleteNamespace(namespace string) error
|
||||||
GetConfigMapsAndSecrets(namespace string) ([]models.K8sConfigMapOrSecret, error)
|
GetConfigMapsAndSecrets(namespace string) ([]models.K8sConfigMapOrSecret, error)
|
||||||
GetIngressControllers() (models.K8sIngressControllers, error)
|
GetIngressControllers() (models.K8sIngressControllers, error)
|
||||||
|
|
|
@ -2,13 +2,29 @@ import { useQuery } from 'react-query';
|
||||||
|
|
||||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||||
import { error as notifyError } from '@/portainer/services/notifications';
|
import { error as notifyError } from '@/portainer/services/notifications';
|
||||||
|
import { getIngresses } from '@/kubernetes/react/views/networks/ingresses/service';
|
||||||
|
|
||||||
import { getNamespaces, getNamespace } from './service';
|
import { getNamespaces, getNamespace } from './service';
|
||||||
|
import { Namespaces } from './types';
|
||||||
|
|
||||||
export function useNamespaces(environmentId: EnvironmentId) {
|
export function useNamespaces(environmentId: EnvironmentId) {
|
||||||
return useQuery(
|
return useQuery(
|
||||||
['environments', environmentId, 'kubernetes', 'namespaces'],
|
['environments', environmentId, 'kubernetes', 'namespaces'],
|
||||||
() => getNamespaces(environmentId),
|
async () => {
|
||||||
|
const namespaces = await getNamespaces(environmentId);
|
||||||
|
const settledNamespacesPromise = await Promise.allSettled(
|
||||||
|
Object.keys(namespaces).map((namespace) =>
|
||||||
|
getIngresses(environmentId, namespace).then(() => namespace)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const ns: Namespaces = {};
|
||||||
|
settledNamespacesPromise.forEach((namespace) => {
|
||||||
|
if (namespace.status === 'fulfilled') {
|
||||||
|
ns[namespace.value] = namespaces[namespace.value];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ns;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
onError: (err) => {
|
onError: (err) => {
|
||||||
notifyError('Failure', err as Error, 'Unable to get namespaces.');
|
notifyError('Failure', err as Error, 'Unable to get namespaces.');
|
||||||
|
|
|
@ -8,23 +8,23 @@ export async function getNamespace(
|
||||||
namespace: string
|
namespace: string
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const { data: ingress } = await axios.get<Namespaces>(
|
const { data: ns } = await axios.get<Namespaces>(
|
||||||
buildUrl(environmentId, namespace)
|
buildUrl(environmentId, namespace)
|
||||||
);
|
);
|
||||||
return ingress;
|
return ns;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw parseAxiosError(e as Error, 'Unable to retrieve network details');
|
throw parseAxiosError(e as Error, 'Unable to retrieve namespace');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNamespaces(environmentId: EnvironmentId) {
|
export async function getNamespaces(environmentId: EnvironmentId) {
|
||||||
try {
|
try {
|
||||||
const { data: ingresses } = await axios.get<Namespaces>(
|
const { data: namespaces } = await axios.get<Namespaces>(
|
||||||
buildUrl(environmentId)
|
buildUrl(environmentId)
|
||||||
);
|
);
|
||||||
return ingresses;
|
return namespaces;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw parseAxiosError(e as Error, 'Unable to retrieve network details');
|
throw parseAxiosError(e as Error, 'Unable to retrieve namespaces');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue