-
Notifications
You must be signed in to change notification settings - Fork 1
Add a new dynamic IP function #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,8 @@ import ( | |
| "net" | ||
| "net/http" | ||
| "os" | ||
| "os/exec" | ||
| "strings" | ||
| "time" | ||
|
|
||
| "github.com/doubleunion/accesscontrol/door" | ||
|
|
@@ -19,6 +21,9 @@ import ( | |
| "golang.org/x/crypto/acme/autocert" | ||
| ) | ||
|
|
||
| const serviceFilePath = "/etc/systemd/system/accesscontrol.service" | ||
| const ipQueryURL = "https://wtfismyip.com/text" | ||
|
|
||
| var localInternetAddress = os.Getenv("LOCAL_INTERNET_ADDRESS") | ||
|
|
||
| func RunRouter() { | ||
|
|
@@ -111,3 +116,68 @@ func requireLocalNetworkMiddleware(next echo.HandlerFunc) echo.HandlerFunc { | |
| return next(c) | ||
| } | ||
| } | ||
|
|
||
| func UpdateIPAndRestart() error { | ||
| // Step 1: Query current IP address | ||
| resp, err := http.Get(ipQueryURL) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rather than relying on a 3rd party API, I think this could be simplified to do a DNS lookup, something like: ips, err := net.LookupIP("doubleunion.tplinkdns.com")
...(error handling)...
fmt.Printf("IP address: %s\n", ips[0].String())There should always just be a single IPv4 address in the result ( |
||
| if err != nil { | ||
| return err | ||
| } | ||
| defer resp.Body.Close() | ||
|
|
||
| ipBytes, err := io.ReadAll(resp.Body) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| currentIP := strings.TrimSpace(string(ipBytes)) | ||
|
|
||
| // Step 2: Read the service file | ||
| content, err := os.ReadFile(serviceFilePath) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Step 3: Check if the IP matches | ||
| lines := strings.Split(string(content), "\n") | ||
| var updatedContent []string | ||
| ipUpdated := false | ||
| for _, line := range lines { | ||
| if strings.HasPrefix(line, "Environment=LOCAL_INTERNET_ADDRESS=") { | ||
| fileIP := strings.TrimPrefix(line, "Environment=LOCAL_INTERNET_ADDRESS=") | ||
| if fileIP != currentIP { | ||
| line = "Environment=LOCAL_INTERNET_ADDRESS=" + currentIP | ||
| ipUpdated = true | ||
| } | ||
| } | ||
| updatedContent = append(updatedContent, line) | ||
| } | ||
|
|
||
| // Step 4: Update the file if necessary | ||
| if ipUpdated { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of editing the If there's still a compelling reason for a cache, it still might be cleaner to make a new file that we write just the IP to, and that we read it from at each app startup (instead of from ENV). Then instead of rebooting, you can just exit and wait for the service to restart the process. |
||
| // first we have to output the new contents to a temporary file | ||
| // because we don't have access to the service file directly | ||
| tempFilePath := "/tmp/accesscontrol.service" | ||
| err = os.WriteFile(tempFilePath, []byte(strings.Join(updatedContent, "\n")), 0644) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // then we copy the temporary file to the service file path | ||
| // the path is owned by the process user so this is allowed by the OS without sudo | ||
| cmd := exec.Command("cp", tempFilePath, serviceFilePath) | ||
| err = cmd.Run() | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Step 5: Restart the Raspberry Pi | ||
| cmd = exec.Command("sudo", "shutdown", "-r", "now") | ||
| //log.Printf("Error in updateIPAndRestart: %v", err) | ||
| err = cmd.Run() | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small suggestion – it might be cleaner to move this to the router module, and put all the logic around it in a new file
e.g.
dynamic_ip.gomight have: