<template>
  <el-container>
    <el-header height="220">
      <h3>系统更新</h3>
      <el-row style="margin-top: 10px">
        <span>节点类型</span>
        <el-select
          v-model="queryInfo.nodeType"
          size="mini"
          placeholder="节点类型"
          style="margin-left: 5px"
          @change="onSelectChange"
        >
          <el-option label="mgr" value="mgr" />
          <el-option label="agent" value="agent" />
        </el-select>
        <el-button size="mini" type="warning" icon="el-icon-files" style="margin-left: 5px" @click="handleAgentConfig">节点配置列表</el-button>
        <el-button size="mini" type="warning" icon="el-icon-refresh" style="margin-left: 5px" @click="getData">刷新</el-button>
        <el-button size="mini" type="warning" icon="el-icon-plus" style="margin-left: 5px" @click="handleAdd">添加节点</el-button>
        <el-button size="mini" type="warning" icon="el-icon-upload" style="margin-left: 5px" @click="handleUpdate">更新</el-button>
      </el-row>
    </el-header>
    <el-main>
      <el-row>
        <el-col style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
          <el-table
            :data="dataList"
            border
            height="480"
            style="width: 100%"
          >
            <el-table-column
              prop="nodeType"
              label="节点类型"
            />
            <el-table-column
              prop="host"
              label="部署的机器地址"
            />
            <el-table-column
              prop="appDir"
              label="应用目录"
            />
            <el-table-column
              prop="config"
              label="配置"
            >
              <template slot-scope="scope">
                <el-button
                  style="margin-top: 5px; margin-left: 5px"
                  size="mini"
                  type="success"
                  @click="handleShowConfig(scope.$index, scope.row)"
                >查看</el-button>
              </template>
            </el-table-column>
            <el-table-column
              prop="appVersion"
              label="应用版本"
            />
            <el-table-column
              prop="updateTime"
              label="更新时间"
            />
            <el-table-column
              fixed="right"
              label="操作"
              width="120"
            >
              <template slot-scope="scope">
                <el-button
                  style="margin-top: 5px; margin-left: 5px"
                  size="mini"
                  type="danger"
                  @click="handleDelete(scope.$index, scope.row)"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-col>
      </el-row>
    </el-main>

    <el-dialog
      title="添加节点"
      append-to-body
      :visible.sync="showAddDialog"
      width="50%"
      center
    >
      <div>
        <el-form :model="addForm" label-width="80px">
          <el-form-item label="节点类型" style="width: 70%; padding-right: 2px">
            <el-input v-model="queryInfo.nodeType" style="width: 70%; padding-right: 2px" readonly />
          </el-form-item>
          <el-form-item label="部署的机器地址">
            <el-input v-model="addForm.host" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <el-form-item label="SSH 端口">
            <el-input v-model="addForm.port" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <el-form-item label="认证方式" style="width: 70%; padding-right: 2px">
            <el-select v-model="addForm.authType" placeholder="选择认证方式">
              <el-option label="密码认证" value="password" />
              <el-option label="私钥认证" value="privateKey" />
            </el-select>
          </el-form-item>
          <el-form-item label="用户名" style="width: 70%; padding-right: 2px">
            <el-input v-model="addForm.username" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <el-form-item v-if="addForm.authType === 'password'" label="密码" style="width: 70%; padding-right: 2px">
            <el-input v-model="addForm.password" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <el-form-item v-else label="私钥" style="width: 70%; padding-right: 2px">
            <el-input
              v-model="addForm.privateKey"
              type="textarea"
              maxlength="10000"
              :rows="10"
              style="padding: 5px"
            />
          </el-form-item>
          <el-form-item label="应用目录">
            <el-input v-model="addForm.appDir" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <div v-if="queryInfo.nodeType === 'agent'">
            <el-form-item label="连接的 mgr 地址" style="width: 70%; padding-right: 2px">
              <el-select v-model="addForm.remoteAgentConfig" placeholder="选择 mgr 地址">
                <el-option
                  v-for="(item, index) in agentConfigList"
                  :key="index"
                  :label="item.mgrHost"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </div>
          <div v-else>
            <el-form-item label="mgr 配置" style="width: 70%; padding-right: 2px">
              <el-select v-model="addForm.remoteAgentConfig" placeholder="选择 mgr 配置">
                <el-option
                  v-for="(item, index) in agentConfigList"
                  :key="index"
                  :label="item.id"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </div>
          <el-form-item>
            <el-button type="primary" @click="onAdd">确定</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-dialog>
    <el-dialog
      title="节点配置列表"
      append-to-body
      :visible.sync="showAgentConfigDialog"
      center
    >
      <template>
        <el-button size="mini" type="warning" icon="el-icon-plus" style="margin: 5px" @click="handleAgentConfigAdd">添加</el-button>
        <el-table
          :data="agentConfigList"
          border
          height="480"
          style="width: 100%"
        >
          <el-table-column
            prop="id"
            label="ID"
          />
          <el-table-column
            prop="nodeType"
            label="节点类型"
          />
          <el-table-column
            prop="mgrProtocol"
            label="协议"
          />
          <el-table-column
            prop="mgrHost"
            label="mgr 地址"
          />
          <el-table-column
            prop="mgrPort"
            label="mgr 端口"
          />
          <el-table-column
            prop="mgrConfig"
            label="mgr 配置"
          />
          <el-table-column
            fixed="right"
            label="操作"
            width="120"
          >
            <template slot-scope="scope">
              <el-button
                style="margin-top: 5px; margin-left: 5px"
                size="mini"
                type="danger"
                @click="handleAgentConfigDelete(scope.$index, scope.row)"
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </template>
    </el-dialog>
    <el-dialog
      title="添加节点配置"
      append-to-body
      :visible.sync="addAgentConfigDialog"
      center
    >
      <template>
        <el-form :model="configForm" label-width="80px">
          <el-form-item label="节点类型" style="width: 70%; padding-right: 2px">
            <el-input v-model="queryInfo.nodeType" style="width: 70%; padding-right: 2px" />
          </el-form-item>
          <div v-if="queryInfo.nodeType === 'agent'">
            <el-form-item label="mgr 协议" style="width: 70%; padding-right: 2px">
              <el-select v-model="configForm.mgrProtocol" placeholder="选择 websocket 协议">
                <el-option label="ws" value="ws" />
                <el-option label="wss" value="wss" />
              </el-select>
            </el-form-item>
            <el-form-item label="mgr 地址" style="width: 70%; padding-right: 2px">
              <el-input v-model="configForm.mgrHost" style="width: 70%; padding-right: 2px" />
            </el-form-item>
            <el-form-item label="mgr 端口" style="width: 70%; padding-right: 2px">
              <el-input v-model="configForm.mgrPort" style="width: 70%; padding-right: 2px" />
            </el-form-item>
          </div>
          <div v-else>
            <el-form-item label="mgr 配置" style="width: 70%; padding-right: 2px">
              <el-input
                v-model="configForm.mgrConfig"
                type="textarea"
                maxlength="10000"
                :rows="10"
                style="padding: 5px"
              />
            </el-form-item>
          </div>
          <el-form-item>
            <el-button type="primary" @click="onAgentConfigAdd">确定</el-button>
          </el-form-item>
        </el-form>
      </template>
    </el-dialog>
    <el-dialog
      :title="title"
      append-to-body
      :visible.sync="showConfigDialog"
      center
    >
      <template>
        <span v-if="queryInfo.nodeType === 'agent'">
          <el-form :model="configForm" label-width="80px">
            <el-form-item label="mgr 协议" style="width: 70%; padding-right: 2px">
              <el-input v-model="configForm.mgrProtocol" style="width: 70%; padding-right: 2px" readonly />
            </el-form-item>
            <el-form-item label="mgr 地址" style="width: 70%; padding-right: 2px">
              <el-input v-model="configForm.mgrHost" style="width: 70%; padding-right: 2px" readonly />
            </el-form-item>
            <el-form-item label="mgr 端口" style="width: 70%; padding-right: 2px">
              <el-input v-model="configForm.mgrPort" style="width: 70%; padding-right: 2px" readonly />
            </el-form-item>
          </el-form>
        </span>
        <span v-else>
          <el-form>
            <el-form-item style="width: 70%; padding-right: 2px">
              <el-input
                v-model="configForm.mgrConfig"
                type="textarea"
                maxlength="10000"
                :rows="10"
                style="padding: 5px"
                readonly
              />
            </el-form-item>
          </el-form>
        </span>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import {
  addAgentConfig,
  addRemoteHost, deleteAgentConfig,
  deleteRemoteHost,
  getAgentConfigList,
  getRemoteHostList,
  updateRemoteApp
} from '@/api/devops'

export default {
  name: 'SysUpdate',
  data() {
    return {
      queryInfo: {
        nodeType: 'agent'
      },
      dataList: [],
      // **********************************************************************
      showAddDialog: false,
      addForm: {
        nodeType: 'agent',
        host: '',
        port: 22,
        authType: 'password',
        username: 'root',
        password: '',
        privateKey: '',
        appDir: '/opt/app/devops',
        remoteAgentConfig: null
      },
      // **********************************************************************
      showAgentConfigDialog: false,
      agentConfigList: [],
      addAgentConfigDialog: false,
      configForm: {
        nodeType: '',
        mgrProtocol: 'ws',
        mgrHost: '127.0.0.1',
        mgrPort: 4030,
        mgrConfig: ''
      },
      // **********************************************************************
      showConfigDialog: false,
      title: ' 节点配置',
      mgrConfig: ''
    }
  },
  created() {
    document.title = '系统更新'
    this.getData()
  },
  methods: {
    getData() {
      this.dataList = []
      getRemoteHostList(this.queryInfo).then(resp => {
        if (resp.code === 0) {
          this.dataList = resp.data
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      })
    },
    onSelectChange() {
      this.getData()
    },
    handleAdd() {
      getAgentConfigList(this.queryInfo).then(resp => {
        if (resp.code === 0) {
          this.agentConfigList = resp.data
          this.showAddDialog = true
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      })
    },
    onAdd() {
      this.addForm.nodeType = this.queryInfo.nodeType
      addRemoteHost(this.addForm).then(resp => {
        if (resp.code === 0) {
          this.getData()
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      }).finally(() => {
        this.showAddDialog = false
      })
    },
    handleDelete(index, row) {
      const form = {}
      form.id = row.id
      deleteRemoteHost(form).then(resp => {
        if (resp.code === 0) {
          this.getData()
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      })
    },
    handleUpdate() {
      const hostList = []
      for (const item of this.dataList) {
        hostList.push(item.host)
      }
      this.$confirm('确定要更新所有机器上的 ' + this.queryInfo.nodeType + '?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const form = {}
        form.hostList = hostList
        updateRemoteApp(form).then(resp => {
          this.$message.warning(resp.msg)
        }).catch(error => {
          this.$message.error(error.message)
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消'
        })
      }).finally(() => {
        this.loading = false
      })
    },
    handleAgentConfig() {
      getAgentConfigList(this.queryInfo).then(resp => {
        if (resp.code === 0) {
          this.agentConfigList = resp.data
          this.showAgentConfigDialog = true
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      })
    },
    handleAgentConfigAdd() {
      this.addAgentConfigDialog = true
    },
    onAgentConfigAdd() {
      this.configForm.nodeType = this.queryInfo.nodeType
      addAgentConfig(this.configForm).then(resp => {
        if (resp.code === 0) {
          this.handleAgentConfig()
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      }).finally(() => {
        this.addAgentConfigDialog = false
      })
    },
    handleAgentConfigDelete(index, row) {
      const form = {}
      form.id = row.id
      deleteAgentConfig(form).then(resp => {
        if (resp.code === 0) {
          this.handleAgentConfig()
        } else {
          this.$message.warning(resp.msg)
        }
      }).catch(error => {
        this.$message.error(error.message)
      })
    },
    handleShowConfig(index, row) {
      this.configForm = row.remoteAgentConfig
      this.title = this.queryInfo.nodeType + ' 节点配置'
      this.showConfigDialog = true
    }
  }
}
</script>

<style>
</style>
