Jelajahi Sumber

aws provisioning integration

sunguroku 5 tahun lalu
induk
melakukan
329582ebcb

+ 1 - 1
dashboard/src/main/home/Home.tsx

@@ -63,7 +63,7 @@ export default class Home extends Component<PropsType, StateType> {
           console.log(err);
           console.log(err);
           return;
           return;
         }
         }
-        console.log(currentCluster);
+        
         if (!currentCluster && !includesCompletedInfraSet(res.data)) {
         if (!currentCluster && !includesCompletedInfraSet(res.data)) {
           this.setState({ currentView: 'provisioner', sidebarReady: true, });
           this.setState({ currentView: 'provisioner', sidebarReady: true, });
         } else {
         } else {

+ 1 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/Logs.tsx

@@ -21,7 +21,6 @@ export default class Logs extends Component<PropsType, StateType> {
   }
   }
 
 
   ws = null as any;
   ws = null as any;
-  scrollRef = React.createRef<HTMLDivElement>()
   parentRef = React.createRef<HTMLDivElement>()
   parentRef = React.createRef<HTMLDivElement>()
 
 
   scrollToBottom = (smooth: boolean) => {
   scrollToBottom = (smooth: boolean) => {
@@ -58,7 +57,7 @@ export default class Logs extends Component<PropsType, StateType> {
 
 
     this.ws.onmessage = (evt: MessageEvent) => {
     this.ws.onmessage = (evt: MessageEvent) => {
       this.setState({ logs: [...this.state.logs, evt.data] }, () => {
       this.setState({ logs: [...this.state.logs, evt.data] }, () => {
-        if (this.state.scroll && this.state.logs.length >50) {
+        if (this.state.scroll) {
           this.scrollToBottom(false)
           this.scrollToBottom(false)
         }
         }
       })
       })
@@ -99,7 +98,6 @@ export default class Logs extends Component<PropsType, StateType> {
       <LogStream>
       <LogStream>
         <Wrapper ref={this.parentRef}>
         <Wrapper ref={this.parentRef}>
           {this.renderLogs()}
           {this.renderLogs()}
-          <div ref={this.scrollRef} />
         </Wrapper>
         </Wrapper>
         <Options>
         <Options>
           <Scroll onClick={()=> {
           <Scroll onClick={()=> {

+ 0 - 2
dashboard/src/main/home/provisioner/AWSFormSection.tsx

@@ -195,9 +195,7 @@ export default class AWSFormSection extends Component<PropsType, StateType> {
     let { projectName, setCurrentView } = this.props;
     let { projectName, setCurrentView } = this.props;
     let { selectedInfras } = this.state;
     let { selectedInfras } = this.state;
 
 
-    console.log(selectedInfras);
     if (!projectName) {
     if (!projectName) {
-      console.log(selectedInfras)
       if (selectedInfras.length === 2) {
       if (selectedInfras.length === 2) {
         // Case: project exists, provision ECR + EKS
         // Case: project exists, provision ECR + EKS
         this.provisionECR(this.provisionEKS);
         this.provisionECR(this.provisionEKS);

+ 1 - 1
dashboard/src/main/home/provisioner/InfraStatuses.tsx

@@ -31,7 +31,7 @@ export default class InfraStatuses extends Component<PropsType, StateType> {
       <StyledInfraStatuses>
       <StyledInfraStatuses>
         {this.props.infras.map((infra: InfraType, i: number) => {
         {this.props.infras.map((infra: InfraType, i: number) => {
           return (
           return (
-            <InfraRow>
+            <InfraRow key={infra.id}>
               {this.renderStatusIcon(infra.status)}
               {this.renderStatusIcon(infra.status)}
               {infraNames[infra.kind]}
               {infraNames[infra.kind]}
             </InfraRow>
             </InfraRow>

+ 96 - 22
dashboard/src/main/home/provisioner/ProvisionerStatus.tsx

@@ -45,6 +45,16 @@ export default class Provisioner extends Component<PropsType, StateType> {
     infras: [] as InfraType[],
     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() {
   componentDidMount() {
     let { currentProject } = this.context;
     let { currentProject } = this.context;
     let protocol = process.env.NODE_ENV == 'production' ? 'wss' : 'ws'
     let protocol = process.env.NODE_ENV == 'production' ? 'wss' : 'ws'
@@ -58,34 +68,36 @@ export default class Provisioner extends Component<PropsType, StateType> {
       } 
       } 
       let infras = filterOldInfras(res.data);
       let infras = filterOldInfras(res.data);
       let error = false;
       let error = false;
+
+      let maxStep = {} as Record<string, number>
+
       infras.forEach((infra: InfraType, i: number) => {
       infras.forEach((infra: InfraType, i: number) => {
+        maxStep[infra.kind] = null;
         if (infra.status === 'error') {
         if (infra.status === 'error') {
           error = true;
           error = true;
         }
         }
       });
       });
 
 
+      console.log(infras)
+
       // Filter historical infras list for most current instances of each
       // Filter historical infras list for most current instances of each
       let websockets = infras.map((infra: any) => {
       let websockets = infras.map((infra: any) => {
-        let ws = new WebSocket(`${protocol}://${process.env.API_SERVER}/api/projects/${currentProject.id}/provision/${infra.kind}/${infra.infra_id}/logs`)
+        let ws = new WebSocket(`${protocol}://${process.env.API_SERVER}/api/projects/${currentProject.id}/provision/${infra.kind}/${infra.id}/logs`)
         return this.setupWebsocket(ws, infra)
         return this.setupWebsocket(ws, infra)
       });
       });
   
   
-      this.setState({ error, infras, websockets, logs: ["Provisioning resources..."] });
+      this.setState({ error, infras, websockets, maxStep, logs: ["Provisioning resources..."] });
     });
     });
   }
   }
 
 
   componentWillUnmount() {
   componentWillUnmount() {
-    if (!this.state.websockets) { return; }
+    if (this.state.websockets.length == 0) { return; }
 
 
     this.state.websockets.forEach((ws: any) => {
     this.state.websockets.forEach((ws: any) => {
       ws.close()
       ws.close()
     })
     })
   }
   }
 
 
-  scrollToBottom = () => {
-    this.scrollRef.current.scrollTop = this.scrollRef.current.scrollHeight
-  }
-
   isJSON = (str: string) => {
   isJSON = (str: string) => {
     try {
     try {
       JSON.parse(str);
       JSON.parse(str);
@@ -104,6 +116,7 @@ export default class Provisioner extends Component<PropsType, StateType> {
       let event = JSON.parse(evt.data);
       let event = JSON.parse(evt.data);
       let validEvents = [] as any[];
       let validEvents = [] as any[];
       let err = null;
       let err = null;
+
       
       
       for (var i = 0; i < event.length; i++) {
       for (var i = 0; i < event.length; i++) {
         let msg = event[i];
         let msg = event[i];
@@ -111,6 +124,7 @@ export default class Provisioner extends Component<PropsType, StateType> {
           let d = JSON.parse(msg["Values"]["data"]);
           let d = JSON.parse(msg["Values"]["data"]);
 
 
           if (d["kind"] == "error") {
           if (d["kind"] == "error") {
+            console.log(d)
             err = d["log"];
             err = d["log"];
             break;
             break;
           }
           }
@@ -123,17 +137,25 @@ export default class Provisioner extends Component<PropsType, StateType> {
       }
       }
 
 
       if (err) {
       if (err) {
+        console.log(err)
         let e = ansiparse(err).map((el: any) => {
         let e = ansiparse(err).map((el: any) => {
           return el.text;
           return el.text;
         })
         })
-        this.setState({ logs: e, error: true });
+
+        console.log(e)
+
+        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: e, error: true, infras });
         return;
         return;
       }
       }
 
 
       if (validEvents.length == 0) {
       if (validEvents.length == 0) {
         return;
         return;
       }
       }
-      
+
       if (!this.state.maxStep[infra.kind] || !this.state.maxStep[infra.kind]["total_resources"]) {
       if (!this.state.maxStep[infra.kind] || !this.state.maxStep[infra.kind]["total_resources"]) {
         this.setState({
         this.setState({
           maxStep: {
           maxStep: {
@@ -159,12 +181,12 @@ export default class Provisioner extends Component<PropsType, StateType> {
           [infra.kind] : validEvents[validEvents.length - 1]["created_resources"]
           [infra.kind] : validEvents[validEvents.length - 1]["created_resources"]
         },
         },
       }, () => {
       }, () => {
-        this.scrollToBottom()
+        this.scrollToBottom(false)
       })
       })
     }
     }
 
 
     ws.onerror = (err: ErrorEvent) => {
     ws.onerror = (err: ErrorEvent) => {
-      console.log(err)
+      console.log('websocket err', err)
     }
     }
 
 
     ws.onclose = () => {
     ws.onclose = () => {
@@ -174,8 +196,6 @@ export default class Provisioner extends Component<PropsType, StateType> {
     return ws
     return ws
   }
   }
 
 
-  scrollRef = React.createRef<HTMLDivElement>();
-
   renderLogs = () => {
   renderLogs = () => {
     return this.state.logs.map((log, i) => {
     return this.state.logs.map((log, i) => {
       return <Log key={i}>{log}</Log>;
       return <Log key={i}>{log}</Log>;
@@ -199,6 +219,29 @@ export default class Provisioner extends Component<PropsType, StateType> {
       });
       });
     }, 1000);
     }, 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() {
   render() {
     let { error, triggerEnd, infras } = this.state;
     let { error, triggerEnd, infras } = this.state;
@@ -206,17 +249,19 @@ export default class Provisioner extends Component<PropsType, StateType> {
     
     
     let maxStep = 0;
     let maxStep = 0;
     let currentStep = 0;
     let currentStep = 0;
-
-    for (let key in this.state.maxStep) {
-      if (key == 'eks') {
-        maxStep += this.state.maxStep[key]
+    let skip = false;
+    
+    for (let i = 0; i < infras.length; i++) {
+      if (!this.state.maxStep[infras[i].kind]) {
+        skip = true;
       }
       }
     }
     }
 
 
-    for (let key in this.state.currentStep) {
-      if (key == 'eks') {
+    if (!skip) {
+      for (let key in this.state.maxStep) {
+        maxStep += this.state.maxStep[key]
         currentStep += this.state.currentStep[key]
         currentStep += this.state.currentStep[key]
-      }
+      }  
     }
     }
 
 
     if (maxStep !== 0 && currentStep === maxStep && !triggerEnd) {
     if (maxStep !== 0 && currentStep === maxStep && !triggerEnd) {
@@ -266,8 +311,8 @@ export default class Provisioner extends Component<PropsType, StateType> {
         </LoadingBar>
         </LoadingBar>
         <InfraStatuses infras={infras} />
         <InfraStatuses infras={infras} />
 
 
-        <LogStream ref={this.scrollRef}>
-          <Wrapper>{this.renderLogs()}</Wrapper>
+        <LogStream>
+          <Wrapper ref={this.parentRef}>{this.renderLogs()}</Wrapper>
         </LogStream>
         </LogStream>
 
 
         <Helper>
         <Helper>
@@ -280,6 +325,35 @@ export default class Provisioner extends Component<PropsType, StateType> {
 
 
 Provisioner.contextType = Context;
 Provisioner.contextType = Context;
 
 
+const Options = styled.div`
+  width: 100%;
+  height: 25px;
+  background: #397ae3;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+`
+
+const Refresh = styled.div`
+  display: flex;
+  align-items: center;
+  width: 87px;
+  user-select: none;
+  cursor: pointer;
+  height: 100%;
+
+  > i {
+    margin-left: 6px;
+    font-size: 17px;
+    margin-right: 6px;
+  }
+
+  :hover {
+    background: #2468d6;
+  }
+`
+
 const Link = styled.a`
 const Link = styled.a`
   cursor: pointer;
   cursor: pointer;
   margin-left: 5px;
   margin-left: 5px;

+ 2 - 2
dashboard/src/shared/api.tsx

@@ -328,7 +328,7 @@ const createGCR = baseApi<{
 }, {
 }, {
   project_id: number,
   project_id: number,
 }>('POST', pathParams => {
 }>('POST', pathParams => {
-  return `/api/projects/${pathParams.project_id}/provision/gcr`;
+  return `/api/projects/${pathParams.project_id}/provision/test`;
 });
 });
 
 
 const createGKE = baseApi<{
 const createGKE = baseApi<{
@@ -337,7 +337,7 @@ const createGKE = baseApi<{
 }, {
 }, {
   project_id: number,
   project_id: number,
 }>('POST', pathParams => {
 }>('POST', pathParams => {
-  return `/api/projects/${pathParams.project_id}/provision/gke`;
+  return `/api/projects/${pathParams.project_id}/provision/test`;
 });
 });
 
 
 const createInvite = baseApi<{
 const createInvite = baseApi<{