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,7 +3,6 @@ package main | ||
3 | import ( | 3 | import ( |
4 | "html/template" | 4 | "html/template" |
5 | "net/http" | 5 | "net/http" |
6 | - "os" | ||
7 | "sync" | 6 | "sync" |
8 | 7 | ||
9 | "github.com/gin-contrib/multitemplate" | 8 | "github.com/gin-contrib/multitemplate" |
@@ -23,17 +22,9 @@ var indexPage = template.Must(template.New("index.html").Parse(` | @@ -23,17 +22,9 @@ var indexPage = template.Must(template.New("index.html").Parse(` | ||
23 | <body> | 22 | <body> |
24 | <h1>{{.Device}} Configuration</h1> | 23 | <h1>{{.Device}} Configuration</h1> |
25 | <div> | 24 | <div> |
26 | - <p>System Version: {{.Version}}</p> | 25 | + <p>System Version: {{.falinux_version}}</p> |
27 | </div> | 26 | </div> |
28 | <hr> | 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 | <h1>Updating System</h1> | 28 | <h1>Updating System</h1> |
38 | <div> | 29 | <div> |
39 | <form action="/system" method="post" enctype="multipart/form-data"> | 30 | <form action="/system" method="post" enctype="multipart/form-data"> |
@@ -58,6 +49,101 @@ var indexPage = template.Must(template.New("index.html").Parse(` | @@ -58,6 +49,101 @@ var indexPage = template.Must(template.New("index.html").Parse(` | ||
58 | </html> | 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 | var rebootPage = template.Must(template.New("reboot.html").Parse(` | 147 | var rebootPage = template.Must(template.New("reboot.html").Parse(` |
62 | <html> | 148 | <html> |
63 | <head> | 149 | <head> |
@@ -81,11 +167,18 @@ func runHttp() { | @@ -81,11 +167,18 @@ func runHttp() { | ||
81 | r.Add("index.html", indexPage) | 167 | r.Add("index.html", indexPage) |
82 | r.Add("reboot.html", rebootPage) | 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 | g.HTMLRender = r | 176 | g.HTMLRender = r |
85 | 177 | ||
86 | g.GET("/", renderIndex) | 178 | g.GET("/", renderIndex) |
179 | + g.GET("/network", renderNetwork) | ||
87 | 180 | ||
88 | - g.POST("/address", handleAddress) | 181 | + g.POST("/network", handleNetwork) |
89 | g.POST("/system", handleSystem) | 182 | g.POST("/system", handleSystem) |
90 | g.POST("/application", handleApplication) | 183 | g.POST("/application", handleApplication) |
91 | 184 | ||
@@ -95,19 +188,26 @@ func runHttp() { | @@ -95,19 +188,26 @@ func runHttp() { | ||
95 | g.Run(":8988") | 188 | g.Run(":8988") |
96 | } | 189 | } |
97 | 190 | ||
98 | -func handleAddress(c *gin.Context) { | 191 | +func handleNetwork(c *gin.Context) { |
99 | mu.Lock() | 192 | mu.Lock() |
100 | defer mu.Unlock() | 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 | return | 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 | func handleSystem(c *gin.Context) { | 213 | func handleSystem(c *gin.Context) { |
@@ -160,17 +260,16 @@ func handleRestore(c *gin.Context) { | @@ -160,17 +260,16 @@ func handleRestore(c *gin.Context) { | ||
160 | } | 260 | } |
161 | 261 | ||
162 | func renderIndex(c *gin.Context) { | 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 | func saveFormFile(c *gin.Context, name string, dst string) error { | 275 | func saveFormFile(c *gin.Context, name string, dst string) error { |
go/src/themaru/ip.go
@@ -1,77 +0,0 @@ | @@ -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 | package main | 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 | func main() { | 16 | func main() { |
4 | runHttp() | 17 | runHttp() |
5 | } | 18 | } |
go/src/themaru/network.go
@@ -0,0 +1,95 @@ | @@ -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 | +} |