@@ -3,11 +3,14 @@ package main
33import (
44 "fmt"
55 "os/user"
6+ "strings"
67
78 "github.com/devetek/d-panel-cli/internal/api"
89 "github.com/devetek/d-panel-cli/internal/helper"
910 "github.com/devetek/d-panel-cli/internal/logger"
11+ "github.com/devetek/d-panel-cli/internal/tunnel"
1012 "github.com/devetek/d-panel/pkg/dmachine"
13+ "github.com/devetek/d-panel/pkg/drouter"
1114 "github.com/devetek/d-panel/pkg/dsecret"
1215 "github.com/spf13/cobra"
1316 "go.uber.org/zap"
@@ -20,6 +23,13 @@ type MachineCmd struct {
2023 sshIP string
2124 sshPort string
2225 httpPort string
26+ // use behind tunnel if this machine is behind NAT without public IP
27+ behindTunnel bool
28+ // used when your machine want to expose dPanel agent behind proxy
29+ // this option used by dPanel to access your machine, example input:
30+ // - http://my-machine-01.devetek.app -> for insecure connection / HTTP
31+ // - https://my-machine-01.devetek.app -> for Secure connection / HTTPS
32+ domain string
2333}
2434
2535func NewMachineCmd (logger * zap.Logger ) * MachineCmd {
@@ -48,7 +58,7 @@ func (m *MachineCmd) create() *cobra.Command {
4858 Run : func (cmd * cobra.Command , args []string ) {
4959 // check if user has sudo access in golang
5060 if ! helper .IsSudo () {
51- logger .Error ("You must run this command as sudo" )
61+ logger .Error ("You must run this command as sudo, currenty dpanel-agent required to running under root " )
5262 return
5363 }
5464
@@ -58,7 +68,7 @@ func (m *MachineCmd) create() *cobra.Command {
5868 // check if session exist
5969 err := client .CheckSessionExist ()
6070 if err != nil {
61- logger .Error ("Error check session exist: " + err . Error () )
71+ logger .Error ("Please login to your dPanel account, use command 'dnocs auth login --email= \" email@email.com \" --password= \" password \" '" )
6272 return
6373 }
6474
@@ -104,25 +114,27 @@ func (m *MachineCmd) create() *cobra.Command {
104114 }
105115 }
106116
107- // make sure sshIP is not empty
108- if m .sshIP == "" {
109- // get my public IP automatically
110- m .sshIP , err = helper .GetMyIP ()
111- if err != nil {
112- logger .Error ("Error get my public IP " + err .Error ())
113- return
117+ if ! m .behindTunnel {
118+ // make sure sshIP is not empty
119+ if m .sshIP == "" {
120+ // get my public IP automatically
121+ m .sshIP , err = helper .GetMyIP ()
122+ if err != nil {
123+ logger .Error ("Error get my public IP " + err .Error ())
124+ return
125+ }
114126 }
115- }
116127
117- if m .httpPort == "" {
118- // get available port
119- availablePort , err := helper .FindAvailablePort ()
120- if err != nil {
121- logger .Error ("Error get available port + " + err .Error ())
122- return
123- }
128+ if m .httpPort == "" {
129+ // get available port
130+ availablePort , err := helper .FindAvailablePort ()
131+ if err != nil {
132+ logger .Error ("Error get available port + " + err .Error ())
133+ return
134+ }
124135
125- m .httpPort = fmt .Sprintf ("%d" , availablePort )
136+ m .httpPort = fmt .Sprintf ("%d" , availablePort )
137+ }
126138 }
127139
128140 currentUser , err := user .Current ()
@@ -131,18 +143,69 @@ func (m *MachineCmd) create() *cobra.Command {
131143 return
132144 }
133145
146+ // integrate with tunnel
147+ if m .behindTunnel {
148+ var currentTunnel = tunnel .NewTunnel ()
149+
150+ // check tunnel configs
151+ var tunnelConfig = currentTunnel .GetConfig ()
152+ if len (tunnelConfig ) == 0 {
153+ logger .Error ("This machine is not connected to dPanel tunnel" )
154+ return
155+ }
156+
157+ var tunnelHTTPPort string
158+ var originHTTPPort string
159+ for _ , tunnel := range tunnelConfig {
160+ if strings .Contains (tunnel .ID , "ssh-" ) {
161+ m .sshIP = tunnel .TunnelHost
162+ m .sshPort = tunnel .ListenerPort
163+ }
164+
165+ if strings .Contains (tunnel .ID , "http-" ) {
166+ tunnelHTTPPort = tunnel .ListenerPort
167+ originHTTPPort = tunnel .ServicePort
168+ }
169+ }
170+
171+ // set payload
172+ var payload = drouter.PayloadRouter {
173+ AdvanceMode : false ,
174+ Type : "proxy_pass" ,
175+ Name : fmt .Sprintf ("http-%s-to-%s" , tunnelHTTPPort , originHTTPPort ),
176+ Domain : fmt .Sprintf ("http-%s-to-%s 1" , tunnelHTTPPort , originHTTPPort ),
177+ MachineID : 11 ,
178+ Upstream : fmt .Sprintf ("localhost:%s" , tunnelHTTPPort ),
179+ }
180+
181+ router , err := client .CreateRouter (payload )
182+ if err != nil {
183+ logger .Error ("Failed to create HTTP server for this machine, with error " + err .Error ())
184+ logger .Error ("Login to dPanel, open https://cloud-beta.terpusat.com/router, and delete existing domain" )
185+ return
186+ }
187+
188+ // set domain for this machine
189+ m .httpPort = tunnelHTTPPort
190+ m .domain = router .Data .Domain
191+ }
192+
134193 // register new server
135194 newServer := dmachine.Payload {
136195 Provider : "other" ,
137196 SecretID : fmt .Sprintf ("%d" , mySSHKey .ID ),
138197 Address : m .sshIP ,
139198 SSHPort : m .sshPort ,
140199 HTTPPort : m .httpPort ,
141- Domain : "" ,
200+ Domain : m . domain ,
142201 SSHUser : currentUser .Username ,
143202 }
144203
145- // TODO: Create file ~/.devetek/machine.json to prevent multiple registration
204+ // check if server already registered
205+ if client .IsRegistered () {
206+ logger .Error ("Server already registered with your account" )
207+ return
208+ }
146209
147210 // register new server
148211 server , err := client .RegisterServer (newServer )
@@ -164,7 +227,9 @@ func (m *MachineCmd) create() *cobra.Command {
164227
165228 runCmd .PersistentFlags ().StringVarP (& m .sshIP , "ssh-ip" , "i" , "" , "SSH IP of your machine" )
166229 runCmd .PersistentFlags ().StringVarP (& m .sshPort , "ssh-port" , "s" , "22" , "SSH port of your machine" )
167- runCmd .PersistentFlags ().StringVarP (& m .httpPort , "http-port" , "t" , "9000" , "HTTP port of your machine" )
230+ runCmd .PersistentFlags ().StringVarP (& m .httpPort , "http-port" , "p" , "9000" , "HTTP port of your machine" )
231+ runCmd .PersistentFlags ().StringVarP (& m .domain , "http-domain" , "d" , "" , "HTTP domain of agent (optional)" )
232+ runCmd .PersistentFlags ().BoolVarP (& m .behindTunnel , "behind-tunnel" , "t" , false , "Read tunnel config and auto create domain" )
168233
169234 return runCmd
170235}
0 commit comments