Commit c35246804fff2e5be6f4302d89a1d7b48c8c891f

Authored by 김태훈
1 parent 476d2547ea
Exists in master

기능 추가 및 변경

- 네트워크 설정 페이지 추가
  - 기존 IP 주소 설정 항목 제거
  - 추가된 페이지에 이더넷 주소, IP 주소, 넷마스크, 게이트웨이 설정 항목 추가
- 실행 명령줄 인자로 네트워크 인터페이스 갯수 설정
  - 인자에 "-dual"을 추가하면 네트워크 인터페이스 갯수가 2개인 것으로 동작
- 실행 명령줄 인자로 장치 이름 설정하는 방법 변경
  - 인자에 "-device "<장치 이름>""을 추가하는 방법으로 변경 (기존은 첫 번째 인자를 그대로 사용)
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(&quot;index.html&quot;).Parse(` @@ -23,17 +22,9 @@ var indexPage = template.Must(template.New(&quot;index.html&quot;).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(&quot;index.html&quot;).Parse(` @@ -58,6 +49,101 @@ var indexPage = template.Must(template.New(&quot;index.html&quot;).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 +}