Commit c35246804fff2e5be6f4302d89a1d7b48c8c891f
1 parent
476d2547ea
Exists in
master
기능 추가 및 변경
- 네트워크 설정 페이지 추가 - 기존 IP 주소 설정 항목 제거 - 추가된 페이지에 이더넷 주소, IP 주소, 넷마스크, 게이트웨이 설정 항목 추가 - 실행 명령줄 인자로 네트워크 인터페이스 갯수 설정 - 인자에 "-dual"을 추가하면 네트워크 인터페이스 갯수가 2개인 것으로 동작 - 실행 명령줄 인자로 장치 이름 설정하는 방법 변경 - 인자에 "-device "<장치 이름>""을 추가하는 방법으로 변경 (기존은 첫 번째 인자를 그대로 사용)
Showing
4 changed files
with
234 additions
and
104 deletions
Show diff stats
go/src/themaru/http.go
... | ... | @@ -3,7 +3,6 @@ package main |
3 | 3 | import ( |
4 | 4 | "html/template" |
5 | 5 | "net/http" |
6 | - "os" | |
7 | 6 | "sync" |
8 | 7 | |
9 | 8 | "github.com/gin-contrib/multitemplate" |
... | ... | @@ -23,17 +22,9 @@ var indexPage = template.Must(template.New("index.html").Parse(` |
23 | 22 | <body> |
24 | 23 | <h1>{{.Device}} Configuration</h1> |
25 | 24 | <div> |
26 | - <p>System Version: {{.Version}}</p> | |
25 | + <p>System Version: {{.falinux_version}}</p> | |
27 | 26 | </div> |
28 | 27 | <hr> |
29 | - <h1>Setting IP Address</h1> | |
30 | - <div> | |
31 | - <form action="/address" method="post"> | |
32 | - <input type="text" name="address" value="{{.IP}}" required /> | |
33 | - <input type="text" name="address2" value="{{.IP2}}" required /> | |
34 | - <input type="submit" value="Set" /> | |
35 | - </form> | |
36 | - </div> | |
37 | 28 | <h1>Updating System</h1> |
38 | 29 | <div> |
39 | 30 | <form action="/system" method="post" enctype="multipart/form-data"> |
... | ... | @@ -58,6 +49,101 @@ var indexPage = template.Must(template.New("index.html").Parse(` |
58 | 49 | </html> |
59 | 50 | `)) |
60 | 51 | |
52 | +var networkPage = template.Must(template.New("network.html").Parse(` | |
53 | +<html> | |
54 | +<head> | |
55 | + <title>Network Configuration</title> | |
56 | + <style type="text/css"> | |
57 | + div { margin-left: 20px; } | |
58 | + </style> | |
59 | +</head> | |
60 | +<body> | |
61 | + <form action="/network" method="post"> | |
62 | + <h1>Setting Network</h1> | |
63 | + <div> | |
64 | + <p> | |
65 | + <label for="ethaddr">Ethernet Address</label><br /> | |
66 | + <input type="text" id="ethaddr" name="ethaddr" value="{{.ethaddr}}" required /> | |
67 | + </p> | |
68 | + <p> | |
69 | + <label for="ipaddr">IP Address</label><br /> | |
70 | + <input type="text" id="ipaddr" name="ipaddr" value="{{.ipaddr}}" required /> | |
71 | + </p> | |
72 | + <p> | |
73 | + <label for="netmask">Netmask</label><br /> | |
74 | + <input type="text" id="netmask" name="netmask" value="{{.netmask}}" required /> | |
75 | + </p> | |
76 | + <p> | |
77 | + <label for="gateway">Gateway</label><br /> | |
78 | + <input type="text" id="gateway" name="gateway" value="{{.gateway}}" required /> | |
79 | + </p> | |
80 | + </div> | |
81 | + <label for="submit"><h1>Click to Apply</h1></label> | |
82 | + <div> | |
83 | + <p><input id="submit" type="submit" value="Set" /></p> | |
84 | + </div> | |
85 | + </form> | |
86 | +</body> | |
87 | +</html> | |
88 | +`)) | |
89 | + | |
90 | +var networkPageDual = template.Must(template.New("network.html").Parse(` | |
91 | +<html> | |
92 | +<head> | |
93 | + <title>Network Configuration</title> | |
94 | + <style type="text/css"> | |
95 | + div { margin-left: 20px; } | |
96 | + </style> | |
97 | +</head> | |
98 | +<body> | |
99 | + <form action="/network" method="post"> | |
100 | + <h1>Setting Network</h1> | |
101 | + <div> | |
102 | + <p> | |
103 | + <label for="ethaddr">Ethernet Address</label><br /> | |
104 | + <input type="text" id="ethaddr" name="ethaddr" value="{{.ethaddr}}" required /> | |
105 | + </p> | |
106 | + <p> | |
107 | + <label for="ipaddr">IP Address</label><br /> | |
108 | + <input type="text" id="ipaddr" name="ipaddr" value="{{.ipaddr}}" required /> | |
109 | + </p> | |
110 | + <p> | |
111 | + <label for="netmask">Netmask</label><br /> | |
112 | + <input type="text" id="netmask" name="netmask" value="{{.netmask}}" required /> | |
113 | + </p> | |
114 | + <p> | |
115 | + <label for="gateway">Gateway</label><br /> | |
116 | + <input type="text" id="gateway" name="gateway" value="{{.gateway}}" required /> | |
117 | + </p> | |
118 | + </div> | |
119 | + <h1>Setting Network 2</h1> | |
120 | + <div> | |
121 | + <p> | |
122 | + <label for="ethaddr2">Ethernet Address</label><br /> | |
123 | + <input type="text" id="ethaddr2" name="ethaddr2" value="{{.ethaddr2}}" required /> | |
124 | + </p> | |
125 | + <p> | |
126 | + <label for="ipaddr2">IP Address</label><br /> | |
127 | + <input type="text" id="ipaddr2" name="ipaddr2" value="{{.ipaddr2}}" required /> | |
128 | + </p> | |
129 | + <p> | |
130 | + <label for="netmask2">Netmask</label><br /> | |
131 | + <input type="text" id="netmask2" name="netmask2" value="{{.netmask2}}" required /> | |
132 | + </p> | |
133 | + <p> | |
134 | + <label for="gateway2">Gateway</label><br /> | |
135 | + <input type="text" id="gateway2" name="gateway2" value="{{.gateway2}}" required /> | |
136 | + </p> | |
137 | + </div> | |
138 | + <label for="submit"><h1>Click to Apply</h1></label> | |
139 | + <div> | |
140 | + <p><input id="submit" type="submit" value="Set" /></p> | |
141 | + </div> | |
142 | + </form> | |
143 | +</body> | |
144 | +</html> | |
145 | +`)) | |
146 | + | |
61 | 147 | var rebootPage = template.Must(template.New("reboot.html").Parse(` |
62 | 148 | <html> |
63 | 149 | <head> |
... | ... | @@ -81,11 +167,18 @@ func runHttp() { |
81 | 167 | r.Add("index.html", indexPage) |
82 | 168 | r.Add("reboot.html", rebootPage) |
83 | 169 | |
170 | + if hasDualNetwork { | |
171 | + r.Add("network.html", networkPageDual) | |
172 | + } else { | |
173 | + r.Add("network.html", networkPage) | |
174 | + } | |
175 | + | |
84 | 176 | g.HTMLRender = r |
85 | 177 | |
86 | 178 | g.GET("/", renderIndex) |
179 | + g.GET("/network", renderNetwork) | |
87 | 180 | |
88 | - g.POST("/address", handleAddress) | |
181 | + g.POST("/network", handleNetwork) | |
89 | 182 | g.POST("/system", handleSystem) |
90 | 183 | g.POST("/application", handleApplication) |
91 | 184 | |
... | ... | @@ -95,19 +188,26 @@ func runHttp() { |
95 | 188 | g.Run(":8988") |
96 | 189 | } |
97 | 190 | |
98 | -func handleAddress(c *gin.Context) { | |
191 | +func handleNetwork(c *gin.Context) { | |
99 | 192 | mu.Lock() |
100 | 193 | defer mu.Unlock() |
101 | 194 | |
102 | - addr := c.PostForm("address") | |
103 | - addr2 := c.PostForm("address2") | |
195 | + keyList := []string{"ethaddr", "ipaddr", "netmask", "gateway"} | |
196 | + if hasDualNetwork { | |
197 | + keyList = append(keyList, "ethaddr2", "ipaddr2", "netmask2", "gateway2") | |
198 | + } | |
199 | + | |
200 | + env := map[string]string{} | |
201 | + for _, key := range keyList { | |
202 | + env[key] = c.PostForm(key) | |
203 | + } | |
104 | 204 | |
105 | - if err := setIpAddress(addr, addr2); err != nil { | |
106 | - c.String(http.StatusBadRequest, "address: setIpAddress: %s", err.Error()) | |
205 | + if err := setNetwork(env); err != nil { | |
206 | + c.String(http.StatusBadRequest, "network: setNetwork: %s", err.Error()) | |
107 | 207 | return |
108 | 208 | } |
109 | 209 | |
110 | - c.HTML(http.StatusOK, "reboot.html", gin.H{"Message": "IP address is updated."}) | |
210 | + c.HTML(http.StatusOK, "reboot.html", gin.H{"Message": "Network is configured."}) | |
111 | 211 | } |
112 | 212 | |
113 | 213 | func handleSystem(c *gin.Context) { |
... | ... | @@ -160,17 +260,16 @@ func handleRestore(c *gin.Context) { |
160 | 260 | } |
161 | 261 | |
162 | 262 | func renderIndex(c *gin.Context) { |
163 | - device := "System" | |
164 | - if len(os.Args) > 1 { | |
165 | - device = os.Args[1] | |
166 | - } | |
263 | + env, _ := getEnv(1) | |
264 | + env["Device"] = deviceName | |
265 | + | |
266 | + c.HTML(http.StatusOK, "index.html", env) | |
267 | +} | |
268 | + | |
269 | +func renderNetwork(c *gin.Context) { | |
270 | + env, _ := getEnv(0) | |
167 | 271 | |
168 | - c.HTML(http.StatusOK, "index.html", gin.H{ | |
169 | - "Device": device, | |
170 | - "IP": getIpAddress(), | |
171 | - "IP2": getIpAddress2(), | |
172 | - "Version": getVersion(), | |
173 | - }) | |
272 | + c.HTML(http.StatusOK, "network.html", env) | |
174 | 273 | } |
175 | 274 | |
176 | 275 | func saveFormFile(c *gin.Context, name string, dst string) error { | ... | ... |
go/src/themaru/ip.go
... | ... | @@ -1,77 +0,0 @@ |
1 | -package main | |
2 | - | |
3 | -import ( | |
4 | - "errors" | |
5 | - "regexp" | |
6 | - "strconv" | |
7 | -) | |
8 | - | |
9 | -func getIpAddress() string { | |
10 | - env, err := getEnv(0) | |
11 | - if err != nil { | |
12 | - return "" | |
13 | - } | |
14 | - | |
15 | - return env["ipaddr"] | |
16 | -} | |
17 | - | |
18 | -func getIpAddress2() string { | |
19 | - env, err := getEnv(0) | |
20 | - if err != nil { | |
21 | - return "" | |
22 | - } | |
23 | - | |
24 | - return env["ipaddr2"] | |
25 | -} | |
26 | - | |
27 | -func setIpAddress(address, address2 string) error { | |
28 | - address = extractIpAddress(address) | |
29 | - if address == "" { | |
30 | - return errors.New("invalid IP address") | |
31 | - } | |
32 | - | |
33 | - address2 = extractIpAddress(address2) | |
34 | - if address2 == "" { | |
35 | - return errors.New("invalid IP address2") | |
36 | - } | |
37 | - | |
38 | - env, err := getEnv(0) | |
39 | - if err != nil { | |
40 | - return err | |
41 | - } | |
42 | - | |
43 | - env["ipaddr"] = address | |
44 | - env["ipaddr2"] = address2 | |
45 | - | |
46 | - err = setEnv(0, env) | |
47 | - if err != nil { | |
48 | - return err | |
49 | - } | |
50 | - | |
51 | - return nil | |
52 | -} | |
53 | - | |
54 | -func extractIpAddress(address string) string { | |
55 | - r := regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)`) | |
56 | - s := r.FindStringSubmatch(address) | |
57 | - if len(s) != 5 { | |
58 | - return "" | |
59 | - } | |
60 | - | |
61 | - for i, v := range s { | |
62 | - if i == 0 { | |
63 | - continue | |
64 | - } | |
65 | - | |
66 | - u, err := strconv.ParseUint(v, 10, 8) | |
67 | - if err != nil { | |
68 | - return "" | |
69 | - } | |
70 | - | |
71 | - if u > 255 { | |
72 | - return "" | |
73 | - } | |
74 | - } | |
75 | - | |
76 | - return s[0] | |
77 | -} |
go/src/themaru/main.go
1 | 1 | package main |
2 | 2 | |
3 | +import ( | |
4 | + "flag" | |
5 | +) | |
6 | + | |
7 | +var deviceName string | |
8 | +var hasDualNetwork bool | |
9 | + | |
10 | +func init() { | |
11 | + flag.StringVar(&deviceName, "device", "System", "Set device name") | |
12 | + flag.BoolVar(&hasDualNetwork, "dual", false, "Set if it has dual network") | |
13 | + flag.Parse() | |
14 | +} | |
15 | + | |
3 | 16 | func main() { |
4 | 17 | runHttp() |
5 | 18 | } | ... | ... |
go/src/themaru/network.go
... | ... | @@ -0,0 +1,95 @@ |
1 | +package main | |
2 | + | |
3 | +import ( | |
4 | + "errors" | |
5 | + "regexp" | |
6 | + "strconv" | |
7 | +) | |
8 | + | |
9 | +func setNetwork(env map[string]string) error { | |
10 | + if ok := validateEthernetAddr(env["ethaddr"]); !ok { | |
11 | + return errors.New("invalid ethernet address") | |
12 | + } | |
13 | + | |
14 | + if ok := validateIpAddr(env["ipaddr"]); !ok { | |
15 | + return errors.New("invalid ip address") | |
16 | + } | |
17 | + | |
18 | + if ok := validateIpAddr(env["netmask"]); !ok { | |
19 | + return errors.New("invalid netmask") | |
20 | + } | |
21 | + | |
22 | + if ok := validateIpAddr(env["gateway"]); !ok { | |
23 | + return errors.New("invalid gateway") | |
24 | + } | |
25 | + | |
26 | + if hasDualNetwork { | |
27 | + if ok := validateEthernetAddr(env["ethaddr2"]); !ok { | |
28 | + return errors.New("invalid ethernet address 2") | |
29 | + } | |
30 | + | |
31 | + if ok := validateIpAddr(env["ipaddr2"]); !ok { | |
32 | + return errors.New("invalid ip address 2") | |
33 | + } | |
34 | + | |
35 | + if ok := validateIpAddr(env["netmask2"]); !ok { | |
36 | + return errors.New("invalid netmask 2") | |
37 | + } | |
38 | + | |
39 | + if ok := validateIpAddr(env["gateway2"]); !ok { | |
40 | + return errors.New("invalid gateway 2") | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + return setEnv(0, env) | |
45 | +} | |
46 | + | |
47 | +func validateEthernetAddr(addr string) (ok bool) { | |
48 | + r := regexp.MustCompile(`([0-9a-fA-F]{2}):([0-9a-fA-F]{2}):([0-9a-fA-F]{2}):([0-9a-fA-F]{2}):([0-9a-fA-F]{2}):([0-9a-fA-F]{2})`) | |
49 | + s := r.FindStringSubmatch(addr) | |
50 | + if len(s) != 7 || s[0] != addr { | |
51 | + return false | |
52 | + } | |
53 | + | |
54 | + for i, v := range s { | |
55 | + if i == 0 { | |
56 | + continue | |
57 | + } | |
58 | + | |
59 | + u, err := strconv.ParseUint(v, 16, 8) | |
60 | + if err != nil { | |
61 | + return false | |
62 | + } | |
63 | + | |
64 | + if u > 255 { | |
65 | + return false | |
66 | + } | |
67 | + } | |
68 | + | |
69 | + return true | |
70 | +} | |
71 | + | |
72 | +func validateIpAddr(addr string) (ok bool) { | |
73 | + r := regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)`) | |
74 | + s := r.FindStringSubmatch(addr) | |
75 | + if len(s) != 5 || s[0] != addr { | |
76 | + return false | |
77 | + } | |
78 | + | |
79 | + for i, v := range s { | |
80 | + if i == 0 { | |
81 | + continue | |
82 | + } | |
83 | + | |
84 | + u, err := strconv.ParseUint(v, 10, 8) | |
85 | + if err != nil { | |
86 | + return false | |
87 | + } | |
88 | + | |
89 | + if u > 255 { | |
90 | + return false | |
91 | + } | |
92 | + } | |
93 | + | |
94 | + return true | |
95 | +} | ... | ... |