Skip to content

Commit

Permalink
Get Process Ports
Browse files Browse the repository at this point in the history
  • Loading branch information
F1bonacc1 committed Jul 20, 2023
1 parent 43ac3cc commit c51b8a7
Show file tree
Hide file tree
Showing 18 changed files with 231 additions and 39 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/InVisionApp/go-health/v2 v2.1.3
github.com/adrg/xdg v0.4.0
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
github.com/f1bonacc1/glippy v0.0.0-20230203184233-82c6562cecd1
github.com/fatih/color v1.15.0
github.com/gdamore/tcell/v2 v2.6.0
Expand All @@ -16,10 +17,13 @@ require (
github.com/spf13/cobra v1.7.0
github.com/swaggo/swag v1.16.1
gopkg.in/yaml.v2 v2.4.0
//github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
)

replace github.com/InVisionApp/go-health/v2 => github.com/f1bonacc1/go-health/v2 v2.1.3

replace github.com/cakturk/go-netstat => github.com/mololab/netstat v0.0.0-20221129160431-27c9226a45b1

require (
github.com/InVisionApp/go-logger v1.0.1 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/InVisionApp/go-logger v1.0.1 h1:WFL19PViM1mHUmUWfsv5zMo379KSWj2MRmBlz
github.com/InVisionApp/go-logger v1.0.1/go.mod h1:+cGTDSn+P8105aZkeOfIhdd7vFO5X1afUHcjvanY0L8=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
Expand All @@ -14,6 +16,8 @@ github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQ
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g=
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
Expand Down Expand Up @@ -128,6 +132,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
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/mololab/netstat v0.0.0-20221129160431-27c9226a45b1 h1:3k8Fbl7pFlde2/847ox7l/Wqql9Ww644JsQoPaY3/1o=
github.com/mololab/netstat v0.0.0-20221129160431-27c9226a45b1/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down
32 changes: 2 additions & 30 deletions process-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,36 +84,8 @@ processes:
success_threshold: 1
failure_threshold: 3

# nginx:
# command: "docker run -d --rm -p80:80 --name nginx_test nginx"
# # availability:
# # restart: on_failure
# is_daemon: true
# shutdown:
# command: "docker stop nginx_test"
# signal: 15
# timeout_seconds: 5
# liveness_probe:
# exec:
# command: "[ $(docker inspect -f '{{.State.Running}}' nginx_test) = 'true' ]"
# initial_delay_seconds: 5
# period_seconds: 2
# timeout_seconds: 5
# success_threshold: 1
# failure_threshold: 3
# readiness_probe:
# http_get:
# host: 127.0.0.1
# path: "/"
# port: 80
# initial_delay_seconds: 5
# period_seconds: 10
# timeout_seconds: 5
# success_threshold: 1
# failure_threshold: 3
# availability:
# restart: "always"
# backoff_seconds: 2
server:
command: "python3 -m http.server 4040"

kcalc:
command: "kcalc"
Expand Down
20 changes: 20 additions & 0 deletions src/api/pc_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,23 @@ func (api *PcApi) GetHostName(c *gin.Context) {

c.JSON(http.StatusOK, gin.H{"name": name})
}

// @Schemes
// @Description Retrieves process open ports
// @Tags Process
// @Summary Get process ports
// @Produce json
// @Param name path string true "Process Name"
// @Success 200 {object} object "Process Ports"
// @Router /process/ports/{name} [get]
func (api *PcApi) GetProcessPorts(c *gin.Context) {
name := c.Param("name")

ports, err := api.project.GetProcessPorts(name)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, ports)
}
1 change: 1 addition & 0 deletions src/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func InitRoutes(useLogger bool, handler *PcApi) *gin.Engine {
r.GET("/processes", handler.GetProcesses)
r.GET("/process/:name", handler.GetProcess)
r.GET("/process/info/:name", handler.GetProcessInfo)
r.GET("/process/ports/:name", handler.GetProcessPorts)
r.GET("/process/logs/:name/:endOffset/:limit", handler.GetProcessLogs)
r.PATCH("/process/stop/:name", handler.StopProcess)
r.POST("/process/start/:name", handler.StartProcess)
Expand Down
20 changes: 19 additions & 1 deletion src/app/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"context"
"fmt"
"github.com/cakturk/go-netstat/netstat"
"github.com/f1bonacc1/process-compose/src/types"
"io"
"math/rand"
Expand Down Expand Up @@ -160,7 +161,7 @@ func (p *Process) getBackoff() time.Duration {

func (p *Process) getProcessEnvironment() []string {
env := []string{
"PC_PROC_NAME=" + p.getName(),
"PC_PROC_NAME=" + p.procConf.Name,
"PC_REPLICA_NUM=" + strconv.Itoa(p.procConf.ReplicaNum),
}
env = append(env, os.Environ()...)
Expand Down Expand Up @@ -528,3 +529,20 @@ func (p *Process) validateProcess() error {
}
return nil
}

func (p *Process) getOpenPorts(ports *types.ProcessPorts) error {
socks, err := netstat.TCPSocks(func(s *netstat.SockTabEntry) bool {
return s.State == netstat.Listen
})
if err != nil {
log.Err(err).Msgf("failed to get open ports for %s", p.getName())
return err
}
for _, e := range socks {
if e.Process != nil && e.Process.Pid == p.procState.Pid {
log.Debug().Msgf("%s is listening on %d", p.getName(), e.LocalAddr.Port)
ports.TcpPorts = append(ports.TcpPorts, e.LocalAddr.Port)
}
}
return nil
}
1 change: 1 addition & 0 deletions src/app/project_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ type IProject interface {
StartProcess(name string) error
RestartProcess(name string) error
ScaleProcess(name string, scale int) error
GetProcessPorts(name string) (*types.ProcessPorts, error)
}
18 changes: 18 additions & 0 deletions src/app/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,24 @@ func (p *ProjectRunner) GetProcessInfo(name string) (*types.ProcessConfig, error
}
}

func (p *ProjectRunner) GetProcessPorts(name string) (*types.ProcessPorts, error) {
proc := p.getRunningProcess(name)
if proc == nil {
return nil, fmt.Errorf("can't get ports: process %s is not running", name)
}

ports := &types.ProcessPorts{
Name: name,
TcpPorts: make([]uint16, 0),
UdpPorts: make([]uint16, 0),
}
err := proc.getOpenPorts(ports)
if err != nil {
return nil, err
}
return ports, nil
}

func (p *ProjectRunner) ShutDownProject() {
p.runProcMutex.Lock()
defer p.runProcMutex.Unlock()
Expand Down
7 changes: 5 additions & 2 deletions src/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ func (p *PcClient) GetLexicographicProcessNames() ([]string, error) {
}

func (p *PcClient) GetProcessInfo(name string) (*types.ProcessConfig, error) {
config, err := GetProcessInfo(p.address, p.port, name)
return config, err
return GetProcessInfo(p.address, p.port, name)
}

func (p *PcClient) GetProcessPorts(name string) (*types.ProcessPorts, error) {
return GetProcessPorts(p.address, p.port, name)
}

func (p *PcClient) GetProcessState(name string) (*types.ProcessState, error) {
Expand Down
19 changes: 18 additions & 1 deletion src/client/processes.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ func GetProcessInfo(address string, port int, name string) (*types.ProcessConfig
return nil, err
}
defer resp.Body.Close()
//Create a variable of the same type as our model
var sResp types.ProcessConfig

//Decode the data
Expand All @@ -76,3 +75,21 @@ func GetProcessInfo(address string, port int, name string) (*types.ProcessConfig

return &sResp, nil
}

func GetProcessPorts(address string, port int, name string) (*types.ProcessPorts, error) {
url := fmt.Sprintf("http://%s:%d/process/ports/%s", address, port, name)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var sResp types.ProcessPorts

//Decode the data
if err := json.NewDecoder(resp.Body).Decode(&sResp); err != nil {
log.Err(err).Msgf("what I got: %s", err.Error())
return nil, err
}

return &sResp, nil
}
30 changes: 30 additions & 0 deletions src/cmd/ports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cmd

import (
"fmt"
"github.com/f1bonacc1/process-compose/src/client"
"github.com/rs/zerolog/log"

"github.com/spf13/cobra"
)

// portsCmd represents the ports command
var portsCmd = &cobra.Command{
Use: "ports [PROCESS]",
Short: "Get the ports that a process is listening on",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
name := args[0]
ports, err := client.GetProcessPorts(pcAddress, port, name)
if err != nil {
logFatal(err, "failed to get process %s ports", name)
return
}
log.Info().Msgf("Process %s TCP ports: %v", name, ports.TcpPorts)
fmt.Printf("Process %s TCP ports: %v\n", name, ports.TcpPorts)
},
}

func init() {
processCmd.AddCommand(portsCmd)
}
8 changes: 8 additions & 0 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"fmt"
"github.com/f1bonacc1/process-compose/src/api"
"github.com/f1bonacc1/process-compose/src/loader"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -79,3 +80,10 @@ func getConfigDefault() []string {
}
return []string{}
}

func logFatal(err error, format string, args ...interface{}) {
fmt.Printf(format, args...)
fmt.Printf(": %v\n", err)
log.Err(err).Msgf(format, args...)
os.Exit(1)
}
29 changes: 29 additions & 0 deletions src/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,35 @@ const docTemplate = `{
}
}
},
"/process/ports/{name}": {
"get": {
"description": "Retrieves process open ports",
"produces": [
"application/json"
],
"tags": [
"Process"
],
"summary": "Get process ports",
"parameters": [
{
"type": "string",
"description": "Process Name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Process Ports",
"schema": {
"type": "object"
}
}
}
}
},
"/process/restart/{name}": {
"post": {
"description": "Restarts the process",
Expand Down
29 changes: 29 additions & 0 deletions src/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,35 @@
}
}
},
"/process/ports/{name}": {
"get": {
"description": "Retrieves process open ports",
"produces": [
"application/json"
],
"tags": [
"Process"
],
"summary": "Get process ports",
"parameters": [
{
"type": "string",
"description": "Process Name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Process Ports",
"schema": {
"type": "object"
}
}
}
}
},
"/process/restart/{name}": {
"post": {
"description": "Restarts the process",
Expand Down
19 changes: 19 additions & 0 deletions src/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ paths:
summary: Get process logs
tags:
- Process
/process/ports/{name}:
get:
description: Retrieves process open ports
parameters:
- description: Process Name
in: path
name: name
required: true
type: string
produces:
- application/json
responses:
"200":
description: Process Ports
schema:
type: object
summary: Get process ports
tags:
- Process
/process/restart/{name}:
post:
description: Restarts the process
Expand Down
Loading

0 comments on commit c51b8a7

Please sign in to comment.