Skip to content

Commit 1413d7b

Browse files
authored
Add support for wireless.wifi-iface
We make it possible to define wireless networks. This is maybe the last big piece to having a usable OpenWrt router in the 21st century. Most everyone is going to have a need for at least one wireless network these days (cell phones and laptops most notably). This is much like the rest of the resources. Because wireless networks have a lot of features, we only support a subset to start. We'll add more as we go along. But, this should be enough to get the minimum going. Branch: joneshf/add-support-for-wireless-wifi-iface Pull-Request: #125
1 parent 39cc576 commit 1413d7b

File tree

9 files changed

+647
-0
lines changed

9 files changed

+647
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "openwrt_wireless_wifi_iface Data Source - openwrt"
4+
subcategory: ""
5+
description: |-
6+
A wireless network.
7+
---
8+
9+
# openwrt_wireless_wifi_iface (Data Source)
10+
11+
A wireless network.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "openwrt_wireless_wifi_iface" "testing" {
17+
id = "testing"
18+
}
19+
```
20+
21+
<!-- schema generated by tfplugindocs -->
22+
## Schema
23+
24+
### Required
25+
26+
- `id` (String) Name of the section. This name is only used when interacting with UCI directly.
27+
28+
### Read-Only
29+
30+
- `device` (String) Name of the physical device. This name is what the device is known as in LuCI/UCI, or the `id` field in Terraform.
31+
- `encryption` (String) Encryption method. Currently, only PSK encryption methods are supported. Must be one of: "none", "psk", "psk2", "psk2+aes", "psk2+ccmp", "psk2+tkip", "psk2+tkip+aes", "psk2+tkip+ccmp", "psk+aes", "psk+ccmp", "psk-mixed", "psk-mixed+aes", "psk-mixed+ccmp", "psk-mixed+tkip", "psk-mixed+tkip+aes", "psk-mixed+tkip+ccmp", "psk+tkip", "psk+tkip+aes", "psk+tkip+ccmp", "sae", "sae-mixed".
32+
- `isolate` (Boolean) Isolate wireless clients from each other.
33+
- `key` (String, Sensitive) The pre-shared passphrase from which the pre-shared key will be derived. The clear text key has to be 8-63 characters long.
34+
- `mode` (String) The operation mode of the wireless network interface controller.. Currently only "ap" is supported.
35+
- `network` (String) Network interface to attach the wireless network. This name is what the interface is known as in UCI, or the `id` field in Terraform.
36+
- `ssid` (String) The broadcasted SSID of the wireless network. This is what actual clients will see the network as.
37+
- `wpa_disable_eapol_key_retries` (Boolean) Enable WPA key reinstallation attack (KRACK) workaround. This should be `true` to enable KRACK workaround (you almost surely want this enabled).
38+
39+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "openwrt_wireless_wifi_iface Resource - openwrt"
4+
subcategory: ""
5+
description: |-
6+
A wireless network.
7+
---
8+
9+
# openwrt_wireless_wifi_iface (Resource)
10+
11+
A wireless network.
12+
13+
## Example Usage
14+
15+
```terraform
16+
resource "openwrt_network_interface" "home" {
17+
device = "eth0"
18+
dns = [
19+
"9.9.9.9",
20+
"1.1.1.1",
21+
]
22+
id = "home"
23+
ipaddr = "192.168.3.1"
24+
netmask = "255.255.255.0"
25+
proto = "static"
26+
}
27+
28+
resource "openwrt_wireless_wifi_device" "five_ghz" {
29+
band = "5g"
30+
channel = "auto"
31+
id = "radio0"
32+
type = "mac80211"
33+
}
34+
35+
resource "openwrt_wireless_wifi_iface" "home" {
36+
device = openwrt_wireless_wifi_device.five_ghz.id
37+
encryption = "sae"
38+
id = "wifinet0"
39+
key = "password"
40+
mode = "ap"
41+
network = openwrt_network_interface.home.id
42+
ssid = "home"
43+
wpa_disable_eapol_key_retries = true
44+
}
45+
```
46+
47+
<!-- schema generated by tfplugindocs -->
48+
## Schema
49+
50+
### Required
51+
52+
- `device` (String) Name of the physical device. This name is what the device is known as in LuCI/UCI, or the `id` field in Terraform.
53+
- `id` (String) Name of the section. This name is only used when interacting with UCI directly.
54+
- `mode` (String) The operation mode of the wireless network interface controller.. Currently only "ap" is supported.
55+
- `network` (String) Network interface to attach the wireless network. This name is what the interface is known as in UCI, or the `id` field in Terraform.
56+
- `ssid` (String) The broadcasted SSID of the wireless network. This is what actual clients will see the network as.
57+
58+
### Optional
59+
60+
- `encryption` (String) Encryption method. Currently, only PSK encryption methods are supported. Must be one of: "none", "psk", "psk2", "psk2+aes", "psk2+ccmp", "psk2+tkip", "psk2+tkip+aes", "psk2+tkip+ccmp", "psk+aes", "psk+ccmp", "psk-mixed", "psk-mixed+aes", "psk-mixed+ccmp", "psk-mixed+tkip", "psk-mixed+tkip+aes", "psk-mixed+tkip+ccmp", "psk+tkip", "psk+tkip+aes", "psk+tkip+ccmp", "sae", "sae-mixed".
61+
- `isolate` (Boolean) Isolate wireless clients from each other.
62+
- `key` (String, Sensitive) The pre-shared passphrase from which the pre-shared key will be derived. The clear text key has to be 8-63 characters long.
63+
- `wpa_disable_eapol_key_retries` (Boolean) Enable WPA key reinstallation attack (KRACK) workaround. This should be `true` to enable KRACK workaround (you almost surely want this enabled).
64+
65+
## Import
66+
67+
Import is supported using the following syntax:
68+
69+
```shell
70+
# Find the Terraform id from LuCI's JSON-RPC API.
71+
# One way to find this information is with `curl` and `jq`:
72+
#
73+
# curl \
74+
# --data '{"id": 0, "method": "foreach", "params": ["wireless", "wifi-iface"]}' \
75+
# http://192.168.1.1/cgi-bin/luci/rpc/uci?auth=$AUTH_TOKEN \
76+
# | jq '.result | map({terraformId: .[".name"]})'
77+
#
78+
# This command will output something like:
79+
#
80+
# [
81+
# {
82+
# "terraformId": "cfg123456",
83+
# },
84+
# {
85+
# "terraformId": "cfg123457",
86+
# }
87+
# ]
88+
#
89+
# We'd then use the information to import the appropriate resource:
90+
91+
terraform import openwrt_wireless_wifi_iface.home_network cfg123456
92+
```
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
data "openwrt_wireless_wifi_iface" "testing" {
2+
id = "testing"
3+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Find the Terraform id from LuCI's JSON-RPC API.
2+
# One way to find this information is with `curl` and `jq`:
3+
#
4+
# curl \
5+
# --data '{"id": 0, "method": "foreach", "params": ["wireless", "wifi-iface"]}' \
6+
# http://192.168.1.1/cgi-bin/luci/rpc/uci?auth=$AUTH_TOKEN \
7+
# | jq '.result | map({terraformId: .[".name"]})'
8+
#
9+
# This command will output something like:
10+
#
11+
# [
12+
# {
13+
# "terraformId": "cfg123456",
14+
# },
15+
# {
16+
# "terraformId": "cfg123457",
17+
# }
18+
# ]
19+
#
20+
# We'd then use the information to import the appropriate resource:
21+
22+
terraform import openwrt_wireless_wifi_iface.home_network cfg123456
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
resource "openwrt_network_interface" "home" {
2+
device = "eth0"
3+
dns = [
4+
"9.9.9.9",
5+
"1.1.1.1",
6+
]
7+
id = "home"
8+
ipaddr = "192.168.3.1"
9+
netmask = "255.255.255.0"
10+
proto = "static"
11+
}
12+
13+
resource "openwrt_wireless_wifi_device" "five_ghz" {
14+
band = "5g"
15+
channel = "auto"
16+
id = "radio0"
17+
type = "mac80211"
18+
}
19+
20+
resource "openwrt_wireless_wifi_iface" "home" {
21+
device = openwrt_wireless_wifi_device.five_ghz.id
22+
encryption = "sae"
23+
id = "wifinet0"
24+
key = "password"
25+
mode = "ap"
26+
network = openwrt_network_interface.home.id
27+
ssid = "home"
28+
wpa_disable_eapol_key_retries = true
29+
}

openwrt/provider.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/joneshf/terraform-provider-openwrt/openwrt/network/switchvlan"
2525
"github.com/joneshf/terraform-provider-openwrt/openwrt/system/system"
2626
"github.com/joneshf/terraform-provider-openwrt/openwrt/wireless/wifidevice"
27+
"github.com/joneshf/terraform-provider-openwrt/openwrt/wireless/wifiiface"
2728
)
2829

2930
const (
@@ -163,6 +164,7 @@ func (p *openWrtProvider) DataSources(
163164
switchvlan.NewDataSource,
164165
system.NewDataSource,
165166
wifidevice.NewDataSource,
167+
wifiiface.NewDataSource,
166168
}
167169
}
168170

@@ -188,6 +190,7 @@ func (p *openWrtProvider) Resources(
188190
switchvlan.NewResource,
189191
system.NewResource,
190192
wifidevice.NewResource,
193+
wifiiface.NewResource,
191194
}
192195
}
193196

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//go:build acceptance.test
2+
3+
package wifiiface_test
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"log"
9+
"os"
10+
"testing"
11+
12+
"github.com/joneshf/terraform-provider-openwrt/internal/acceptancetest"
13+
"github.com/joneshf/terraform-provider-openwrt/lucirpc"
14+
"github.com/ory/dockertest/v3"
15+
"golang.org/x/crypto/ssh"
16+
"gotest.tools/v3/assert"
17+
)
18+
19+
var (
20+
dockerPool *dockertest.Pool
21+
)
22+
23+
func TestMain(m *testing.M) {
24+
var (
25+
code int
26+
err error
27+
tearDown func()
28+
)
29+
ctx := context.Background()
30+
tearDown, dockerPool, err = acceptancetest.Setup(ctx)
31+
defer func() {
32+
tearDown()
33+
os.Exit(code)
34+
}()
35+
if err != nil {
36+
fmt.Printf("Problem setting up tests: %s", err)
37+
code = 1
38+
return
39+
}
40+
41+
log.Printf("Running tests")
42+
code = m.Run()
43+
}
44+
45+
// runOpenWrtServerWithWireless starts an OpenWrt server,
46+
// and sets up the wireless config.
47+
// Without setting up the config,
48+
// the tests in this package will fail.
49+
func runOpenWrtServerWithWireless(
50+
ctx context.Context,
51+
dockerPool dockertest.Pool,
52+
t *testing.T,
53+
) (*lucirpc.Client, string) {
54+
openWrtServer := acceptancetest.RunOpenWrtServer(
55+
ctx,
56+
dockerPool,
57+
t,
58+
)
59+
sshURL := fmt.Sprintf("%s:%d", openWrtServer.Hostname, openWrtServer.SSHPort)
60+
sshConfig := &ssh.ClientConfig{
61+
Auth: []ssh.AuthMethod{
62+
ssh.Password(openWrtServer.Password),
63+
},
64+
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
65+
User: openWrtServer.Username,
66+
}
67+
sshClient, err := ssh.Dial("tcp", sshURL, sshConfig)
68+
assert.NilError(t, err)
69+
t.Cleanup(func() {
70+
sshClient.Close()
71+
})
72+
session, err := sshClient.NewSession()
73+
assert.NilError(t, err)
74+
t.Cleanup(func() {
75+
session.Close()
76+
})
77+
err = session.Run("touch /etc/config/wireless")
78+
assert.NilError(t, err)
79+
client := openWrtServer.LuCIRPCClient(
80+
ctx,
81+
t,
82+
)
83+
providerBlock := openWrtServer.ProviderBlock()
84+
return client, providerBlock
85+
}

0 commit comments

Comments
 (0)