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.getKubernetesNamespaces)).Methods(http.MethodGet)
|
||||
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
|
||||
// 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)
|
||||
}
|
||||
|
||||
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 {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
|
|
@ -44,6 +44,21 @@ func (kcl *KubeClient) GetNamespaces() (map[string]portainer.K8sNamespaceInfo, e
|
|||
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.
|
||||
func (kcl *KubeClient) CreateNamespace(info models.K8sNamespaceDetails) error {
|
||||
client := kcl.cli.CoreV1().Namespaces()
|
||||
|
|
|
@ -1357,6 +1357,7 @@ type (
|
|||
CreateNamespace(info models.K8sNamespaceDetails) error
|
||||
UpdateNamespace(info models.K8sNamespaceDetails) error
|
||||
GetNamespaces() (map[string]K8sNamespaceInfo, error)
|
||||
GetNamespace(string) (K8sNamespaceInfo, error)
|
||||
DeleteNamespace(namespace string) error
|
||||
GetConfigMapsAndSecrets(namespace string) ([]models.K8sConfigMapOrSecret, error)
|
||||
GetIngressControllers() (models.K8sIngressControllers, error)
|
||||
|
|
|
@ -2,13 +2,29 @@ import { useQuery } from 'react-query';
|
|||
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import { error as notifyError } from '@/portainer/services/notifications';
|
||||
import { getIngresses } from '@/kubernetes/react/views/networks/ingresses/service';
|
||||
|
||||
import { getNamespaces, getNamespace } from './service';
|
||||
import { Namespaces } from './types';
|
||||
|
||||
export function useNamespaces(environmentId: EnvironmentId) {
|
||||
return useQuery(
|
||||
['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) => {
|
||||
notifyError('Failure', err as Error, 'Unable to get namespaces.');
|
||||
|
|
|
@ -8,23 +8,23 @@ export async function getNamespace(
|
|||
namespace: string
|
||||
) {
|
||||
try {
|
||||
const { data: ingress } = await axios.get<Namespaces>(
|
||||
const { data: ns } = await axios.get<Namespaces>(
|
||||
buildUrl(environmentId, namespace)
|
||||
);
|
||||
return ingress;
|
||||
return ns;
|
||||
} 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) {
|
||||
try {
|
||||
const { data: ingresses } = await axios.get<Namespaces>(
|
||||
const { data: namespaces } = await axios.get<Namespaces>(
|
||||
buildUrl(environmentId)
|
||||
);
|
||||
return ingresses;
|
||||
return namespaces;
|
||||
} 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