diff --git a/ui/litellm-dashboard/src/components/admins.tsx b/ui/litellm-dashboard/src/components/admins.tsx index 94722923b..85b5dc3d4 100644 --- a/ui/litellm-dashboard/src/components/admins.tsx +++ b/ui/litellm-dashboard/src/components/admins.tsx @@ -50,6 +50,9 @@ import { setCallbacksCall, invitationCreateCall, getPossibleUserRoles, + addAllowedIP, + getAllowedIPs, + deleteAllowedIP, } from "./networking"; const AdminPanel: React.FC = ({ @@ -98,29 +101,60 @@ const AdminPanel: React.FC = ({ } nonSssoUrl += "/fallback/login"; - const handleShowAllowedIPs = () => { - // In a real application, you would fetch the allowed IPs from your backend here - setAllowedIPs(['192.168.1.1', '10.0.0.1', '172.16.0.1']); - setIsAllowedIPModalVisible(true); + const handleShowAllowedIPs = async () => { + try { + if (accessToken) { + const data = await getAllowedIPs(accessToken); + setAllowedIPs(data.length > 0 ? data : ["All IP Addresses"]); + } else { + setAllowedIPs(["All IP Addresses"]); + } + } catch (error) { + console.error("Error fetching allowed IPs:", error); + message.error("Failed to fetch allowed IPs"); + setAllowedIPs(["All IP Addresses"]); + } finally { + setIsAllowedIPModalVisible(true); + } }; - - const handleAddIP = (values: { ip: string }) => { - setAllowedIPs([...allowedIPs, values.ip]); - setIsAddIPModalVisible(false); - message.success('IP address added successfully'); + + const handleAddIP = async (values: { ip: string }) => { + try { + if (accessToken) { + await addAllowedIP(accessToken, values.ip); + // Fetch the updated list of IPs + const updatedIPs = await getAllowedIPs(accessToken); + setAllowedIPs(updatedIPs); + message.success('IP address added successfully'); + } + } catch (error) { + console.error("Error adding IP:", error); + message.error('Failed to add IP address'); + } finally { + setIsAddIPModalVisible(false); + } }; - - const handleDeleteIP = (ip: string) => { + + const handleDeleteIP = async (ip: string) => { setIPToDelete(ip); setIsDeleteIPModalVisible(true); }; - - const confirmDeleteIP = () => { - if (ipToDelete) { - setAllowedIPs(allowedIPs.filter(ip => ip !== ipToDelete)); - setIsDeleteIPModalVisible(false); - setIPToDelete(null); - message.success('IP address deleted successfully'); + + const confirmDeleteIP = async () => { + if (ipToDelete && accessToken) { + try { + await deleteAllowedIP(accessToken, ipToDelete); + // Fetch the updated list of IPs + const updatedIPs = await getAllowedIPs(accessToken); + setAllowedIPs(updatedIPs.length > 0 ? updatedIPs : ["All IP Addresses"]); + message.success('IP address deleted successfully'); + } catch (error) { + console.error("Error deleting IP:", error); + message.error('Failed to delete IP address'); + } finally { + setIsDeleteIPModalVisible(false); + setIPToDelete(null); + } } }; diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 75819af58..e50fc37e8 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -788,6 +788,95 @@ export const modelHubCall = async (accessToken: String) => { } }; +// Function to get allowed IPs +export const getAllowedIPs = async (accessToken: String) => { + try { + let url = proxyBaseUrl + ? `${proxyBaseUrl}/get/allowed_ips` + : `/get/allowed_ips`; + + const response = await fetch(url, { + method: "GET", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + throw new Error(`Network response was not ok: ${errorData}`); + } + + const data = await response.json(); + console.log("getAllowedIPs:", data); + return data.data; // Assuming the API returns { data: [...] } + } catch (error) { + console.error("Failed to get allowed IPs:", error); + throw error; + } +}; + +// Function to add an allowed IP +export const addAllowedIP = async (accessToken: String, ip: String) => { + try { + let url = proxyBaseUrl + ? `${proxyBaseUrl}/add/allowed_ip` + : `/add/allowed_ip`; + + const response = await fetch(url, { + method: "POST", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ ip: ip }), + }); + + if (!response.ok) { + const errorData = await response.text(); + throw new Error(`Network response was not ok: ${errorData}`); + } + + const data = await response.json(); + console.log("addAllowedIP:", data); + return data; + } catch (error) { + console.error("Failed to add allowed IP:", error); + throw error; + } +}; + +// Function to delete an allowed IP +export const deleteAllowedIP = async (accessToken: String, ip: String) => { + try { + let url = proxyBaseUrl + ? `${proxyBaseUrl}/delete/allowed_ip` + : `/delete/allowed_ip`; + + const response = await fetch(url, { + method: "POST", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ ip: ip }), + }); + + if (!response.ok) { + const errorData = await response.text(); + throw new Error(`Network response was not ok: ${errorData}`); + } + + const data = await response.json(); + console.log("deleteAllowedIP:", data); + return data; + } catch (error) { + console.error("Failed to delete allowed IP:", error); + throw error; + } +}; + export const modelMetricsCall = async ( accessToken: String, userID: String,