feat(wip): node management #70

This commit is contained in:
0xJacky 2023-05-14 22:39:09 +08:00
parent 3ed9ff1a19
commit 47ea62adb2
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
41 changed files with 1932 additions and 482 deletions

View file

@ -13,9 +13,9 @@ bin = "tmp/main"
# Customize binary.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html", "conf", "ini", "toml"]
include_ext = ["go", "tpl", "tmpl", "html", "toml"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules", "upload", "docs", "resources"]
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules", "upload", "docs", "resources", "frontend/src"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.

View file

@ -11,8 +11,8 @@ RUN set -x \
&& adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx \
&& apt update && apt install -y wget nginx gcc curl
RUN wget https://go.dev/dl/go1.20.1.linux-arm64.tar.gz && \
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.1.linux-arm64.tar.gz && rm -f go1.20.1.linux-arm64.tar.gz
RUN wget https://go.dev/dl/go1.20.4.linux-arm64.tar.gz && \
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.4.linux-arm64.tar.gz && rm -f go1.20.4.linux-arm64.tar.gz
ENV PATH="${PATH}:/usr/local/go/bin"

View file

@ -10,6 +10,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
AAvatar: typeof import('ant-design-vue/es')['Avatar']
ABadge: typeof import('ant-design-vue/es')['Badge']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
@ -37,6 +38,7 @@ declare module '@vue/runtime-core' {
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
AList: typeof import('ant-design-vue/es')['List']
AListItem: typeof import('ant-design-vue/es')['ListItem']
AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
@ -64,6 +66,7 @@ declare module '@vue/runtime-core' {
ChartRadialBarChart: typeof import('./src/components/Chart/RadialBarChart.vue')['default']
ChatGPTChatGPT: typeof import('./src/components/ChatGPT/ChatGPT.vue')['default']
CodeEditorCodeEditor: typeof import('./src/components/CodeEditor/CodeEditor.vue')['default']
EnvIndicatorEnvIndicator: typeof import('./src/components/EnvIndicator/EnvIndicator.vue')['default']
FooterToolbarFooterToolBar: typeof import('./src/components/FooterToolbar/FooterToolBar.vue')['default']
LogoLogo: typeof import('./src/components/Logo/Logo.vue')['default']
NginxControlNginxControl: typeof import('./src/components/NginxControl/NginxControl.vue')['default']

View file

@ -0,0 +1,5 @@
import Curd from '@/api/curd'
const environment = new Curd('/environment')
export default environment

View file

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1683971182420" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2501" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 896H256c-72.533333 0-128-55.466667-128-128V256c0-72.533333 55.466667-128 128-128h512c72.533333 0 128 55.466667 128 128v512c0 72.533333-55.466667 128-128 128zM256 213.333333c-25.6 0-42.666667 17.066667-42.666667 42.666667v512c0 25.6 17.066667 42.666667 42.666667 42.666667h512c25.6 0 42.666667-17.066667 42.666667-42.666667V256c0-25.6-17.066667-42.666667-42.666667-42.666667H256z" p-id="2502"></path><path d="M640 682.666667H384c-25.6 0-42.666667-17.066667-42.666667-42.666667V384c0-25.6 17.066667-42.666667 42.666667-42.666667h256c25.6 0 42.666667 17.066667 42.666667 42.666667v256c0 25.6-17.066667 42.666667-42.666667 42.666667z m-213.333333-85.333334h170.666666v-170.666666h-170.666666v170.666666zM384 213.333333c-25.6 0-42.666667-17.066667-42.666667-42.666666V42.666667c0-25.6 17.066667-42.666667 42.666667-42.666667s42.666667 17.066667 42.666667 42.666667v128c0 25.6-17.066667 42.666667-42.666667 42.666666zM640 213.333333c-25.6 0-42.666667-17.066667-42.666667-42.666666V42.666667c0-25.6 17.066667-42.666667 42.666667-42.666667s42.666667 17.066667 42.666667 42.666667v128c0 25.6-17.066667 42.666667-42.666667 42.666666zM384 1024c-25.6 0-42.666667-17.066667-42.666667-42.666667v-128c0-25.6 17.066667-42.666667 42.666667-42.666666s42.666667 17.066667 42.666667 42.666666v128c0 25.6-17.066667 42.666667-42.666667 42.666667zM640 1024c-25.6 0-42.666667-17.066667-42.666667-42.666667v-128c0-25.6 17.066667-42.666667 42.666667-42.666666s42.666667 17.066667 42.666667 42.666666v128c0 25.6-17.066667 42.666667-42.666667 42.666667zM981.333333 426.666667h-128c-25.6 0-42.666667-17.066667-42.666666-42.666667s17.066667-42.666667 42.666666-42.666667h128c25.6 0 42.666667 17.066667 42.666667 42.666667s-17.066667 42.666667-42.666667 42.666667zM981.333333 640h-128c-25.6 0-42.666667-17.066667-42.666666-42.666667s17.066667-42.666667 42.666666-42.666666h128c25.6 0 42.666667 17.066667 42.666667 42.666666s-17.066667 42.666667-42.666667 42.666667zM170.666667 426.666667H42.666667c-25.6 0-42.666667-17.066667-42.666667-42.666667s17.066667-42.666667 42.666667-42.666667h128c25.6 0 42.666667 17.066667 42.666666 42.666667s-17.066667 42.666667-42.666666 42.666667zM170.666667 640H42.666667c-25.6 0-42.666667-17.066667-42.666667-42.666667s17.066667-42.666667 42.666667-42.666666h128c25.6 0 42.666667 17.066667 42.666666 42.666666s-17.066667 42.666667-42.666666 42.666667z" p-id="2503"></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1683972914887" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5222" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M922.688 810.624h-149.312a37.376 37.376 0 0 1-37.312-37.376L736 736h-49.792v74.688H611.584V736h-49.792v74.688H462.208V736h-49.728v74.688H337.792V736H288l-0.256 37.248a37.312 37.312 0 0 1-37.312 37.376h-149.12A37.312 37.312 0 0 1 64 773.248V250.752c0-20.672 16.704-37.376 37.312-37.376h821.312a37.312 37.312 0 0 1 37.376 37.376v522.496a37.312 37.312 0 0 1-37.312 37.376z m-37.376-177.344h-39.168a37.376 37.376 0 0 1 0-74.752h39.168V288.128H138.688v270.4h37.952a37.376 37.376 0 0 1 0 74.752h-37.952v102.528H213.12l0.256-49.6c0-20.672 4.288-24.896 24.896-24.896h547.584c20.608 0 24.896 4.224 24.896 24.896v49.6h74.624V633.28zM736 337.792h74.688V512H736V337.792z m-174.208 0h74.688V512H561.792V337.792z m-174.208 0h74.688V512H387.584V337.792z m-174.272 0H288V512l-73.472-0.128-1.216-174.08z" p-id="5223"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1683971747666" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8583" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M448 938.666667a21.333333 21.333333 0 0 1-20.38-15.06L272.6 419.833333l-61.52 123.04A21.333333 21.333333 0 0 1 192 554.666667H21.333333a21.333333 21.333333 0 0 1 0-42.666667h157.48l79.44-158.873333a21.333333 21.333333 0 0 1 39.466667 3.266666L444.666667 834 597.84 144.706667a21.333333 21.333333 0 0 1 41.213333-1.646667l155.013334 503.773333 61.52-123.04A21.333333 21.333333 0 0 1 874.666667 512h128a21.333333 21.333333 0 0 1 0 42.666667h-114.813334l-79.44 158.873333a21.333333 21.333333 0 0 1-39.466666-3.266667L622 232.666667 468.826667 921.96a21.333333 21.333333 0 0 1-20 16.666667z" fill="#5C5C66" p-id="8584"></path></svg>

After

Width:  |  Height:  |  Size: 961 B

View file

@ -0,0 +1,86 @@
<script setup lang="ts">
import {useGettext} from 'vue3-gettext'
import {CloseOutlined, DashboardOutlined, DatabaseOutlined} from '@ant-design/icons-vue'
import {useSettingsStore} from '@/pinia'
import {storeToRefs} from 'pinia'
import {useRouter} from 'vue-router'
import {computed, watch} from 'vue'
const {$gettext} = useGettext()
const settingsStore = useSettingsStore()
const {environment} = storeToRefs(settingsStore)
const router = useRouter()
function clear_env() {
router.push('/dashboard')
location.reload()
settingsStore.clear_environment()
}
const is_local = computed(() => {
return environment.value.id === 0
})
const node_id = computed(() => environment.value.id)
watch(node_id, () => {
router.push('/dashboard')
location.reload()
})
</script>
<template>
<div class="indicator">
<div class="container">
<database-outlined/>
<span class="env-name" v-if="is_local">
{{ $gettext('Local') }}
</span>
<span class="env-name" v-else>
{{ environment.name }}
</span>
<a-tag @click="clear_env">
<dashboard-outlined v-if="is_local"/>
<close-outlined v-else/>
</a-tag>
</div>
</div>
</template>
<style scoped lang="less">
.ant-layout-sider-collapsed {
.ant-tag, .env-name {
display: none;
}
.indicator {
.container {
justify-content: center;
}
}
}
.indicator {
padding: 20px;
.container {
border-radius: 16px;
border: 1px solid #91d5ff;
background: #e6f7ff;
padding: 5px 15px;
color: #096dd9;
display: flex;
align-items: center;
justify-content: space-between;
.ant-tag {
cursor: pointer;
margin-right: 0;
padding: 0 5px;
}
}
}
</style>

View file

@ -86,8 +86,14 @@ function add() {
visible.value = true
}
function get_list() {
const t: Table = table.value!
t!.get_list()
}
defineExpose({
add,
get_list,
data
})
@ -109,8 +115,7 @@ const ok = async () => {
props.api!.save(data.id, data).then((r: any) => {
message.success($gettext('Save Successfully'))
Object.assign(data, r)
const t: Table = table.value!
t!.get_list()
get_list()
}).catch((e: any) => {
message.error($gettext(e?.message ?? 'Server error'), 5)
@ -144,7 +149,7 @@ const selectedRowKeys = ref([])
<div class="std-curd">
<a-card :title="title||$gettext('Table')">
<template v-if="!disable_add" #extra>
<a @click="add" v-translate>Add</a>
<a @click="add">{{ $gettext('Add') }}</a>
</template>
<std-table

View file

@ -2,7 +2,8 @@
import Logo from '@/components/Logo/Logo.vue'
import {routes} from '@/routes'
import {useRoute} from 'vue-router'
import {computed, ref, watch} from 'vue'
import {computed, ComputedRef, ref, watch} from 'vue'
import EnvIndicator from '@/components/EnvIndicator/EnvIndicator.vue'
const route = useRoute()
@ -30,6 +31,7 @@ const sidebars = computed(() => {
interface meta {
icon: any
hiddenInSidebar: boolean
hideChildren: boolean
}
interface sidebar {
@ -39,7 +41,7 @@ interface sidebar {
children: sidebar[]
}
const visible = computed(() => {
const visible: ComputedRef<sidebar[]> = computed(() => {
const res: sidebar[] = [];
@ -71,6 +73,9 @@ const visible = computed(() => {
<template>
<div class="sidebar">
<logo/>
<env-indicator/>
<a-menu
:openKeys="openKeys"
mode="inline"
@ -78,7 +83,7 @@ const visible = computed(() => {
v-model:selectedKeys="selectedKey"
>
<template v-for="sidebar in visible">
<a-menu-item v-if="sidebar.children.length===0 || sidebar.meta.hideChildren === true"
<a-menu-item v-if="sidebar.children.length===0 || sidebar.meta.hideChildren"
:key="sidebar.name"
@click="$router.push('/'+sidebar.path).catch(() => {})">
<component :is="sidebar.meta.icon"/>

View file

@ -1,3 +1,6 @@
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
function bytesToSize(bytes: number) {
if (bytes === 0) return '0 B'
@ -60,9 +63,25 @@ function createEnum(definition: any) {
}
}
function fromNow(t: string) {
dayjs.extend(relativeTime)
return dayjs(t).fromNow()
}
function formatDate(t: string) {
return dayjs(t).format('YYYY.MM.DD')
}
function formatDateTime(t: string) {
return dayjs(t).format('YYYY-MM-DD HH:mm:ss')
}
export {
bytesToSize,
downloadCsv,
urlJoin,
createEnum
createEnum,
fromNow,
formatDate,
formatDateTime
}

View file

@ -1,5 +1,5 @@
import axios, {AxiosRequestConfig} from 'axios'
import {useUserStore} from '@/pinia'
import {useSettingsStore, useUserStore} from '@/pinia'
import {storeToRefs} from 'pinia'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
@ -7,7 +7,7 @@ import 'nprogress/nprogress.css'
import router from '@/routes'
const user = useUserStore()
const settings = useSettingsStore()
const {token} = storeToRefs(user)
let instance = axios.create({
@ -31,6 +31,9 @@ instance.interceptors.request.use(
if (token) {
(config.headers as any).Authorization = token.value
}
if (settings.environment.id) {
(config.headers as any)['X-Node-ID'] = settings.environment.id
}
return config
},
err => {

View file

@ -1,24 +1,26 @@
import ReconnectingWebSocket from 'reconnecting-websocket'
import {useUserStore} from '@/pinia'
import {useSettingsStore, useUserStore} from '@/pinia'
import {storeToRefs} from 'pinia'
import {urlJoin} from '@/lib/helper'
function ws(url: string, reconnect: boolean = true): ReconnectingWebSocket | WebSocket {
const user = useUserStore()
const settings = useSettingsStore()
const {token} = storeToRefs(user)
const protocol = location.protocol === 'https:' ? 'wss://' : 'ws://'
const node_id = (settings.environment.id > 0) ? ('&x_node_id=' + settings.environment.id) : ''
const _url = urlJoin(protocol + window.location.host, window.location.pathname,
url, '?token=' + btoa(token.value))
url, '?token=' + btoa(token.value), node_id)
if (reconnect) {
return new ReconnectingWebSocket(_url)
}
return new WebSocket(_url)
}
export default ws

View file

@ -4,7 +4,11 @@ export const useSettingsStore = defineStore('settings', {
state: () => ({
language: '',
theme: 'light',
preference_theme: 'auto'
preference_theme: 'auto',
environment: {
id: 0,
name: 'Local'
}
}),
getters: {},
actions: {
@ -16,6 +20,10 @@ export const useSettingsStore = defineStore('settings', {
},
set_preference_theme(t: string) {
this.preference_theme = t
},
clear_environment() {
this.environment.id = 0
this.environment.name = 'Local'
}
},
persist: true

View file

@ -5,6 +5,7 @@ import {useUserStore} from '@/pinia'
import {
CloudOutlined,
CodeOutlined,
DatabaseOutlined,
FileOutlined,
FileTextOutlined,
HomeOutlined,
@ -34,14 +35,6 @@ export const routes = [
icon: HomeOutlined
}
},
{
path: 'user',
name: () => $gettext('Manage Users'),
component: () => import('@/views/user/User.vue'),
meta: {
icon: UserOutlined
}
},
{
path: 'domain',
name: () => $gettext('Manage Sites'),
@ -135,6 +128,22 @@ export const routes = [
}
}]
},
{
path: 'environment',
name: () => $gettext('Environment'),
component: () => import('@/views/environment/environment.vue'),
meta: {
icon: DatabaseOutlined
}
},
{
path: 'user',
name: () => $gettext('Manage Users'),
component: () => import('@/views/user/User.vue'),
meta: {
icon: UserOutlined
}
},
{
path: 'preference',
name: () => $gettext('Preference'),

View file

@ -1 +1 @@
{"version":"1.9.9","build_id":109,"total_build":179}
{"version":"1.9.9","build_id":113,"total_build":183}

View file

@ -1,330 +1,15 @@
<script setup lang="ts">
import AreaChart from '@/components/Chart/AreaChart.vue'
import RadialBarChart from '@/components/Chart/RadialBarChart.vue'
import {useGettext} from 'vue3-gettext'
import {onMounted, onUnmounted, reactive, ref} from 'vue'
import analytic from '@/api/analytic'
import ws from '@/lib/websocket'
import {bytesToSize} from '@/lib/helper'
import ReconnectingWebSocket from 'reconnecting-websocket'
const {$gettext} = useGettext()
let websocket: ReconnectingWebSocket | WebSocket
const host = reactive({})
const cpu = ref('0.0')
const cpu_info = reactive([])
const cpu_analytic_series = reactive([{name: 'User', data: <any>[]}, {name: 'Total', data: <any>[]}])
const net_analytic = reactive([{name: $gettext('Receive'), data: <any>[]},
{name: $gettext('Send'), data: <any>[]}])
const disk_io_analytic = reactive([{name: $gettext('Writes'), data: <any>[]},
{name: $gettext('Reads'), data: <any>[]}])
const memory = reactive({})
const disk = reactive({})
const disk_io = reactive({writes: 0, reads: 0})
const uptime = ref('')
const loadavg = reactive({})
const net = reactive({recv: 0, sent: 0, last_recv: 0, last_sent: 0})
const net_formatter = (bytes: number) => {
return bytesToSize(bytes) + '/s'
}
interface Usage {
x: number
y: number
}
onMounted(() => {
analytic.init().then(r => {
Object.assign(host, r.host)
Object.assign(cpu_info, r.cpu.info)
Object.assign(memory, r.memory)
Object.assign(disk, r.disk)
// uptime
handle_uptime(r.host?.uptime)
// load_avg
Object.assign(loadavg, r.loadavg)
net.last_recv = r.network.init.bytesRecv
net.last_sent = r.network.init.bytesSent
r.cpu.user.forEach((u: Usage) => {
cpu_analytic_series[0].data.push([u.x, u.y.toFixed(2)])
})
r.cpu.total.forEach((u: Usage) => {
cpu_analytic_series[1].data.push([u.x, u.y.toFixed(2)])
})
r.network.bytesRecv.forEach((u: Usage) => {
net_analytic[0].data.push([u.x, u.y.toFixed(2)])
})
r.network.bytesSent.forEach((u: Usage) => {
net_analytic[1].data.push([u.x, u.y.toFixed(2)])
})
disk_io_analytic[0].data = disk_io_analytic[0].data.concat(r.disk_io.writes)
disk_io_analytic[1].data = disk_io_analytic[1].data.concat(r.disk_io.reads)
websocket = ws('/api/analytic')
websocket.onmessage = wsOnMessage
})
})
onUnmounted(() => {
websocket.close()
})
function handle_uptime(t: number) {
// uptime
let _uptime = Math.floor(t)
let uptime_days = Math.floor(_uptime / 86400)
_uptime -= uptime_days * 86400
let uptime_hours = Math.floor(_uptime / 3600)
_uptime -= uptime_hours * 3600
uptime.value = uptime_days + 'd ' + uptime_hours + 'h ' + Math.floor(_uptime / 60) + 'm'
}
function wsOnMessage(m: { data: any }) {
const r = JSON.parse(m.data)
const cpu_usage = r.cpu.system + r.cpu.user
cpu.value = cpu_usage.toFixed(2)
const time = new Date().getTime()
cpu_analytic_series[0].data.push([time, r.cpu.user.toFixed(2)])
cpu_analytic_series[1].data.push([time, cpu.value])
if (cpu_analytic_series[0].data.length > 100) {
cpu_analytic_series[0].data.shift()
cpu_analytic_series[1].data.shift()
}
// mem
Object.assign(memory, r.memory)
// disk
Object.assign(disk, r.disk)
disk_io.writes = r.disk.writes.y
disk_io.reads = r.disk.reads.y
// uptime
handle_uptime(r.uptime)
// loadavg
Object.assign(loadavg, r.loadavg)
// network
Object.assign(net, r.network)
net.recv = r.network.bytesRecv - net.last_recv
net.sent = r.network.bytesSent - net.last_sent
net.last_recv = r.network.bytesRecv
net.last_sent = r.network.bytesSent
net_analytic[0].data.push([time, net.recv])
net_analytic[1].data.push([time, net.sent])
if (net_analytic[0].data.length > 100) {
net_analytic[0].data.shift()
net_analytic[1].data.shift()
}
disk_io_analytic[0].data.push(r.disk.writes)
disk_io_analytic[1].data.push(r.disk.reads)
if (disk_io_analytic[0].data.length > 100) {
disk_io_analytic[0].data.shift()
disk_io_analytic[1].data.shift()
}
}
import ServerAnalytic from '@/views/dashboard/ServerAnalytic.vue'
import Environments from '@/views/dashboard/Environments.vue'
</script>
<template>
<div>
<a-row :gutter="[{xs: 0, sm: 16}, 16]" class="first-row">
<a-col :xl="7" :lg="24" :md="24" :xs="24">
<a-card :title="$gettext('Server Info')" :bordered="false">
<p>
<translate>Uptime:</translate>
{{ uptime }}
</p>
<p>
<translate>Load Averages:</translate>
<span class="load-avg-describe"> 1min:</span>{{ ' ' + loadavg?.load1?.toFixed(2) }}
<span class="load-avg-describe"> | 5min:</span>{{ loadavg?.load5?.toFixed(2) }}
<span class="load-avg-describe"> | 15min:</span>{{ loadavg?.load15?.toFixed(2) }}
</p>
<p>
<translate>OS:</translate>
<span class="os-platform">{{ ' ' + host.platform }}</span> {{ host.platformVersion }}
<span class="os-info">({{ host.os }} {{ host.kernelVersion }}
{{ host.kernelArch }})</span>
</p>
<p v-if="cpu_info">
{{ $gettext('CPU:') + ' ' }}
<span class="cpu-model">{{ cpu_info[0]?.modelName || 'core' }}</span>
<span class="cpu-mhz">{{ (cpu_info[0]?.mhz / 1000).toFixed(2) + 'GHz' }}</span>
* {{ cpu_info.length }}
</p>
</a-card>
</a-col>
<a-col :xl="10" :lg="16" :md="24" :xs="24" class="chart_dashboard">
<a-card :title="$gettext('Memory and Storage')" :bordered="false">
<a-row :gutter="[0,16]">
<a-col :xs="24" :sm="24" :md="8">
<radial-bar-chart :name="$gettext('Memory')" :series="[memory.pressure]"
:centerText="memory.used" :bottom-text="memory.total" colors="#36a3eb"/>
</a-col>
<a-col :xs="24" :sm="12" :md="8">
<radial-bar-chart :name="$gettext('Swap')" :series="[memory.swap_percent]"
:centerText="memory.swap_used"
:bottom-text="memory.swap_total" colors="#ff6385"/>
</a-col>
<a-col :xs="24" :sm="12" :md="8">
<radial-bar-chart :name="$gettext('Storage')" :series="[disk.percentage]"
:centerText="disk.used" :bottom-text="disk.total" colors="#87d068"/>
</a-col>
</a-row>
</a-card>
</a-col>
<a-col :xl="7" :lg="8" :sm="24" :xs="24" class="chart_dashboard network-total">
<a-card :title="$gettext('Network Statistics')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="bytesToSize(net.last_recv)"
:title="$gettext('Network Total Receive')"/>
</a-col>
<a-col :span="12">
<a-statistic :value="bytesToSize(net.last_sent)"
:title="$gettext('Network Total Send')"/>
</a-col>
</a-row>
</a-card>
</a-col>
</a-row>
<a-row :gutter="[{xs: 0, sm: 16}, 16]" class="row-two">
<a-col :xl="8" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('CPU Status')" :bordered="false">
<a-statistic :value="cpu" title="CPU">
<template v-slot:suffix>
<span>%</span>
</template>
</a-statistic>
<area-chart :series="cpu_analytic_series" :max="100"/>
</a-card>
</a-col>
<a-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('Network')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="bytesToSize(net.recv)"
:title="$gettext('Receive')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
<a-col :span="12">
<a-statistic :value="bytesToSize(net.sent)" :title="$gettext('Send')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
</a-row>
<area-chart :series="net_analytic" :y_formatter="net_formatter"/>
</a-card>
</a-col>
<a-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('Disk IO')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="disk_io.writes"
:title="$gettext('Writes')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
<a-col :span="12">
<a-statistic :value="disk_io.reads" :title="$gettext('Reads')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
</a-row>
<area-chart :series="disk_io_analytic"/>
</a-card>
</a-col>
</a-row>
<server-analytic/>
<environments/>
</div>
</template>
<style lang="less" scoped>
.first-row {
.ant-card {
min-height: 227px;
<style scoped lang="less">
p {
margin-bottom: 8px;
}
}
margin-bottom: 20px;
}
.ant-card {
.ant-statistic {
margin: 0 0 10px 10px
}
.chart {
max-width: 800px;
max-height: 350px;
}
.chart_dashboard {
padding: 60px;
.description {
width: 120px;
text-align: center
}
}
@media (max-width: 512px) {
margin: 10px 0;
.chart_dashboard {
padding: 20px;
}
}
}
.load-avg-describe {
@media (max-width: 1600px) and (min-width: 1200px) {
display: none;
}
}
.os-info {
@media (max-width: 1600px) and (min-width: 1200px) {
display: none;
}
}
.cpu-model {
@media (max-width: 1790px) and (min-width: 1200px) {
display: none;
}
}
.cpu-mhz {
@media (min-width: 1790px) or (max-width: 1200px) {
display: none;
}
}
</style>

View file

@ -0,0 +1,102 @@
<script setup lang="ts">
import {useSettingsStore} from '@/pinia'
import {useGettext} from 'vue3-gettext'
import {computed, ref} from 'vue'
import environment from '@/api/environment'
import Icon, {LinkOutlined, SendOutlined, ThunderboltOutlined} from '@ant-design/icons-vue'
import logo from '@/assets/img/logo.png'
import pulse from '@/assets/svg/pulse.svg'
import cpu from '@/assets/svg/cpu.svg'
import memory from '@/assets/svg/memory.svg'
import {formatDateTime} from '@/lib/helper'
const settingsStore = useSettingsStore()
const {$gettext} = useGettext()
const data = ref([])
environment.get_list().then(r => {
data.value = r.data
})
export interface Node {
id: number
name: string
token: string
}
const {environment: env} = settingsStore
function link_start(node: Node) {
env.id = node.id
env.name = node.name
}
const visible = computed(() => {
if (env.id > 0) {
return false
} else {
return data.value?.length
}
})
</script>
<template>
<a-card class="env-list-card" :title="$gettext('Environments')" v-if="visible">
<a-list item-layout="horizontal" :data-source="data">
<template #renderItem="{ item }">
<a-list-item>
<template #actions>
<a-button type="primary" @click="link_start(item)" :disabled="env.id===item.id" ghost>
<send-outlined/>
{{ env.id !== item.id ? $gettext('Link Start') : $gettext('Connected') }}
</a-button>
</template>
<a-list-item-meta>
<template #title>
{{ item.name }}
<a-tag color="blue" v-if="item.status">{{ $gettext('Online') }}</a-tag>
<a-tag color="error" v-else>{{ $gettext('Offline') }}</a-tag>
<div class="runtime-meta">
<span><Icon :component="pulse"/> {{ formatDateTime(item.response_at) }}</span>
<span><thunderbolt-outlined/>{{ item.version }}</span>
<span><link-outlined/>{{ item.url }}</span>
</div>
</template>
<template #avatar>
<a-avatar :src="logo"/>
</template>
<template #description>
<div class="runtime-meta">
<span><Icon :component="cpu"/> {{ item.cpu_num }} CPU</span>
<span><Icon :component="memory"/> {{ item.memory_total }}</span>
</div>
</template>
</a-list-item-meta>
</a-list-item>
</template>
</a-list>
</a-card>
</template>
<style scoped lang="less">
.env-list-card {
margin-top: 16px;
.runtime-meta {
display: inline-flex;
margin-left: 8px;
span {
font-weight: 400;
font-size: 13px;
margin-right: 16px;
color: #9b9b9b;
&.anticon {
margin-right: 4px;
}
}
}
}
</style>

View file

@ -0,0 +1,330 @@
<script setup lang="ts">
import AreaChart from '@/components/Chart/AreaChart.vue'
import RadialBarChart from '@/components/Chart/RadialBarChart.vue'
import {useGettext} from 'vue3-gettext'
import {onMounted, onUnmounted, reactive, ref} from 'vue'
import analytic from '@/api/analytic'
import ws from '@/lib/websocket'
import {bytesToSize} from '@/lib/helper'
import ReconnectingWebSocket from 'reconnecting-websocket'
const {$gettext} = useGettext()
let websocket: ReconnectingWebSocket | WebSocket
const host = reactive({})
const cpu = ref('0.0')
const cpu_info = reactive([])
const cpu_analytic_series = reactive([{name: 'User', data: <any>[]}, {name: 'Total', data: <any>[]}])
const net_analytic = reactive([{name: $gettext('Receive'), data: <any>[]},
{name: $gettext('Send'), data: <any>[]}])
const disk_io_analytic = reactive([{name: $gettext('Writes'), data: <any>[]},
{name: $gettext('Reads'), data: <any>[]}])
const memory = reactive({})
const disk = reactive({})
const disk_io = reactive({writes: 0, reads: 0})
const uptime = ref('')
const loadavg = reactive({})
const net = reactive({recv: 0, sent: 0, last_recv: 0, last_sent: 0})
const net_formatter = (bytes: number) => {
return bytesToSize(bytes) + '/s'
}
interface Usage {
x: number
y: number
}
onMounted(() => {
analytic.init().then(r => {
Object.assign(host, r.host)
Object.assign(cpu_info, r.cpu.info)
Object.assign(memory, r.memory)
Object.assign(disk, r.disk)
// uptime
handle_uptime(r.host?.uptime)
// load_avg
Object.assign(loadavg, r.loadavg)
net.last_recv = r.network.init.bytesRecv
net.last_sent = r.network.init.bytesSent
r.cpu.user.forEach((u: Usage) => {
cpu_analytic_series[0].data.push([u.x, u.y.toFixed(2)])
})
r.cpu.total.forEach((u: Usage) => {
cpu_analytic_series[1].data.push([u.x, u.y.toFixed(2)])
})
r.network.bytesRecv.forEach((u: Usage) => {
net_analytic[0].data.push([u.x, u.y.toFixed(2)])
})
r.network.bytesSent.forEach((u: Usage) => {
net_analytic[1].data.push([u.x, u.y.toFixed(2)])
})
disk_io_analytic[0].data = disk_io_analytic[0].data.concat(r.disk_io.writes)
disk_io_analytic[1].data = disk_io_analytic[1].data.concat(r.disk_io.reads)
websocket = ws('/api/analytic')
websocket.onmessage = wsOnMessage
})
})
onUnmounted(() => {
websocket.close()
})
function handle_uptime(t: number) {
// uptime
let _uptime = Math.floor(t)
let uptime_days = Math.floor(_uptime / 86400)
_uptime -= uptime_days * 86400
let uptime_hours = Math.floor(_uptime / 3600)
_uptime -= uptime_hours * 3600
uptime.value = uptime_days + 'd ' + uptime_hours + 'h ' + Math.floor(_uptime / 60) + 'm'
}
function wsOnMessage(m: { data: any }) {
const r = JSON.parse(m.data)
const cpu_usage = r.cpu.system + r.cpu.user
cpu.value = cpu_usage.toFixed(2)
const time = new Date().getTime()
cpu_analytic_series[0].data.push([time, r.cpu.user.toFixed(2)])
cpu_analytic_series[1].data.push([time, cpu.value])
if (cpu_analytic_series[0].data.length > 100) {
cpu_analytic_series[0].data.shift()
cpu_analytic_series[1].data.shift()
}
// mem
Object.assign(memory, r.memory)
// disk
Object.assign(disk, r.disk)
disk_io.writes = r.disk.writes.y
disk_io.reads = r.disk.reads.y
// uptime
handle_uptime(r.uptime)
// loadavg
Object.assign(loadavg, r.loadavg)
// network
Object.assign(net, r.network)
net.recv = r.network.bytesRecv - net.last_recv
net.sent = r.network.bytesSent - net.last_sent
net.last_recv = r.network.bytesRecv
net.last_sent = r.network.bytesSent
net_analytic[0].data.push([time, net.recv])
net_analytic[1].data.push([time, net.sent])
if (net_analytic[0].data.length > 100) {
net_analytic[0].data.shift()
net_analytic[1].data.shift()
}
disk_io_analytic[0].data.push(r.disk.writes)
disk_io_analytic[1].data.push(r.disk.reads)
if (disk_io_analytic[0].data.length > 100) {
disk_io_analytic[0].data.shift()
disk_io_analytic[1].data.shift()
}
}
</script>
<template>
<div>
<a-row :gutter="[{xs: 0, sm: 16}, 16]" class="first-row">
<a-col :xl="7" :lg="24" :md="24" :xs="24">
<a-card :title="$gettext('Server Info')" :bordered="false">
<p>
<translate>Uptime:</translate>
{{ uptime }}
</p>
<p>
<translate>Load Averages:</translate>
<span class="load-avg-describe"> 1min:</span>{{ ' ' + loadavg?.load1?.toFixed(2) }}
<span class="load-avg-describe"> | 5min:</span>{{ loadavg?.load5?.toFixed(2) }}
<span class="load-avg-describe"> | 15min:</span>{{ loadavg?.load15?.toFixed(2) }}
</p>
<p>
<translate>OS:</translate>
<span class="os-platform">{{ ' ' + host.platform }}</span> {{ host.platformVersion }}
<span class="os-info">({{ host.os }} {{ host.kernelVersion }}
{{ host.kernelArch }})</span>
</p>
<p v-if="cpu_info">
{{ $gettext('CPU:') + ' ' }}
<span class="cpu-model">{{ cpu_info[0]?.modelName || 'core' }}</span>
<span class="cpu-mhz">{{ (cpu_info[0]?.mhz / 1000).toFixed(2) + 'GHz' }}</span>
* {{ cpu_info.length }}
</p>
</a-card>
</a-col>
<a-col :xl="10" :lg="16" :md="24" :xs="24" class="chart_dashboard">
<a-card :title="$gettext('Memory and Storage')" :bordered="false">
<a-row :gutter="[0,16]">
<a-col :xs="24" :sm="24" :md="8">
<radial-bar-chart :name="$gettext('Memory')" :series="[memory.pressure]"
:centerText="memory.used" :bottom-text="memory.total" colors="#36a3eb"/>
</a-col>
<a-col :xs="24" :sm="12" :md="8">
<radial-bar-chart :name="$gettext('Swap')" :series="[memory.swap_percent]"
:centerText="memory.swap_used"
:bottom-text="memory.swap_total" colors="#ff6385"/>
</a-col>
<a-col :xs="24" :sm="12" :md="8">
<radial-bar-chart :name="$gettext('Storage')" :series="[disk.percentage]"
:centerText="disk.used" :bottom-text="disk.total" colors="#87d068"/>
</a-col>
</a-row>
</a-card>
</a-col>
<a-col :xl="7" :lg="8" :sm="24" :xs="24" class="chart_dashboard network-total">
<a-card :title="$gettext('Network Statistics')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="bytesToSize(net.last_recv)"
:title="$gettext('Network Total Receive')"/>
</a-col>
<a-col :span="12">
<a-statistic :value="bytesToSize(net.last_sent)"
:title="$gettext('Network Total Send')"/>
</a-col>
</a-row>
</a-card>
</a-col>
</a-row>
<a-row :gutter="[{xs: 0, sm: 16}, 16]" class="row-two">
<a-col :xl="8" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('CPU Status')" :bordered="false">
<a-statistic :value="cpu" title="CPU">
<template v-slot:suffix>
<span>%</span>
</template>
</a-statistic>
<area-chart :series="cpu_analytic_series" :max="100"/>
</a-card>
</a-col>
<a-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('Network')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="bytesToSize(net.recv)"
:title="$gettext('Receive')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
<a-col :span="12">
<a-statistic :value="bytesToSize(net.sent)" :title="$gettext('Send')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
</a-row>
<area-chart :series="net_analytic" :y_formatter="net_formatter"/>
</a-card>
</a-col>
<a-col :xl="8" :lg="12" :md="24" :sm="24" :xs="24">
<a-card :title="$gettext('Disk IO')" :bordered="false">
<a-row :gutter="16">
<a-col :span="12">
<a-statistic :value="disk_io.writes"
:title="$gettext('Writes')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
<a-col :span="12">
<a-statistic :value="disk_io.reads" :title="$gettext('Reads')">
<template v-slot:suffix>
<span>/s</span>
</template>
</a-statistic>
</a-col>
</a-row>
<area-chart :series="disk_io_analytic"/>
</a-card>
</a-col>
</a-row>
</div>
</template>
<style lang="less" scoped>
.first-row {
.ant-card {
min-height: 227px;
p {
margin-bottom: 8px;
}
}
margin-bottom: 20px;
}
.ant-card {
.ant-statistic {
margin: 0 0 10px 10px
}
.chart {
max-width: 800px;
max-height: 350px;
}
.chart_dashboard {
padding: 60px;
.description {
width: 120px;
text-align: center
}
}
@media (max-width: 512px) {
margin: 10px 0;
.chart_dashboard {
padding: 20px;
}
}
}
.load-avg-describe {
@media (max-width: 1600px) and (min-width: 1200px) {
display: none;
}
}
.os-info {
@media (max-width: 1600px) and (min-width: 1200px) {
display: none;
}
}
.cpu-model {
@media (max-width: 1790px) and (min-width: 1200px) {
display: none;
}
}
.cpu-mhz {
@media (min-width: 1790px) or (max-width: 1200px) {
display: none;
}
}
</style>

View file

@ -0,0 +1,73 @@
<script setup lang="tsx">
import {useGettext} from 'vue3-gettext'
import {customRender, datetime} from '@/components/StdDataDisplay/StdTableTransformer'
import environment from '@/api/environment'
import StdCurd from '@/components/StdDataDisplay/StdCurd.vue'
import {input} from '@/components/StdDataEntry'
import {h} from 'vue'
import {Badge} from 'ant-design-vue'
const {$gettext, interpolate} = useGettext()
const columns = [{
title: () => $gettext('Name'),
dataIndex: 'name',
sorter: true,
pithy: true,
edit: {
type: input
}
}, {
title: () => $gettext('URL'),
dataIndex: 'url',
sorter: true,
pithy: true,
edit: {
type: input,
placeholder: () => 'https://10.0.0.1:9000'
}
}, {
title: () => $gettext('Token'),
dataIndex: 'token',
sorter: true,
display: false,
edit: {
type: input
}
}, {
title: () => $gettext('Status'),
dataIndex: 'status',
customRender: (args: customRender) => {
const template: any = []
const {text} = args
if (text === true || text > 0) {
template.push(<Badge status="success"/>)
template.push($gettext('Online'))
} else {
template.push(<Badge status="error"/>)
template.push($gettext('Offline'))
}
return h('div', template)
},
sorter: true,
pithy: true
}, {
title: () => $gettext('Updated at'),
dataIndex: 'updated_at',
customRender: datetime,
sorter: true,
pithy: true
}, {
title: () => $gettext('Action'),
dataIndex: 'action'
}]
</script>
<template>
<std-curd :title="$gettext('Environment')" :api="environment" :columns="columns"/>
</template>
<style lang="less" scoped>
</style>

View file

@ -1 +1 @@
{"version":"1.9.9","build_id":109,"total_build":179}
{"version":"1.9.9","build_id":113,"total_build":183}

View file

@ -75,6 +75,6 @@ export default defineConfig({
}
},
build: {
chunkSizeWarningLimit: 600
chunkSizeWarningLimit: 1000
}
})

100
go.mod
View file

@ -6,39 +6,39 @@ require (
github.com/BurntSushi/toml v1.2.1
github.com/creack/pty v1.1.18
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.13.0
github.com/fatih/color v1.15.0
github.com/gin-contrib/static v0.0.1
github.com/gin-gonic/gin v1.9.0
github.com/go-acme/lego/v4 v4.10.2
github.com/go-co-op/gocron v1.20.1
github.com/go-playground/validator/v10 v10.12.0
github.com/go-acme/lego/v4 v4.11.0
github.com/go-co-op/gocron v1.27.0
github.com/go-playground/validator/v10 v10.13.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/hpcloud/tail v1.0.0
github.com/jpillora/overseer v1.1.6
github.com/lib/pq v1.10.7
github.com/lib/pq v1.10.9
github.com/pkg/errors v0.9.1
github.com/sashabaranov/go-openai v1.7.0
github.com/shirou/gopsutil/v3 v3.23.3
github.com/sashabaranov/go-openai v1.9.4
github.com/shirou/gopsutil/v3 v3.23.4
github.com/spf13/cast v1.5.0
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508112508-44b3f58122c3
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508164033-d7b72d6cd0d5
github.com/unknwon/com v1.0.1
go.uber.org/zap v1.24.0
golang.org/x/crypto v0.8.0
golang.org/x/crypto v0.9.0
gopkg.in/ini.v1 v1.67.0
gorm.io/driver/sqlite v1.5.0
gorm.io/gen v0.3.21
gorm.io/gorm v1.25.0
gorm.io/gen v0.3.22
gorm.io/gorm v1.25.1
gorm.io/plugin/dbresolver v1.4.1
)
require (
cloud.google.com/go/compute v1.19.1 // indirect
cloud.google.com/go/compute v1.19.2 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
@ -50,16 +50,16 @@ require (
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.62.281 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.62.318 // indirect
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/aws/aws-sdk-go v1.44.242 // indirect
github.com/aws/aws-sdk-go v1.44.262 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/bytedance/sonic v1.8.7 // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/bytedance/sonic v1.8.8 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/civo/civogo v0.3.29 // indirect
github.com/cloudflare/cloudflare-go v0.49.0 // indirect
github.com/civo/civogo v0.3.34 // indirect
github.com/cloudflare/cloudflare-go v0.67.0 // indirect
github.com/cpu/goacmedns v0.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deepmap/oapi-codegen v1.12.4 // indirect
@ -72,25 +72,29 @@ require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.1 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.3 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
github.com/gophercloud/gophercloud v1.3.0 // indirect
github.com/gophercloud/utils v0.0.0-20230330070308-5bd5e1d608f8 // indirect
github.com/gophercloud/utils v0.0.0-20230418172808-6eab72e966e1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
@ -103,8 +107,8 @@ require (
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect
github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect
github.com/labbsr0x/goh v1.0.1 // indirect
github.com/leodido/go-urn v1.2.3 // indirect
github.com/linode/linodego v1.16.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/linode/linodego v1.16.2 // indirect
github.com/liquidweb/go-lwApi v0.0.5 // indirect
github.com/liquidweb/liquidweb-cli v0.6.10 // indirect
github.com/liquidweb/liquidweb-go v1.6.3 // indirect
@ -112,7 +116,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/miekg/dns v1.1.53 // indirect
github.com/miekg/dns v1.1.54 // indirect
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@ -125,6 +129,7 @@ require (
github.com/nrdcg/freemyip v0.2.0 // indirect
github.com/nrdcg/goinwx v0.8.2 // indirect
github.com/nrdcg/namesilo v0.2.1 // indirect
github.com/nrdcg/nodion v0.1.0 // indirect
github.com/nrdcg/porkbun v0.2.0 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
@ -134,31 +139,33 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/pquerna/otp v1.4.0 // indirect
github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sacloud/api-client-go v0.2.7 // indirect
github.com/sacloud/go-http v0.1.5 // indirect
github.com/sacloud/iaas-api-go v1.9.2 // indirect
github.com/sacloud/iaas-api-go v1.10.0 // indirect
github.com/sacloud/packages-go v0.0.8 // indirect
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15 // indirect
github.com/shoenig/go-m1cpu v0.1.5 // indirect
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
github.com/softlayer/softlayer-go v1.1.2 // indirect
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.2 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.637 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.637 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.655 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.655 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/transip/gotransip/v6 v6.20.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/ultradns/ultradns-go-sdk v1.4.1-20230224143201-0d8b0f6 // indirect
github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c // indirect
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
github.com/vultr/govultr/v2 v2.17.2 // indirect
github.com/yandex-cloud/go-genproto v0.0.0-20230410092700-15216dc82345 // indirect
github.com/yandex-cloud/go-sdk v0.0.0-20230403093608-cc5174142a48 // indirect
github.com/yandex-cloud/go-genproto v0.0.0-20230511103421-ecb0cd1514ab // indirect
github.com/yandex-cloud/go-sdk v0.0.0-20230511104317-0ccfef4d3a91 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
@ -166,24 +173,33 @@ require (
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.8.0 // indirect
google.golang.org/api v0.118.0 // indirect
golang.org/x/tools v0.9.1 // indirect
google.golang.org/api v0.122.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/grpc v1.55.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/ns1/ns1-go.v2 v2.7.5 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ns1/ns1-go.v2 v2.7.6 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/datatypes v1.2.0 // indirect
gorm.io/driver/mysql v1.5.0 // indirect
gorm.io/hints v1.1.1 // indirect
gorm.io/hints v1.1.2 // indirect
k8s.io/api v0.27.1 // indirect
k8s.io/apimachinery v0.27.1 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
replace github.com/cloudflare/cloudflare-go v0.67.0 => github.com/cloudflare/cloudflare-go v0.49.0

222
go.sum
View file

@ -9,6 +9,8 @@ cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
cloud.google.com/go/compute v1.19.2 h1:GbJtPo8OKVHbVep8jvM57KidbYHxeE68LOVqouNLrDY=
cloud.google.com/go/compute v1.19.2/go.mod h1:5f5a+iC1IriXYauaQ0EyQmEAEq9CGRnV5xJSQSlTV08=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
@ -24,7 +26,10 @@ github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW
github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=
github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=
github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs=
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk=
@ -49,6 +54,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
@ -62,6 +68,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v1.62.281 h1:sN94THxWQA+nPMDZD0esg1PGy6pmkTh7SCVc1MQaKzA=
github.com/aliyun/alibaba-cloud-sdk-go v1.62.281/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
github.com/aliyun/alibaba-cloud-sdk-go v1.62.318 h1:1ntKWopst53IVWKlEVrgutJpEgQN+FyNZXO+h6ePgXw=
github.com/aliyun/alibaba-cloud-sdk-go v1.62.318/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
@ -70,8 +78,12 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.44.242 h1:bb6Rqd7dxh1gTUoVXLJTNC2c+zNaHpLRlNKk0kGN3fc=
github.com/aws/aws-sdk-go v1.44.242/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.262 h1:gyXpcJptWoNkK+DiAiaBltlreoWKQXjAIh6FRh60F+I=
github.com/aws/aws-sdk-go v1.44.262/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -85,10 +97,14 @@ github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.8.7 h1:d3sry5vGgVq/OpgozRUNP6xBsSo0mtNdwliApw+SAMQ=
github.com/bytedance/sonic v1.8.7/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/bytedance/sonic v1.8.8 h1:Kj4AYbZSeENfyXicsYppYKO0K2YWab+i2UTSY7Ukz9Q=
github.com/bytedance/sonic v1.8.8/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -100,9 +116,13 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/civo/civogo v0.3.29 h1:N87pFQxEpiqaDiFkeDMxvd6YLHHTmSC2/+9v5l93bO0=
github.com/civo/civogo v0.3.29/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak=
github.com/civo/civogo v0.3.34 h1:E78ExdJLtrLvpMqJb3kq5Y/p200m6S2l/2piFDNqzPQ=
github.com/civo/civogo v0.3.34/go.mod h1:ovGwXtszFiTsVq1OgKG9CtE8q8TPm+4bwE13KuJBr9E=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.49.0 h1:KqJYk/YQ5ZhmyYz1oa4kGDskfF1gVuZfqesaJ/XDLto=
github.com/cloudflare/cloudflare-go v0.49.0/go.mod h1:h0QgcIZ3qEXwFiwfBO8sQxjVdYsLX+PfD7NFEnANaKg=
github.com/cloudflare/cloudflare-go v0.67.0 h1:cTwYOAlycKb7cx4+ObSNd9iW8Om4ydqNhwcWEnVyRaE=
github.com/cloudflare/cloudflare-go v0.67.0/go.mod h1:FfMEQEtz3ZciNqer63pwAnQTpAn0pijqov0WxnOQ7rM=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
@ -132,8 +152,10 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/dnsimple/dnsimple-go v1.2.0 h1:ddTGyLVKly5HKb5L65AkLqFqwZlWo3WnR0BlFZlIddM=
github.com/dnsimple/dnsimple-go v1.2.0/go.mod h1:z/cs26v/eiRvUyXsHQBLd8lWF8+cD6GbmkPH84plM4U=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@ -141,11 +163,14 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exoscale/egoscale v0.90.0 h1:DZBXVU3iHqu5Ju5lQ5jWVlPo0IpI98SUo8Aa1UQVrmo=
github.com/exoscale/egoscale v0.90.0/go.mod h1:wyXE5zrnFynMXA0jMhwQqSe24CfUhmBk2WI5wFZcq6Y=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
@ -165,9 +190,13 @@ github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
github.com/go-acme/lego/v4 v4.10.2 h1:5eW3qmda5v/LP21v1Hj70edKY1jeFZQwO617tdkwp6Q=
github.com/go-acme/lego/v4 v4.10.2/go.mod h1:EMbf0Jmqwv94nJ5WL9qWnSXIBZnvsS9gNypansHGc6U=
github.com/go-acme/lego/v4 v4.11.0 h1:oIPoU7zBJoTfoVrbqk62+/2NsGCSgCVK1JtZSZZ28SU=
github.com/go-acme/lego/v4 v4.11.0/go.mod h1:dENL0J3/WughN2NLy0T35otK5k1EWCmXTwCw0+X5ZaE=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-co-op/gocron v1.20.1 h1:wCGabII3xf/NrrYeOzJ4voLBBtA5k7Rb99+7l/iiu+g=
github.com/go-co-op/gocron v1.20.1/go.mod h1:UqVyvM90I1q/R1qGEX6cBORI6WArLuEgYlbncLMvzRM=
github.com/go-co-op/gocron v1.27.0 h1:GbP9A0wauIeGbMCUzdGb2IAi1JHzNHT/H/lLW2ODwLE=
github.com/go-co-op/gocron v1.27.0/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
@ -177,10 +206,19 @@ github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxF
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -192,11 +230,15 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI=
github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA=
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
@ -205,6 +247,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
@ -241,6 +285,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@ -251,6 +296,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
@ -258,13 +304,19 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.1 h1:XJQvZvUdPzOGdf4ZMQc78wYt9XrdIZOl//n03i8P68Q=
github.com/google/s2a-go v0.1.1/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM=
github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE=
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@ -279,6 +331,8 @@ github.com/gophercloud/gophercloud v1.3.0 h1:RUKyCMiZoQR3VlVR5E3K7PK1AC3/qppsWYo
github.com/gophercloud/gophercloud v1.3.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gophercloud/utils v0.0.0-20230330070308-5bd5e1d608f8 h1:K9r5WEeAiaEgFZsuOP0OYjE4TtyFcCLG1nI08t9AP6A=
github.com/gophercloud/utils v0.0.0-20230330070308-5bd5e1d608f8/go.mod h1:VSalo4adEk+3sNkmVJLnhHoOyOYYS8sTWLG4mv5BKto=
github.com/gophercloud/utils v0.0.0-20230418172808-6eab72e966e1 h1:vJyXd9+MB5vAKxpOo4z/PDSiPgKmEyJwHIDOdV4Y0KY=
github.com/gophercloud/utils v0.0.0-20230418172808-6eab72e966e1/go.mod h1:VSalo4adEk+3sNkmVJLnhHoOyOYYS8sTWLG4mv5BKto=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@ -314,6 +368,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -347,6 +402,7 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/overseer v1.1.6 h1:3ygYfNcR3FfOr22miu3vR1iQcXKMHbmULBh98rbkIyo=
github.com/jpillora/overseer v1.1.6/go.mod h1:aPXQtxuVb9PVWRWTXpo+LdnC/YXQ0IBLNXqKMJmgk88=
github.com/jpillora/s3 v1.1.4 h1:YCCKDWzb/Ye9EBNd83ATRF/8wPEy0xd43Rezb6u6fzc=
@ -366,6 +422,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
@ -376,7 +433,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -388,10 +448,16 @@ github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/linode/linodego v1.16.1 h1:5otq57M4PdHycPERRfSFZ0s1yz1ETVWGjCp3hh7+F9w=
github.com/linode/linodego v1.16.1/go.mod h1:aESRAbpLY9R6IA1WGAWHikRI9DU9Lhesapv1MhKmPHM=
github.com/linode/linodego v1.16.2 h1:LwtCQxEvXu57zn1c+0kH5jh/xUnv3YBYYFhHWyohlbk=
github.com/linode/linodego v1.16.2/go.mod h1:n4KKMzPcmZ18qOdYzixRXTPmBv3r4KkVu4pNT6pIN5M=
github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs=
github.com/liquidweb/go-lwApi v0.0.5 h1:CT4cdXzJXmo0bon298kS7NeSk+Gt8/UHpWBBol1NGCA=
github.com/liquidweb/go-lwApi v0.0.5/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs=
@ -405,6 +471,7 @@ github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0g
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@ -433,6 +500,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/miekg/dns v1.1.47/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/mimuret/golang-iij-dpf v0.9.1 h1:Gj6EhHJkOhr+q2RnvRPJsPMcjuVnWPSccEHyoEehU34=
github.com/mimuret/golang-iij-dpf v0.9.1/go.mod h1:sl9KyOkESib9+KRD3HaGpgi1xk7eoN2+d96LCLsME2M=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -448,6 +517,7 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -455,7 +525,9 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
@ -472,6 +544,8 @@ github.com/nrdcg/goinwx v0.8.2 h1:RmjiHlEA+lzi3toXyPSaE6hWnBQ0+G+1u7w8C6Fpp4g=
github.com/nrdcg/goinwx v0.8.2/go.mod h1:mnMSTi7CXBu2io4DzdOBoGFA1XclD0sEPWJaDhNgkA4=
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/nrdcg/nodion v0.1.0 h1:zLKaqTn2X0aDuBHHfyA1zFgeZfiCpmu/O9DM73okavw=
github.com/nrdcg/nodion v0.1.0/go.mod h1:inbuh3neCtIWlMPZHtEpe43TmRXxHV6+hk97iCZicms=
github.com/nrdcg/porkbun v0.2.0 h1:ghaqPtIKcffba99epWFkK3VWf6TKJT9WMXMgaTqv95Y=
github.com/nrdcg/porkbun v0.2.0/go.mod h1:i0uLMn9ItFsLsSQIAeEu1wQ9/+6EvX1eQw15hulMMRw=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@ -484,12 +558,31 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc=
github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk=
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
@ -503,6 +596,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -517,6 +611,8 @@ github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3g
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308 h1:JfSau4YABtkm5gRtFWuRWHT2Lsw4ZbyB4F/qORwf+BA=
github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308/go.mod h1:hxhFuMswfNko9fAxYeqBapfUdJHAgDafBs/MzOZh0X8=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@ -538,7 +634,11 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sacloud/api-client-go v0.2.7 h1:u8e8UdvYtpLiqTsmbJ6fLXceTievQ104ZKZb7VQ5wq8=
@ -547,21 +647,33 @@ github.com/sacloud/go-http v0.1.5 h1:Ov1Vr4Olf0P+FG2okmpSaftCQnyHoCKZtbCC6RlNZUI
github.com/sacloud/go-http v0.1.5/go.mod h1:jlBMvkz4PuAelewTMOVzNQVuI2EyBYJGHS7nub79Yh0=
github.com/sacloud/iaas-api-go v1.9.2 h1:j+8E3RESsCp5hMzeDbldOv2/lmDKMvUoZOz3L90/0iY=
github.com/sacloud/iaas-api-go v1.9.2/go.mod h1:A3shH+pHq9V1ZXw15KScArLs8BstYsdyrBQkxFM5Bcs=
github.com/sacloud/iaas-api-go v1.10.0 h1:dBXqyUr3bQR0hQppIesFD4MbFernmqG+5wl6RWUNoxg=
github.com/sacloud/iaas-api-go v1.10.0/go.mod h1:JRu6N3Dh2MNcznmYfC9OjM/4zVHWua2flIRWp7d5DBw=
github.com/sacloud/packages-go v0.0.8 h1:9l1XrukLdLPd6l/y2et9foQK2Z00ZQEGCInZMRGivAA=
github.com/sacloud/packages-go v0.0.8/go.mod h1:btPji+wtZ+Pk7MeCy+zo61o5IziBoLdHIrdGiYq9Kb8=
github.com/sashabaranov/go-openai v1.7.0 h1:D1dBXoZhtf/aKNu6WFf0c7Ah2NM30PZ/3Mqly6cZ7fk=
github.com/sashabaranov/go-openai v1.7.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sashabaranov/go-openai v1.9.4 h1:KanoCEoowAI45jVXlenMCckutSRr39qOmSi9MyPBfZM=
github.com/sashabaranov/go-openai v1.9.4/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15 h1:Y7xOFbD+3jaPw+VN7lkakNJ/pa+ZSQVFp1ONtJaBxns=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16 h1:Ted1/3BGV1d0c7J+69N+brveAgJNWZlWnI8iYP3dZMs=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE=
github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU=
github.com/shirou/gopsutil/v3 v3.23.4 h1:hZwmDxZs7Ewt75DV81r4pFMqbq+di2cbt9FsQBqLD2o=
github.com/shirou/gopsutil/v3 v3.23.4/go.mod h1:ZcGxyfzAMRevhUR2+cfhXDH6gQdFYE/t8j1nsU4mPI8=
github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
github.com/shoenig/go-m1cpu v0.1.5 h1:LF57Z/Fpb/WdGLjt2HZilNnmZOxg/q2bSKTQhgbrLrQ=
github.com/shoenig/go-m1cpu v0.1.5/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c=
github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 h1:ZTzdx88+AcnjqUfJwnz89UBrMSBQ1NEysg9u5d+dU9c=
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04/go.mod h1:5KS21fpch8TIMyAUv/qQqTa3GZfBDYgjaZbd2KXKYfg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
@ -584,6 +696,7 @@ github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVd
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@ -597,6 +710,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@ -616,8 +730,12 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.637 h1:qFqiFFxUQUixUn5op2w8CnBCWC7gAsvyx3/m8LsHx60=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.637/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.655 h1:wXBlXLfBbqTBpsiKBBULW63KvMy3wsu3/CD25cR9NEA=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.655/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.637 h1:9r85LEYF4CcKDbQQhJ5b3hYh5vj1WNvjsHrWHAV3c60=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.637/go.mod h1:5z3RG36i3UQvMr3aHVjPfrEzLdmk+sTiLgip3aFvKBo=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.655 h1:LgLA3nzvsBggdt1NRDNi6KVk9HRHLwBUltxXupdRMeM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.655/go.mod h1:v8wyOnL22mqDNeBqsasAQzP6eQI0Lpa+cAxFtVThHTk=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
@ -627,6 +745,8 @@ github.com/transip/gotransip/v6 v6.20.0 h1:AuvwyOZ51f2brzMbTqlRy/wmaM3kF7Vx5Wds8
github.com/transip/gotransip/v6 v6.20.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c=
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508112508-44b3f58122c3 h1:JtqbmHUcarxOxHSmTPKBHiLQWp66tGf4D4xOzHFRQCI=
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508112508-44b3f58122c3/go.mod h1:4fTjBxMoWGOIVnGFSTS9GAZ0yMyiGzTdATQS0krQv18=
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508164033-d7b72d6cd0d5 h1:FkmR72IA+ZHvCbMG4Mbl5+9oovKUfHsayzBM90GP1LE=
github.com/tufanbarisyildirim/gonginx v0.0.0-20230508164033-d7b72d6cd0d5/go.mod h1:4fTjBxMoWGOIVnGFSTS9GAZ0yMyiGzTdATQS0krQv18=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
@ -639,6 +759,8 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/ultradns/ultradns-go-sdk v1.4.1-20230224143201-0d8b0f6 h1:QLAl5WjtTCho+BEY7jfYjF6I9eK2jSfvMxjeRjP34PQ=
github.com/ultradns/ultradns-go-sdk v1.4.1-20230224143201-0d8b0f6/go.mod h1:F4UyVEmq4/m5lAmx+GccrxyRCXmnBjzUL09JLTQFp94=
github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c h1:mKnW6IGLw7uXu6DL6RitufZWcXS6hCnauXRUFof7rKM=
github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c/go.mod h1:F4UyVEmq4/m5lAmx+GccrxyRCXmnBjzUL09JLTQFp94=
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ=
@ -652,10 +774,16 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/yandex-cloud/go-genproto v0.0.0-20230403093326-123923969dc6/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
github.com/yandex-cloud/go-genproto v0.0.0-20230410092700-15216dc82345 h1:GpSlltaiDKRYF1JgqQO+cSLMNuADuSfKqRNaxgmXV+Q=
github.com/yandex-cloud/go-genproto v0.0.0-20230410092700-15216dc82345/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
github.com/yandex-cloud/go-genproto v0.0.0-20230511103421-ecb0cd1514ab h1:Y9sWstUXfHwHufw95mI58ZEvZ720KWyR+niLQbd2q1k=
github.com/yandex-cloud/go-genproto v0.0.0-20230511103421-ecb0cd1514ab/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
github.com/yandex-cloud/go-sdk v0.0.0-20230403093608-cc5174142a48 h1:C3yjOqP3gGxwiW3bXDAGI8tS+eKjxySJ9Ix7lpdtKZw=
github.com/yandex-cloud/go-sdk v0.0.0-20230403093608-cc5174142a48/go.mod h1:+bvtdW+7bn1Yc7xUCbITnEalQ+hwkAAbUFHpeIY2wUQ=
github.com/yandex-cloud/go-sdk v0.0.0-20230511104317-0ccfef4d3a91 h1:bYY90Y33XH7xJh8Qa5ZIgmjyWDp2S6sixTRxYbHCQLU=
github.com/yandex-cloud/go-sdk v0.0.0-20230511104317-0ccfef4d3a91/go.mod h1:QOnqdE3DjwgoKvhw4Scx6HTCfAlYHZMoUzyaC8kcdzk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
@ -670,6 +798,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@ -694,11 +823,15 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -717,9 +850,15 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -738,6 +877,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@ -750,17 +890,28 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -772,6 +923,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -813,6 +966,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -821,15 +976,24 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -838,12 +1002,17 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -865,15 +1034,26 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@ -881,6 +1061,8 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.118.0 h1:FNfHq9Z2GKULxu7cEhCaB0wWQHg43UpomrrN+24ZRdE=
google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E=
google.golang.org/api v0.122.0 h1:zDobeejm3E7pEG1mNHvdxvjs5XJoCMzyNH+CmwL94Es=
google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -898,6 +1080,7 @@ google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBr
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
@ -915,6 +1098,8 @@ google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzI
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -923,10 +1108,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@ -935,11 +1123,14 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@ -948,6 +1139,8 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ns1/ns1-go.v2 v2.7.5 h1:tE4SLOAFx2YXawh6MPv57lmlaBFUTyxSYOWKOGDgkM4=
gopkg.in/ns1/ns1-go.v2 v2.7.5/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
gopkg.in/ns1/ns1-go.v2 v2.7.6 h1:mCPl7q0jbIGACXvGBljAuuApmKZo3rRi4tlRIEbMvjA=
gopkg.in/ns1/ns1-go.v2 v2.7.6/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
@ -961,6 +1154,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@ -976,14 +1170,20 @@ gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
gorm.io/gen v0.3.21 h1:t8329wT4tW1ZZWOm7vn4LV6OIrz8a5zCg+p78ezt+rA=
gorm.io/gen v0.3.21/go.mod h1:aWgvoKdG9f8Des4TegSa0N5a+gwhGsFo0JJMaLwokvk=
gorm.io/gen v0.3.22 h1:K7u5tCyaZfe1cbQFD8N2xrTqUuqximNFSRl7zOFPq+M=
gorm.io/gen v0.3.22/go.mod h1:dQcELeF/7Kf82M6AQF+O/rKT5r1sjv49TlGz0cerPn4=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU=
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/hints v1.1.1 h1:NPampLxQujY+277452rt4yqtg6JmzNZ1jA2olk0eFXw=
gorm.io/hints v1.1.1/go.mod h1:zdwzfFqvBWGbpuKiAhLFOSGSpeD3/VsRgkXR9Y7Z3cs=
gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o=
gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg=
gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk=
gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
@ -992,5 +1192,27 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/api v0.27.1 h1:Z6zUGQ1Vd10tJ+gHcNNNgkV5emCyW+v2XTmn+CLjSd0=
k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E=
k8s.io/apimachinery v0.27.1 h1:EGuZiLI95UQQcClhanryclaQE6xjg1Bts6/L3cD7zyc=
k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

111
server/api/environment.go Normal file
View file

@ -0,0 +1,111 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/model"
"github.com/0xJacky/Nginx-UI/server/query"
"github.com/0xJacky/Nginx-UI/server/service"
"github.com/gin-gonic/gin"
"github.com/spf13/cast"
"net/http"
)
func GetEnvironment(c *gin.Context) {
id := cast.ToInt(c.Param("id"))
envQuery := query.Environment
environment, err := envQuery.FirstByID(id)
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, environment)
}
func GetEnvironmentList(c *gin.Context) {
data, err := service.RetrieveEnvironmentList()
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"data": data,
})
}
type EnvironmentManageJson struct {
Name string `json:"name" binding:"required"`
URL string `json:"url" binding:"required"`
Token string `json:"token" binding:"required"`
}
func AddEnvironment(c *gin.Context) {
var json EnvironmentManageJson
if !BindAndValid(c, &json) {
return
}
environment := model.Environment{
Name: json.Name,
URL: json.URL,
Token: json.Token,
}
envQuery := query.Environment
err := envQuery.Create(&environment)
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, environment)
}
func EditEnvironment(c *gin.Context) {
id := cast.ToInt(c.Param("id"))
var json EnvironmentManageJson
if !BindAndValid(c, &json) {
return
}
envQuery := query.Environment
environment, err := envQuery.FirstByID(id)
if err != nil {
ErrHandler(c, err)
return
}
_, err = envQuery.Where(envQuery.ID.Eq(environment.ID)).Updates(&model.Environment{
Name: json.Name,
URL: json.URL,
Token: json.Token,
})
if err != nil {
ErrHandler(c, err)
return
}
GetEnvironment(c)
}
func DeleteEnvironment(c *gin.Context) {
id := cast.ToInt(c.Param("id"))
envQuery := query.Environment
environment, err := envQuery.FirstByID(id)
if err != nil {
ErrHandler(c, err)
return
}
err = envQuery.DeleteByID(environment.ID)
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusNoContent, nil)
}

View file

@ -1,76 +1,77 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/model"
"github.com/0xJacky/Nginx-UI/server/query"
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"net/http"
"github.com/0xJacky/Nginx-UI/server/model"
"github.com/0xJacky/Nginx-UI/server/query"
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"net/http"
)
func installLockStatus() bool {
return "" != settings.ServerSettings.JwtSecret
return "" != settings.ServerSettings.JwtSecret
}
func InstallLockCheck(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"lock": installLockStatus(),
})
c.JSON(http.StatusOK, gin.H{
"lock": installLockStatus(),
})
}
type InstallJson struct {
Email string `json:"email" binding:"required,email"`
Username string `json:"username" binding:"required,max=255"`
Password string `json:"password" binding:"required,max=255"`
Database string `json:"database"`
Email string `json:"email" binding:"required,email"`
Username string `json:"username" binding:"required,max=255"`
Password string `json:"password" binding:"required,max=255"`
Database string `json:"database"`
}
func InstallNginxUI(c *gin.Context) {
// Visit this api after installed is forbidden
if installLockStatus() {
c.JSON(http.StatusForbidden, gin.H{
"error": "installed",
})
return
}
var json InstallJson
ok := BindAndValid(c, &json)
if !ok {
return
}
// Visit this api after installed is forbidden
if installLockStatus() {
c.JSON(http.StatusForbidden, gin.H{
"error": "installed",
})
return
}
var json InstallJson
ok := BindAndValid(c, &json)
if !ok {
return
}
settings.ServerSettings.JwtSecret = uuid.New().String()
settings.ServerSettings.Email = json.Email
if "" != json.Database {
settings.ServerSettings.Database = json.Database
}
settings.ReflectFrom()
settings.ServerSettings.JwtSecret = uuid.New().String()
settings.ServerSettings.NodeSecret = uuid.New().String()
settings.ServerSettings.Email = json.Email
if "" != json.Database {
settings.ServerSettings.Database = json.Database
}
settings.ReflectFrom()
err := settings.Save()
if err != nil {
ErrHandler(c, err)
return
}
err := settings.Save()
if err != nil {
ErrHandler(c, err)
return
}
// Init model
db := model.Init()
query.Init(db)
// Init model
db := model.Init()
query.Init(db)
pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
u := query.Auth
err = u.Create(&model.Auth{
Name: json.Username,
Password: string(pwd),
})
u := query.Auth
err = u.Create(&model.Auth{
Name: json.Username,
Password: string(pwd),
})
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"message": "ok",
})
if err != nil {
ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"message": "ok",
})
}

35
server/api/node.go Normal file
View file

@ -0,0 +1,35 @@
package api
import (
"github.com/0xJacky/Nginx-UI/server/service"
"github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v3/cpu"
"net/http"
)
func GetCurrentNode(c *gin.Context) {
if _, ok := c.Get("NodeSecret"); !ok {
c.JSON(http.StatusNotAcceptable, gin.H{
"message": "node secret not exist",
})
return
}
runtimeInfo, err := service.GetRuntimeInfo()
if err != nil {
ErrHandler(c, err)
return
}
cpuInfo, _ := cpu.Info()
memory, _ := getMemoryStat()
ver, _ := service.GetCurrentVersion()
c.JSON(http.StatusOK, gin.H{
"request_node_secret": c.MustGet("NodeSecret"),
"node_runtime_info": runtimeInfo,
"cpu_num": len(cpuInfo),
"memory_total": memory.Total,
"version": ver.Version,
})
}

View file

@ -0,0 +1 @@
package environment

View file

@ -1,11 +1,11 @@
package logger
import (
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
var logger *zap.SugaredLogger
@ -31,7 +31,7 @@ func init() {
consoleErrors := zapcore.Lock(os.Stderr)
encoderConfig := zap.NewDevelopmentEncoderConfig()
encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
encoderConfig.ConsoleSeparator = " "
encoderConfig.ConsoleSeparator = "\t"
encoderConfig.EncodeLevel = colorLevelEncoder
consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)

View file

@ -0,0 +1,8 @@
package model
type Environment struct {
Model
Name string `json:"name"`
URL string `json:"url"`
Token string `json:"token"`
}

View file

@ -32,6 +32,7 @@ func GenerateAllModel() []any {
ChatGPTLog{},
Site{},
DnsCredential{},
Environment{},
}
}

View file

@ -166,6 +166,11 @@ func (a certBelongsToDnsCredential) WithContext(ctx context.Context) *certBelong
return &a
}
func (a certBelongsToDnsCredential) Session(session *gorm.Session) *certBelongsToDnsCredential {
a.db = a.db.Session(session)
return &a
}
func (a certBelongsToDnsCredential) Model(m *model.Cert) *certBelongsToDnsCredentialTx {
return &certBelongsToDnsCredentialTx{a.db.Model(m).Association(a.Name())}
}

View file

@ -0,0 +1,378 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"strings"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/0xJacky/Nginx-UI/server/model"
)
func newEnvironment(db *gorm.DB, opts ...gen.DOOption) environment {
_environment := environment{}
_environment.environmentDo.UseDB(db, opts...)
_environment.environmentDo.UseModel(&model.Environment{})
tableName := _environment.environmentDo.TableName()
_environment.ALL = field.NewAsterisk(tableName)
_environment.ID = field.NewInt(tableName, "id")
_environment.CreatedAt = field.NewTime(tableName, "created_at")
_environment.UpdatedAt = field.NewTime(tableName, "updated_at")
_environment.DeletedAt = field.NewField(tableName, "deleted_at")
_environment.Name = field.NewString(tableName, "name")
_environment.URL = field.NewString(tableName, "url")
_environment.Token = field.NewString(tableName, "token")
_environment.fillFieldMap()
return _environment
}
type environment struct {
environmentDo
ALL field.Asterisk
ID field.Int
CreatedAt field.Time
UpdatedAt field.Time
DeletedAt field.Field
Name field.String
URL field.String
Token field.String
fieldMap map[string]field.Expr
}
func (e environment) Table(newTableName string) *environment {
e.environmentDo.UseTable(newTableName)
return e.updateTableName(newTableName)
}
func (e environment) As(alias string) *environment {
e.environmentDo.DO = *(e.environmentDo.As(alias).(*gen.DO))
return e.updateTableName(alias)
}
func (e *environment) updateTableName(table string) *environment {
e.ALL = field.NewAsterisk(table)
e.ID = field.NewInt(table, "id")
e.CreatedAt = field.NewTime(table, "created_at")
e.UpdatedAt = field.NewTime(table, "updated_at")
e.DeletedAt = field.NewField(table, "deleted_at")
e.Name = field.NewString(table, "name")
e.URL = field.NewString(table, "url")
e.Token = field.NewString(table, "token")
e.fillFieldMap()
return e
}
func (e *environment) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := e.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (e *environment) fillFieldMap() {
e.fieldMap = make(map[string]field.Expr, 7)
e.fieldMap["id"] = e.ID
e.fieldMap["created_at"] = e.CreatedAt
e.fieldMap["updated_at"] = e.UpdatedAt
e.fieldMap["deleted_at"] = e.DeletedAt
e.fieldMap["name"] = e.Name
e.fieldMap["url"] = e.URL
e.fieldMap["token"] = e.Token
}
func (e environment) clone(db *gorm.DB) environment {
e.environmentDo.ReplaceConnPool(db.Statement.ConnPool)
return e
}
func (e environment) replaceDB(db *gorm.DB) environment {
e.environmentDo.ReplaceDB(db)
return e
}
type environmentDo struct{ gen.DO }
// FirstByID Where("id=@id")
func (e environmentDo) FirstByID(id int) (result *model.Environment, err error) {
var params []interface{}
var generateSQL strings.Builder
params = append(params, id)
generateSQL.WriteString("id=? ")
var executeSQL *gorm.DB
executeSQL = e.UnderlyingDB().Where(generateSQL.String(), params...).Take(&result) // ignore_security_alert
err = executeSQL.Error
return
}
// DeleteByID update @@table set deleted_at=strftime('%Y-%m-%d %H:%M:%S','now') where id=@id
func (e environmentDo) DeleteByID(id int) (err error) {
var params []interface{}
var generateSQL strings.Builder
params = append(params, id)
generateSQL.WriteString("update environments set deleted_at=strftime('%Y-%m-%d %H:%M:%S','now') where id=? ")
var executeSQL *gorm.DB
executeSQL = e.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
err = executeSQL.Error
return
}
func (e environmentDo) Debug() *environmentDo {
return e.withDO(e.DO.Debug())
}
func (e environmentDo) WithContext(ctx context.Context) *environmentDo {
return e.withDO(e.DO.WithContext(ctx))
}
func (e environmentDo) ReadDB() *environmentDo {
return e.Clauses(dbresolver.Read)
}
func (e environmentDo) WriteDB() *environmentDo {
return e.Clauses(dbresolver.Write)
}
func (e environmentDo) Session(config *gorm.Session) *environmentDo {
return e.withDO(e.DO.Session(config))
}
func (e environmentDo) Clauses(conds ...clause.Expression) *environmentDo {
return e.withDO(e.DO.Clauses(conds...))
}
func (e environmentDo) Returning(value interface{}, columns ...string) *environmentDo {
return e.withDO(e.DO.Returning(value, columns...))
}
func (e environmentDo) Not(conds ...gen.Condition) *environmentDo {
return e.withDO(e.DO.Not(conds...))
}
func (e environmentDo) Or(conds ...gen.Condition) *environmentDo {
return e.withDO(e.DO.Or(conds...))
}
func (e environmentDo) Select(conds ...field.Expr) *environmentDo {
return e.withDO(e.DO.Select(conds...))
}
func (e environmentDo) Where(conds ...gen.Condition) *environmentDo {
return e.withDO(e.DO.Where(conds...))
}
func (e environmentDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *environmentDo {
return e.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
}
func (e environmentDo) Order(conds ...field.Expr) *environmentDo {
return e.withDO(e.DO.Order(conds...))
}
func (e environmentDo) Distinct(cols ...field.Expr) *environmentDo {
return e.withDO(e.DO.Distinct(cols...))
}
func (e environmentDo) Omit(cols ...field.Expr) *environmentDo {
return e.withDO(e.DO.Omit(cols...))
}
func (e environmentDo) Join(table schema.Tabler, on ...field.Expr) *environmentDo {
return e.withDO(e.DO.Join(table, on...))
}
func (e environmentDo) LeftJoin(table schema.Tabler, on ...field.Expr) *environmentDo {
return e.withDO(e.DO.LeftJoin(table, on...))
}
func (e environmentDo) RightJoin(table schema.Tabler, on ...field.Expr) *environmentDo {
return e.withDO(e.DO.RightJoin(table, on...))
}
func (e environmentDo) Group(cols ...field.Expr) *environmentDo {
return e.withDO(e.DO.Group(cols...))
}
func (e environmentDo) Having(conds ...gen.Condition) *environmentDo {
return e.withDO(e.DO.Having(conds...))
}
func (e environmentDo) Limit(limit int) *environmentDo {
return e.withDO(e.DO.Limit(limit))
}
func (e environmentDo) Offset(offset int) *environmentDo {
return e.withDO(e.DO.Offset(offset))
}
func (e environmentDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *environmentDo {
return e.withDO(e.DO.Scopes(funcs...))
}
func (e environmentDo) Unscoped() *environmentDo {
return e.withDO(e.DO.Unscoped())
}
func (e environmentDo) Create(values ...*model.Environment) error {
if len(values) == 0 {
return nil
}
return e.DO.Create(values)
}
func (e environmentDo) CreateInBatches(values []*model.Environment, batchSize int) error {
return e.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (e environmentDo) Save(values ...*model.Environment) error {
if len(values) == 0 {
return nil
}
return e.DO.Save(values)
}
func (e environmentDo) First() (*model.Environment, error) {
if result, err := e.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.Environment), nil
}
}
func (e environmentDo) Take() (*model.Environment, error) {
if result, err := e.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.Environment), nil
}
}
func (e environmentDo) Last() (*model.Environment, error) {
if result, err := e.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.Environment), nil
}
}
func (e environmentDo) Find() ([]*model.Environment, error) {
result, err := e.DO.Find()
return result.([]*model.Environment), err
}
func (e environmentDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Environment, err error) {
buf := make([]*model.Environment, 0, batchSize)
err = e.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (e environmentDo) FindInBatches(result *[]*model.Environment, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return e.DO.FindInBatches(result, batchSize, fc)
}
func (e environmentDo) Attrs(attrs ...field.AssignExpr) *environmentDo {
return e.withDO(e.DO.Attrs(attrs...))
}
func (e environmentDo) Assign(attrs ...field.AssignExpr) *environmentDo {
return e.withDO(e.DO.Assign(attrs...))
}
func (e environmentDo) Joins(fields ...field.RelationField) *environmentDo {
for _, _f := range fields {
e = *e.withDO(e.DO.Joins(_f))
}
return &e
}
func (e environmentDo) Preload(fields ...field.RelationField) *environmentDo {
for _, _f := range fields {
e = *e.withDO(e.DO.Preload(_f))
}
return &e
}
func (e environmentDo) FirstOrInit() (*model.Environment, error) {
if result, err := e.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.Environment), nil
}
}
func (e environmentDo) FirstOrCreate() (*model.Environment, error) {
if result, err := e.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.Environment), nil
}
}
func (e environmentDo) FindByPage(offset int, limit int) (result []*model.Environment, count int64, err error) {
result, err = e.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = e.Offset(-1).Limit(-1).Count()
return
}
func (e environmentDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = e.Count()
if err != nil {
return
}
err = e.Offset(offset).Limit(limit).Scan(result)
return
}
func (e environmentDo) Scan(result interface{}) (err error) {
return e.DO.Scan(result)
}
func (e environmentDo) Delete(models ...*model.Environment) (result gen.ResultInfo, err error) {
return e.DO.Delete(models)
}
func (e *environmentDo) withDO(do gen.Dao) *environmentDo {
e.DO = *do.(*gen.DO)
return e
}

View file

@ -23,6 +23,7 @@ var (
ChatGPTLog *chatGPTLog
ConfigBackup *configBackup
DnsCredential *dnsCredential
Environment *environment
Site *site
)
@ -34,6 +35,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
ChatGPTLog = &Q.ChatGPTLog
ConfigBackup = &Q.ConfigBackup
DnsCredential = &Q.DnsCredential
Environment = &Q.Environment
Site = &Q.Site
}
@ -46,6 +48,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
ChatGPTLog: newChatGPTLog(db, opts...),
ConfigBackup: newConfigBackup(db, opts...),
DnsCredential: newDnsCredential(db, opts...),
Environment: newEnvironment(db, opts...),
Site: newSite(db, opts...),
}
}
@ -59,6 +62,7 @@ type Query struct {
ChatGPTLog chatGPTLog
ConfigBackup configBackup
DnsCredential dnsCredential
Environment environment
Site site
}
@ -73,6 +77,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
ChatGPTLog: q.ChatGPTLog.clone(db),
ConfigBackup: q.ConfigBackup.clone(db),
DnsCredential: q.DnsCredential.clone(db),
Environment: q.Environment.clone(db),
Site: q.Site.clone(db),
}
}
@ -94,6 +99,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
ChatGPTLog: q.ChatGPTLog.replaceDB(db),
ConfigBackup: q.ConfigBackup.replaceDB(db),
DnsCredential: q.DnsCredential.replaceDB(db),
Environment: q.Environment.replaceDB(db),
Site: q.Site.replaceDB(db),
}
}
@ -105,6 +111,7 @@ type queryCtx struct {
ChatGPTLog *chatGPTLogDo
ConfigBackup *configBackupDo
DnsCredential *dnsCredentialDo
Environment *environmentDo
Site *siteDo
}
@ -116,6 +123,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
ChatGPTLog: q.ChatGPTLog.WithContext(ctx),
ConfigBackup: q.ConfigBackup.WithContext(ctx),
DnsCredential: q.DnsCredential.WithContext(ctx),
Environment: q.Environment.WithContext(ctx),
Site: q.Site.WithContext(ctx),
}
}
@ -125,10 +133,14 @@ func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) er
}
func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
return &QueryTx{q.clone(q.db.Begin(opts...))}
tx := q.db.Begin(opts...)
return &QueryTx{Query: q.clone(tx), Error: tx.Error}
}
type QueryTx struct{ *Query }
type QueryTx struct {
*Query
Error error
}
func (q *QueryTx) Commit() error {
return q.db.Commit().Error

View file

@ -40,28 +40,38 @@ func recovery() gin.HandlerFunc {
func authRequired() gin.HandlerFunc {
return func(c *gin.Context) {
abortWithAuthFailure := func() {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"message": "Authorization failed",
})
}
token := c.GetHeader("Authorization")
if token == "" {
tmp, _ := base64.StdEncoding.DecodeString(c.Query("token"))
token = string(tmp)
if token == "" {
c.JSON(http.StatusForbidden, gin.H{
"message": "Authorization failed",
})
c.Abort()
if token = c.GetHeader("X-Node-Secret"); token != "" && token == settings.ServerSettings.NodeSecret {
c.Set("NodeSecret", token)
c.Next()
return
} else {
c.Set("ProxyNodeID", c.Query("x_node_id"))
tokenBytes, _ := base64.StdEncoding.DecodeString(c.Query("token"))
token = string(tokenBytes)
if token == "" {
abortWithAuthFailure()
return
}
}
}
n := model.CheckToken(token)
if n < 1 {
c.JSON(http.StatusForbidden, gin.H{
"message": "Authorization failed",
})
c.Abort()
if model.CheckToken(token) < 1 {
abortWithAuthFailure()
return
}
if nodeID := c.GetHeader("X-Node-ID"); nodeID != "" {
c.Set("ProxyNodeID", nodeID)
}
c.Next()
}
}
@ -73,7 +83,12 @@ type serverFileSystemType struct {
func (f serverFileSystemType) Exists(prefix string, _path string) bool {
file, err := f.Open(path.Join(prefix, _path))
if file != nil {
defer file.Close()
defer func(file http.File) {
err = file.Close()
if err != nil {
logger.Error("file not found", err)
}
}(file)
}
return err == nil
}

92
server/router/proxy.go Normal file
View file

@ -0,0 +1,92 @@
package router
import (
"crypto/tls"
"github.com/0xJacky/Nginx-UI/server/internal/logger"
"github.com/0xJacky/Nginx-UI/server/query"
"github.com/gin-gonic/gin"
"github.com/spf13/cast"
"io"
"net/http"
"net/url"
)
func proxy() gin.HandlerFunc {
return func(c *gin.Context) {
nodeID, ok := c.Get("ProxyNodeID")
if !ok {
c.Next()
return
}
id := cast.ToInt(nodeID)
if id == 0 {
c.Next()
return
}
defer c.Abort()
env := query.Environment
environment, err := env.Where(env.ID.Eq(id)).First()
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(http.StatusServiceUnavailable, gin.H{
"message": err.Error(),
})
return
}
u, err := url.JoinPath(environment.URL, c.Request.RequestURI)
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
decodedUri, err := url.QueryUnescape(u)
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
logger.Debug("Proxy request", decodedUri)
client := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
req, err := http.NewRequest(c.Request.Method, decodedUri, c.Request.Body)
req.Header.Set("X-Node-Secret", environment.Token)
resp, err := client.Do(req)
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
defer resp.Body.Close()
c.Writer.WriteHeader(resp.StatusCode)
c.Writer.Header().Add("Content-Type", resp.Header.Get("Content-Type"))
_, err = io.Copy(c.Writer, resp.Body)
if err != nil {
logger.Error(err)
return
}
}
}

90
server/router/proxy_ws.go Normal file
View file

@ -0,0 +1,90 @@
package router
import (
"github.com/0xJacky/Nginx-UI/server/internal/logger"
"github.com/0xJacky/Nginx-UI/server/query"
"github.com/gin-gonic/gin"
"github.com/pretty66/websocketproxy"
"github.com/spf13/cast"
"net/http"
"net/url"
"strings"
)
func proxyWs() gin.HandlerFunc {
return func(c *gin.Context) {
nodeID, ok := c.Get("ProxyNodeID")
if !ok {
c.Next()
return
}
id := cast.ToInt(nodeID)
if id == 0 {
c.Next()
return
}
defer c.Abort()
env := query.Environment
environment, err := env.Where(env.ID.Eq(id)).First()
if err != nil {
logger.Error(err)
return
}
baseUrl, err := url.Parse(environment.URL)
if err != nil {
logger.Error(err)
return
}
logger.Debug(baseUrl.Port())
defaultPort := ""
if baseUrl.Port() == "" {
switch baseUrl.Scheme {
default:
fallthrough
case "http":
defaultPort = "80"
case "https":
defaultPort = "443"
}
baseUrl.Host = baseUrl.Hostname() + ":" + defaultPort
}
logger.Debug(baseUrl.String())
u, err := url.JoinPath(baseUrl.String(), c.Request.RequestURI)
if err != nil {
logger.Error(err)
return
}
decodedUri, err := url.QueryUnescape(u)
if err != nil {
logger.Error(err)
return
}
// http will be replaced with ws, https will be replaced with wss
decodedUri = strings.ReplaceAll(decodedUri, "http", "ws")
logger.Debug("Proxy request", decodedUri)
wp, err := websocketproxy.NewProxy(decodedUri, func(r *http.Request) error {
r.Header.Set("X-Node-Secret", environment.Token)
return nil
})
if err != nil {
logger.Error(err)
return
}
wp.Proxy(c.Writer, c.Request)
}
}

View file

@ -18,7 +18,9 @@ func InitRouter() *gin.Engine {
r.Use(static.Serve("/", mustFS("")))
r.NoRoute(func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/")
c.JSON(http.StatusNotFound, gin.H{
"message": "not found",
})
})
root := r.Group("/api")
@ -29,9 +31,19 @@ func InitRouter() *gin.Engine {
root.POST("/login", api.Login)
root.DELETE("/logout", api.Logout)
g := root.Group("/", authRequired())
w := root.Group("/", authRequired(), proxyWs())
{
g.GET("analytic", api.Analytic)
// Analytic
w.GET("analytic", api.Analytic)
// pty
w.GET("pty", api.Pty)
// Nginx log
w.GET("nginx_log", api.NginxLog)
}
g := root.Group("/", authRequired(), proxy())
{
g.GET("analytic/init", api.GetAnalyticInit)
g.GET("users", api.GetUsers)
@ -52,13 +64,10 @@ func InitRouter() *gin.Engine {
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
// Format nginx configuration code
g.POST("ngx/format_code", api.FormatNginxConfig)
// nginx reload
g.POST("nginx/reload", api.ReloadNginx)
// nginx restart
g.POST("nginx/restart", api.RestartNginx)
// nginx test
g.POST("nginx/test", api.TestNginx)
// nginx status
g.GET("nginx/status", api.NginxStatus)
g.POST("domain/:name/enable", api.EnableDomain)
@ -66,7 +75,7 @@ func InitRouter() *gin.Engine {
g.POST("domain/:name/advance", api.DomainEditByAdvancedMode)
g.DELETE("domain/:name", api.DeleteDomain)
// duplicate site
g.POST("domain/:name/duplicate", api.DuplicateSite)
g.GET("domain/:name/cert", api.IssueCert)
@ -104,11 +113,6 @@ func InitRouter() *gin.Engine {
g.POST("dns_credential/:id", api.EditDnsCredential)
g.DELETE("dns_credential/:id", api.DeleteDnsCredential)
// pty
g.GET("pty", api.Pty)
// Nginx log
g.GET("nginx_log", api.NginxLog)
g.POST("nginx_log", api.GetNginxLogPage)
// Settings
@ -121,8 +125,21 @@ func InitRouter() *gin.Engine {
g.GET("upgrade/perform", api.PerformCoreUpgrade)
// ChatGPT
g.POST("/chat_gpt", api.MakeChatCompletionRequest)
g.POST("/chat_gpt_record", api.StoreChatGPTRecord)
g.POST("chat_gpt", api.MakeChatCompletionRequest)
g.POST("chat_gpt_record", api.StoreChatGPTRecord)
// Environment
g.GET("environments", api.GetEnvironmentList)
envGroup := g.Group("environment")
{
envGroup.GET("/:id", api.GetEnvironment)
envGroup.POST("", api.AddEnvironment)
envGroup.POST("/:id", api.EditEnvironment)
envGroup.DELETE("/:id", api.DeleteEnvironment)
}
// node
g.GET("node", api.GetCurrentNode)
}
}

View file

@ -10,6 +10,7 @@ import (
"github.com/0xJacky/Nginx-UI/server/router"
"github.com/0xJacky/Nginx-UI/server/settings"
"github.com/go-co-op/gocron"
"github.com/google/uuid"
"github.com/jpillora/overseer"
"log"
"mime"
@ -30,6 +31,18 @@ func Program(state overseer.State) {
query.Init(db)
}
if "" == settings.ServerSettings.NodeSecret {
logger.Warn("NodeSecret is empty")
settings.ServerSettings.NodeSecret = uuid.New().String()
settings.ReflectFrom()
err := settings.Save()
if err != nil {
logger.Error("Error save settings")
}
logger.Warn("Generated NodeSecret: ", settings.ServerSettings.NodeSecret)
}
s := gocron.NewScheduler(time.UTC)
job, err := s.Every(30).Minute().SingletonMode().Do(cert.AutoObtain)

View file

@ -0,0 +1,94 @@
package service
import (
"crypto/tls"
"encoding/json"
"github.com/0xJacky/Nginx-UI/server/internal/logger"
"github.com/0xJacky/Nginx-UI/server/model"
"github.com/0xJacky/Nginx-UI/server/query"
"io"
"net/http"
"net/url"
"time"
)
type Environment struct {
*model.Environment
Status bool `json:"status"`
NodeInfo
}
func RetrieveEnvironmentList() (envs []*Environment, err error) {
envQuery := query.Environment
data, err := envQuery.Find()
if err != nil {
return
}
for _, v := range data {
t := &Environment{
Environment: v,
}
node, status := t.GetNode()
t.Status = status
t.NodeInfo = node
envs = append(envs, t)
}
return
}
type NodeInfo struct {
RequestNodeSecret string `json:"request_node_secret"`
NodeRuntimeInfo RuntimeInfo `json:"node_runtime_info"`
Version string `json:"version"`
CPUNum int `json:"cpu_num"`
MemoryTotal string `json:"memory_total"`
ResponseAt time.Time `json:"response_at"`
}
func (env *Environment) GetNode() (node NodeInfo, status bool) {
u, err := url.JoinPath(env.URL, "/api/node")
if err != nil {
logger.Error(err)
return
}
client := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
req, err := http.NewRequest("GET", u, nil)
req.Header.Set("X-Node-Secret", env.Token)
resp, err := client.Do(req)
if err != nil {
logger.Error(err)
return
}
defer resp.Body.Close()
bytes, _ := io.ReadAll(resp.Body)
if resp.StatusCode != 200 {
logger.Error(string(bytes))
return
}
logger.Debug(string(bytes))
err = json.Unmarshal(bytes, &node)
if err != nil {
logger.Error(err)
return
}
node.ResponseAt = time.Now()
status = true
return
}

View file

@ -19,6 +19,7 @@ type Server struct {
HttpPort string `json:"http_port"`
RunMode string `json:"run_mode"`
JwtSecret string `json:"jwt_secret"`
NodeSecret string `json:"node_secret"`
HTTPChallengePort string `json:"http_challenge_port"`
Email string `json:"email"`
Database string `json:"database"`