package main import ( "io/ioutil" "log" "net/http" "os" "git.scc.kit.edu/feudal/feudalClient/config" deps "git.scc.kit.edu/feudal/feudalClient/deployments" "git.scc.kit.edu/feudal/feudalClient/sink" "git.scc.kit.edu/feudal/feudalClient/sink/script" "git.scc.kit.edu/feudal/feudalClient/source" "git.scc.kit.edu/feudal/feudalClient/source/amqp" "git.scc.kit.edu/feudal/feudalClient/source/rest" kingpin "gopkg.in/alecthomas/kingpin.v2" ) var ( app = kingpin.New( "FEUDAL Client", "Client for the Federated User Credential Deployment Portal (FEUDAL)", ).Author( "Lukas Burgey", ).Version( "v2.1.0", ) cmdStart = app.Command("start", "Starts the client in its normal operation mode.").Default() cmdDeregister = app.Command("deregister", "Before disabling the client: Use deregister to inform the backend that the client ceases operation.") cmdSchema = app.Command("schema", "Can be used to generate a JSON schema (Draft 4, see json-schema.org) for the validation of script inputs, outputs and the config of this client.") printSelector = cmdSchema.Arg("selector", "Select the schema to generate. Options: input, output, config").Required().Enum("input", "output", "config") cmdValidate = app.Command("validate", "Validate a input/output/config json. The json needs to be passed via stdin.") validateSelector = cmdValidate.Arg("selector", "Select the schema to validate against. Options: input, output, config").Required().Enum("input", "output", "config") configFile = app.Flag("config", "Config file to use.").Short('c').String() scriptDebugging = app.Flag("debug-scripts", "Display debugging info concerning executed scripts").Bool() backendDebugging = app.Flag("debug-backend", "Display debugging info concerning the backend").Bool() debugAll = app.Flag("debug", "Display all debugging info").Bool() sequentialExecution = app.Flag("seq", "Execute tasks sequentially").Bool() ) func deregister(conf *config.Config) { var ( err error req *http.Request resp *http.Response ) log.Printf("Deregistering this client at the backend") req, err = http.NewRequest( "PUT", "https://"+conf.Hostname+"/backend/clientapi/deregister", nil, ) if err != nil { log.Fatalf("Unable to deregister: %s", err) } req.SetBasicAuth(conf.Username, conf.Password) resp, err = (&http.Client{}).Do(req) if err != nil { log.Fatalf("Unable to deregister: %s", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatalf("Cannot read response body") } log.Printf("Response: %s", body) } func start(conf *config.Config) { if len(conf.EntitlementToServiceIDs) == 0 && len(conf.GroupToServiceIDs) == 0 { log.Printf("[P] Not starting pubsub because the are no services to subscribe to") return } // wire the pipes from sources to sink(s) sources := []source.Source{new(rest.Source), new(amqp.Source)} srcPipes := make([]<-chan deps.Dep, len(sources)) sinks := []sink.Sink{new(script.Sink)} sinkPipe := make(chan deps.Dep) var err error for _, sink := range sinks { sink.Init(conf) err = sink.Connect((<-chan deps.Dep)(sinkPipe)) if err != nil { log.Printf("Error connecting sink: %s", err) } } for i, src := range sources { src.Init(conf) srcPipes[i], err = src.Connect() if err != nil { log.Printf("Error connecting source: %s", err) } } // TODO rework var received deps.Dep for { select { case received = <-srcPipes[0]: sinkPipe <- received case received = <-srcPipes[1]: sinkPipe <- received } } } func prepareDebugging(conf *config.Config) { // Override the debug configuration with parameters if *debugAll { *scriptDebugging = true *backendDebugging = true } if *scriptDebugging { conf.Debug.Scripts = true } if *backendDebugging { conf.Debug.Backend = true } if *sequentialExecution { conf.Debug.Sequential = true } if conf.Debug.Scripts { log.Printf("[Debug] script debugging enabled") } if conf.Debug.Backend { log.Printf("[Debug] backend debugging enabled") } if conf.Debug.Sequential { log.Printf("[Debug] Executing tasks sequentially") } } func main() { var err error // get arguments cmd := kingpin.MustParse(app.Parse(os.Args[1:])) // Execute commands that don't need the config switch cmd { case "schema": printSchema(*printSelector) return case "validate": result, err := validateJSON(*validateSelector, os.Stdin) if err != nil { log.Fatal(err) } printValidationResult(result) return } // read the config file conf, err := config.ReadConfig(*configFile) if err != nil { log.Fatalf("[Conf] %s", err) } prepareDebugging(conf) switch cmd { case "start": // sync the config with the backend if conf.Sync() != nil { log.Printf("[Conf] Error synchronizing configuration: %s", err) return } start(conf) case "deregister": deregister(conf) } }