节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
11.57 KiB
Stardust
@{
    var theme = NewLife.Cube.CubeSetting.Current.Theme;
    if (String.IsNullOrEmpty(theme)) theme = "ACE";

    Layout = "~/Views/" + theme + "/_Layout.cshtml";
    ViewBag.Title = "StarAgent远程部署";
}

<div class="clearfix">
    <div class="container-fluid">
        <h3><i class="fa fa-rocket"></i> StarAgent远程部署</h3>
        <p class="text-muted">通过SSH远程部署StarAgent到目标服务器</p>

        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">部署配置</h4>
            </div>
            <div class="panel-body">
                <form id="deployForm" class="form-horizontal" role="form">
                    <!-- 目标主机 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">目标主机 *</label>
                        <div class="col-sm-8">
                            <textarea id="hosts" name="hosts" class="form-control" rows="4" placeholder="支持单个IP、多个IP(逗号或换行分隔)、或CIDR网段(如192.168.1.0/24)"></textarea>
                            <span class="help-block">示例:192.168.1.100 或 192.168.1.100,192.168.1.101 或 192.168.1.0/24</span>
                        </div>
                    </div>

                    <!-- SSH连接信息 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">用户名 *</label>
                        <div class="col-sm-4">
                            <input type="text" id="userName" name="userName" class="form-control" placeholder="root" />
                        </div>
                        <label class="col-sm-2 control-label">SSH端口</label>
                        <div class="col-sm-2">
                            <input type="number" id="port" name="port" class="form-control" value="22" />
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">密码 *</label>
                        <div class="col-sm-8">
                            <input type="password" id="password" name="password" class="form-control" />
                        </div>
                    </div>

                    <!-- 系统配置 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">操作系统</label>
                        <div class="col-sm-4">
                            <select id="osType" name="osType" class="form-control">
                                <option value="Linux">Linux</option>
                                <option value="Windows">Windows</option>
                            </select>
                        </div>
                        <label class="col-sm-2 control-label">.NET版本</label>
                        <div class="col-sm-2">
                            <select id="dotnetVersion" name="dotnetVersion" class="form-control">
                                <option value="9">9.0</option>
                                <option value="8">8.0</option>
                                <option value="10">10.0</option>
                            </select>
                        </div>
                    </div>

                    <!-- StarServer地址 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">服务器地址 *</label>
                        <div class="col-sm-8">
                            <input type="text" id="serverUrl" name="serverUrl" class="form-control" value="@ViewBag.ServerUrl" />
                            <span class="help-block">StarAgent安装后将连接到此服务器</span>
                        </div>
                    </div>

                    <!-- 下载地址 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">下载地址</label>
                        <div class="col-sm-8">
                            <input type="text" id="downloadUrl" name="downloadUrl" class="form-control" value="@ViewBag.DownloadUrl" />
                            <span class="help-block">StarAgent安装包下载地址</span>
                        </div>
                    </div>

                    <!-- 执行位置 -->
                    <div class="form-group">
                        <label class="col-sm-2 control-label">执行位置</label>
                        <div class="col-sm-8">
                            <label class="radio-inline">
                                <input type="radio" name="executeOn" value="server" checked> StarServer执行(推荐)
                            </label>
                            <label class="radio-inline">
                                <input type="radio" name="executeOn" value="web"> StarWeb本地执行
                            </label>
                            <span class="help-block">StarServer执行适合大规模部署,StarWeb执行适合快速测试</span>
                        </div>
                    </div>

                    <!-- 按钮 -->
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-8">
                            <button type="button" class="btn btn-info" onclick="testConnection()">
                                <i class="fa fa-plug"></i> 测试连接
                            </button>
                            <button type="button" class="btn btn-primary" onclick="startDeploy()">
                                <i class="fa fa-rocket"></i> 开始部署
                            </button>
                            <button type="reset" class="btn btn-default">
                                <i class="fa fa-refresh"></i> 重置
                            </button>
                        </div>
                    </div>
                </form>
            </div>
        </div>

        <!-- 部署结果 -->
        <div id="resultPanel" class="panel panel-info" style="display:none;">
            <div class="panel-heading">
                <h4 class="panel-title">部署结果</h4>
            </div>
            <div class="panel-body">
                <div id="deployResult"></div>
            </div>
        </div>
    </div>
</div>

<script>
function getFormData() {
    return {
        hosts: $('#hosts').val().trim(),
        port: parseInt($('#port').val()) || 22,
        userName: $('#userName').val().trim(),
        password: $('#password').val(),
        osType: $('#osType').val(),
        serverUrl: $('#serverUrl').val().trim(),
        downloadUrl: $('#downloadUrl').val().trim(),
        dotnetVersion: parseInt($('#dotnetVersion').val()) || 9
    };
}

function validateForm() {
    var data = getFormData();
    if (!data.hosts) {
        alert('请输入目标主机');
        return false;
    }
    if (!data.userName) {
        alert('请输入用户名');
        return false;
    }
    if (!data.password) {
        alert('请输入密码');
        return false;
    }
    if (!data.serverUrl) {
        alert('请输入服务器地址');
        return false;
    }
    return true;
}

function testConnection() {
    if (!validateForm()) return;

    var data = getFormData();
    var executeOn = $('input[name="executeOn"]:checked').val();

    // 只测试第一个IP
    var host = data.hosts.split(/[,;\n\r]/)[0].trim();

    $.ajax({
        url: '/Nodes/AgentDeploy/TestConnection',
        type: 'POST',
        data: {
            host: host,
            port: data.port,
            userName: data.userName,
            password: data.password,
            executeOn: executeOn
        },
        success: function(response) {
            if (response.code === 0 && response.data && response.data.success) {
                alert('连接测试成功!');
            } else {
                alert('连接测试失败:' + (response.data?.message || response.message || '未知错误'));
            }
        },
        error: function(xhr, status, error) {
            alert('连接测试失败:' + error);
        }
    });
}

function startDeploy() {
    if (!validateForm()) return;

    if (!confirm('确定要开始部署吗?')) return;

    var data = getFormData();
    var executeOn = $('input[name="executeOn"]:checked').val();

    $('#deployResult').html('<div class="alert alert-info"><i class="fa fa-spinner fa-spin"></i> 正在部署,请稍候...</div>');
    $('#resultPanel').show();

    $.ajax({
        url: '/Nodes/AgentDeploy/Deploy?executeOn=' + executeOn,
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(data),
        success: function(response) {
            if (response.code === 0 && response.data) {
                showDeployResult(response.data);
            } else {
                $('#deployResult').html('<div class="alert alert-danger"><i class="fa fa-times"></i> 部署失败:' + (response.message || '未知错误') + '</div>');
            }
        },
        error: function(xhr, status, error) {
            var errorMsg = '部署失败:' + error;
            if (xhr.responseJSON && xhr.responseJSON.message) {
                errorMsg = '部署失败:' + xhr.responseJSON.message;
            }
            $('#deployResult').html('<div class="alert alert-danger"><i class="fa fa-times"></i> ' + errorMsg + '</div>');
        }
    });
}

function showDeployResult(results) {
    var html = '<div class="table-responsive"><table class="table table-striped table-bordered">';
    html += '<thead><tr><th>主机</th><th>状态</th><th>消息</th><th>详细输出</th></tr></thead><tbody>';

    var successCount = 0;
    var failCount = 0;

    for (var i = 0; i < results.length; i++) {
        var result = results[i];
        var statusClass = result.success ? 'success' : 'danger';
        var statusIcon = result.success ? 'fa-check' : 'fa-times';
        var statusText = result.success ? '成功' : '失败';

        if (result.success) successCount++;
        else failCount++;

        html += '<tr class="' + statusClass + '">';
        html += '<td>' + result.host + '</td>';
        html += '<td><i class="fa ' + statusIcon + '"></i> ' + statusText + '</td>';
        html += '<td>' + (result.message || '') + '</td>';
        html += '<td><button class="btn btn-xs btn-info" onclick="showOutput(' + i + ')">查看</button></td>';
        html += '</tr>';
    }

    html += '</tbody></table></div>';

    html = '<div class="alert alert-info"><strong>部署完成</strong>:成功 ' + successCount + ' 个,失败 ' + failCount + ' 个</div>' + html;

    $('#deployResult').html(html);

    // 保存结果用于详细输出
    window.deployResults = results;
}

function showOutput(index) {
    var result = window.deployResults[index];
    var output = result.output || '无输出';

    var modal = $('<div class="modal fade" tabindex="-1" role="dialog">' +
        '<div class="modal-dialog modal-lg" role="document">' +
        '<div class="modal-content">' +
        '<div class="modal-header">' +
        '<button type="button" class="close" data-dismiss="modal">&times;</button>' +
        '<h4 class="modal-title">部署输出 - ' + result.host + '</h4>' +
        '</div>' +
        '<div class="modal-body">' +
        '<pre style="max-height: 400px; overflow-y: auto;">' + output + '</pre>' +
        '</div>' +
        '<div class="modal-footer">' +
        '<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>' +
        '</div>' +
        '</div></div></div>');

    modal.modal('show');
    modal.on('hidden.bs.modal', function () {
        modal.remove();
    });
}
</script>