fix: redis 终端连接方式改为 cmd 直连

This commit is contained in:
ssongliu 2022-12-29 17:06:04 +08:00
parent 2ca45d31e8
commit a8b6c85a8f
17 changed files with 500 additions and 57 deletions

View File

@ -67,7 +67,7 @@ func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) {
} else {
res.Message = i18n.GetMsgWithMap(msgKey, map[string]interface{}{"detail": err})
}
global.LOG.Error(res.Message)
global.LOG.Errorf("request: %s, error: %s", ctx.Request.URL.Path, res.Message)
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}

View File

@ -127,6 +127,7 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
upMap["auth_mode"] = req.AuthMode
upMap["password"] = req.Password
upMap["private_key"] = req.PrivateKey
upMap["description"] = req.Description
if err := hostService.Update(req.ID, upMap); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -2,15 +2,13 @@ package v1
import (
"errors"
"os/exec"
"runtime"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/mfa"
"github.com/beevik/ntp"
"github.com/1Panel-dev/1Panel/backend/utils/ntp"
"github.com/gin-gonic/gin"
)
@ -87,19 +85,16 @@ func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
}
func (b *BaseApi) SyncTime(c *gin.Context) {
ntime, err := ntp.Time("pool.ntp.org")
ntime, err := ntp.Getremotetime()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
system := runtime.GOOS
if system == "linux" {
cmd := exec.Command("date", "-s", ntime.Format("2006-01-02 15:04:05"))
stdout, err := cmd.CombinedOutput()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New(string(stdout)))
return
}
ts := ntime.Format("2006-01-02 15:04:05")
if err := ntp.UpdateSystemDate(ts); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, ntime.Format("2006-01-02 15:04:05 MST -0700"))

View File

@ -1,6 +1,7 @@
package v1
import (
"fmt"
"net/http"
"strconv"
"time"
@ -78,6 +79,57 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
}
}
func (b *BaseApi) RedisWsSsh(c *gin.Context) {
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
global.LOG.Errorf("gin context http handler failed, err: %v", err)
return
}
defer wsConn.Close()
redisConf, err := redisService.LoadConf()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
auth := ""
if len(redisConf.Requirepass) != 0 {
auth = fmt.Sprintf("-a %s --no-auth-warning", redisConf.Requirepass)
}
slave, err := terminal.NewCommand(redisConf.ContainerName, auth)
if wshandleError(wsConn, err) {
return
}
defer slave.Close()
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
if wshandleError(wsConn, err) {
return
}
quitChan := make(chan bool, 3)
tty.Start(quitChan)
go slave.Wait(quitChan)
<-quitChan
global.LOG.Info("websocket finished")
if wshandleError(wsConn, err) {
return
}
}
func wshandleError(ws *websocket.Conn, err error) bool {
if err != nil {
global.LOG.Errorf("handler ws faled:, err: %v", err)

View File

@ -84,6 +84,7 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
upMap["auth_mode"] = req.AuthMode
upMap["password"] = req.Password
upMap["private_key"] = req.PrivateKey
upMap["description"] = req.Description
if err := hostRepo.Update(sameHostID, upMap); err != nil {
return nil, err
}

View File

@ -37,7 +37,7 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
cmdRouter.GET("/redis/persistence/conf", baseApi.LoadPersistenceConf)
cmdRouter.GET("/redis/status", baseApi.LoadRedisStatus)
cmdRouter.GET("/redis/conf", baseApi.LoadRedisConf)
cmdRouter.GET("/redis/exec", baseApi.RedisExec)
cmdRouter.GET("/redis/exec", baseApi.RedisWsSsh)
cmdRouter.POST("/redis/password", baseApi.ChangeRedisPassword)
cmdRouter.POST("/redis/backup", baseApi.RedisBackup)
cmdRouter.POST("/redis/recover", baseApi.RedisRecover)

71
backend/utils/ntp/ntp.go Normal file
View File

@ -0,0 +1,71 @@
package ntp
import (
"encoding/binary"
"fmt"
"net"
"runtime"
"time"
"github.com/gogf/gf/os/gproc"
)
const ntpEpochOffset = 2208988800
type packet struct {
Settings uint8
Stratum uint8
Poll int8
Precision int8
RootDelay uint32
RootDispersion uint32
ReferenceID uint32
RefTimeSec uint32
RefTimeFrac uint32
OrigTimeSec uint32
OrigTimeFrac uint32
RxTimeSec uint32
RxTimeFrac uint32
TxTimeSec uint32
TxTimeFrac uint32
}
func Getremotetime() (time.Time, error) {
conn, err := net.Dial("udp", "pool.ntp.org:123")
if err != nil {
return time.Time{}, fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
if err := conn.SetDeadline(time.Now().Add(15 * time.Second)); err != nil {
return time.Time{}, fmt.Errorf("failed to set deadline: %v", err)
}
req := &packet{Settings: 0x1B}
if err := binary.Write(conn, binary.BigEndian, req); err != nil {
return time.Time{}, fmt.Errorf("failed to set request: %v", err)
}
rsp := &packet{}
if err := binary.Read(conn, binary.BigEndian, rsp); err != nil {
return time.Time{}, fmt.Errorf("failed to read server response: %v", err)
}
secs := float64(rsp.TxTimeSec) - ntpEpochOffset
nanos := (int64(rsp.TxTimeFrac) * 1e9) >> 32
showtime := time.Unix(int64(secs), nanos)
return showtime, nil
}
func UpdateSystemDate(dateTime string) error {
system := runtime.GOOS
if system == "linux" {
if _, err := gproc.ShellExec(`date -s "` + dateTime + `"`); err != nil {
return fmt.Errorf("update system date failed, err: %v", err)
}
return nil
}
return fmt.Errorf("The current system architecture does not support synchronization")
}

View File

@ -99,6 +99,6 @@ func (sws *ExecWsSession) sendWebsocketInputCommandToSshSessionStdinPipe(cmdByte
_, _ = sws.conn.Write(cmdBytes)
}
func (sws *ExecWsSession) ResizeTerminal(width int, height int) {
_, _ = sws.conn.Write([]byte(fmt.Sprintf("stty cols %d rows %d && clear \r", width, height)))
func (sws *ExecWsSession) ResizeTerminal(rows int, cols int) {
_, _ = sws.conn.Write([]byte(fmt.Sprintf("stty cols %d rows %d && clear \r", cols, rows)))
}

View File

@ -0,0 +1,111 @@
package terminal
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
"unsafe"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/creack/pty"
"github.com/pkg/errors"
)
const (
DefaultCloseSignal = syscall.SIGINT
DefaultCloseTimeout = 10 * time.Second
)
type LocalCommand struct {
closeSignal syscall.Signal
closeTimeout time.Duration
cmd *exec.Cmd
pty *os.File
ptyClosed chan struct{}
}
func NewCommand(containerName string, auth string) (*LocalCommand, error) {
cmd := exec.Command("sh", "-c", fmt.Sprintf("docker exec -it %s redis-cli %s", containerName, auth))
pty, err := pty.Start(cmd)
if err != nil {
return nil, errors.Wrapf(err, "failed to start command")
}
ptyClosed := make(chan struct{})
lcmd := &LocalCommand{
closeSignal: DefaultCloseSignal,
closeTimeout: DefaultCloseTimeout,
cmd: cmd,
pty: pty,
ptyClosed: ptyClosed,
}
return lcmd, nil
}
func (lcmd *LocalCommand) Read(p []byte) (n int, err error) {
return lcmd.pty.Read(p)
}
func (lcmd *LocalCommand) Write(p []byte) (n int, err error) {
return lcmd.pty.Write(p)
}
func (lcmd *LocalCommand) Close() error {
if lcmd.cmd != nil && lcmd.cmd.Process != nil {
_ = lcmd.cmd.Process.Signal(lcmd.closeSignal)
}
for {
select {
case <-lcmd.ptyClosed:
return nil
case <-lcmd.closeTimeoutC():
_ = lcmd.cmd.Process.Signal(syscall.SIGKILL)
}
}
}
func (lcmd *LocalCommand) ResizeTerminal(width int, height int) error {
window := struct {
row uint16
col uint16
x uint16
y uint16
}{
uint16(height),
uint16(width),
0,
0,
}
_, _, errno := syscall.Syscall(
syscall.SYS_IOCTL,
lcmd.pty.Fd(),
syscall.TIOCSWINSZ,
uintptr(unsafe.Pointer(&window)),
)
if errno != 0 {
return errno
} else {
return nil
}
}
func (lcmd *LocalCommand) Wait(quitChan chan bool) {
if err := lcmd.cmd.Wait(); err != nil {
global.LOG.Errorf("ssh session wait failed, err: %v", err)
setQuit(quitChan)
}
}
func (lcmd *LocalCommand) closeTimeoutC() <-chan time.Time {
if lcmd.closeTimeout >= 0 {
return time.After(lcmd.closeTimeout)
}
return make(chan time.Time)
}

View File

@ -0,0 +1,99 @@
package terminal
import (
"encoding/base64"
"encoding/json"
"sync"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
)
type LocalWsSession struct {
slave *LocalCommand
wsConn *websocket.Conn
writeMutex sync.Mutex
}
func NewLocalWsSession(cols, rows int, wsConn *websocket.Conn, slave *LocalCommand) (*LocalWsSession, error) {
if err := slave.ResizeTerminal(cols, rows); err != nil {
global.LOG.Errorf("ssh pty change windows size failed, err: %v", err)
}
return &LocalWsSession{
slave: slave,
wsConn: wsConn,
}, nil
}
func (sws *LocalWsSession) Start(quitChan chan bool) {
go sws.handleSlaveEvent(quitChan)
go sws.receiveWsMsg(quitChan)
}
func (sws *LocalWsSession) handleSlaveEvent(exitCh chan bool) {
defer setQuit(exitCh)
buffer := make([]byte, 1024)
for {
select {
case <-exitCh:
return
default:
n, _ := sws.slave.Read(buffer)
_ = sws.masterWrite(buffer[:n])
}
}
}
func (sws *LocalWsSession) masterWrite(data []byte) error {
sws.writeMutex.Lock()
defer sws.writeMutex.Unlock()
err := sws.wsConn.WriteMessage(websocket.TextMessage, data)
if err != nil {
return errors.Wrapf(err, "failed to write to master")
}
return nil
}
func (sws *LocalWsSession) receiveWsMsg(exitCh chan bool) {
wsConn := sws.wsConn
defer setQuit(exitCh)
for {
select {
case <-exitCh:
return
default:
_, wsData, err := wsConn.ReadMessage()
if err != nil {
global.LOG.Errorf("reading webSocket message failed, err: %v", err)
return
}
msgObj := wsMsg{}
_ = json.Unmarshal(wsData, &msgObj)
switch msgObj.Type {
case wsMsgResize:
if msgObj.Cols > 0 && msgObj.Rows > 0 {
if err := sws.slave.ResizeTerminal(msgObj.Cols, msgObj.Rows); err != nil {
global.LOG.Errorf("ssh pty change windows size failed, err: %v", err)
}
}
case wsMsgCmd:
decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd)
if err != nil {
global.LOG.Errorf("websock cmd string base64 decoding failed, err: %v", err)
}
sws.sendWebsocketInputCommandToSshSessionStdinPipe(decodeBytes)
}
}
}
}
func (sws *LocalWsSession) sendWebsocketInputCommandToSshSessionStdinPipe(cmdBytes []byte) {
if _, err := sws.slave.Write(cmdBytes); err != nil {
global.LOG.Errorf("ws cmd bytes write to ssh.stdin pipe failed, err: %v", err)
}
}

View File

@ -165,6 +165,19 @@ func (sws *LogicSshWsSession) sendComboOutput(exitCh chan bool) {
return
}
bs := sws.comboOutput.Bytes()
if string(bs) == string([]byte{13, 10, 108, 111, 103, 111, 117, 116, 13, 10}) {
err := wsConn.WriteMessage(websocket.TextMessage, bs)
if err != nil {
global.LOG.Errorf("ssh sending combo output to webSocket failed, err: %v", err)
}
_, err = sws.logBuff.Write(bs)
if err != nil {
global.LOG.Errorf("combo output to log buffer failed, err: %v", err)
}
sws.comboOutput.buffer.Reset()
sws.Close()
return
}
if len(bs) > 0 {
err := wsConn.WriteMessage(websocket.TextMessage, bs)
if err != nil {

View File

@ -37,7 +37,7 @@
<el-button
v-if="item.status === 'closed'"
icon="Refresh"
style="color: #f56c6c"
style="color: white"
size="default"
link
@click="onReconnect(item)"
@ -292,7 +292,7 @@ const loadHost = async () => {
continue;
}
for (const host of item.children) {
if (host.label.indexOf('127.0.0.1')) {
if (host.label.indexOf('127.0.0.1') !== -1) {
localHostID.value = host.id;
if (terminalTabs.value.length === 0) {
onConnLocal();
@ -374,6 +374,7 @@ const onReconnect = async (item: any) => {
}
item.Refresh = !item.Refresh;
ctx.refs[`Ref${item.key}`];
syncTerminal();
};
const submitAddHost = (formEl: FormInstance | undefined, ops: string) => {
@ -424,7 +425,7 @@ onMounted(() => {
loadCommand();
timer = setInterval(() => {
syncTerminal();
}, 1000 * 8);
}, 1000 * 5);
});
onBeforeMount(() => {
clearInterval(Number(timer));

View File

@ -108,8 +108,10 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="onSubmit(formRef)">
<el-button :disabled="loading" @click="dialogVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>

View File

@ -1,7 +1,7 @@
<template>
<div>
<Submenu activeName="panel" />
<el-form :model="form" ref="panelFormRef" label-position="left" label-width="160px">
<el-form :model="form" ref="panelFormRef" label-position="left" v-loading="loading" label-width="160px">
<el-card style="margin-top: 20px">
<template #header>
<div class="card-header">
@ -122,7 +122,14 @@
:title="$t('setting.changePassword')"
width="30%"
>
<el-form ref="passFormRef" label-width="80px" label-position="left" :model="passForm" :rules="passRules">
<el-form
v-loading="dialogLoading"
ref="passFormRef"
label-width="80px"
label-position="left"
:model="passForm"
:rules="passRules"
>
<el-form-item :label="$t('setting.oldPassword')" prop="oldPassword">
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
</el-form-item>
@ -146,8 +153,10 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="passwordVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="submitChangePassword(passFormRef)">
<el-button :disabled="dialogLoading" @click="passwordVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="dialogLoading" @click="submitChangePassword(passFormRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
@ -167,6 +176,8 @@ import { GlobalStore } from '@/store';
import { useI18n } from 'vue-i18n';
import { useTheme } from '@/hooks/use-theme';
const loading = ref(false);
const dialogLoading = ref(false);
const i18n = useI18n();
const globalStore = GlobalStore();
const themeConfig = computed(() => globalStore.themeConfig);
@ -203,7 +214,7 @@ const search = async () => {
const res = await getSettingInfo();
form.userName = res.data.userName;
form.password = '******';
form.sessionTimeout = res.data.sessionTimeout;
form.sessionTimeout = Number(res.data.sessionTimeout);
form.localTime = res.data.localTime;
form.panelName = res.data.panelName;
form.theme = res.data.theme;
@ -221,6 +232,7 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
if (val === '') {
return;
}
loading.value = true;
switch (key) {
case 'Language':
i18n.locale.value = val;
@ -249,9 +261,15 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
key: key,
value: val + '',
};
await updateSetting(param);
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
search();
await updateSetting(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
search();
})
.catch(() => {
loading.value = false;
});
};
function callback(error: any) {
if (error) {
@ -287,18 +305,32 @@ const submitChangePassword = async (formEl: FormInstance | undefined) => {
ElMessage.error(i18n.t('setting.duplicatePassword'));
return;
}
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password });
passwordVisiable.value = false;
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
router.push({ name: 'login', params: { code: '' } });
globalStore.setLogStatus(false);
dialogLoading.value = true;
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password })
.then(() => {
dialogLoading.value = false;
passwordVisiable.value = false;
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
router.push({ name: 'login', params: { code: '' } });
globalStore.setLogStatus(false);
})
.catch(() => {
dialogLoading.value = false;
});
});
};
const onSyncTime = async () => {
const res = await syncTime();
form.localTime = res.data;
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
loading.value = true;
await syncTime()
.then((res) => {
loading.value = false;
form.localTime = res.data;
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
};
onMounted(() => {

View File

@ -1,7 +1,7 @@
<template>
<div>
<Submenu activeName="safe" />
<el-form :model="form" ref="panelFormRef" label-position="left" label-width="160px">
<el-form :model="form" ref="panelFormRef" v-loading="loading" label-position="left" label-width="160px">
<el-card style="margin-top: 20px">
<template #header>
<div class="card-header">
@ -129,6 +129,7 @@ import { dateFromat } from '@/utils/util';
const emit = defineEmits(['on-save', 'search']);
const loading = ref(false);
const form = reactive({
serverPort: '',
securityEntrance: '',
@ -148,7 +149,7 @@ const timeoutForm = reactive({
const search = async () => {
const res = await getSettingInfo();
form.securityEntrance = res.data.securityEntrance;
form.expirationDays = res.data.expirationDays;
form.expirationDays = Number(res.data.expirationDays);
form.expirationTime = res.data.expirationTime;
form.complexityVerification = res.data.complexityVerification;
form.mfaStatus = res.data.mfaStatus;
@ -176,9 +177,16 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
key: key,
value: val + '',
};
await updateSetting(param);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
search();
loading.value = true;
await updateSetting(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
search();
})
.catch(() => {
loading.value = false;
});
};
function callback(error: any) {
if (error) {
@ -195,17 +203,31 @@ const handleMFA = async () => {
otp.qrImage = res.data.qrImage;
isMFAShow.value = true;
} else {
await updateSetting({ key: 'MFAStatus', value: 'disable' });
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
loading.value = true;
await updateSetting({ key: 'MFAStatus', value: 'disable' })
.then(() => {
loading.value = false;
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}
};
const onBind = async () => {
await bindMFA({ code: mfaCode.value, secret: otp.secret });
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
isMFAShow.value = false;
loading.value = true;
await bindMFA({ code: mfaCode.value, secret: otp.secret })
.then(() => {
loading.value = false;
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
isMFAShow.value = false;
})
.catch(() => {
loading.value = false;
});
};
const onCancelMfaBind = async () => {
@ -223,11 +245,18 @@ const submitTimeout = async (formEl: FormInstance | undefined) => {
formEl.validate(async (valid) => {
if (!valid) return;
let time = new Date(new Date().getTime() + 3600 * 1000 * 24 * timeoutForm.days);
await updateSetting({ key: 'ExpirationDays', value: timeoutForm.days + '' });
emit('search');
loadTimeOut();
form.expirationTime = dateFromat(0, 0, time);
timeoutVisiable.value = false;
loading.value = true;
await updateSetting({ key: 'ExpirationDays', value: timeoutForm.days + '' })
.then(() => {
loading.value = false;
emit('search');
loadTimeOut();
form.expirationTime = dateFromat(0, 0, time);
timeoutVisiable.value = false;
})
.catch(() => {
loading.value = false;
});
});
};

7
go.mod
View File

@ -5,8 +5,8 @@ go 1.18
require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
github.com/aws/aws-sdk-go v1.44.99
github.com/beevik/ntp v0.3.0
github.com/compose-spec/compose-go v1.6.0
github.com/creack/pty v1.1.18
github.com/dgraph-io/badger/v3 v3.2103.2
github.com/docker/docker v20.10.18+incompatible
github.com/docker/go-connections v0.4.0
@ -19,6 +19,7 @@ require (
github.com/go-gormigrate/gormigrate/v2 v2.0.2
github.com/go-playground/validator/v10 v10.11.0
github.com/go-sql-driver/mysql v1.6.0
github.com/gogf/gf v1.16.9
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/gorilla/csrf v1.7.1
github.com/gorilla/websocket v1.5.0
@ -75,6 +76,7 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
@ -111,6 +113,7 @@ require (
github.com/leodido/go-urn v1.2.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
@ -145,6 +148,8 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.3.0 // indirect
go.opentelemetry.io/otel/trace v1.3.0 // indirect
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect

35
go.sum
View File

@ -106,8 +106,6 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.44.99 h1:ITZ9q/fmH+Ksaz2TbyMU2d19vOOWs/hAlt8NbXAieHw=
github.com/aws/aws-sdk-go v1.44.99/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw=
github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
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=
@ -144,6 +142,8 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 h1:LdXxtjzvZYhhUaonAaAKArG3pyC67kGL3YY+6hGG8G4=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
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=
@ -267,6 +267,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
@ -330,7 +332,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
@ -369,6 +373,11 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
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.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
@ -413,6 +422,8 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogf/gf v1.16.9 h1:Q803UmmRo59+Ws08sMVFOcd8oNpkSWL9vS33hlo/Cyk=
github.com/gogf/gf v1.16.9/go.mod h1:8Q/kw05nlVRp+4vv7XASBsMe9L1tsVKiGoeP2AHnlkk=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -466,6 +477,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
@ -526,6 +539,8 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@ -649,13 +664,18 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
@ -722,6 +742,8 @@ github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n5
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -822,6 +844,7 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@ -985,6 +1008,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -1094,6 +1123,7 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@ -1210,6 +1240,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=