diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 06408485..3c377298 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -8,6 +8,7 @@ import SelectServer from "./components/select-server"; import ClusterList from "./components/cluster-list"; import ClusterManagement from "./components/cluster-management"; import FederationList from "./components/federation-list"; +import TrustBundleCreate from "components/trustbundle-create"; import AgentList from "./components/agent-list"; import CreateJoinToken from "./components/agent-create-join-token"; import EntryList from "./components/entry-list"; @@ -38,6 +39,7 @@ function App() { + diff --git a/frontend/src/components/navbar.tsx b/frontend/src/components/navbar.tsx index 3e294a68..7d074528 100644 --- a/frontend/src/components/navbar.tsx +++ b/frontend/src/components/navbar.tsx @@ -239,10 +239,12 @@ class NavigationBar extends Component { withAuth={Boolean(withAuth)} subLinks={[ { label: 'Federations List', to: '/federations' }, + { label: 'Obtain Trust Bundle', to: '/trustbundle', adminOnly: true}, + { label: 'Create Federation', to: '/federation/create', adminOnly: true}, ]} /> - +
Tornjak ServerInfo diff --git a/frontend/src/components/trustbundle-create.tsx b/frontend/src/components/trustbundle-create.tsx new file mode 100644 index 00000000..d27ecde1 --- /dev/null +++ b/frontend/src/components/trustbundle-create.tsx @@ -0,0 +1,142 @@ +import { Component } from 'react'; +import axios from 'axios'; +import { InlineNotification, TextArea, Button } from 'carbon-components-react'; +import { ToastContainer } from 'react-toastify'; +import GetApiServerUri from './helpers'; +import TornjakApi from './tornjak-api-helpers'; +import { connect } from 'react-redux'; +import { + tornjakMessageFunc, + serverInfoUpdateFunc, + agentsListUpdateFunc, + clusterTypeInfoFunc, + tornjakServerInfoUpdateFunc, + selectorInfoFunc, + serverSelectedFunc +} from 'redux/actions'; +import { RootState } from 'redux/reducers'; +import { showResponseToast } from './error-api'; +import './style.css'; + +type TrustBundleCreateProps = { + tornjakMessageFunc: (globalErrorMessage: string) => void, + serverInfoUpdateFunc: Function, + agentsListUpdateFunc: Function, + clusterTypeInfoFunc: Function, + tornjakServerInfoUpdateFunc: Function, + selectorInfoFunc: Function, + serverSelectedFunc: Function, + globalErrorMessage: string, + globalServerSelected: string, +}; + +type TrustBundleCreateState = { + trustBundle: string, + loading: boolean, + error: string +} + +class TrustBundleCreate extends Component { + TornjakApi: TornjakApi; + constructor(props: TrustBundleCreateProps) { + super(props); + this.TornjakApi = new TornjakApi(props); + this.state = { + trustBundle: "", + loading: false, + error: "" + }; + this.getTrustBundle = this.getTrustBundle.bind(this); + } + + getTrustBundle() { + this.setState({loading: true, error: "", trustBundle: ""}); + const endpoint = GetApiServerUri('/api/v1/spire/bundle'); + + console.log("Got: " + endpoint); + + axios.get(endpoint) + .then(res => { + this.setState({ + trustBundle: JSON.stringify(res.data, null, 2), + loading: false + }); + }) + .catch(err => { + console.error("Error fetching trust bundle:", err); + let errorMessage = "Failed to fetch trust bundle. Could not connect to backend"; + if (err.response) { + errorMessage = `Failed to fetch trust bundle. Server returned status ${err.response.status}`; + } else if (err.request) { + errorMessage = "Failed to fetch trust bundle. No response received from backend."; + } + + this.setState({loading: false, error: errorMessage}); + showResponseToast(err); + }); + } + + render() { + const { trustBundle, loading, error } = this.state; + return ( +
+

Obtain Trust Bundle

+
+ +
+ {loading && ( + + )} + {error && ( + + )} + {!loading && !error && trustBundle && ( +
+