Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
K
koko
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
koko
Commits
f2079123
Commit
f2079123
authored
May 14, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
[Update] 修改分页
parents
4864ccfb
9d0d79f5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
323 additions
and
34 deletions
+323
-34
pagination.go
pkg/handler/pagination.go
+245
-0
session.go
pkg/handler/session.go
+66
-28
assets.go
pkg/model/assets.go
+1
-1
parser.go
pkg/proxy/parser.go
+4
-4
switch.go
pkg/proxy/switch.go
+1
-1
terminal.go
pkg/utils/terminal.go
+6
-0
No files found.
pkg/handler/pagination.go
0 → 100644
View file @
f2079123
package
handler
import
(
"fmt"
"strconv"
"strings"
"github.com/olekukonko/tablewriter"
"cocogo/pkg/config"
"cocogo/pkg/model"
"cocogo/pkg/utils"
)
const
(
IDColumnMinSize
=
4
HostNameColumnMaxSize
=
15
IPColumnSize
=
16
CommentColumnMinSize
=
2
)
type
AssetPagination
struct
{
term
*
utils
.
Terminal
CurrentPage
int
TotalPage
int
PageSize
int
TotalNumber
int
Data
[]
model
.
Asset
dataBulk
[][]
string
columnSize
[
5
]
int
}
func
(
p
*
AssetPagination
)
Initial
()
{
var
(
pageSize
int
totalPage
int
)
_
,
height
:=
p
.
term
.
GetSize
()
switch
config
.
Conf
.
AssetListPageSize
{
case
"auto"
:
pageSize
=
height
-
7
case
"all"
:
pageSize
=
p
.
TotalNumber
default
:
if
value
,
err
:=
strconv
.
Atoi
(
config
.
Conf
.
AssetListPageSize
);
err
==
nil
{
pageSize
=
value
}
else
{
pageSize
=
height
-
7
}
}
if
pageSize
<=
0
{
pageSize
=
1
}
if
p
.
TotalNumber
%
pageSize
==
0
{
totalPage
=
p
.
TotalNumber
/
pageSize
}
else
{
totalPage
=
p
.
TotalNumber
/
pageSize
+
1
}
p
.
CurrentPage
=
1
p
.
PageSize
=
pageSize
p
.
TotalPage
=
totalPage
p
.
dataBulk
=
make
([][]
string
,
0
)
}
func
(
p
*
AssetPagination
)
setPageSize
()
{
if
config
.
Conf
.
AssetListPageSize
==
"auto"
{
var
pageSize
int
_
,
height
:=
p
.
term
.
GetSize
()
remainSize
:=
height
-
7
if
remainSize
>
0
{
pageSize
=
remainSize
}
else
{
pageSize
=
1
}
if
p
.
PageSize
!=
pageSize
{
p
.
PageSize
=
pageSize
p
.
CurrentPage
=
1
if
p
.
TotalNumber
%
pageSize
==
0
{
p
.
TotalPage
=
p
.
TotalNumber
/
pageSize
}
else
{
p
.
TotalPage
=
p
.
TotalNumber
/
pageSize
+
1
}
}
}
}
func
(
p
*
AssetPagination
)
getColumnMaxSize
()
{
var
(
IDSize
int
HostNameSize
int
systemUserSize
int
CommentSize
int
)
p
.
setPageSize
()
IDSize
=
IDColumnMinSize
CommentSize
=
CommentColumnMinSize
endIndex
:=
p
.
CurrentPage
*
p
.
PageSize
startIndex
:=
endIndex
-
p
.
PageSize
if
endIndex
>
len
(
p
.
Data
)
{
endIndex
=
len
(
p
.
Data
)
}
if
len
(
strconv
.
Itoa
(
endIndex
))
>
IDColumnMinSize
{
IDSize
=
len
(
strconv
.
Itoa
(
endIndex
))
}
p
.
dataBulk
=
p
.
dataBulk
[
:
0
]
for
i
,
item
:=
range
p
.
Data
[
startIndex
:
endIndex
]
{
tmpDat
:=
make
([]
string
,
5
)
var
tmpSystemUserArray
[]
string
result
:=
selectHighestPrioritySystemUsers
(
item
.
SystemUsers
)
tmpSystemUserArray
=
make
([]
string
,
len
(
result
))
for
index
,
sysUser
:=
range
result
{
tmpSystemUserArray
[
index
]
=
sysUser
.
Name
}
tmpSystemUserStr
:=
fmt
.
Sprintf
(
"[%s]"
,
strings
.
Join
(
tmpSystemUserArray
,
","
))
if
len
(
tmpSystemUserStr
)
>
systemUserSize
{
systemUserSize
=
len
(
tmpSystemUserStr
)
}
if
len
(
item
.
Hostname
)
>=
HostNameColumnMaxSize
{
HostNameSize
=
HostNameColumnMaxSize
tmpDat
[
1
]
=
item
.
Hostname
[
:
HostNameColumnMaxSize
]
}
else
if
len
(
item
.
Hostname
)
<
HostNameColumnMaxSize
&&
len
(
item
.
Hostname
)
>
HostNameSize
{
HostNameSize
=
len
(
item
.
Hostname
)
tmpDat
[
1
]
=
item
.
Hostname
}
else
{
tmpDat
[
1
]
=
item
.
Hostname
}
if
len
(
item
.
Comment
)
>
CommentSize
{
CommentSize
=
len
(
item
.
Comment
)
}
tmpDat
[
0
]
=
strconv
.
Itoa
(
startIndex
+
i
+
1
)
tmpDat
[
2
]
=
item
.
Ip
tmpDat
[
3
]
=
tmpSystemUserStr
p
.
dataBulk
=
append
(
p
.
dataBulk
,
tmpDat
)
}
// table writer 空白空间占用宽度 4 + (columnNum - 1) * 4
width
,
_
:=
p
.
term
.
GetSize
()
remainSize
:=
width
-
16
-
IDSize
-
HostNameSize
-
IPColumnSize
-
systemUserSize
if
remainSize
>
0
&&
CommentSize
<
remainSize
{
CommentSize
=
remainSize
}
for
i
,
item
:=
range
p
.
Data
[
startIndex
:
endIndex
]
{
if
len
(
item
.
Comment
)
>
CommentSize
{
p
.
dataBulk
[
i
][
4
]
=
item
.
Comment
[
:
CommentSize
]
}
else
{
p
.
dataBulk
[
i
][
4
]
=
item
.
Comment
}
}
p
.
columnSize
=
[
5
]
int
{
IDSize
,
HostNameSize
,
IPColumnSize
,
systemUserSize
,
CommentSize
}
fmt
.
Println
(
p
.
columnSize
)
}
func
(
p
*
AssetPagination
)
PaginationState
()
[]
model
.
Asset
{
done
:=
make
(
chan
struct
{})
defer
close
(
done
)
if
p
.
PageSize
>
p
.
TotalNumber
{
p
.
displayAssets
()
return
[]
model
.
Asset
{}
}
for
{
p
.
displayAssets
()
p
.
displayTipsInfo
()
line
,
err
:=
p
.
term
.
ReadLine
()
if
err
!=
nil
{
return
[]
model
.
Asset
{}
}
line
=
strings
.
TrimSpace
(
line
)
switch
len
(
line
)
{
case
0
,
1
:
switch
strings
.
ToLower
(
line
)
{
case
"p"
:
p
.
CurrentPage
--
if
p
.
CurrentPage
<=
0
{
p
.
CurrentPage
=
1
}
continue
case
""
,
"n"
:
p
.
CurrentPage
++
if
p
.
CurrentPage
>=
p
.
TotalPage
{
p
.
CurrentPage
=
p
.
TotalPage
}
continue
case
"b"
:
return
[]
model
.
Asset
{}
}
}
if
indexID
,
err
:=
strconv
.
Atoi
(
line
);
err
==
nil
{
if
indexID
>
0
&&
indexID
<=
p
.
TotalNumber
{
return
[]
model
.
Asset
{
p
.
Data
[
indexID
-
1
]}
}
}
}
}
func
(
p
*
AssetPagination
)
displayAssets
()
{
p
.
getColumnMaxSize
()
_
,
_
=
p
.
term
.
Write
([]
byte
(
utils
.
CharClear
))
table
:=
tablewriter
.
NewWriter
(
p
.
term
)
table
.
SetHeader
([]
string
{
"ID"
,
"Hostname"
,
"IP"
,
"LoginAs"
,
"Comment"
})
table
.
AppendBulk
(
p
.
dataBulk
)
table
.
SetBorder
(
false
)
greens
:=
tablewriter
.
Colors
{
tablewriter
.
Normal
,
tablewriter
.
FgGreenColor
}
table
.
SetHeaderColor
(
greens
,
greens
,
greens
,
greens
,
greens
)
table
.
SetHeaderAlignment
(
tablewriter
.
ALIGN_LEFT
)
table
.
SetAlignment
(
tablewriter
.
ALIGN_LEFT
)
for
i
,
value
:=
range
p
.
columnSize
{
table
.
SetColMinWidth
(
i
,
value
)
}
currentCapMsg
:=
fmt
.
Sprintf
(
"Page: %d, Count: %d, Total Page: %d, Total Count:%d
\n
"
,
p
.
CurrentPage
,
p
.
PageSize
,
p
.
TotalPage
,
p
.
TotalNumber
)
table
.
SetCaption
(
true
,
utils
.
WrapperString
(
currentCapMsg
,
utils
.
Green
))
table
.
Render
()
}
func
(
p
*
AssetPagination
)
displayTipsInfo
()
{
tips
:=
[]
string
{
"
\n
Tips: Enter the asset ID and log directly into the asset.
\n
"
,
"
\n
Page up: P/p Page down: Enter|N/n BACK: b.
\n
"
,
}
for
_
,
tip
:=
range
tips
{
_
,
_
=
p
.
term
.
Write
([]
byte
(
tip
))
}
}
type
Pagination
interface
{
GetNextPageData
()
[]
interface
{}
GetPrePageData
()
[]
interface
{}
GetPageData
(
p
int
)
[]
interface
{}
CurrentPage
()
int
TotalCount
()
int
TotalPage
()
int
SetPageSize
(
int
)
GetPageSize
()
int
}
pkg/handler/session.go
View file @
f2079123
...
...
@@ -27,7 +27,8 @@ func SessionHandler(sess ssh.Session) {
ctx
,
cancel
:=
cctx
.
NewContext
(
sess
)
defer
cancel
()
handler
:=
newInteractiveHandler
(
sess
,
ctx
.
User
())
logger
.
Debugf
(
"User Request pty %s: %s"
,
pty
.
Term
,
sess
.
User
())
handler
.
termHeight
,
handler
.
termWidth
=
pty
.
Window
.
Height
,
pty
.
Window
.
Width
logger
.
Debugf
(
"User Request pty: %s %s"
,
sess
.
User
(),
pty
.
Term
)
handler
.
Dispatch
(
ctx
)
}
else
{
utils
.
IgnoreErrWriteString
(
sess
,
"No PTY requested.
\n
"
)
...
...
@@ -36,16 +37,17 @@ func SessionHandler(sess ssh.Session) {
}
func
newInteractiveHandler
(
sess
ssh
.
Session
,
user
*
model
.
User
)
*
interactiveHandler
{
term
:=
terminal
.
NewTerminal
(
sess
,
"Opt> "
)
term
:=
utils
.
NewTerminal
(
sess
,
"Opt> "
)
handler
:=
&
interactiveHandler
{
sess
:
sess
,
user
:
user
,
term
:
term
}
handler
.
Initial
()
return
handler
}
type
interactiveHandler
struct
{
sess
ssh
.
Session
user
*
model
.
User
term
*
terminal
.
Terminal
sess
ssh
.
Session
user
*
model
.
User
term
*
utils
.
Terminal
winWatchChan
chan
bool
assetSelect
*
model
.
Asset
systemUserSelect
*
model
.
SystemUser
...
...
@@ -53,6 +55,9 @@ type interactiveHandler struct {
searchResult
model
.
AssetList
nodes
model
.
NodeList
mu
*
sync
.
RWMutex
termWidth
int
termHeight
int
}
func
(
h
*
interactiveHandler
)
Initial
()
{
...
...
@@ -60,19 +65,29 @@ func (h *interactiveHandler) Initial() {
h
.
loadUserAssets
()
h
.
loadUserAssetNodes
()
h
.
searchResult
=
h
.
assets
h
.
winWatchChan
=
make
(
chan
bool
)
}
func
(
h
*
interactiveHandler
)
displayBanner
()
{
displayBanner
(
h
.
sess
,
h
.
user
.
Name
)
}
func
(
h
*
interactiveHandler
)
watchWinSizeChange
(
winCh
<-
chan
ssh
.
Window
,
done
<-
chan
struct
{})
{
func
(
h
*
interactiveHandler
)
watchWinSizeChange
()
{
_
,
sessChan
,
_
:=
h
.
sess
.
Pty
()
winChan
:=
sessChan
for
{
select
{
case
<-
done
:
logger
.
Debug
(
"Interactive handler watch win size done"
)
return
case
win
,
ok
:=
<-
winCh
:
case
sig
,
ok
:=
<-
h
.
winWatchChan
:
if
!
ok
{
return
}
switch
sig
{
case
false
:
winChan
=
nil
case
true
:
winChan
=
sessChan
}
case
win
,
ok
:=
<-
winChan
:
if
!
ok
{
return
}
...
...
@@ -82,13 +97,19 @@ func (h *interactiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
}
}
func
(
h
*
interactiveHandler
)
pauseWatchWinSize
()
{
h
.
winWatchChan
<-
false
}
func
(
h
*
interactiveHandler
)
resumeWatchWinSize
()
{
h
.
winWatchChan
<-
true
}
func
(
h
*
interactiveHandler
)
Dispatch
(
ctx
cctx
.
Context
)
{
_
,
winCh
,
_
:=
h
.
sess
.
Pty
()
go
h
.
watchWinSizeChange
()
for
{
doneChan
:=
make
(
chan
struct
{})
go
h
.
watchWinSizeChange
(
winCh
,
doneChan
)
line
,
err
:=
h
.
term
.
ReadLine
()
close
(
doneChan
)
if
err
!=
nil
{
if
err
!=
io
.
EOF
{
...
...
@@ -98,13 +119,12 @@ func (h *interactiveHandler) Dispatch(ctx cctx.Context) {
}
break
}
line
=
strings
.
TrimSpace
(
line
)
switch
len
(
line
)
{
case
0
,
1
:
switch
strings
.
ToLower
(
line
)
{
case
""
,
"p"
:
h
.
displayAssets
(
h
.
assets
)
//h.Proxy(ctx)
case
"g"
:
h
.
displayNodes
(
h
.
nodes
)
case
"h"
:
...
...
@@ -210,19 +230,19 @@ func (h *interactiveHandler) displayAssets(assets model.AssetList) {
if
len
(
assets
)
==
0
{
_
,
_
=
io
.
WriteString
(
h
.
term
,
"
\r\n
No Assets
\r\n\r
"
)
}
else
{
table
:=
tablewriter
.
NewWriter
(
h
.
term
)
table
.
SetHeader
([]
string
{
"ID"
,
"Hostname"
,
"IP"
,
"LoginAs"
,
"Comment"
})
for
index
,
assetItem
:=
range
assets
{
sysUserArray
:=
make
([]
string
,
len
(
assetItem
.
SystemUsers
))
for
index
,
sysUser
:=
range
assetItem
.
SystemUsers
{
sysUserArray
[
index
]
=
sysUser
.
Name
}
sysUsers
:=
"["
+
strings
.
Join
(
sysUserArray
,
" "
)
+
"]"
table
.
Append
([]
string
{
strconv
.
Itoa
(
index
+
1
),
assetItem
.
Hostname
,
assetItem
.
Ip
,
sysUsers
,
assetItem
.
Comment
})
pag
:=
AssetPagination
{
term
:
h
.
term
,
TotalNumber
:
len
(
assets
),
Data
:
assets
,
}
pag
.
Initial
()
selectOneAssets
:=
pag
.
PaginationState
()
if
len
(
selectOneAssets
)
==
1
{
systemUser
:=
h
.
chooseSystemUser
(
selectOneAssets
[
0
]
.
SystemUsers
)
h
.
assetSelect
=
&
selectOneAssets
[
0
]
h
.
systemUserSelect
=
&
systemUser
h
.
Proxy
(
context
.
TODO
())
}
table
.
SetBorder
(
false
)
table
.
Render
()
}
}
...
...
@@ -299,7 +319,9 @@ func (h *interactiveHandler) Proxy(ctx context.Context) {
Asset
:
h
.
assetSelect
,
SystemUser
:
h
.
systemUserSelect
,
}
h
.
pauseWatchWinSize
()
p
.
Proxy
()
h
.
resumeWatchWinSize
()
}
func
ConstructAssetNodeTree
(
assetNodes
[]
model
.
Node
)
treeprint
.
Tree
{
...
...
@@ -335,6 +357,22 @@ func isSubstring(sArray []string, substr string) bool {
return
false
}
func
selectHighestPrioritySystemUsers
(
systemUsers
[]
model
.
SystemUser
)
[]
model
.
SystemUser
{
var
result
=
make
([]
model
.
SystemUser
,
0
)
length
:=
len
(
systemUsers
)
model
.
SortSystemUserByPriority
(
systemUsers
)
highestPriority
:=
systemUsers
[
length
-
1
]
.
Priority
result
=
append
(
result
,
systemUsers
[
length
-
1
])
for
i
:=
length
-
2
;
i
>=
0
;
i
--
{
if
highestPriority
==
systemUsers
[
i
]
.
Priority
{
result
=
append
(
result
,
systemUsers
[
i
])
}
}
return
result
}
//func (h *InteractiveHandler) JoinShareRoom(roomID string) {
//sshConn := userhome.NewSSHConn(h.sess)
//ctx, cancelFuc := context.WithCancel(h.sess.Context())
...
...
pkg/model/assets.go
View file @
f2079123
...
...
@@ -158,7 +158,7 @@ func (s *systemUserSorter) Less(i, j int) bool {
}
func
systemUserPrioritySort
(
use1
,
user2
*
SystemUser
)
bool
{
return
use1
.
Priority
<
=
user2
.
Priority
return
use1
.
Priority
<
user2
.
Priority
}
func
SortSystemUserByPriority
(
users
[]
SystemUser
)
{
...
...
pkg/proxy/parser.go
View file @
f2079123
...
...
@@ -42,7 +42,7 @@ type Parser struct {
userOutputChan
chan
[]
byte
srvInputChan
chan
[]
byte
srvOutputChan
chan
[]
byte
cmd
Chan
chan
[
2
]
string
cmd
RecordChan
chan
[
2
]
string
inputInitial
bool
inputPreState
bool
...
...
@@ -76,7 +76,7 @@ func (p *Parser) initial() {
p
.
userOutputChan
=
make
(
chan
[]
byte
,
1024
)
p
.
srvInputChan
=
make
(
chan
[]
byte
,
1024
)
p
.
srvOutputChan
=
make
(
chan
[]
byte
,
1024
)
p
.
cmdChan
=
make
(
chan
[
2
]
string
,
1024
)
p
.
cmd
Record
Chan
=
make
(
chan
[
2
]
string
,
1024
)
}
func
(
p
*
Parser
)
Parse
()
{
...
...
@@ -124,7 +124,7 @@ func (p *Parser) parseInputState(b []byte) []byte {
// 用户又开始输入,并上次不处于输入状态,开始结算上次命令的结果
if
!
p
.
inputPreState
{
p
.
parseCmdOutput
()
p
.
cmdChan
<-
[
2
]
string
{
p
.
command
,
p
.
output
}
p
.
cmd
Record
Chan
<-
[
2
]
string
{
p
.
command
,
p
.
output
}
}
}
return
b
...
...
@@ -232,6 +232,6 @@ func (p *Parser) Close() {
close
(
p
.
userOutputChan
)
close
(
p
.
srvInputChan
)
close
(
p
.
srvOutputChan
)
close
(
p
.
cmdChan
)
close
(
p
.
cmd
Record
Chan
)
p
.
closed
=
true
}
pkg/proxy/switch.go
View file @
f2079123
...
...
@@ -150,7 +150,7 @@ func (s *SwitchSession) readParserToUser(ctx context.Context) {
}
func
(
s
*
SwitchSession
)
recordCmd
()
{
for
cmd
:=
range
s
.
cmdRecordChan
{
for
cmd
:=
range
s
.
parser
.
cmdRecordChan
{
s
.
cmdRecorder
.
Record
(
cmd
)
}
}
...
...
pkg/utils/terminal.go
View file @
f2079123
...
...
@@ -890,6 +890,12 @@ func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
t
.
moveCursorToPos
(
t
.
pos
)
}
func
(
t
*
Terminal
)
GetSize
()
(
width
,
height
int
)
{
t
.
lock
.
Lock
()
defer
t
.
lock
.
Unlock
()
return
t
.
termWidth
,
t
.
termHeight
}
func
(
t
*
Terminal
)
SetSize
(
width
,
height
int
)
error
{
t
.
lock
.
Lock
()
defer
t
.
lock
.
Unlock
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment