Skip to content

Commit 60739bf

Browse files
authored
Base containerized application workflow (#17)
* feat: sample TCP server + broken pipe * fix: local package path for benchmark utility * refactor: MQTT republisher example to stream * refactor: client-server model to new file * fix: test config. & final directory structure * feat: internal Docker host config (MQTT) * feat: SHA256 hash & file contents test case * docs: example failed test case * Revert "docs: example failed test case" This reverts commit d5283b1. * docs: bump directory structure tree
1 parent ec2d157 commit 60739bf

14 files changed

+333
-250
lines changed

Dockerfile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# syntax=docker/dockerfile:1
2+
# Data Diode CLI in Go via container image.
3+
# https://docs.docker.com/language/golang/build-images/
4+
5+
FROM golang:alpine
6+
WORKDIR /cli
7+
COPY . /cli
8+
RUN CGO_ENABLED=0 GOOS=linux go build -o diode
9+
CMD [ "./diode", "mqtt" ]

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
build:
2-
go build -o diode -ldflags="-X main.SemVer=0.0.5" diode.go
2+
go build -o diode -ldflags="-X main.SemVer=0.0.6" diode.go
33

44
test:
55
go test -v

README.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,24 @@ Scripts for verifying TCP passthrough functionality.
2323

2424
```zsh
2525
.
26-
├── benchmark
26+
├── config
2727
├── config.yaml
28-
├── data
2928
├── diode.go
3029
├── diode_test.go
30+
├── docker-compose.yaml
31+
├── Dockerfile
3132
├── go.mod
3233
├── go.sum
3334
├── Makefile
3435
├── mqtt
3536
├── Pipfile
3637
├── Pipfile.lock
3738
├── README.md
38-
└── sample
39+
├── sample
40+
└── utility
41+
42+
4 directories, 11 files
3943

40-
4 directories, 9 files
4144
```
4245

4346
## User Stories

benchmark/utility.go

-36
This file was deleted.

config/mosquitto.conf

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
listener 1883
2+
allow_anonymous true
3+
persistence false
4+
5+
# https://hub.docker.com/_/eclipse-mosquitto
6+
# persistence_location /mosquitto/data/
7+
# log_dest file /mosquitto/log/mosquitto.log

data/logbook.ipynb

-50
This file was deleted.

diode.go

+19-145
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ package main
1010
import (
1111
"fmt"
1212
"log"
13-
"net"
1413
"os"
1514
"time"
1615

17-
mqtt "github.com/eclipse/paho.mqtt.golang"
16+
"github.com/acep-uaf/data-diode/utility"
1817
"github.com/urfave/cli/v2"
1918
"gopkg.in/yaml.v2"
2019
)
@@ -40,147 +39,11 @@ type Configuration struct {
4039
}
4140
}
4241

43-
func newClient(ip string, port int) {
44-
// Create a socket
45-
46-
client, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), time.Second)
47-
48-
if err != nil {
49-
fmt.Println(">> Error establishing connection to the diode input side: ", err.Error())
50-
log.Fatal(err)
51-
}
52-
defer client.Close()
53-
54-
numberOfSends := 1
55-
56-
for {
57-
sendMessage := fmt.Sprintf("This is TCP passthrough test message number: %d", numberOfSends)
58-
_, err := client.Write([]byte(sendMessage))
59-
if err != nil {
60-
fmt.Println(">> Error sending message to the diode input side: ", err.Error())
61-
log.Fatal(err)
62-
break
63-
}
64-
65-
// if string(response) == "OK\r\n" {
66-
// fmt.Println(">> Message sent successfully!")
67-
// }
68-
69-
numberOfSends++
70-
71-
time.Sleep(1 * time.Second)
72-
}
73-
}
74-
75-
func newServer(ip string, port int) {
76-
// Begin listening for incoming connections
77-
78-
server, err := net.Listen("tcp", fmt.Sprintf("%s:%d", ip, port))
79-
80-
if err != nil {
81-
fmt.Println(">> Error listening for incoming connections: ", err.Error())
82-
return
83-
}
84-
defer server.Close()
85-
86-
fmt.Printf(">> Server listening on %s:%d\n", ip, port)
87-
88-
for {
89-
// Wait for connection
90-
connection, err := server.Accept()
91-
92-
if err != nil {
93-
fmt.Println(">> Error accepting connection: ", err.Error())
94-
return
95-
}
96-
97-
fmt.Println("Connected to client IP:", connection.RemoteAddr().String())
98-
99-
go communicationHandler(connection)
100-
101-
}
102-
103-
}
104-
105-
func communicationHandler(connection net.Conn) {
106-
107-
defer connection.Close()
108-
109-
// Buffer for incoming data (holding recieved data)
110-
buffer := make([]byte, 10240)
111-
112-
for {
113-
// Read incoming data into buffer
114-
bytesRead, err := connection.Read(buffer)
115-
if err != nil {
116-
fmt.Println(">> Error reading: ", err.Error())
117-
break
118-
}
119-
120-
if bytesRead > 0 {
121-
fmt.Println(">> Message recieved: ", string(buffer[:bytesRead]))
122-
}
123-
124-
if bytesRead < 10240 {
125-
break
126-
}
127-
}
128-
129-
}
130-
131-
func sampleMetrics() {
42+
func sampleMetrics(server string, port int) {
13243
fmt.Println(">> Local time: ", time.Now())
13344
fmt.Println(">> UTC time: ", time.Now().UTC())
134-
}
135-
136-
func demoRepublisher(server string, port int, topic string, message string) {
137-
fmt.Println(">> MQTT")
138-
fmt.Println(">> Broker: ", server)
139-
fmt.Println(">> Port: ", port)
140-
141-
// Source: https://github.com/eclipse/paho.mqtt.golang/blob/master/cmd/simple/main.go
142-
var example mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
143-
fmt.Printf(">> Topic: %s\n", msg.Topic())
144-
fmt.Printf(">> Message: %s\n", msg.Payload())
145-
}
146-
147-
mqtt.DEBUG = log.New(os.Stdout, "", 0)
148-
mqtt.ERROR = log.New(os.Stdout, "", 0)
149-
150-
// Initial Connection
151-
opts := mqtt.NewClientOptions().AddBroker(fmt.Sprintf("tcp://%s:%d", server, port))
152-
opts.SetKeepAlive(2 * time.Second)
153-
opts.SetDefaultPublishHandler(example)
154-
opts.SetPingTimeout(1 * time.Second)
155-
156-
// Create and start a client using the above ClientOptions
157-
client := mqtt.NewClient(opts)
158-
if token := client.Connect(); token.Wait() && token.Error() != nil {
159-
panic(token.Error())
160-
}
161-
162-
// Subscribe to a topic
163-
if token := client.Subscribe(topic, 0, nil); token.Wait() && token.Error() != nil {
164-
fmt.Println(token.Error())
165-
os.Exit(1)
166-
}
167-
168-
// Publish to a topic
169-
token := client.Publish(topic, 0, false, message)
170-
token.Wait()
171-
172-
time.Sleep(6 * time.Second)
173-
174-
// Disconnect from the broker
175-
if token := client.Unsubscribe(topic); token.Wait() && token.Error() != nil {
176-
fmt.Println(token.Error())
177-
os.Exit(1)
178-
}
179-
180-
client.Disconnect(250)
181-
182-
time.Sleep(1 * time.Second)
183-
45+
fmt.Println(">> Value: ", utility.Value())
46+
// utility.Client(server, port)
18447
}
18548

18649
func main() {
@@ -222,7 +85,7 @@ func main() {
22285
Usage: "Input side of the data diode",
22386
Action: func(cCtx *cli.Context) error {
22487
fmt.Println("----- INPUT -----")
225-
newClient(diodeInputSideIP, diodeTCPPassthroughPort)
88+
utility.Client(diodeInputSideIP, diodeTCPPassthroughPort)
22689
return nil
22790
},
22891
},
@@ -232,7 +95,18 @@ func main() {
23295
Usage: "Output side of the data diode",
23396
Action: func(sCtx *cli.Context) error {
23497
fmt.Println("----- OUTPUT -----")
235-
newServer(targetTCPServerIP, targetTCPServerPort)
98+
utility.Server(targetTCPServerIP, targetTCPServerPort)
99+
return nil
100+
},
101+
},
102+
{
103+
Name: "test",
104+
Aliases: []string{"t"},
105+
Usage: "Testing state synchronization via diode I/O",
106+
Action: func(tCtx *cli.Context) error {
107+
fmt.Println("----- TEST -----")
108+
example := utility.Checksum()
109+
fmt.Printf(">> Checksum: %x\n", example)
236110
return nil
237111
},
238112
},
@@ -252,7 +126,7 @@ func main() {
252126
Usage: "System benchmark analysis + report performance metrics",
253127
Action: func(bCtx *cli.Context) error {
254128
fmt.Println("----- BENCHMARKS -----")
255-
sampleMetrics()
129+
sampleMetrics(utility.CONN_HOST, 3333)
256130
return nil
257131
},
258132
},
@@ -262,7 +136,7 @@ func main() {
262136
Usage: "MQTT (TCP stream) demo",
263137
Action: func(mCtx *cli.Context) error {
264138
fmt.Println("----- MQTT -----")
265-
demoRepublisher(mqttBrokerIP, mqttBrokerPort, mqttBrokerTopic, mqttBrokerMessage)
139+
utility.Republisher(mqttBrokerIP, mqttBrokerPort, mqttBrokerTopic, mqttBrokerMessage)
266140
return nil
267141
},
268142
},

diode_test.go

+29-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
11
package main
22

3-
import "testing"
3+
import (
4+
"fmt"
5+
"testing"
46

5-
func TestNewClient(t *testing.T) {
6-
name := "Input"
7-
t.Run(name, func(t *testing.T) {
8-
t.Parallel()
9-
})
7+
"github.com/acep-uaf/data-diode/utility"
8+
)
9+
10+
func TestCLI(t *testing.T) {
11+
got := "diode"
12+
want := "diode"
13+
14+
if got != want {
15+
t.Errorf("got %q, want %q", got, want)
16+
}
17+
}
18+
19+
func TestConfiguration(t *testing.T) {
20+
got := Configuration{}
21+
want := Configuration{}
22+
23+
if got != want {
24+
t.Errorf("got %q, want %q", got, want)
25+
}
1026
}
1127

12-
func TestNewServer(t *testing.T) {
13-
name := "Output"
14-
t.Run(name, func(t *testing.T) {
15-
t.Parallel()
16-
})
28+
func TestFileContents(t *testing.T) {
29+
got := fmt.Sprintf("%x", utility.Checksum())
30+
want := "ed03bb5d7385010c645c2c72ceabea3b15806db757005071309745c59933586f"
31+
32+
if got != want {
33+
t.Errorf("got %q, want %q", got, want)
34+
}
1735
}

0 commit comments

Comments
 (0)