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
19d3d1be
Commit
19d3d1be
authored
May 14, 2019
by
Eric
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] add pagination for interactivehandler
parent
6cbe3f88
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
307 additions
and
26 deletions
+307
-26
pagination.go
pkg/handler/pagination.go
+258
-0
session.go
pkg/handler/session.go
+48
-25
assets.go
pkg/model/assets.go
+1
-1
No files found.
pkg/handler/pagination.go
0 → 100644
View file @
19d3d1be
package
handler
import
(
"fmt"
"strconv"
"strings"
"github.com/gliderlabs/ssh"
"github.com/olekukonko/tablewriter"
"golang.org/x/crypto/ssh/terminal"
"cocogo/pkg/config"
"cocogo/pkg/logger"
"cocogo/pkg/model"
"cocogo/pkg/utils"
)
const
(
IDColumnMinSize
=
4
HostNameColumnMaxSize
=
15
IPColumnSize
=
16
CommentColumnMinSize
=
2
)
type
AssetPagination
struct
{
term
*
terminal
.
Terminal
winChan
<-
chan
ssh
.
Window
TermWidth
int
TermHeight
int
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
)
switch
config
.
Conf
.
AssetListPageSize
{
case
"auto"
:
pageSize
=
p
.
TermHeight
-
7
case
"all"
:
pageSize
=
p
.
TotalNumber
default
:
if
value
,
err
:=
strconv
.
Atoi
(
config
.
Conf
.
AssetListPageSize
);
err
==
nil
{
pageSize
=
value
}
else
{
pageSize
=
p
.
TermHeight
-
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
)
watchWinSizeChange
(
done
<-
chan
struct
{})
{
for
{
select
{
case
<-
done
:
logger
.
Debug
(
"Pagination watch win size done"
)
return
case
win
,
ok
:=
<-
p
.
winChan
:
if
!
ok
{
return
}
p
.
TermHeight
,
p
.
TermWidth
=
win
.
Height
,
win
.
Width
logger
.
Debugf
(
"Term window size change: %d*%d"
,
win
.
Height
,
win
.
Width
)
_
=
p
.
term
.
SetSize
(
win
.
Width
,
win
.
Height
)
}
}
}
func
(
p
*
AssetPagination
)
setPageSize
()
{
if
config
.
Conf
.
AssetListPageSize
==
"auto"
{
var
pageSize
int
remainSize
:=
p
.
TermHeight
-
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
remainSize
:=
p
.
TermWidth
-
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
{})
go
p
.
watchWinSizeChange
(
done
)
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
))
}
}
pkg/handler/session.go
View file @
19d3d1be
...
@@ -22,11 +22,12 @@ import (
...
@@ -22,11 +22,12 @@ import (
)
)
func
SessionHandler
(
sess
ssh
.
Session
)
{
func
SessionHandler
(
sess
ssh
.
Session
)
{
pty
,
_
,
ok
:=
sess
.
Pty
()
pty
,
winCH
,
ok
:=
sess
.
Pty
()
if
ok
{
if
ok
{
ctx
,
cancel
:=
cctx
.
NewContext
(
sess
)
ctx
,
cancel
:=
cctx
.
NewContext
(
sess
)
defer
cancel
()
defer
cancel
()
handler
:=
newInteractiveHandler
(
sess
,
ctx
.
User
())
handler
:=
newInteractiveHandler
(
sess
,
ctx
.
User
(),
winCH
)
handler
.
termHeight
,
handler
.
termWidth
=
pty
.
Window
.
Height
,
pty
.
Window
.
Width
logger
.
Debugf
(
"User Request pty: %s %s"
,
sess
.
User
(),
pty
.
Term
)
logger
.
Debugf
(
"User Request pty: %s %s"
,
sess
.
User
(),
pty
.
Term
)
handler
.
Dispatch
(
ctx
)
handler
.
Dispatch
(
ctx
)
}
else
{
}
else
{
...
@@ -35,17 +36,18 @@ func SessionHandler(sess ssh.Session) {
...
@@ -35,17 +36,18 @@ func SessionHandler(sess ssh.Session) {
}
}
}
}
func
newInteractiveHandler
(
sess
ssh
.
Session
,
user
*
model
.
User
)
*
interactiveHandler
{
func
newInteractiveHandler
(
sess
ssh
.
Session
,
user
*
model
.
User
,
winCh
<-
chan
ssh
.
Window
)
*
interactiveHandler
{
term
:=
terminal
.
NewTerminal
(
sess
,
"Opt> "
)
term
:=
terminal
.
NewTerminal
(
sess
,
"Opt> "
)
handler
:=
&
interactiveHandler
{
sess
:
sess
,
user
:
user
,
term
:
term
}
handler
:=
&
interactiveHandler
{
sess
:
sess
,
user
:
user
,
term
:
term
,
winChan
:
winCh
}
handler
.
Initial
()
handler
.
Initial
()
return
handler
return
handler
}
}
type
interactiveHandler
struct
{
type
interactiveHandler
struct
{
sess
ssh
.
Session
sess
ssh
.
Session
user
*
model
.
User
user
*
model
.
User
term
*
terminal
.
Terminal
term
*
terminal
.
Terminal
winChan
<-
chan
ssh
.
Window
assetSelect
*
model
.
Asset
assetSelect
*
model
.
Asset
systemUserSelect
*
model
.
SystemUser
systemUserSelect
*
model
.
SystemUser
...
@@ -53,6 +55,9 @@ type interactiveHandler struct {
...
@@ -53,6 +55,9 @@ type interactiveHandler struct {
searchResult
model
.
AssetList
searchResult
model
.
AssetList
nodes
model
.
NodeList
nodes
model
.
NodeList
mu
*
sync
.
RWMutex
mu
*
sync
.
RWMutex
termWidth
int
termHeight
int
}
}
func
(
h
*
interactiveHandler
)
Initial
()
{
func
(
h
*
interactiveHandler
)
Initial
()
{
...
@@ -66,16 +71,17 @@ func (h *interactiveHandler) displayBanner() {
...
@@ -66,16 +71,17 @@ func (h *interactiveHandler) displayBanner() {
displayBanner
(
h
.
sess
,
h
.
user
.
Name
)
displayBanner
(
h
.
sess
,
h
.
user
.
Name
)
}
}
func
(
h
*
interactiveHandler
)
watchWinSizeChange
(
winCh
<-
chan
ssh
.
Window
,
done
<-
chan
struct
{})
{
func
(
h
*
interactiveHandler
)
watchWinSizeChange
(
done
<-
chan
struct
{})
{
for
{
for
{
select
{
select
{
case
<-
done
:
case
<-
done
:
logger
.
Debug
(
"Interactive handler watch win size done"
)
logger
.
Debug
(
"Interactive handler watch win size done"
)
return
return
case
win
,
ok
:=
<-
winCh
:
case
win
,
ok
:=
<-
h
.
winChan
:
if
!
ok
{
if
!
ok
{
return
return
}
}
h
.
termHeight
,
h
.
termWidth
=
win
.
Height
,
win
.
Width
logger
.
Debugf
(
"Term window size change: %d*%d"
,
win
.
Height
,
win
.
Width
)
logger
.
Debugf
(
"Term window size change: %d*%d"
,
win
.
Height
,
win
.
Width
)
_
=
h
.
term
.
SetSize
(
win
.
Width
,
win
.
Height
)
_
=
h
.
term
.
SetSize
(
win
.
Width
,
win
.
Height
)
}
}
...
@@ -83,10 +89,9 @@ func (h *interactiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
...
@@ -83,10 +89,9 @@ func (h *interactiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
}
}
func
(
h
*
interactiveHandler
)
Dispatch
(
ctx
cctx
.
Context
)
{
func
(
h
*
interactiveHandler
)
Dispatch
(
ctx
cctx
.
Context
)
{
_
,
winCh
,
_
:=
h
.
sess
.
Pty
()
for
{
for
{
doneChan
:=
make
(
chan
struct
{})
doneChan
:=
make
(
chan
struct
{})
go
h
.
watchWinSizeChange
(
winCh
,
doneChan
)
go
h
.
watchWinSizeChange
(
doneChan
)
line
,
err
:=
h
.
term
.
ReadLine
()
line
,
err
:=
h
.
term
.
ReadLine
()
close
(
doneChan
)
close
(
doneChan
)
...
@@ -98,13 +103,12 @@ func (h *interactiveHandler) Dispatch(ctx cctx.Context) {
...
@@ -98,13 +103,12 @@ func (h *interactiveHandler) Dispatch(ctx cctx.Context) {
}
}
break
break
}
}
line
=
strings
.
TrimSpace
(
line
)
switch
len
(
line
)
{
switch
len
(
line
)
{
case
0
,
1
:
case
0
,
1
:
switch
strings
.
ToLower
(
line
)
{
switch
strings
.
ToLower
(
line
)
{
case
""
,
"p"
:
case
""
,
"p"
:
h
.
displayAssets
(
h
.
assets
)
h
.
displayAssets
(
h
.
assets
)
//h.Proxy(ctx)
case
"g"
:
case
"g"
:
h
.
displayNodes
(
h
.
nodes
)
h
.
displayNodes
(
h
.
nodes
)
case
"h"
:
case
"h"
:
...
@@ -210,19 +214,22 @@ func (h *interactiveHandler) displayAssets(assets model.AssetList) {
...
@@ -210,19 +214,22 @@ func (h *interactiveHandler) displayAssets(assets model.AssetList) {
if
len
(
assets
)
==
0
{
if
len
(
assets
)
==
0
{
_
,
_
=
io
.
WriteString
(
h
.
term
,
"
\r\n
No Assets
\r\n\r
"
)
_
,
_
=
io
.
WriteString
(
h
.
term
,
"
\r\n
No Assets
\r\n\r
"
)
}
else
{
}
else
{
table
:=
tablewriter
.
NewWriter
(
h
.
term
)
pageTerm
:=
terminal
.
NewTerminal
(
h
.
sess
,
":"
)
table
.
SetHeader
([]
string
{
"ID"
,
"Hostname"
,
"IP"
,
"LoginAs"
,
"Comment"
})
pag
:=
AssetPagination
{
for
index
,
assetItem
:=
range
assets
{
term
:
pageTerm
,
sysUserArray
:=
make
([]
string
,
len
(
assetItem
.
SystemUsers
))
TermWidth
:
h
.
termWidth
,
for
index
,
sysUser
:=
range
assetItem
.
SystemUsers
{
TermHeight
:
h
.
termHeight
,
sysUserArray
[
index
]
=
sysUser
.
Name
TotalNumber
:
len
(
assets
),
}
winChan
:
h
.
winChan
,
sysUsers
:=
"["
+
strings
.
Join
(
sysUserArray
,
" "
)
+
"]"
Data
:
assets
}
table
.
Append
([]
string
{
strconv
.
Itoa
(
index
+
1
),
assetItem
.
Hostname
,
assetItem
.
Ip
,
sysUsers
,
assetItem
.
Comment
})
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
()
}
}
}
}
...
@@ -335,6 +342,22 @@ func isSubstring(sArray []string, substr string) bool {
...
@@ -335,6 +342,22 @@ func isSubstring(sArray []string, substr string) bool {
return
false
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) {
//func (h *InteractiveHandler) JoinShareRoom(roomID string) {
//sshConn := userhome.NewSSHConn(h.sess)
//sshConn := userhome.NewSSHConn(h.sess)
//ctx, cancelFuc := context.WithCancel(h.sess.Context())
//ctx, cancelFuc := context.WithCancel(h.sess.Context())
...
...
pkg/model/assets.go
View file @
19d3d1be
...
@@ -158,7 +158,7 @@ func (s *systemUserSorter) Less(i, j int) bool {
...
@@ -158,7 +158,7 @@ func (s *systemUserSorter) Less(i, j int) bool {
}
}
func
systemUserPrioritySort
(
use1
,
user2
*
SystemUser
)
bool
{
func
systemUserPrioritySort
(
use1
,
user2
*
SystemUser
)
bool
{
return
use1
.
Priority
<
=
user2
.
Priority
return
use1
.
Priority
<
user2
.
Priority
}
}
func
SortSystemUserByPriority
(
users
[]
SystemUser
)
{
func
SortSystemUserByPriority
(
users
[]
SystemUser
)
{
...
...
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