Преглед изворни кода

removed deprecated provisioner redirects

jusrhee пре 5 година
родитељ
комит
19e9f8ea4e

+ 91 - 79
dashboard/src/main/Main.tsx

@@ -1,59 +1,57 @@
-import React, { Component } from 'react';
-import styled, { createGlobalStyle } from 'styled-components';
-import { BrowserRouter, Route, Redirect, Switch } from 'react-router-dom';
-import close from 'assets/close.png';
-
-import api from 'shared/api';
-import { Context } from 'shared/Context';
-
-import Login from './Login';
-import Register from './Register';
-import CurrentError from './CurrentError';
-import Home from './home/Home';
-import Loading from 'components/Loading';
-import PorterUrls from 'shared/urls';
-
-type PropsType = {
-};
+import React, { Component } from "react";
+import styled, { createGlobalStyle } from "styled-components";
+import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
+import close from "assets/close.png";
+
+import api from "shared/api";
+import { Context } from "shared/Context";
+
+import Login from "./Login";
+import Register from "./Register";
+import CurrentError from "./CurrentError";
+import Home from "./home/Home";
+import Loading from "components/Loading";
+import { PorterUrls } from "shared/urls";
+
+type PropsType = {};
 
 
 type StateType = {
 type StateType = {
-  loading: boolean,
-  isLoggedIn: boolean,
-  initialized: boolean,
+  loading: boolean;
+  isLoggedIn: boolean;
+  initialized: boolean;
 };
 };
 
 
 export default class Main extends Component<PropsType, StateType> {
 export default class Main extends Component<PropsType, StateType> {
-  
   state = {
   state = {
     loading: true,
     loading: true,
-    isLoggedIn : false,
-    initialized: localStorage.getItem("init") === 'true'
-  }
+    isLoggedIn: false,
+    initialized: localStorage.getItem("init") === "true",
+  };
 
 
   componentDidMount() {
   componentDidMount() {
     let { setUser } = this.context;
     let { setUser } = this.context;
-    api.checkAuth('', {}, {}, (err: any, res: any) => {    
+    api.checkAuth("", {}, {}, (err: any, res: any) => {
       if (err && err.response?.status == 403) {
       if (err && err.response?.status == 403) {
-        this.setState({ isLoggedIn: false, loading: false })
+        this.setState({ isLoggedIn: false, loading: false });
       }
       }
 
 
       if (res && res.data) {
       if (res && res.data) {
         setUser(res?.data?.id, res?.data?.email);
         setUser(res?.data?.id, res?.data?.email);
         this.setState({ isLoggedIn: true, initialized: true, loading: false });
         this.setState({ isLoggedIn: true, initialized: true, loading: false });
       } else {
       } else {
-        this.setState({ isLoggedIn: false, loading: false })
+        this.setState({ isLoggedIn: false, loading: false });
       }
       }
     });
     });
   }
   }
 
 
   initialize = () => {
   initialize = () => {
-    this.setState({isLoggedIn: true, initialized: true});
-    localStorage.setItem('init', 'true');
-  }
-  
+    this.setState({ isLoggedIn: true, initialized: true });
+    localStorage.setItem("init", "true");
+  };
+
   authenticate = () => {
   authenticate = () => {
     this.setState({ isLoggedIn: true, initialized: true });
     this.setState({ isLoggedIn: true, initialized: true });
-  }
+  };
 
 
   handleLogOut = () => {
   handleLogOut = () => {
     // Clears local storage for proper rendering of clusters
     // Clears local storage for proper rendering of clusters
@@ -61,75 +59,89 @@ export default class Main extends Component<PropsType, StateType> {
 
 
     this.context.clearContext();
     this.context.clearContext();
     this.setState({ isLoggedIn: false, initialized: true });
     this.setState({ isLoggedIn: false, initialized: true });
-  }
+  };
 
 
   renderMain = () => {
   renderMain = () => {
     if (this.state.loading) {
     if (this.state.loading) {
-      return <Loading />
+      return <Loading />;
     }
     }
 
 
     const authedUrls: PorterUrls[] = [
     const authedUrls: PorterUrls[] = [
-      "dashboard", "templates", "integrations", "new-project",
-      "cluster-dashboard", "provisioner", "project-settings"
+      "dashboard",
+      "templates",
+      "integrations",
+      "new-project",
+      "cluster-dashboard",
+      "provisioner",
+      "project-settings",
     ];
     ];
 
 
     return (
     return (
       <Switch>
       <Switch>
-        <Route path='/login' render={() => {
-          if (!this.state.isLoggedIn) {
-            return <Login authenticate={this.authenticate} />
-          } else {
-            return <Redirect to='/' />
-          }
-        }} />
-
-        <Route path='/register' render={() => {
-          if (!this.state.isLoggedIn) {
-            return <Register authenticate={this.initialize} />
-          } else {
-            return <Redirect to='/' />
-          }
-        }} />
-
-        // TODO: Possible template this into a map from url to routed home
-        {...authedUrls.map(route =>
-            <Route path={`/${route}`} render={() => {
-            if (this.state.isLoggedIn && this.state.initialized) {
+        <Route
+          path="/login"
+          render={() => {
+            if (!this.state.isLoggedIn) {
+              return <Login authenticate={this.authenticate} />;
+            } else {
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path="/register"
+          render={() => {
+            if (!this.state.isLoggedIn) {
+              return <Register authenticate={this.initialize} />;
+            } else {
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path={`/:subroute`}
+          render={(routeProps) => {
+            const urlRoute = routeProps.location.pathname.slice(1);
+            if (
+              this.state.isLoggedIn &&
+              this.state.initialized &&
+              PorterUrls.includes(urlRoute)
+            ) {
               return (
               return (
-                <Home 
+                <Home
+                  key="home"
                   currentProject={this.context.currentProject}
                   currentProject={this.context.currentProject}
-                  currentCluster={this.context.currentCluster} 
-                  currentRoute={route}
-                  logOut={this.handleLogOut} 
+                  currentCluster={this.context.currentCluster}
+                  currentRoute={urlRoute as PorterUrls}
+                  logOut={this.handleLogOut}
                 />
                 />
               );
               );
             } else {
             } else {
-              return <Redirect to='/' />
+              return <Redirect to="/" />;
+            }
+          }}
+        />
+        <Route
+          path="/"
+          render={() => {
+            if (this.state.isLoggedIn) {
+              return <Redirect to="/dashboard" />;
+            } else if (this.state.initialized) {
+              return <Redirect to="/login" />;
+            } else {
+              return <Redirect to="/register" />;
             }
             }
-          }}/>
-        )}
-        
-
-        <Route path='/' render={() => {
-          if (this.state.isLoggedIn) {
-            return <Redirect to='/dashboard'/>
-          } else if (this.state.initialized) {
-            return <Redirect to='/login'/>
-          } else {
-            return <Redirect to='/register' />
-          }
-        }}/>
+          }}
+        />
       </Switch>
       </Switch>
     );
     );
-  }
+  };
 
 
   render() {
   render() {
     return (
     return (
       <StyledMain>
       <StyledMain>
         <GlobalStyle />
         <GlobalStyle />
-        <BrowserRouter>
-          {this.renderMain()}
-        </BrowserRouter>
+        <BrowserRouter>{this.renderMain()}</BrowserRouter>
         <CurrentError currentError={this.context.currentError} />
         <CurrentError currentError={this.context.currentError} />
       </StyledMain>
       </StyledMain>
     );
     );
@@ -167,4 +179,4 @@ const StyledMain = styled.div`
   left: 0;
   left: 0;
   background: #202227;
   background: #202227;
   color: white;
   color: white;
-`;
+`;

+ 6 - 10
dashboard/src/main/home/Home.tsx

@@ -5,7 +5,6 @@ import styled from 'styled-components';
 import { Context } from 'shared/Context';
 import { Context } from 'shared/Context';
 import api from 'shared/api';
 import api from 'shared/api';
 import { ClusterType, ProjectType } from 'shared/types';
 import { ClusterType, ProjectType } from 'shared/types';
-import { includesCompletedInfraSet } from 'shared/common';
 
 
 import Sidebar from './sidebar/Sidebar';
 import Sidebar from './sidebar/Sidebar';
 import Dashboard from './dashboard/Dashboard';
 import Dashboard from './dashboard/Dashboard';
@@ -24,7 +23,7 @@ import ConfirmOverlay from 'components/ConfirmOverlay';
 import Modal from './modals/Modal';
 import Modal from './modals/Modal';
 import * as FullStory from '@fullstory/browser';
 import * as FullStory from '@fullstory/browser';
 import { Redirect, RouteComponentProps, withRouter } from 'react-router';
 import { Redirect, RouteComponentProps, withRouter } from 'react-router';
-import PorterUrls from 'shared/urls';
+import {PorterUrls} from 'shared/urls';
 
 
 type PropsType = RouteComponentProps & {
 type PropsType = RouteComponentProps & {
   logOut: () => void,
   logOut: () => void,
@@ -42,7 +41,6 @@ type StateType = {
 
 
   // Track last project id for refreshing clusters on project change
   // Track last project id for refreshing clusters on project change
   prevProjectId: number | null,
   prevProjectId: number | null,
-  sidebarReady: boolean, // Fixes error where ~1/3 times reloading to provisioner fails
 };
 };
 
 
 // TODO: Handle cluster connected but with some failed infras (no successful set)
 // TODO: Handle cluster connected but with some failed infras (no successful set)
@@ -65,10 +63,9 @@ class Home extends Component<PropsType, StateType> {
 
 
     if (this.state.ghRedirect) {
     if (this.state.ghRedirect) {
       this.props.history.push("integrations");
       this.props.history.push("integrations");
-      this.setState({ sidebarReady: true, ghRedirect: false });
+      this.setState({ ghRedirect: false });
     } else {
     } else {
       this.props.history.push("dashboard");
       this.props.history.push("dashboard");
-      this.setState({ sidebarReady: true });
     }
     }
   }
   }
 
 
@@ -80,7 +77,7 @@ class Home extends Component<PropsType, StateType> {
         console.log(err);
         console.log(err);
       } else if (res.data) {
       } else if (res.data) {
         if (res.data.length === 0) {
         if (res.data.length === 0) {
-          <Redirect to="new-project"></Redirect>
+          this.props.history.push("new-project");
         } else if (res.data.length > 0 && !currentProject) {
         } else if (res.data.length > 0 && !currentProject) {
           setProjects(res.data);
           setProjects(res.data);
 
 
@@ -92,7 +89,6 @@ class Home extends Component<PropsType, StateType> {
               } 
               } 
             });
             });
             this.context.setCurrentProject(foundProject);
             this.context.setCurrentProject(foundProject);
-            <Redirect to="provisioner"></Redirect>
           }
           }
 
 
           if (!foundProject) {
           if (!foundProject) {
@@ -214,7 +210,7 @@ class Home extends Component<PropsType, StateType> {
   }
   }
 
 
   // TODO: Need to handle the following cases. Do a deep rearchitecture (Prov -> Dashboard?) if need be:
   // TODO: Need to handle the following cases. Do a deep rearchitecture (Prov -> Dashboard?) if need be:
-  // 1. Make sure clicking cluster in course drawer shows cluster-dashboard
+  // 1. Make sure clicking cluster in drawer shows cluster-dashboard
   // 2. Make sure switching projects shows appropriate initial view (dashboard || provisioner)
   // 2. Make sure switching projects shows appropriate initial view (dashboard || provisioner)
   // 3. Make sure initializing from URL (DO oauth) displays the appropriate initial view
   // 3. Make sure initializing from URL (DO oauth) displays the appropriate initial view
   componentDidUpdate(prevProps: PropsType) {
   componentDidUpdate(prevProps: PropsType) {
@@ -264,7 +260,6 @@ class Home extends Component<PropsType, StateType> {
   }
   }
 
 
   renderContents = () => {
   renderContents = () => {
-    // let { handleDO } = this.state;
     let currentView = this.props.currentRoute;
     let currentView = this.props.currentRoute;
     if (this.context.currentProject && currentView !== 'new-project') {
     if (this.context.currentProject && currentView !== 'new-project') {
       if (currentView === 'cluster-dashboard') {
       if (currentView === 'cluster-dashboard') {
@@ -304,6 +299,7 @@ class Home extends Component<PropsType, StateType> {
       } else {
       } else {
         return (
         return (
           <Sidebar
           <Sidebar
+            key="sidebar"
             forceSidebar={this.state.forceSidebar}
             forceSidebar={this.state.forceSidebar}
             setWelcome={(x: boolean) => this.setState({ showWelcome: x })}
             setWelcome={(x: boolean) => this.setState({ showWelcome: x })}
             currentView={this.props.currentRoute}
             currentView={this.props.currentRoute}
@@ -400,7 +396,7 @@ class Home extends Component<PropsType, StateType> {
         }
         }
       }
       }
     });
     });
-    setCurrentModal(null, null)
+    setCurrentModal(null, null);
     this.props.history.push("dashboard");
     this.props.history.push("dashboard");
   }
   }
 
 

+ 13 - 3
dashboard/src/main/home/modals/UpdateClusterModal.tsx

@@ -9,8 +9,9 @@ import { Context } from 'shared/Context';
 import SaveButton from 'components/SaveButton';
 import SaveButton from 'components/SaveButton';
 import InputRow from 'components/values-form/InputRow';
 import InputRow from 'components/values-form/InputRow';
 import ConfirmOverlay from 'components/ConfirmOverlay';
 import ConfirmOverlay from 'components/ConfirmOverlay';
+import { RouteComponentProps, withRouter } from 'react-router';
 
 
-type PropsType = {
+type PropsType = RouteComponentProps & {
   setRefreshClusters: (x: boolean) => void,
   setRefreshClusters: (x: boolean) => void,
 };
 };
 
 
@@ -20,7 +21,7 @@ type StateType = {
   showDeleteOverlay: boolean
   showDeleteOverlay: boolean
 };
 };
 
 
-export default class UpdateClusterModal extends Component<PropsType, StateType> {
+class UpdateClusterModal extends Component<PropsType, StateType> {
   state = {
   state = {
     clusterName: this.context.currentCluster.name,
     clusterName: this.context.currentCluster.name,
     status: null as string | null,
     status: null as string | null,
@@ -42,7 +43,14 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
         return;
         return;
       }
       }
 
 
-      if (!currentCluster?.infra_id) return;
+      if (!currentCluster?.infra_id) {
+        // TODO: make this more declarative from the Home component
+        this.props.setRefreshClusters(true);
+        this.setState({ status: 'successful', showDeleteOverlay: false });
+        this.context.setCurrentModal(null, null);
+        this.props.history.push("dashboard");
+        return;
+      }
 
 
       // Handle destroying infra we've provisioned
       // Handle destroying infra we've provisioned
       switch (currentCluster.service) {
       switch (currentCluster.service) {
@@ -169,6 +177,8 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
 
 
 UpdateClusterModal.contextType = Context;
 UpdateClusterModal.contextType = Context;
 
 
+export default withRouter(UpdateClusterModal);
+
 const Help = styled.a`
 const Help = styled.a`
   position: absolute;
   position: absolute;
   left: 31px;
   left: 31px;

+ 1 - 1
dashboard/src/main/home/project-settings/InviteList.tsx

@@ -312,7 +312,7 @@ const InviteButton = styled.div<{ disabled: boolean }>`
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   padding: 0 15px;
   padding: 0 15px;
-  margin-top: 10px;
+  margin-top: 13px;
   text-align: left;
   text-align: left;
   background: red;
   background: red;
   float: left;
   float: left;

+ 1 - 0
dashboard/src/main/home/provisioner/Provisioner.tsx

@@ -109,6 +109,7 @@ const StyledProvisioner = styled.div`
   width: 100%;
   width: 100%;
   height: 350px;
   height: 350px;
   background: #ffffff11;
   background: #ffffff11;
+  color: #aaaabb;
   border-radius: 5px;
   border-radius: 5px;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;

+ 0 - 433
dashboard/src/main/home/provisioner/ProvisionerStatus.tsx

@@ -1,433 +0,0 @@
-import React, { Component } from 'react';
-import styled from 'styled-components';
-import posthog from 'posthog-js';
-
-import api from 'shared/api';
-import { Context } from 'shared/Context';
-import ansiparse from 'shared/ansiparser'
-import loading from 'assets/loading.gif';
-import warning from 'assets/warning.png';
-import { InfraType } from 'shared/types';
-import { filterOldInfras } from 'shared/common';
-
-import Helper from 'components/values-form/Helper';
-import InfraStatuses from './InfraStatuses';
-import { RouteComponentProps, withRouter } from "react-router";
-import { Link } from "react-router-dom";
-
-type PropsType = RouteComponentProps & {};
-
-type StateType = {
-  error: boolean,
-  logs: string[],
-  websockets: any[],
-  maxStep : Record<string, number>,
-  currentStep: Record<string, number>,
-  triggerEnd: boolean,
-  infras: InfraType[],
-};
-
-const dummyInfras = [
-  { kind: 'ecr', status: 'creating', id: 5, project_id: 1 }, 
-  { kind: 'eks', status: 'error', id: 3, project_id: 1 },
-  { kind: 'eks', status: 'error', id: 1, project_id: 1 },
-  { kind: 'eks', status: 'error', id: 4, project_id: 1 },
-  { kind: 'ecr', status: 'created', id: 2, project_id: 1 },
-];
-
-class ProvisionerStatus extends Component<PropsType, StateType> {
-  state = {
-    error: false,
-    logs: [] as string[],
-    websockets : [] as any[],
-    maxStep: {} as Record<string, any>,
-    currentStep: {} as Record<string, number>,
-    triggerEnd: false,
-    infras: [] as InfraType[],
-  }
-
-  parentRef = React.createRef<HTMLDivElement>()
-
-  scrollToBottom = (smooth: boolean) => {
-    if (smooth) {
-      this.parentRef.current.lastElementChild.scrollIntoView({ behavior: "smooth" })
-    } else {
-      this.parentRef.current.lastElementChild.scrollIntoView({ behavior: "auto" })
-    }
-  }
-
-  componentDidMount() {
-    console.log('mounting provisioner')
-    let { currentProject } = this.context;
-    let protocol = process.env.NODE_ENV == 'production' ? 'wss' : 'ws'
-
-    // Check if current project is provisioning
-    api.getInfra('<token>', {}, { 
-      project_id: currentProject.id 
-    }, (err: any, res: any) => {
-      if (err) {
-        console.log(err);
-      } 
-      
-      let infras = filterOldInfras(res.data);
-      let error = false;
-
-      let maxStep = {} as Record<string, number>
-
-      infras.forEach((infra: InfraType, i: number) => {
-        maxStep[infra.kind] = null;
-        if (infra.status === 'error') {
-          error = true;
-        }
-      });
-
-      // Filter historical infras list for most current instances of each
-      let websockets = infras.map((infra: any) => {
-        let ws = new WebSocket(`${protocol}://${process.env.API_SERVER}/api/projects/${currentProject.id}/provision/${infra.kind}/${infra.id}/logs`)
-        return this.setupWebsocket(ws, infra)
-      });
-  
-      this.setState({ error, infras, websockets, maxStep, logs: ["Provisioning resources..."] });
-    });
-  }
-
-  componentWillUnmount() {
-    if (this.state.websockets.length == 0) { return; }
-
-    this.state.websockets.forEach((ws: any) => {
-      ws.close()
-    })
-  }
-
-  isJSON = (str: string) => {
-    try {
-      JSON.parse(str);
-    } catch (e) {
-      return false;
-    }
-    return true;
-  }
-
-  setupWebsocket = (ws: WebSocket, infra: any) => {
-    ws.onopen = () => {
-      console.log('connected to websocket')
-    }
-
-    ws.onmessage = (evt: MessageEvent) => {
-      let event = JSON.parse(evt.data);
-      let validEvents = [] as any[];
-      let err = null;
-      
-      for (var i = 0; i < event.length; i++) {
-        let msg = event[i];
-        if (msg["Values"] && msg["Values"]["data"] && this.isJSON(msg["Values"]["data"])) { 
-          let d = JSON.parse(msg["Values"]["data"]);
-
-          if (d["kind"] == "error") {
-            err = d["log"];
-            break;
-          }
-
-          // add only valid events
-          if (d["log"] != null && d["created_resources"] != null && d["total_resources"] != null) {
-            validEvents.push(d);
-          }
-        }
-      }
-
-      if (err) {
-        posthog.capture('Provisioning Error', {error: err});
-
-        let e = ansiparse(err).map((el: any) => {
-          return el.text;
-        })
-
-        let index = this.state.infras.findIndex(el => el.kind === infra.kind)
-        infra.status = "error"
-        let infras = this.state.infras
-        infras[index] = infra
-        this.setState({ logs: [...this.state.logs, ...e], error: true, infras });
-        return;
-      }
-
-      if (validEvents.length == 0) {
-        return;
-      }
-
-      if (!this.state.maxStep[infra.kind] || !this.state.maxStep[infra.kind]["total_resources"]) {
-        this.setState({
-          maxStep: {
-            ...this.state.maxStep,
-            [infra.kind] : validEvents[validEvents.length - 1]["total_resources"]
-          }
-        })
-      }
-      
-      let logs = [] as any[]
-      validEvents.forEach((e: any) => {
-        logs.push(...ansiparse(e["log"]))
-      })
-
-      logs = logs.map((log: any) => {
-        return log.text
-      })
-
-      this.setState({ 
-        logs: [...this.state.logs, ...logs], 
-        currentStep: {
-          ...this.state.currentStep,
-          [infra.kind] : validEvents[validEvents.length - 1]["created_resources"]
-        },
-      }, () => {
-        this.scrollToBottom(false)
-      })
-    }
-
-    ws.onerror = (err: ErrorEvent) => {
-      console.log('websocket err', err)
-    }
-
-    ws.onclose = () => {
-      console.log('closing provisioner websocket')
-    }
-
-    return ws
-  }
-
-  renderLogs = () => {
-    return this.state.logs.map((log, i) => {
-      return <Log key={i}>{log}</Log>;
-    });
-  }
-
-  onEnd = () => {
-    let myInterval = setInterval(() => {
-      api.getClusters('<token>', {}, { 
-        id: this.context.currentProject.id 
-      }, (err: any, res: any) => {
-        if (err) {
-          console.log(err);
-        } else if (res.data) {
-          let clusters = res.data;
-          if (clusters.length > 0) {
-            this.props.history.push("dashboard");
-            // console.log('provision end project: ', this.context.currentProject);
-            // console.log('provision end cluster: ', this.context.currentCluster);
-            clearInterval(myInterval);
-          } else {
-            // console.log('looped!')
-            // console.log('response :', res.data);
-            // console.log('provision end project: ', this.context.currentProject);
-            // console.log('provision end cluster: ', this.context.currentCluster);
-          }
-        }
-      });
-    }, 1000);
-  }
-
-  refreshLogs = () => {
-    if (this.state.websockets.length == 0) { return; }
-    let { currentProject } = this.context;
-    let protocol = process.env.NODE_ENV == 'production' ? 'wss' : 'ws'
-
-    this.state.websockets.forEach((ws: any) => {
-      ws.close()
-    })
-
-    this.setState({ 
-      websockets: [],
-      logs: []
-    })
-
-    let websockets = this.state.infras.map((infra: any) => {
-      let ws = new WebSocket(`${protocol}://${process.env.API_SERVER}/api/projects/${currentProject.id}/provision/${infra.kind}/${infra.infra_id}/logs`)
-      return this.setupWebsocket(ws, infra)
-    });
-
-    this.setState({ websockets, logs: ["Provisioning resources..."] });
-    
-  }
-  
-  render() {
-    let { error, triggerEnd, infras } = this.state;
-    
-    let maxStep = 0;
-    let currentStep = 0;
-    let skip = false;
-    
-    for (let i = 0; i < infras.length; i++) {
-      if (!this.state.maxStep[infras[i].kind]) {
-        skip = true;
-      }
-    }
-
-    if (!skip) {
-      for (let key in this.state.maxStep) {
-        maxStep += this.state.maxStep[key]
-        currentStep += this.state.currentStep[key]
-      }  
-    }
-
-    if (maxStep !== 0 && currentStep === maxStep && !triggerEnd) {
-      posthog.capture('Provisioning complete!')
-      this.onEnd()
-      this.setState({ triggerEnd: true });
-    }
-
-    return (
-      <StyledProvisioner>
-        {error ? (
-          <>
-            <TitleSection>
-              <Title>
-                <img src={warning} /> Provisioning Error
-              </Title>
-            </TitleSection>
-
-            <Helper>
-              Porter encountered an error while provisioning.
-              <Link to="dashboard">Exit to dashboard</Link>
-              to try again with new credentials.
-            </Helper>
-          </>
-        ) : (
-          <>
-            <TitleSection>
-              <Title>
-                <img src={loading} /> Setting Up Porter
-              </Title>
-            </TitleSection>
-            <Helper>
-              Porter is currently provisioning resources in your cloud provider:
-            </Helper>
-          </>
-        )}
-
-        <LoadingBar>
-          <Loaded
-            progress={
-              error
-                ? "0%"
-                : (
-                    (currentStep / (maxStep == 0 ? 1 : maxStep)) *
-                    100
-                  ).toString() + "%"
-            }
-          />
-        </LoadingBar>
-
-        <LogStream>
-          <Wrapper ref={this.parentRef}>{this.renderLogs()}</Wrapper>
-        </LogStream>
-
-        <Helper>(Provisioning usually takes around 15 minutes)</Helper>
-      </StyledProvisioner>
-    );
-  }
-}
-
-ProvisionerStatus.contextType = Context;
-
-export default withRouter(ProvisionerStatus);
-
-const Wrapper = styled.div`
-  width: 100%;
-  height: 100%;
-  overflow: auto;
-  padding: 20px 25px;
-`;
-
-const Log = styled.div`
-  font-family: monospace;
-`;
-
-const LogStream = styled.div`
-  height: 300px;
-  margin-top: 20px;
-  font-size: 13px;
-  border: 2px solid #ffffff55;
-  border-radius: 10px;
-  width: 100%;
-  background: #00000022;
-  user-select: text;
-`;
-
-const Message = styled.div`
-  display: flex;
-  height: 100%;
-  width: 100%;
-  align-items: center;
-  justify-content: center;
-  color: #ffffff44;
-  font-size: 13px;
-`;
-
-const Loaded = styled.div<{ progress: string }>`
-  width: ${props => props.progress};
-  height: 100%;
-  background: linear-gradient(to right, #4f8aff, #8e7dff, #4f8aff);
-  background-size: 400% 400%;
-
-  animation: linkLoad 2s infinite;
-
-  @keyframes linkLoad {
-    0%{background-position:91% 100%}
-    100%{background-position:10% 0%}
-  }
-`;
-
-const LoadingBar = styled.div`
-  width: 100%;
-  margin-top: 24px;
-  overflow: hidden;
-  height: 20px;
-  background: #ffffff11;
-  border-radius: 30px;
-`;
-
-const Title = styled.div`
-  font-size: 24px;
-  font-weight: 600;
-  font-family: 'Work Sans', sans-serif;
-  color: #ffffff;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-
-  > img {
-    width: 20px;
-    margin-right: 10px;
-    margin-bottom: -2px;
-  }
-`;
-
-const TitleSection = styled.div`
-  margin-bottom: 20px;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-
-  > a {
-    > i {
-      display: flex;
-      align-items: center;
-      margin-bottom: -2px;
-      font-size: 18px;
-      margin-left: 18px;
-      color: #858FAAaa;
-      cursor: pointer;
-      :hover {
-        color: #aaaabb;
-      }
-    }
-  }
-`;
-
-const StyledProvisioner = styled.div`
-  width: calc(90% - 150px);
-  min-width: 300px;
-  height: 600px;
-  position: relative;
-  padding-top: 50px;
-  margin-top: calc(50vh - 350px);
-`;

+ 1 - 1
dashboard/src/main/home/sidebar/ClusterSection.tsx

@@ -77,7 +77,7 @@ class ClusterSection extends Component<PropsType, StateType> {
           ) {
           ) {
             this.setState({ clusters: [] });
             this.setState({ clusters: [] });
             setCurrentCluster(null);
             setCurrentCluster(null);
-            this.props.history.push('dashboard');
+            // this.props.history.push("dashboard");
           }
           }
         }
         }
       }
       }

+ 0 - 69
dashboard/src/shared/common.tsx

@@ -78,73 +78,4 @@ export const getIgnoreCase = (object: any, key: string) => {
   return object[Object.keys(object)
   return object[Object.keys(object)
     .find(k => k.toLowerCase() === key.toLowerCase())
     .find(k => k.toLowerCase() === key.toLowerCase())
   ];
   ];
-}
-
-export const includesCompletedInfraSet = (infras: InfraType[]): boolean => {
-  // TODO: declare globally while avoidiing changes to the array on helper call
-  let infraSets = [
-    ['ecr', 'eks'],
-    ['gcr', 'gke'],
-    ['docr', 'doks']
-  ];
-  if (infras.length === 0) {
-    return false;
-  }
-
-  let completed = [] as string[];
-  infras.forEach((infra: InfraType, i: number) => {
-    if (infra.status === 'created') {
-      completed.push(infra.kind);
-    }
-  });
-
-  completed.forEach((kind: string, i: number) => {
-    infraSets.forEach((infraSet: string[], i: number) => {
-      infraSet.includes(kind) && infraSet.splice(infraSet.indexOf(kind), 1);
-    });
-  });
-
-  let anyCompleted = false;
-  infraSets.forEach((infraSet: string[], i: number) => {
-    if (infraSet.length === 0) {
-      anyCompleted = true;
-    }
-  })
-  return anyCompleted;
-}
-
-export const filterOldInfras = (infras: InfraType[]): InfraType[] => {
-  let infraSets = [
-    ['ecr', 'eks'],
-    ['gcr', 'gke'],
-    ['docr', 'doks']
-  ];
-  let newestInstances = {} as any;
-  let newestId = -1;
-  let whitelistedInfras = [] as string[];
-  infras.forEach((infra: InfraType, i: number) => {
-
-    // Determine the most recent set for which provisioning was attempted
-    if (infra.id > newestId) {
-      newestId = infra.id;
-      infraSets.forEach((infraSet: string[]) => {
-        infraSet.includes(infra.kind) ? whitelistedInfras = infraSet : null;
-      });
-    }
-
-    if (!newestInstances[infra.kind]) {
-      newestInstances[infra.kind] = infra;
-    } else {
-      let existingId = newestInstances[infra.kind].id;
-      if (infra.id > existingId) {
-        newestInstances[infra.kind] = infra;
-      }
-    }
-  });
-
-  let newestInfras = Object.values(newestInstances) as InfraType[];
-  let result = newestInfras.filter((x: InfraType) => {
-    return whitelistedInfras.includes(x.kind)
-  });
-  return result;
 }
 }

+ 10 - 10
dashboard/src/shared/urls.tsx

@@ -1,11 +1,11 @@
-type PorterUrls =
-  | "dashboard"
-  | "templates"
-  | "integrations"
-  | "new-project"
-  | "cluster-dashboard"
-  | "provisioner"
-  | "project-settings";
+export const PorterUrls = [
+  "dashboard",
+  "templates",
+  "integrations",
+  "new-project",
+  "cluster-dashboard",
+  "provisioner",
+  "project-settings",
+];
 
 
-
-export default PorterUrls;
+export type PorterUrls = typeof PorterUrls[number];

+ 3 - 6
internal/kubernetes/provisioner/global_stream.go

@@ -6,6 +6,7 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"regexp"
 	"regexp"
+	"strings"
 
 
 	"github.com/aws/aws-sdk-go/service/ecr"
 	"github.com/aws/aws-sdk-go/service/ecr"
 	"github.com/porter-dev/porter/internal/repository"
 	"github.com/porter-dev/porter/internal/repository"
@@ -49,16 +50,14 @@ func InitGlobalStream(client *redis.Client) error {
 		GlobalStreamName,
 		GlobalStreamName,
 	).Result()
 	).Result()
 
 
-	fmt.Println(xInfoGroups, err)
-
-	if err != nil {
+	// if error is not NOGROUP error, return
+	if err != nil && !strings.Contains(err.Error(), "NOGROUP") {
 		return err
 		return err
 	}
 	}
 
 
 	for _, group := range xInfoGroups {
 	for _, group := range xInfoGroups {
 		// if the group exists, return with no error
 		// if the group exists, return with no error
 		if group.Name == GlobalStreamGroupName {
 		if group.Name == GlobalStreamGroupName {
-			fmt.Println("group already exists")
 			return nil
 			return nil
 		}
 		}
 	}
 	}
@@ -71,8 +70,6 @@ func InitGlobalStream(client *redis.Client) error {
 		"$",
 		"$",
 	).Result()
 	).Result()
 
 
-	fmt.Println("xgroup created", err)
-
 	return err
 	return err
 }
 }