Compare commits

..

10 Commits

Author SHA1 Message Date
Mike Holloway
0cd721909b On branch master
Changes to be committed:
	modified:   Questions_Answers.md
2021-06-28 21:08:17 -04:00
Mike Holloway
315aa55ab7 On branch master
Changes to be committed:
	modified:   Questions_Answers.md
		Markdown adjustments for legibility
2021-06-28 21:06:26 -04:00
Mike Holloway
4d180a1212 On branch master
Changes to be committed:
	new file:   Questions_Answers.md
	new file:   README
	deleted:    main
2021-06-28 20:59:23 -04:00
Mike Holloway
3c420dc3db Whoops, > -> < 2021-06-28 00:15:21 -04:00
Mike Holloway
54b52273da On branch pseudocode
Changes to be committed:
	modified:   main.go
		Due tomorrow, only a few hours found for this project, so
		the choice to flesh out ideas in pseudocode was made.
2021-06-28 00:11:40 -04:00
Mike Holloway
93fd6f916b On branch timer
Changes to be committed:
	modified:   main.go
		Arrays for each line of the tcp file.
2021-06-26 17:11:23 -04:00
Mike Holloway
8e2f4e3db8 On branch timer
Changes to be committed:
	modified:   main.go
		Adding use of time package directly
	modified:   timer/timer.go
		Simplifying this away.
2021-06-26 17:07:48 -04:00
Mike Holloway
bb77957ed4 On branch master
Changes to be committed:
	modified:   main.go
		Adding '_' to characters ignored by regex replace.
2021-06-26 13:00:58 -04:00
Mike Holloway
a46c855960 On branch timer
Changes to be committed:
	modified:   main.go
		Add call to timer
	new file:   timer/timer.go
		New 10 second timer
2021-06-25 00:20:30 -04:00
Mike Holloway
0ea14fd132 On branch fix-colons
Changes to be committed:
	modified:   main.go
		No longer replacing colons with ','
2021-06-24 23:01:12 -04:00
5 changed files with 156 additions and 10 deletions

55
Questions_Answers.md Normal file
View File

@ -0,0 +1,55 @@
## Level 1 Questions
1. How would you prove the code is correct?
To prove the code is correct I suppose I could set up a test environment
where I could account for all connections and run tests like
ssh connections, dhclient or dig (dns) connections, nmap port
scans, and then ensure the connections I expect from the tests
appear in the program's output.
2. How would you make this solution better?
I'd improve the solution by making the functions more focused on
specific tasks, improving how I present the interface of each
function to each other to more specifically eliminate type
or value errors. I'd also allot more time to complete the task
since I wasn't able to find enough before the deadline.
3. Is it possible for this program to miss a connection?
Yes, if the connection is brief enough so as not to last more than 10
seconds and thereby be missed by the most recent read of the
/proc/net/tcp file
4. If you weren't following these requirements, how would you solve the problem of logging every new connection?
I would likely find a solution that leverages inotify to detect any change to the file and then read it,
rather than polling it every 10 seconds.
## Level 2 Questions
1. Why did you choose 'x' to write the build automation?
I would simply choose bash, as it's what I'm most familiar with and it
can reliably use the go build tools as well as invoke testing
systems like kvm/qemu, docker/podman and the like.
2. Is there anything else you would test if you had more time?
If I had more time I'd spend it fleshing out my testing as outlined above
and doing a more thorough job of structuring my data in the way
that I've modeled it in my head - the choice of go definitely
consigned me to reading more than writing with the little time
I had. Should have gone with bash I think.
3. What is the most important tool, script, or technique you have for solving
problems in production? Explain why this tool/script/technique is the most important.
## Level 3 Questions
1. If you had to deploy this program to hundreds of servers, what would be your
preferred method and why?
I would use ansible and use git to clone, build, and install the script.
This method is my preferred one because it's simple to
troubleshoot in the event that I run into issues and
ansible doesn't require a central orchestrator node. It's
also the Infrastructure-as-code tool I'm most familiar with.
2. What is the hardest technical problem or outage you've had to solve in your
career? Explain what made it so difficult?

24
README Normal file
View File

@ -0,0 +1,24 @@
# teleport_devops_challenge
WARNING: This program is in an incomplete state and does not build successfully.
The latest commit that builds successfully can be found here:
https://git.libre.audio/seasharp/teleport_devops_challenge/commit/93fd6f916bc5a6b7504c5475f7cbcebabaae5277
## Dependencies
- golang 'encoding' package
## Building
Ensure your $GOPATH is set correctly and run:
1. Execute `go build main.go` in repository root
2. Execute `go install teleport_devops_challenge`
## Executing
Ensure GOPATH/bin (GOPATH = `go env GOPATH`) has been added to your shell $PATH
or execute the following:
`PATH=/home/$(whoami)/go/bin:$PATH teleport_devops_challenge`

BIN
main

Binary file not shown.

52
main.go
View File

@ -1,5 +1,9 @@
package main package main
import ( import (
"reflect"
//"./timer"
"time"
"fmt" "fmt"
"strings" "strings"
"regexp" "regexp"
@ -8,7 +12,10 @@ import (
) )
var tcp_data string = read_tcp_file("/proc/net/tcp")
func main() { func main() {
var loops int = 0
// How to split on space-delimited fields, then colon-delimited fields? // How to split on space-delimited fields, then colon-delimited fields?
// How to turn this byte into a string? // How to turn this byte into a string?
@ -16,7 +23,28 @@ func main() {
// and then converted byte by byte (2 char at a time) // and then converted byte by byte (2 char at a time)
//fmt.Println(convert_address(reverse_string(reverse_bytes("0100007F")))) //fmt.Println(convert_address(reverse_string(reverse_bytes("0100007F"))))
tcp_rows(read_tcp_file("/proc/net/tcp")) for _ = range time.Tick(10 * time.Second) {
fmt.Println("Waiting 10 seconds...")
for num, row := range get_tcp_rows(tcp_data) {
row_type := reflect.TypeOf(row)
fmt.Println(num, " ", row_type)
}
// if loops modulo 6 (1min) then
// for address in address_list do
// if (grep address address_list | wc -l >=3) then
// This is a port scan!
// fi
// done
// elseif (wc -l old_tcp_file < wc -l tcp_file) then
// for i in (wc -l tcp_file - wc -l old_tcp_flle) do
// print New Connection! reverse_strng(reverse_bytes(tcp_file[i])) // This oversimplifies row value selection for the sake
// // of pseudocode
// done
// else
// "No new connections. Waiting another 10 seconds..."
// fi
loops++
}
} }
func check(e error) { func check(e error) {
@ -25,17 +53,21 @@ func check(e error) {
} }
} }
func tcp_rows(connections_file string) { // Aiming for an array of [string]string maps
regexpression := regexp.MustCompile(`[^a-zA-Z0-9\r\n\t\v]+`) // Am I looking for a map[string]interface here?
tcp_lines := strings.Split(connections_file, "\n") func get_tcp_rows(connections_file string) []string {
tcp_lines := strings.Split(connections_file, "\n")
regexpression := regexp.MustCompile(`[\r\n\t\f\v]+`)
tcp_columns := regexpression.Split(tcp_lines[0], -1)
var tcp_values map[string]string
for _, line := range tcp_lines { for i, line := range tcp_lines[1:] {
trim_line := strings.TrimSpace(line) trim_line := strings.TrimSpace(line)
values := regexpression.ReplaceAllString(trim_line, ",") values := regexpression.Split(trim_line, -1)
// Debug column := tcp_columns[i]
// fmt.Println("New Line ==========") tcp_values[column] = values
fmt.Println(values)
} }
return tcp_values
} }
// Take a string, create a rune slice, and use a loop to reverse it character-wise. // Take a string, create a rune slice, and use a loop to reverse it character-wise.

35
timer/timer.go Normal file
View File

@ -0,0 +1,35 @@
package timer
import (
"fmt"
"time"
//"reflect"
)
func New(duration_int int, unit string) *time.Timer {
start := time.NewTimer(0)
duration := time.Duration(duration_int)
// fmt.Println(reflect.TypeOf(duration))
// timer_10s := time.NewTimer(10 * time.Second)
// timer_1m := time.NewTimer(1 * time.Minute)
fmt.Println("Duration: ", duration_int, "Unit: ", unit, ".")
if unit == "Second" {
start = time.NewTimer(duration * time.Second)
} else if unit == "Minute" {
start = time.NewTimer(duration * time.Minute)
} else {
fmt.Println("Unit not recognized.")
}
fmt.Println("Waiting ", duration_int, " ", unit, ".")
if start.Stop() {
<-start.C
fmt.Println("Done waiting ", duration_int, " ", unit, "!")
}
return start
// for elapsed < ten_seconds {
//}
// for
}
func Reset