Start laying out the structure of gooni

This commit is contained in:
Arturo Filastò 2018-02-07 20:02:18 +02:00
commit 7327e1ff7f
22 changed files with 529 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
vendor/
/ooni

42
Gopkg.lock generated Normal file
View File

@ -0,0 +1,42 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/alecthomas/kingpin"
packages = ["."]
revision = "947dcec5ba9c011838740e680966fd7087a71d0d"
version = "v2.2.6"
[[projects]]
branch = "master"
name = "github.com/alecthomas/template"
packages = [
".",
"parse"
]
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
[[projects]]
branch = "master"
name = "github.com/alecthomas/units"
packages = ["."]
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
[[projects]]
branch = "master"
name = "github.com/aybabtme/rgbterm"
packages = ["."]
revision = "cc83f3b3ce5911279513a46d6d3316d67bedaa54"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "4ed0a29997f4d8f197233e4ba7aa66ed7033443a893a795ed2b4a9a5ec4350bd"
solver-name = "gps-cdcl"
solver-version = 1

42
Gopkg.toml Normal file
View File

@ -0,0 +1,42 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]]
name = "github.com/alecthomas/kingpin"
version = "2.2.6"
[[constraint]]
branch = "master"
name = "github.com/aybabtme/rgbterm"
[prune]
go-tests = true
unused-packages = true
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
GO ?= go
build:
@echo "Building ./ooni"
@$(GO) build -o ooni cmd/ooni/main.go
.PHONY: build

23
cmd/ooni/main.go Normal file
View File

@ -0,0 +1,23 @@
package main
import (
// commands
_ "github.com/openobservatory/gooni/internal/cli/info"
_ "github.com/openobservatory/gooni/internal/cli/list"
_ "github.com/openobservatory/gooni/internal/cli/nettest"
_ "github.com/openobservatory/gooni/internal/cli/run"
_ "github.com/openobservatory/gooni/internal/cli/show"
_ "github.com/openobservatory/gooni/internal/cli/upload"
_ "github.com/openobservatory/gooni/internal/cli/version"
"github.com/openobservatory/gooni/internal/util"
"github.com/openobservatory/gooni/internal/cli/app"
)
func main() {
err := app.Run()
if err == nil {
return
}
util.Fatal(err)
}

7
config/advanced.go Normal file
View File

@ -0,0 +1,7 @@
package config
// Advanced settings
type Advanced struct {
IncludeCountry bool `json:"include_country"`
UseDomainFronting bool `json:"use_domain_fronting"`
}

View File

@ -0,0 +1,8 @@
package config
// AutomatedTesting settings
type AutomatedTesting struct {
Enabled bool `json:"enabled"`
EnabledTests []string `json:"enabled_tests"`
MonthlyAllowance string `json:"monthly_allowance"`
}

29
config/nettest_groups.go Normal file
View File

@ -0,0 +1,29 @@
package config
type websiteSettings struct {
EnabledCategories []string `json:"enabled_categories"`
}
type instantMessagingSettings struct {
EnabledTests []string `json:"enabled_tests"`
}
type performanceSettings struct {
EnabledTests []string `json:"enabled_tests"`
NDTServer string `json:"ndt_server"`
NDTServerPort string `json:"ndt_server_port"`
DashServer string `json:"dash_server"`
DashServerPort string `json:"dash_server_port"`
}
type middleboxSettings struct {
EnabledTests []string `json:"enabled_tests"`
}
// NettestGroups related settings
type NettestGroups struct {
Websites websiteSettings `json:"websites"`
InstantMessaging instantMessagingSettings `json:"instant_messaging"`
Performance performanceSettings `json:"performance"`
Middlebox middleboxSettings `json:"middlebox"`
}

8
config/notifications.go Normal file
View File

@ -0,0 +1,8 @@
package config
// Notifications settings
type Notifications struct {
Enabled bool `json:"enabled"`
NotifyOnTestCompletion bool `json:"notify_on_test_completion"`
NotifyOnNews bool `json:"notify_on_news"`
}

10
config/sharing.go Normal file
View File

@ -0,0 +1,10 @@
package config
// Sharing settings
type Sharing struct {
IncludeIP bool `json:"include_ip"`
IncludeASN bool `json:"include_asn"`
IncludeGPS bool `json:"include_gps"`
UploadResults bool `json:"upload_results"`
SendCrashReports bool `json:"send_crash_reports"`
}

17
internal/cli/app/app.go Normal file
View File

@ -0,0 +1,17 @@
package app
import (
"os"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/cli/version"
"github.com/openobservatory/gooni/internal/util"
)
// Run the app. This is the main app entry point
func Run() error {
util.Log("Running")
root.Cmd.Version(version.Version)
_, err := root.Cmd.Parse(os.Args[1:])
return err
}

16
internal/cli/info/info.go Normal file
View File

@ -0,0 +1,16 @@
package info
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("info", "Display information about OONI Probe")
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Info")
return nil
})
}

16
internal/cli/list/list.go Normal file
View File

@ -0,0 +1,16 @@
package list
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("list", "List measurements")
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Listing")
return nil
})
}

View File

@ -0,0 +1,16 @@
package nettest
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("nettest", "Run a specific nettest")
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Nettest")
return nil
})
}

19
internal/cli/root/root.go Normal file
View File

@ -0,0 +1,19 @@
package root
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/util"
)
// Cmd is the root command
var Cmd = kingpin.New("ooni", "")
// Command is syntax sugar for defining sub-commands
var Command = Cmd.Command
func init() {
Cmd.PreAction(func(ctx *kingpin.ParseContext) error {
util.Log("Running pre-action")
return nil
})
}

18
internal/cli/run/run.go Normal file
View File

@ -0,0 +1,18 @@
package run
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("run", "Run a test group or OONI Run link")
nettestGroup := cmd.Arg("name", "the nettest group to run").Required().String()
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Starting %s", nettestGroup)
return nil
})
}

16
internal/cli/show/show.go Normal file
View File

@ -0,0 +1,16 @@
package nettest
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("show", "Show a specific measurement")
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Show")
return nil
})
}

View File

@ -0,0 +1,16 @@
package upload
import (
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
"github.com/openobservatory/gooni/internal/util"
)
func init() {
cmd := root.Command("upload", "Upload a specific measurement")
cmd.Action(func(_ *kingpin.ParseContext) error {
util.Log("Uploading")
return nil
})
}

View File

@ -0,0 +1,18 @@
package version
import (
"fmt"
"github.com/alecthomas/kingpin"
"github.com/openobservatory/gooni/internal/cli/root"
)
const Version = "0.0.1"
func init() {
cmd := root.Command("version", "Show version.")
cmd.Action(func(_ *kingpin.ParseContext) error {
fmt.Println(Version)
return nil
})
}

40
internal/colors/colors.go Normal file
View File

@ -0,0 +1,40 @@
package colors
import (
color "github.com/aybabtme/rgbterm"
)
// Gray string.
func Gray(s string) string {
return color.FgString(s, 150, 150, 150)
}
// Blue string.
func Blue(s string) string {
return color.FgString(s, 77, 173, 247)
}
// Cyan string.
func Cyan(s string) string {
return color.FgString(s, 34, 184, 207)
}
// Green string.
func Green(s string) string {
return color.FgString(s, 0, 200, 255)
}
// Red string.
func Red(s string) string {
return color.FgString(s, 194, 37, 92)
}
// Yellow string.
func Yellow(s string) string {
return color.FgString(s, 252, 196, 25)
}
// Purple string.
func Purple(s string) string {
return color.FgString(s, 96, 97, 190)
}

19
internal/util/util.go Normal file
View File

@ -0,0 +1,19 @@
package util
import (
"fmt"
"os"
"github.com/openobservatory/gooni/internal/colors"
)
// Log outputs a log message.
func Log(msg string, v ...interface{}) {
fmt.Printf(" %s\n", colors.Purple(fmt.Sprintf(msg, v...)))
}
// Fatal error
func Fatal(err error) {
fmt.Fprintf(os.Stderr, "\n %s %s\n\n", colors.Red("Error:"), err)
os.Exit(1)
}

141
ooni.go Normal file
View File

@ -0,0 +1,141 @@
package ooni
import (
"encoding/json"
"io/ioutil"
"os"
"github.com/openobservatory/gooni/config"
"github.com/pkg/errors"
)
// Config for the OONI Probe installation
type Config struct {
// Private settings
Comment string `json:"_"`
ConfigVersion string `json:"_config_version"`
InformedConsent bool `json:"_informed_consent"`
AutoUpdate bool `json:"auto_update"`
Sharing config.Sharing `json:"sharing"`
Notifications config.Notifications `json:"notifications"`
AutomatedTesting config.AutomatedTesting `json:"automated_testing"`
NettestGroups config.NettestGroups `json:"test_settings"`
Advanced config.Sharing `json:"advanced"`
}
// Default config settings
func (c *Config) Default() error {
// This is the default configuration:
/*
_: 'This is your OONI Probe config file. See https://ooni.io/help/ooniprobe-cli for help',
auto_update: true,
sharing: {
include_ip: false,
include_asn: true,
include_gps: true,
upload_results: true,
send_crash_reports: true
},
notifications: {
enabled: true,
notify_on_test_completion: true,
notify_on_news: false
},
automated_testing: {
enabled: false,
enabled_tests: [
'web-connectivity',
'facebook-messenger',
'whatsapp',
'telegram',
'dash',
'ndt',
'http-invalid-request-line',
'http-header-field-manipulation'
],
monthly_allowance: '300MB'
},
test_settings: {
websites: {
enabled_categories: []
},
instant_messaging: {
enabled_tests: [
'facebook-messenger',
'whatsapp',
'telegram'
]
},
performance: {
enabled_tests: [
'ndt'
],
ndt_server: 'auto',
ndt_server_port: 'auto',
dash_server: 'auto',
dash_server_port: 'auto'
},
middlebox: {
enabled_tests: [
'http-invalid-request-line',
'http-header-field-manipulation'
]
}
},
advanced: {
include_country: true,
use_domain_fronting: true
},
_config_version: CONFIG_VERSION,
_informed_consent: false
*/
return nil
}
// Validate the config file
func (c *Config) Validate() error {
return nil
}
// ParseConfig returns config from JSON bytes.
func ParseConfig(b []byte) (*Config, error) {
c := &Config{}
if err := json.Unmarshal(b, c); err != nil {
return nil, errors.Wrap(err, "parsing json")
}
if err := c.Default(); err != nil {
return nil, errors.Wrap(err, "defaulting")
}
if err := c.Validate(); err != nil {
return nil, errors.Wrap(err, "validating")
}
return c, nil
}
// ReadConfig reads the configuration from the path
func ReadConfig(path string) (*Config, error) {
b, err := ioutil.ReadFile(path)
if os.IsNotExist(err) {
c := &Config{}
if err = c.Default(); err != nil {
return nil, errors.Wrap(err, "defaulting")
}
if err = c.Validate(); err != nil {
return nil, errors.Wrap(err, "validating")
}
}
if err != nil {
return nil, errors.Wrap(err, "reading file")
}
return ParseConfig(b)
}