From 75297f1dc5c493c0b74dda2370f02045bb8a4856 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Mon, 1 Mar 2021 22:48:32 +0530 Subject: [PATCH 01/24] identity onoff cmd function --- .../cli/{cmdlineConstants.go => constants.go} | 4 ++ ...cmdlineClientFunctions.go => ipcClient.go} | 14 +--- ...ParseFunctions.go => responseGenerator.go} | 0 service/ziti-tunnel/cli/service.go | 23 +++++++ service/ziti-tunnel/cmd/identities.go | 2 +- service/ziti-tunnel/cmd/identity.go | 65 +++++++++++++++++++ service/ziti-tunnel/cmd/root.go | 3 +- service/ziti-tunnel/cmd/services.go | 3 +- service/ziti-tunnel/dto/clidtos.go | 5 ++ service/ziti-tunnel/main.go | 2 + 10 files changed, 106 insertions(+), 15 deletions(-) rename service/ziti-tunnel/cli/{cmdlineConstants.go => constants.go} (93%) rename service/ziti-tunnel/cli/{cmdlineClientFunctions.go => ipcClient.go} (85%) rename service/ziti-tunnel/cli/{cmdlineParseFunctions.go => responseGenerator.go} (100%) create mode 100644 service/ziti-tunnel/cli/service.go create mode 100644 service/ziti-tunnel/cmd/identity.go diff --git a/service/ziti-tunnel/cli/cmdlineConstants.go b/service/ziti-tunnel/cli/constants.go similarity index 93% rename from service/ziti-tunnel/cli/cmdlineConstants.go rename to service/ziti-tunnel/cli/constants.go index b7f1652c..9a703d39 100644 --- a/service/ziti-tunnel/cli/cmdlineConstants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -26,6 +26,10 @@ var GET_STATUS = dto.CommandMsg{ Function: "Status", } +var ONOFF_IDENTITY = dto.CommandMsg{ + Function: "IdentityOnOff", +} + var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` diff --git a/service/ziti-tunnel/cli/cmdlineClientFunctions.go b/service/ziti-tunnel/cli/ipcClient.go similarity index 85% rename from service/ziti-tunnel/cli/cmdlineClientFunctions.go rename to service/ziti-tunnel/cli/ipcClient.go index 2bc182ac..efe0cc01 100644 --- a/service/ziti-tunnel/cli/cmdlineClientFunctions.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -56,6 +56,7 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchF if err != nil { log.Error(err) + readDone <- struct{}{} return } @@ -66,6 +67,7 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchF dec := json.NewDecoder(strings.NewReader(msg)) var tunnelStatus dto.ZitiTunnelStatus if err := dec.Decode(&tunnelStatus); err == io.EOF { + readDone <- struct{}{} return } else if err != nil { log.Fatal(err) @@ -86,17 +88,7 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchF return } -//GetIdentities is to fetch identities through cmdline -func GetIdentities(args []string, flags map[string]bool) { - getDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, args, flags) -} - -//GetServices is to fetch services through cmdline -func GetServices(args []string, flags map[string]bool) { - getDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, args, flags) -} - -func getDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchFromRTS, args []string, flags map[string]bool) { +func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchFromRTS, args []string, flags map[string]bool) { log.Infof("fetching identities through cmdline...%s", args) log.Debug("Connecting to pipe") diff --git a/service/ziti-tunnel/cli/cmdlineParseFunctions.go b/service/ziti-tunnel/cli/responseGenerator.go similarity index 100% rename from service/ziti-tunnel/cli/cmdlineParseFunctions.go rename to service/ziti-tunnel/cli/responseGenerator.go diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go new file mode 100644 index 00000000..85c72605 --- /dev/null +++ b/service/ziti-tunnel/cli/service.go @@ -0,0 +1,23 @@ +package cli + +import "strings" + +//GetIdentities is to fetch identities through cmdline +func GetIdentities(args []string, flags map[string]bool) { + GetDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, args, flags) +} + +//GetServices is to fetch services through cmdline +func GetServices(args []string, flags map[string]bool) { + GetDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, args, flags) +} + +//GetFeedback is to fetch logs and sysntem info through cmdline +func OnOffIdentity(args []string, flags map[string]bool) { + identityPayload := make(map[string]interface{}) + identityPayload["OnOff"] = strings.EqualFold(args[1], "on") + identityPayload["Fingerprint"] = args[0] + ONOFF_IDENTITY.Payload = identityPayload + log.Infof("OnOffIdentity Payload %v", ONOFF_IDENTITY) + GetDataFromIpcPipe(&ONOFF_IDENTITY, GetServicesFromRTS, args, flags) +} diff --git a/service/ziti-tunnel/cmd/identities.go b/service/ziti-tunnel/cmd/identities.go index fcabe42d..06d6c3c5 100644 --- a/service/ziti-tunnel/cmd/identities.go +++ b/service/ziti-tunnel/cmd/identities.go @@ -26,7 +26,7 @@ var servicesOfID bool // identitiesCmd represents the identities command var identitiesCmd = &cobra.Command{ - Use: "identities", + Use: "identities [all] [idname...]", Short: "Lists identities from ziti-tunnel", Long: `View the identities that this user has access to. The records will be fetched from ziti-tunnel`, diff --git a/service/ziti-tunnel/cmd/identity.go b/service/ziti-tunnel/cmd/identity.go new file mode 100644 index 00000000..5a7598b6 --- /dev/null +++ b/service/ziti-tunnel/cmd/identity.go @@ -0,0 +1,65 @@ +/* +Copyright © 2021 NAME HERE + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "errors" + "fmt" + "strings" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/cli" + + "github.com/spf13/cobra" +) + +// identityCmd represents the identity command +var identityCmd = &cobra.Command{ + Use: "identity [fingerprint] [on/off]", + Short: "enable or disable the identity", + Long: `Enable or disable identity based on the On Off values. + It accepts finger print of the identity followed by On Off values`, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 2 { + return errors.New("requires a 2 arguments, usage: identity [fingerprint] [on/off]") + } + if len(args[0]) == 40 && isValidArg(args[1]) { + return nil + } + return errors.New("incorrect arguments are passed, usage: identity [fingerprint] [on/off]") + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("identity called") + cli.OnOffIdentity(args, nil) + }, +} + +func isValidArg(onOff string) bool { + return (strings.EqualFold(onOff, "on") || strings.EqualFold(onOff, "off")) +} + +func init() { + rootCmd.AddCommand(identityCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // identityCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // identityCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/service/ziti-tunnel/cmd/root.go b/service/ziti-tunnel/cmd/root.go index 0a3cc12a..7fb81ba5 100644 --- a/service/ziti-tunnel/cmd/root.go +++ b/service/ziti-tunnel/cmd/root.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" + "log" "os" "github.com/spf13/cobra" @@ -75,5 +76,5 @@ func initConfig() { } func checkHelp() { - fmt.Println("Use -h or --help option to get the help message") + log.Println("Use -h or --help option to get the help message") } diff --git a/service/ziti-tunnel/cmd/services.go b/service/ziti-tunnel/cmd/services.go index b752294a..3ae39159 100644 --- a/service/ziti-tunnel/cmd/services.go +++ b/service/ziti-tunnel/cmd/services.go @@ -24,7 +24,7 @@ import ( // servicesCmd represents the services command var servicesCmd = &cobra.Command{ - Use: "services", + Use: "services [all] [svc_name...]", Short: "Lists services from ziti-tunnel", Long: `View the services that this user has access to. The records will be fetched from ziti-tunnel`, @@ -37,5 +37,4 @@ var servicesCmd = &cobra.Command{ func init() { listCmd.AddCommand(servicesCmd) - } diff --git a/service/ziti-tunnel/dto/clidtos.go b/service/ziti-tunnel/dto/clidtos.go index 1f6b544c..412cccfc 100644 --- a/service/ziti-tunnel/dto/clidtos.go +++ b/service/ziti-tunnel/dto/clidtos.go @@ -35,3 +35,8 @@ type ServiceCli struct { AssignedHost string OwnsIntercept bool } + +type IdentityOnOffPayload struct { + OnOff string + Fingerprint string +} diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index 6486834e..d9789538 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -105,6 +105,8 @@ func main() { fmt.Println(version()) case "list": commandline.Execute() + case "identity": + commandline.Execute() default: usage(fmt.Sprintf("invalid command %s", cmd)) } From b99b9bcf375701f8af3a13d81f2ec35bb361f13f Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Tue, 2 Mar 2021 14:01:00 +0530 Subject: [PATCH 02/24] identity on off function --- service/ziti-tunnel/cli/ipcClient.go | 62 ++++++++++++++------ service/ziti-tunnel/cli/responseGenerator.go | 16 +++++ service/ziti-tunnel/cli/service.go | 10 ++-- service/ziti-tunnel/cmd/identity.go | 4 +- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index efe0cc01..5d75cc77 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -30,7 +30,8 @@ import ( "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" ) -type fetchFromRTS func([]string, *dto.TunnelStatus, map[string]bool) dto.Response +type fetchStatusFromRTS func([]string, *dto.TunnelStatus, map[string]bool) dto.Response +type fetchResponseFromRTS func([]string, dto.Response, map[string]bool) dto.Response func sendMessagetoPipe(ipcPipeConn net.Conn, commandMsg *dto.CommandMsg, args []string) error { writer := bufio.NewWriter(ipcPipeConn) @@ -49,7 +50,7 @@ func sendMessagetoPipe(ipcPipeConn net.Conn, commandMsg *dto.CommandMsg, args [] return nil } -func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchFromRTS, args []string, flags map[string]bool) { +func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { reader := bufio.NewReader(ipcPipeConn) msg, err := reader.ReadString('\n') @@ -65,30 +66,55 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchF } dec := json.NewDecoder(strings.NewReader(msg)) - var tunnelStatus dto.ZitiTunnelStatus - if err := dec.Decode(&tunnelStatus); err == io.EOF { - readDone <- struct{}{} - return - } else if err != nil { - log.Fatal(err) + + if fn != nil { + var tunnelStatus dto.ZitiTunnelStatus + if err := dec.Decode(&tunnelStatus); err == io.EOF { + readDone <- struct{}{} + return + } else if err != nil { + log.Fatal(err) + } + + if tunnelStatus.Status != nil { + responseMsg := fn(args, tunnelStatus.Status, flags) + if responseMsg.Code == service.SUCCESS { + log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) + } else { + log.Info(responseMsg.Error) + } + } else { + log.Errorf("Ziti tunnel retuned nil status") + } } - if tunnelStatus.Status != nil { - responseMsg := fn(args, tunnelStatus.Status, flags) - if responseMsg.Code == service.SUCCESS { - log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) - } else { - log.Info(responseMsg.Error) + if responseFn != nil { + var response dto.Response + if err := dec.Decode(&response); err == io.EOF { + readDone <- struct{}{} + return + } else if err != nil { + log.Fatal(err) + } + + if response.Message != "" { + responseMsg := responseFn(args, response, flags) + if responseMsg.Code == service.SUCCESS { + log.Infof("Payload : %v", responseMsg.Payload) + log.Infof("Message : %s", responseMsg.Message) + } else { + log.Info(responseMsg.Error) + } + } else { + log.Errorf("Ziti tunnel retuned nil response") } - } else { - log.Errorf("Ziti tunnel retuned nil status") } readDone <- struct{}{} return } -func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchFromRTS, args []string, flags map[string]bool) { +func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { log.Infof("fetching identities through cmdline...%s", args) log.Debug("Connecting to pipe") @@ -103,7 +129,7 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchFromRTS, args []stri readDone := make(chan struct{}) defer close(readDone) // ensure that goroutine exits - go readMessageFromPipe(ipcPipeConn, readDone, fn, args, flags) + go readMessageFromPipe(ipcPipeConn, readDone, fn, responseFn, args, flags) err = sendMessagetoPipe(ipcPipeConn, commandMsg, args) if err != nil { diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index 7ba79ac7..c8a4e189 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -179,3 +179,19 @@ func generateResponse(dataType string, message string, filteredData interface{}, return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: responseStr} } + +// GetIdentityStatusFromRTS is to get identity info from the RTS +func GetIdentityStatusFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { + log.Debugf("Message from ziti-tunnel : %v", status.Message) + if status.Error == "" && status.Payload != nil { + log.Debugf("Payload from RTS %v", status.Payload) + payloadData := status.Payload.(map[string]interface{}) + tunStatus := make(map[string]interface{}) + tunStatus["FingerPrint"] = payloadData["FingerPrint"] + tunStatus["Active"] = payloadData["Active"] + tunStatus["Name"] = payloadData["Name"] + return dto.Response{Message: status.Message, Code: service.SUCCESS, Error: "", Payload: tunStatus} + } else { + return status + } +} diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index 85c72605..96f3b33a 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -4,20 +4,20 @@ import "strings" //GetIdentities is to fetch identities through cmdline func GetIdentities(args []string, flags map[string]bool) { - GetDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, args, flags) + GetDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, nil, args, flags) } //GetServices is to fetch services through cmdline func GetServices(args []string, flags map[string]bool) { - GetDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, args, flags) + GetDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, nil, args, flags) } -//GetFeedback is to fetch logs and sysntem info through cmdline +//OnOffIdentity is to enable or disable the identity through cmdline func OnOffIdentity(args []string, flags map[string]bool) { identityPayload := make(map[string]interface{}) identityPayload["OnOff"] = strings.EqualFold(args[1], "on") identityPayload["Fingerprint"] = args[0] ONOFF_IDENTITY.Payload = identityPayload - log.Infof("OnOffIdentity Payload %v", ONOFF_IDENTITY) - GetDataFromIpcPipe(&ONOFF_IDENTITY, GetServicesFromRTS, args, flags) + log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) + GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityStatusFromRTS, args, flags) } diff --git a/service/ziti-tunnel/cmd/identity.go b/service/ziti-tunnel/cmd/identity.go index 5a7598b6..1644f977 100644 --- a/service/ziti-tunnel/cmd/identity.go +++ b/service/ziti-tunnel/cmd/identity.go @@ -17,7 +17,6 @@ package cmd import ( "errors" - "fmt" "strings" "github.com/openziti/desktop-edge-win/service/ziti-tunnel/cli" @@ -30,7 +29,7 @@ var identityCmd = &cobra.Command{ Use: "identity [fingerprint] [on/off]", Short: "enable or disable the identity", Long: `Enable or disable identity based on the On Off values. - It accepts finger print of the identity followed by On Off values`, + It accepts finger print of the identity followed by on/off value`, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 2 { return errors.New("requires a 2 arguments, usage: identity [fingerprint] [on/off]") @@ -41,7 +40,6 @@ var identityCmd = &cobra.Command{ return errors.New("incorrect arguments are passed, usage: identity [fingerprint] [on/off]") }, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("identity called") cli.OnOffIdentity(args, nil) }, } From 8265e3c0b5c7c95814ee593b62013fb1f7f7bb4d Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Wed, 3 Mar 2021 21:41:59 +0530 Subject: [PATCH 03/24] set loglevel command line option --- service/ziti-tunnel/cli/constants.go | 4 ++ service/ziti-tunnel/cli/ipcClient.go | 15 ++++-- service/ziti-tunnel/cli/responseGenerator.go | 15 +++++- service/ziti-tunnel/cli/service.go | 15 +++++- service/ziti-tunnel/cmd/identities.go | 3 +- service/ziti-tunnel/cmd/identity.go | 44 +++++++-------- service/ziti-tunnel/cmd/loglevel.go | 57 ++++++++++++++++++++ service/ziti-tunnel/main.go | 4 +- 8 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 service/ziti-tunnel/cmd/loglevel.go diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index 9a703d39..f9134514 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -30,6 +30,10 @@ var ONOFF_IDENTITY = dto.CommandMsg{ Function: "IdentityOnOff", } +var SET_LOGLEVEL = dto.CommandMsg{ + Function: "SetLogLevel", +} + var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index 5d75cc77..875fd30d 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -100,7 +100,9 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS if response.Message != "" { responseMsg := responseFn(args, response, flags) if responseMsg.Code == service.SUCCESS { - log.Infof("Payload : %v", responseMsg.Payload) + if responseMsg.Payload != nil { + log.Infof("Payload : %v", responseMsg.Payload) + } log.Infof("Message : %s", responseMsg.Message) } else { log.Info(responseMsg.Error) @@ -115,7 +117,7 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS } func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { - log.Infof("fetching identities through cmdline...%s", args) + log.Infof("Command %s with args %s", commandMsg.Function, args) log.Debug("Connecting to pipe") timeout := 2000 * time.Millisecond @@ -124,6 +126,7 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo if err != nil { log.Errorf("Connection to ipc pipe is not established, %v", err) + log.Errorf("Ziti Desktop Edge app may not be running") return } readDone := make(chan struct{}) @@ -144,8 +147,10 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo } func closeConn(conn net.Conn) { - err := conn.Close() - if err != nil { - log.Warnf("abnormal error while closing connection. %v", err) + if conn != nil { + err := conn.Close() + if err != nil { + log.Warnf("abnormal error while closing connection. %v", err) + } } } diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index c8a4e189..6eec479b 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -180,8 +180,19 @@ func generateResponse(dataType string, message string, filteredData interface{}, return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: responseStr} } -// GetIdentityStatusFromRTS is to get identity info from the RTS -func GetIdentityStatusFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { +func GetLogLevelFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { + + if flags["query"] == true { + message := fmt.Sprintf("Loglevel is currently set to %s", status.LogLevel) + return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: ""} + } + errMsg := fmt.Sprintf("Unknown error: args %s flag %v", args, flags) + return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: ""} + +} + +// GetResponseObjectFromRTS is to get identity info from the RTS +func GetResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { log.Debugf("Message from ziti-tunnel : %v", status.Message) if status.Error == "" && status.Payload != nil { log.Debugf("Payload from RTS %v", status.Payload) diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index 96f3b33a..d6a937c6 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -19,5 +19,18 @@ func OnOffIdentity(args []string, flags map[string]bool) { identityPayload["Fingerprint"] = args[0] ONOFF_IDENTITY.Payload = identityPayload log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) - GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityStatusFromRTS, args, flags) + GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetResponseObjectFromRTS, args, flags) +} + +//SetLogLevel is to change the loglevel through cmdline +func SetLogLevel(args []string, flags map[string]bool) { + if flags["query"] == true { + GetDataFromIpcPipe(&GET_STATUS, GetLogLevelFromRTS, nil, args, flags) + } else { + loglevelPayload := make(map[string]interface{}) + loglevelPayload["Level"] = args[0] + SET_LOGLEVEL.Payload = loglevelPayload + log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) + GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) + } } diff --git a/service/ziti-tunnel/cmd/identities.go b/service/ziti-tunnel/cmd/identities.go index 06d6c3c5..41e4c217 100644 --- a/service/ziti-tunnel/cmd/identities.go +++ b/service/ziti-tunnel/cmd/identities.go @@ -26,7 +26,7 @@ var servicesOfID bool // identitiesCmd represents the identities command var identitiesCmd = &cobra.Command{ - Use: "identities [all] [idname...]", + Use: "identities [all] [idname...] [-s]", Short: "Lists identities from ziti-tunnel", Long: `View the identities that this user has access to. The records will be fetched from ziti-tunnel`, @@ -45,7 +45,6 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - //identitiesCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") identitiesCmd.Flags().BoolVarP(&servicesOfID, "services", "s", false, "Display all services that belonged to the identity") } diff --git a/service/ziti-tunnel/cmd/identity.go b/service/ziti-tunnel/cmd/identity.go index 1644f977..37294ab1 100644 --- a/service/ziti-tunnel/cmd/identity.go +++ b/service/ziti-tunnel/cmd/identity.go @@ -1,20 +1,22 @@ -/* -Copyright © 2021 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + import ( "errors" "strings" @@ -32,7 +34,7 @@ var identityCmd = &cobra.Command{ It accepts finger print of the identity followed by on/off value`, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 2 { - return errors.New("requires a 2 arguments, usage: identity [fingerprint] [on/off]") + return errors.New("requires 2 arguments, usage: identity [fingerprint] [on/off]") } if len(args[0]) == 40 && isValidArg(args[1]) { return nil @@ -50,14 +52,4 @@ func isValidArg(onOff string) bool { func init() { rootCmd.AddCommand(identityCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // identityCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // identityCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } diff --git a/service/ziti-tunnel/cmd/loglevel.go b/service/ziti-tunnel/cmd/loglevel.go new file mode 100644 index 00000000..b43d5f47 --- /dev/null +++ b/service/ziti-tunnel/cmd/loglevel.go @@ -0,0 +1,57 @@ +package cmd + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "errors" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/cli" + "github.com/spf13/cobra" +) + +var currentLogLevel bool + +// loglevelCmd represents the loglevel command +var loglevelCmd = &cobra.Command{ + Use: "loglevel [loglevel]", + Short: "Set the loglevel of the ziti tunnel", + Long: `Allows you to set the log level of ziti tunnel.`, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 && !currentLogLevel { + return errors.New("requires 1 argument or a flag, examples of the accepted loglevel arguments are trace, info, debug etc") + } + return nil + + }, + Run: func(cmd *cobra.Command, args []string) { + flags := map[string]bool{} + flags["query"] = currentLogLevel + cli.SetLogLevel(args, flags) + }, +} + +func init() { + rootCmd.AddCommand(loglevelCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + loglevelCmd.PersistentFlags().BoolVarP(¤tLogLevel, "query", "q", false, "Query current loglevel") + +} diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index d9789538..6576db89 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -107,6 +107,8 @@ func main() { commandline.Execute() case "identity": commandline.Execute() + case "loglevel": + commandline.Execute() default: usage(fmt.Sprintf("invalid command %s", cmd)) } @@ -122,7 +124,7 @@ func usage(errmsg string) { "%s\n\n"+ "usage: %s \n"+ " where is one of\n"+ - " install, remove, debug, start, stop, pause, continue, list or version.\n", + " install, remove, debug, start, stop, pause, continue, list, identity, loglevel or version.\n", errmsg, os.Args[0]) os.Exit(2) } From 00de956e1088f9c260fc030d368b7f423faa83e0 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Fri, 5 Mar 2021 16:02:57 +0530 Subject: [PATCH 04/24] notify the UI through events channel --- service/ziti-tunnel/cli/constants.go | 4 ++++ service/ziti-tunnel/cli/ipcClient.go | 7 ++++--- service/ziti-tunnel/cli/responseGenerator.go | 19 ++++++++++++------- service/ziti-tunnel/cli/service.go | 8 ++++++-- service/ziti-tunnel/dto/dtos.go | 16 +++++++++++----- service/ziti-tunnel/service/events.go | 14 ++++++++++---- service/ziti-tunnel/service/ipc.go | 12 ++++++++++++ 7 files changed, 59 insertions(+), 21 deletions(-) diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index f9134514..41e9712a 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -34,6 +34,10 @@ var SET_LOGLEVEL = dto.CommandMsg{ Function: "SetLogLevel", } +var NOTIFY_UI = dto.CommandMsg{ + Function: "NotifyUIAndUpdateService", +} + var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index 875fd30d..c5711b52 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -116,7 +116,7 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS return } -func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { +func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) bool { log.Infof("Command %s with args %s", commandMsg.Function, args) log.Debug("Connecting to pipe") @@ -127,7 +127,7 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo if err != nil { log.Errorf("Connection to ipc pipe is not established, %v", err) log.Errorf("Ziti Desktop Edge app may not be running") - return + return false } readDone := make(chan struct{}) defer close(readDone) // ensure that goroutine exits @@ -137,13 +137,14 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo err = sendMessagetoPipe(ipcPipeConn, commandMsg, args) if err != nil { log.Errorf("Message is not sent to ipc pipe, %v", err) - return + return false } log.Debugf("Connection to ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) <-readDone log.Debug("read finished normally") + return true } func closeConn(conn net.Conn) { diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index 6eec479b..dcb13dce 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -191,18 +191,23 @@ func GetLogLevelFromRTS(args []string, status *dto.TunnelStatus, flags map[strin } -// GetResponseObjectFromRTS is to get identity info from the RTS -func GetResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { +// GetIdentityResponseObjectFromRTS is to get identity info from the RTS +func GetIdentityResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { log.Debugf("Message from ziti-tunnel : %v", status.Message) if status.Error == "" && status.Payload != nil { log.Debugf("Payload from RTS %v", status.Payload) payloadData := status.Payload.(map[string]interface{}) - tunStatus := make(map[string]interface{}) - tunStatus["FingerPrint"] = payloadData["FingerPrint"] - tunStatus["Active"] = payloadData["Active"] - tunStatus["Name"] = payloadData["Name"] - return dto.Response{Message: status.Message, Code: service.SUCCESS, Error: "", Payload: tunStatus} + identityStatus := make(map[string]interface{}) + identityStatus["FingerPrint"] = payloadData["FingerPrint"] + identityStatus["Active"] = payloadData["Active"] + identityStatus["Name"] = payloadData["Name"] + return dto.Response{Message: status.Message, Code: service.SUCCESS, Error: "", Payload: identityStatus} } else { return status } } + +// GetResponseObjectFromRTS is to get response object info from the RTS +func GetResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { + return status +} diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index d6a937c6..38dc0b0c 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -19,7 +19,7 @@ func OnOffIdentity(args []string, flags map[string]bool) { identityPayload["Fingerprint"] = args[0] ONOFF_IDENTITY.Payload = identityPayload log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) - GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetResponseObjectFromRTS, args, flags) + GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityResponseObjectFromRTS, args, flags) } //SetLogLevel is to change the loglevel through cmdline @@ -31,6 +31,10 @@ func SetLogLevel(args []string, flags map[string]bool) { loglevelPayload["Level"] = args[0] SET_LOGLEVEL.Payload = loglevelPayload log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) - GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) + status := GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) + if status { + log.Infof("Notifying the LogLevel to UI and Ziti monitor service %s", args[0]) + GetDataFromIpcPipe(&NOTIFY_UI, nil, GetResponseObjectFromRTS, args, flags) + } } } diff --git a/service/ziti-tunnel/dto/dtos.go b/service/ziti-tunnel/dto/dtos.go index 200bc8c1..b8827ff4 100644 --- a/service/ziti-tunnel/dto/dtos.go +++ b/service/ziti-tunnel/dto/dtos.go @@ -18,10 +18,11 @@ package dto import ( + "log" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/config" idcfg "github.com/openziti/sdk-golang/ziti/config" "github.com/openziti/sdk-golang/ziti/enroll" - "log" ) type AddIdentity struct { @@ -98,8 +99,8 @@ type TunnelStatus struct { } type ServiceVersion struct { - Version string - Revision string + Version string + Revision string BuildDate string } @@ -109,7 +110,7 @@ type ZitiTunnelStatus struct { } type StatusEvent struct { - Op string + Op string } type ActionEvent struct { @@ -137,4 +138,9 @@ type ServiceEvent struct { type IdentityEvent struct { ActionEvent Id Identity -} \ No newline at end of file +} + +type LogLevelEvent struct { + ActionEvent + LogLevel string +} diff --git a/service/ziti-tunnel/service/events.go b/service/ziti-tunnel/service/events.go index ee204801..9a860bde 100644 --- a/service/ziti-tunnel/service/events.go +++ b/service/ziti-tunnel/service/events.go @@ -19,10 +19,12 @@ package service import "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" const ( - ADDED = "added" - REMOVED = "removed" - SERVICE_OP = "service" + ADDED = "added" + REMOVED = "removed" + SERVICE_OP = "service" IDENTITY_OP = "identity" + LOGLEVEL_OP = "logLevel" + CHANGED = "changed" ) var SERVICE_ADDED = dto.ActionEvent{ @@ -41,4 +43,8 @@ var IDENTITY_ADDED = dto.ActionEvent{ var IDENTITY_REMOVED = dto.ActionEvent{ StatusEvent: dto.StatusEvent{Op: IDENTITY_OP}, Action: REMOVED, -} \ No newline at end of file +} +var LOGLEVEL_CHANGED = dto.ActionEvent{ + StatusEvent: dto.StatusEvent{Op: LOGLEVEL_OP}, + Action: CHANGED, +} diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 21fe16c5..85e54c4a 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -433,6 +433,8 @@ func serveIpc(conn net.Conn) { toggleIdentity(enc, fingerprint, onOff) case "SetLogLevel": setLogLevel(enc, cmd.Payload["Level"].(string)) + case "NotifyUIAndUpdateService": + sendLogLevelAndNotify(enc, cmd.Payload["Level"].(string)) case "ZitiDump": log.Debug("request to ZitiDump received") for _, id := range rts.ids { @@ -998,3 +1000,13 @@ func svcToDto(src cziti.ZService) *dto.Service { return dest } + +func sendLogLevelAndNotify(enc *json.Encoder, loglevel string) { + events.broadcast <- dto.LogLevelEvent{ + ActionEvent: LOGLEVEL_CHANGED, + LogLevel: loglevel, + } + message := fmt.Sprintf("Loglevel %s is sent to the events channel", loglevel) + resp := dto.Response{Message: "success", Code: SUCCESS, Error: "", Payload: message} + respond(enc, resp) +} From 343a52e7c4cc51acc1fa0285cf5374265a6fcd19 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Mon, 8 Mar 2021 15:51:37 +0530 Subject: [PATCH 05/24] sent notify message to UI and monitor for loglevel --- DesktopEdge/MainWindow.xaml.cs | 15 +++++++++++++++ .../DataStructures/DataStructures.cs | 6 ++++++ .../ServiceClient/DataClient.cs | 13 +++++++++++++ service/ziti-tunnel/cli/service.go | 3 ++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index 3bd6b655..2409679b 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -278,6 +278,7 @@ namespace ZitiDesktopEdge { serviceClient.OnMetricsEvent += ServiceClient_OnMetricsEvent; serviceClient.OnServiceEvent += ServiceClient_OnServiceEvent; serviceClient.OnTunnelStatusEvent += ServiceClient_OnTunnelStatusEvent; + serviceClient.OnLogLevelEvent += ServiceClient_OnLogLevelEvent; Application.Current.Properties.Add("ServiceClient", serviceClient); monitorClient = new MonitorClient(); @@ -610,6 +611,20 @@ namespace ZitiDesktopEdge { }); } + private void ServiceClient_OnLogLevelEvent(object sender, LogLevelEvent e) { + if (e.LogLevel != null) { + SetLogLevel_monitor(e.LogLevel); + this.Dispatcher.Invoke(() => { + this.MainMenu.LogLevel = e.LogLevel; + Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.LogLevel); + }); + } + } + + async private void SetLogLevel_monitor(string loglevel) { + await monitorClient.SetLogLevelAsync(loglevel); + } + private void IdentityForgotten(ZitiIdentity forgotten) { ZitiIdentity idToRemove = null; foreach (var id in identities) { diff --git a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs index 777f5827..850dbd01 100644 --- a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs +++ b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs @@ -295,6 +295,12 @@ namespace ZitiDesktopEdge.DataStructures { { public Identity Id { get; set; } } + + public class LogLevelEvent : ActionEvent + { + public string LogLevel { get; set; } + } + public class MonitorServiceStatusEvent : SvcResponse { public string Status { get; set; } diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs index e36a669a..4dbd3ecd 100644 --- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs +++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs @@ -33,6 +33,7 @@ namespace ZitiDesktopEdge.ServiceClient { public event EventHandler> OnMetricsEvent; public event EventHandler OnIdentityEvent; public event EventHandler OnServiceEvent; + public event EventHandler OnLogLevelEvent; protected override void ShutdownEvent(StatusEvent e) { Logger.Debug("Clean shutdown detected from ziti"); @@ -55,6 +56,11 @@ namespace ZitiDesktopEdge.ServiceClient { protected virtual void ServiceEvent(ServiceEvent e) { OnServiceEvent?.Invoke(this, e); } + + protected virtual void LogLevelEvent(LogLevelEvent e) { + OnLogLevelEvent?.Invoke(this, e); + } + protected override void ClientConnected(object e) { base.ClientConnected(e); @@ -235,6 +241,13 @@ namespace ZitiDesktopEdge.ServiceClient { ServiceEvent(svc); } break; + case "logLevel": + LogLevelEvent ll = serializer.Deserialize(jsonReader); + + if (ll != null) { + LogLevelEvent(ll); + } + break; case "shutdown": Logger.Debug("shutdown message received"); var se = new StatusEvent(); diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index 38dc0b0c..5c53c45d 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -33,7 +33,8 @@ func SetLogLevel(args []string, flags map[string]bool) { log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) status := GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) if status { - log.Infof("Notifying the LogLevel to UI and Ziti monitor service %s", args[0]) + NOTIFY_UI.Payload = loglevelPayload + log.Infof("Notifying the LogLevel to UI and Ziti monitor service %v", NOTIFY_UI) GetDataFromIpcPipe(&NOTIFY_UI, nil, GetResponseObjectFromRTS, args, flags) } } From d1766726bbdfd62684cd881056572e1589f3b320 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Mon, 8 Mar 2021 18:33:15 +0530 Subject: [PATCH 06/24] notify ui about identity changes --- DesktopEdge/MainWindow.xaml.cs | 1 + service/ziti-tunnel/cli/constants.go | 8 ++++++-- service/ziti-tunnel/cli/service.go | 13 +++++++++---- service/ziti-tunnel/service/ipc.go | 23 ++++++++++++++++++++++- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index 2409679b..456f1584 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -517,6 +517,7 @@ namespace ZitiDesktopEdge { found.Name = zid.Name; found.ControllerUrl = zid.ControllerUrl; found.IsEnabled = zid.IsEnabled; + LoadIdentities(true); return; } } else { diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index 41e9712a..f2643929 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -34,8 +34,12 @@ var SET_LOGLEVEL = dto.CommandMsg{ Function: "SetLogLevel", } -var NOTIFY_UI = dto.CommandMsg{ - Function: "NotifyUIAndUpdateService", +var NOTIFY_LOGLEVEL_UI_MONITOR = dto.CommandMsg{ + Function: "NotifyLogLevelUIAndUpdateService", +} + +var NOTIFY_IDENTITY_UI = dto.CommandMsg{ + Function: "NotifyIdentityUI", } var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index 5c53c45d..a52dc818 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -19,7 +19,12 @@ func OnOffIdentity(args []string, flags map[string]bool) { identityPayload["Fingerprint"] = args[0] ONOFF_IDENTITY.Payload = identityPayload log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) - GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityResponseObjectFromRTS, args, flags) + status := GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityResponseObjectFromRTS, args, flags) + if status { + NOTIFY_IDENTITY_UI.Payload = identityPayload + log.Infof("Notifying the Identity Status to UI %v", identityPayload) + GetDataFromIpcPipe(&NOTIFY_IDENTITY_UI, nil, GetResponseObjectFromRTS, args, flags) + } } //SetLogLevel is to change the loglevel through cmdline @@ -33,9 +38,9 @@ func SetLogLevel(args []string, flags map[string]bool) { log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) status := GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) if status { - NOTIFY_UI.Payload = loglevelPayload - log.Infof("Notifying the LogLevel to UI and Ziti monitor service %v", NOTIFY_UI) - GetDataFromIpcPipe(&NOTIFY_UI, nil, GetResponseObjectFromRTS, args, flags) + NOTIFY_LOGLEVEL_UI_MONITOR.Payload = loglevelPayload + log.Infof("Notifying the LogLevel to UI and Ziti monitor service %v", loglevelPayload) + GetDataFromIpcPipe(&NOTIFY_LOGLEVEL_UI_MONITOR, nil, GetResponseObjectFromRTS, args, flags) } } } diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 85e54c4a..29627276 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -433,8 +433,10 @@ func serveIpc(conn net.Conn) { toggleIdentity(enc, fingerprint, onOff) case "SetLogLevel": setLogLevel(enc, cmd.Payload["Level"].(string)) - case "NotifyUIAndUpdateService": + case "NotifyLogLevelUIAndUpdateService": sendLogLevelAndNotify(enc, cmd.Payload["Level"].(string)) + case "NotifyIdentityUI": + sendIdentityAndNotifyUI(enc, cmd.Payload["Fingerprint"].(string)) case "ZitiDump": log.Debug("request to ZitiDump received") for _, id := range rts.ids { @@ -1007,6 +1009,25 @@ func sendLogLevelAndNotify(enc *json.Encoder, loglevel string) { LogLevel: loglevel, } message := fmt.Sprintf("Loglevel %s is sent to the events channel", loglevel) + log.Info(message) resp := dto.Response{Message: "success", Code: SUCCESS, Error: "", Payload: message} respond(enc, resp) } + +func sendIdentityAndNotifyUI(enc *json.Encoder, fingerprint string) { + for _, id := range rts.ids { + if id.FingerPrint == fingerprint { + events.broadcast <- dto.IdentityEvent{ + ActionEvent: IDENTITY_ADDED, + Id: id.Identity, + } + message := fmt.Sprintf("Identity %s - %s updated message is sent to the events channel", id.Identity.Name, id.Identity.FingerPrint) + log.Info(message) + resp := dto.Response{Message: "success", Code: SUCCESS, Error: "", Payload: message} + respond(enc, resp) + return + } + } + resp := dto.Response{Message: "", Code: ERROR, Error: "Could not find id matching fingerprint " + fingerprint, Payload: ""} + respond(enc, resp) +} From 2de56dd72fd66d03d6a7494909f8be0104a2bf2b Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Tue, 9 Mar 2021 19:26:17 +0530 Subject: [PATCH 07/24] display proper error message --- service/ziti-tunnel/cli/ipcClient.go | 36 ++++++++++++++++++++-------- service/ziti-tunnel/service/ipc.go | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index c5711b52..d933322e 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -50,14 +50,14 @@ func sendMessagetoPipe(ipcPipeConn net.Conn, commandMsg *dto.CommandMsg, args [] return nil } -func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { +func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan bool, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { reader := bufio.NewReader(ipcPipeConn) msg, err := reader.ReadString('\n') if err != nil { log.Error(err) - readDone <- struct{}{} + readDone <- false return } @@ -70,18 +70,26 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS if fn != nil { var tunnelStatus dto.ZitiTunnelStatus if err := dec.Decode(&tunnelStatus); err == io.EOF { - readDone <- struct{}{} + readDone <- false return } else if err != nil { log.Fatal(err) + readDone <- false + return } if tunnelStatus.Status != nil { responseMsg := fn(args, tunnelStatus.Status, flags) if responseMsg.Code == service.SUCCESS { log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) + readDone <- true + return } else { - log.Info(responseMsg.Error) + if responseMsg.Error != "" { + log.Info(responseMsg.Error) + } else { + log.Info(responseMsg.Message) + } } } else { log.Errorf("Ziti tunnel retuned nil status") @@ -91,10 +99,12 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS if responseFn != nil { var response dto.Response if err := dec.Decode(&response); err == io.EOF { - readDone <- struct{}{} + readDone <- false return } else if err != nil { log.Fatal(err) + readDone <- false + return } if response.Message != "" { @@ -104,15 +114,21 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan struct{}, fn fetchS log.Infof("Payload : %v", responseMsg.Payload) } log.Infof("Message : %s", responseMsg.Message) + readDone <- true + return } else { - log.Info(responseMsg.Error) + if responseMsg.Error != "" { + log.Info(responseMsg.Error) + } else { + log.Info(responseMsg.Message) + } } } else { log.Errorf("Ziti tunnel retuned nil response") } } - readDone <- struct{}{} + readDone <- false return } @@ -129,7 +145,7 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo log.Errorf("Ziti Desktop Edge app may not be running") return false } - readDone := make(chan struct{}) + readDone := make(chan bool) defer close(readDone) // ensure that goroutine exits go readMessageFromPipe(ipcPipeConn, readDone, fn, responseFn, args, flags) @@ -142,9 +158,9 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo log.Debugf("Connection to ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) - <-readDone + status := <-readDone log.Debug("read finished normally") - return true + return status } func closeConn(conn net.Conn) { diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 29627276..04e4d187 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -613,7 +613,7 @@ func toggleIdentity(out *json.Encoder, fingerprint string, onOff bool) { msg := fmt.Sprintf("identity with fingerprint %s not found", fingerprint) log.Warn(msg) respond(out, dto.Response{ - Code: SUCCESS, + Code: IDENTITY_NOT_FOUND, Message: fmt.Sprintf("no update performed. %s", msg), Error: "", Payload: nil, From 6548984434aed92bccdb6aacd288b02a4ea9726f Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Thu, 11 Mar 2021 00:17:36 +0530 Subject: [PATCH 08/24] adding feedback option to the cmd line --- service/ziti-tunnel/cli/constants.go | 2 + service/ziti-tunnel/cli/ipcClient.go | 85 +++++++++++++++++++++++++++ service/ziti-tunnel/cli/service.go | 11 +++- service/ziti-tunnel/cmd/feedback.go | 38 ++++++++++++ service/ziti-tunnel/dto/clidtos.go | 6 ++ service/ziti-tunnel/main.go | 2 + service/ziti-tunnel/service/events.go | 7 +++ 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 service/ziti-tunnel/cmd/feedback.go diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index f2643929..816881e8 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -42,6 +42,8 @@ var NOTIFY_IDENTITY_UI = dto.CommandMsg{ Function: "NotifyIdentityUI", } +var monitorIpcPipe = `\\.\pipe\OpenZiti\ziti-monitor\ipc` + var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index d933322e..3a395e66 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -163,6 +163,91 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo return status } +// monitor ipc messages + +func GetDataFromMonitorIpcPipe(actionMessage *dto.ActionEvent, args []string, flags map[string]bool) bool { + log.Infof("Command %s with args %s", actionMessage.StatusEvent.Op, args) + + log.Debug("Connecting to pipe") + timeout := 2000 * time.Millisecond + ipcPipeConn, err := winio.DialPipe(monitorIpcPipe, &timeout) + defer closeConn(ipcPipeConn) + + if err != nil { + log.Errorf("Connection to monitor ipc pipe is not established, %v", err) + log.Errorf("Ziti Update service may not be running") + return false + } + readDone := make(chan bool) + defer close(readDone) // ensure that goroutine exits + + go readMessageFromMonitorPipe(ipcPipeConn, readDone, args, flags) + + err = sendMessageToMonitorPipe(ipcPipeConn, actionMessage, args) + if err != nil { + log.Errorf("Message is not sent to monitor ipc pipe, %v", err) + return false + } + + log.Debugf("Connection to monitor ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) + + status := <-readDone + log.Debug("read finished normally") + return status +} + +func sendMessageToMonitorPipe(ipcPipeConn net.Conn, actionMessage *dto.ActionEvent, args []string) error { + writer := bufio.NewWriter(ipcPipeConn) + enc := json.NewEncoder(writer) + + err := enc.Encode(actionMessage) + if err != nil { + log.Error("could not encode or write response message, %v", err) + return err + } + + log.Debug("Message sent to monitor ipc pipe") + + writer.Flush() + + return nil +} + +func readMessageFromMonitorPipe(ipcPipeConn net.Conn, readDone chan bool, args []string, flags map[string]bool) { + + reader := bufio.NewReader(ipcPipeConn) + msg, err := reader.ReadString('\n') + + if err != nil { + log.Error(err) + readDone <- false + return + } + + dec := json.NewDecoder(strings.NewReader(msg)) + + var monitorServiceResponse dto.MonitorServiceResponse + if err := dec.Decode(&monitorServiceResponse); err == io.EOF { + readDone <- false + return + } else if err != nil { + log.Fatal(err) + readDone <- false + return + } + + if monitorServiceResponse.Code == service.SUCCESS { + log.Infof("Feedback file %s is created", monitorServiceResponse.Message) + readDone <- true + return + } else { + log.Info(monitorServiceResponse.Error) + } + + readDone <- false + return +} + func closeConn(conn net.Conn) { if conn != nil { err := conn.Close() diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index a52dc818..41e93c45 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -1,6 +1,10 @@ package cli -import "strings" +import ( + "strings" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" +) //GetIdentities is to fetch identities through cmdline func GetIdentities(args []string, flags map[string]bool) { @@ -44,3 +48,8 @@ func SetLogLevel(args []string, flags map[string]bool) { } } } + +//GetFeedback is to create logs zip through cmdline +func GetFeedback(args []string, flags map[string]bool) { + GetDataFromMonitorIpcPipe(&service.FEEDBACK_REQUEST, args, flags) +} diff --git a/service/ziti-tunnel/cmd/feedback.go b/service/ziti-tunnel/cmd/feedback.go new file mode 100644 index 00000000..a1e2e965 --- /dev/null +++ b/service/ziti-tunnel/cmd/feedback.go @@ -0,0 +1,38 @@ +package cmd + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/cli" + "github.com/spf13/cobra" +) + +// feedbackCmd represents the feedback command +var feedbackCmd = &cobra.Command{ + Use: "feedback", + Short: "fetch system information and logs from ziti-tunnel", + Long: `Fetch the system information and logs, zip it and attach it to the email. +User has to send the email to support@netfoundry.io`, + Run: func(cmd *cobra.Command, args []string) { + cli.GetFeedback(args, nil) + }, +} + +func init() { + rootCmd.AddCommand(feedbackCmd) +} diff --git a/service/ziti-tunnel/dto/clidtos.go b/service/ziti-tunnel/dto/clidtos.go index 412cccfc..84700243 100644 --- a/service/ziti-tunnel/dto/clidtos.go +++ b/service/ziti-tunnel/dto/clidtos.go @@ -40,3 +40,9 @@ type IdentityOnOffPayload struct { OnOff string Fingerprint string } + +type MonitorServiceResponse struct { + Code int + Message string + Error string +} diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index 6576db89..2939135e 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -109,6 +109,8 @@ func main() { commandline.Execute() case "loglevel": commandline.Execute() + case "feedback": + commandline.Execute() default: usage(fmt.Sprintf("invalid command %s", cmd)) } diff --git a/service/ziti-tunnel/service/events.go b/service/ziti-tunnel/service/events.go index 9a860bde..f7bc5de0 100644 --- a/service/ziti-tunnel/service/events.go +++ b/service/ziti-tunnel/service/events.go @@ -24,7 +24,9 @@ const ( SERVICE_OP = "service" IDENTITY_OP = "identity" LOGLEVEL_OP = "logLevel" + FEEDBACK_OP = "CaptureLogs" CHANGED = "changed" + NORMAL = "Normal" ) var SERVICE_ADDED = dto.ActionEvent{ @@ -48,3 +50,8 @@ var LOGLEVEL_CHANGED = dto.ActionEvent{ StatusEvent: dto.StatusEvent{Op: LOGLEVEL_OP}, Action: CHANGED, } + +var FEEDBACK_REQUEST = dto.ActionEvent{ + StatusEvent: dto.StatusEvent{Op: FEEDBACK_OP}, + Action: NORMAL, +} From 5198f40ac4ed606813c39f069d1b65d3b47e1bc5 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Thu, 11 Mar 2021 16:11:18 +0530 Subject: [PATCH 09/24] updainge the version --- release-notes.md | 14 ++++++++++++++ service/ziti-tunnel/main.go | 2 +- version | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/release-notes.md b/release-notes.md index 76d7c153..34d71867 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,3 +1,17 @@ +# Release 1.8.3 + +## What's New +* [#322](https://github.com/openziti/desktop-edge-win/issues/322) Ability to toggle identity, set loglevel and generate feedback zip file from cmd line + +## Other changes: +* none + +## Bugs fixed: +* none + +## Dependency Updates +* none + # Release 1.8.2 ## What's New diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index 2939135e..c1c3f236 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -126,7 +126,7 @@ func usage(errmsg string) { "%s\n\n"+ "usage: %s \n"+ " where is one of\n"+ - " install, remove, debug, start, stop, pause, continue, list, identity, loglevel or version.\n", + " install, remove, debug, start, stop, pause, continue, list, identity, loglevel, feedback or version.\n", errmsg, os.Args[0]) os.Exit(2) } diff --git a/version b/version index 53adb84c..a7ee35a3 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.8.2 +1.8.3 From ecdb2307f8310c5d22e0e7cf5a38b26d18a5849c Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Tue, 16 Mar 2021 15:18:15 +0530 Subject: [PATCH 10/24] update version --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index a7ee35a3..bfa363e7 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.8.3 +1.8.4 From 74dbf431b81bf1153bc7b65899407d89e60948f0 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Fri, 19 Mar 2021 15:14:37 +0530 Subject: [PATCH 11/24] fixing build errors after merge --- service/ziti-tunnel/cli/constants.go | 4 ++-- service/ziti-tunnel/cli/responseGenerator.go | 24 ++++++++++++++++---- service/ziti-tunnel/cli/service.go | 4 ++-- service/ziti-tunnel/dto/clidtos.go | 7 +++--- service/ziti-tunnel/dto/events.go | 8 +++---- service/ziti-tunnel/service/ipc.go | 6 +++-- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index 816881e8..3c9f4be5 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -48,8 +48,8 @@ var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint" {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` -var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%40s" "InterceptHost"}} | {{printf "%14s" "InterceptPort"}} | {{printf "%15s" "AssignedIP"}} | {{printf "%15s" "AssignedHost"}} | {{"OwnsIntercept"}} -{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%40s" .InterceptHost}} | {{printf "%14d" .InterceptPort}} | {{printf "%15s" .AssignedIP}} | {{printf "%15s" .AssignedHost}} | {{.OwnsIntercept}} +var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%9s" "Protocols"}} | {{printf "%14s" "Ports"}} | {{printf "%40s" "Addresses"}} | {{"OwnsIntercept"}} +{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%9s" .Protocols}} | {{printf "%14s" .Ports}} | {{printf "%40s" .Addresses}} | {{.OwnsIntercept}} {{end}}` var log = logging.Logger() diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index dcb13dce..83ca8355 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -39,13 +39,29 @@ func convertToIdentityCli(id *dto.Identity) dto.IdentityCli { } func convertToServiceCli(svc dto.Service) dto.ServiceCli { + cliPorts := "" + for _, val := range svc.Ports { + if len(cliPorts) != 0 { + cliPorts = fmt.Sprintf("%s, %d-%d", cliPorts, val.Low, val.High) + } else { + cliPorts = fmt.Sprintf("%d-%d", val.Low, val.High) + } + } + cliAddresses := "" + for _, val := range svc.Addresses { + if len(cliAddresses) != 0 { + cliAddresses = cliAddresses + ", " + val.HostName + "/" + val.IP + } else { + cliAddresses = val.HostName + "/" + val.IP + } + } + return dto.ServiceCli{ Name: svc.Name, Id: svc.Id, - InterceptHost: svc.InterceptHost, - InterceptPort: svc.InterceptPort, - AssignedIP: svc.AssignedIP, - AssignedHost: svc.AssignedHost, + Protocols: strings.Join(svc.Protocols, ","), + Ports: cliPorts, + Addresses: cliAddresses, OwnsIntercept: svc.OwnsIntercept, } } diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index 41e93c45..ebc1b290 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -3,7 +3,7 @@ package cli import ( "strings" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" ) //GetIdentities is to fetch identities through cmdline @@ -51,5 +51,5 @@ func SetLogLevel(args []string, flags map[string]bool) { //GetFeedback is to create logs zip through cmdline func GetFeedback(args []string, flags map[string]bool) { - GetDataFromMonitorIpcPipe(&service.FEEDBACK_REQUEST, args, flags) + GetDataFromMonitorIpcPipe(&dto.FEEDBACK_REQUEST, args, flags) } diff --git a/service/ziti-tunnel/dto/clidtos.go b/service/ziti-tunnel/dto/clidtos.go index 84700243..030cdce8 100644 --- a/service/ziti-tunnel/dto/clidtos.go +++ b/service/ziti-tunnel/dto/clidtos.go @@ -28,11 +28,10 @@ type IdentityCli struct { type ServiceCli struct { Name string - AssignedIP string - InterceptHost string - InterceptPort uint16 Id string - AssignedHost string + Protocols string + Ports string + Addresses string OwnsIntercept bool } diff --git a/service/ziti-tunnel/dto/events.go b/service/ziti-tunnel/dto/events.go index 200788da..401959dd 100644 --- a/service/ziti-tunnel/dto/events.go +++ b/service/ziti-tunnel/dto/events.go @@ -44,12 +44,12 @@ var IDENTITY_REMOVED = ActionEvent{ StatusEvent: StatusEvent{Op: IDENTITY_OP}, Action: REMOVED, } -var LOGLEVEL_CHANGED = dto.ActionEvent{ - StatusEvent: dto.StatusEvent{Op: LOGLEVEL_OP}, +var LOGLEVEL_CHANGED = ActionEvent{ + StatusEvent: StatusEvent{Op: LOGLEVEL_OP}, Action: CHANGED, } -var FEEDBACK_REQUEST = dto.ActionEvent{ - StatusEvent: dto.StatusEvent{Op: FEEDBACK_OP}, +var FEEDBACK_REQUEST = ActionEvent{ + StatusEvent: StatusEvent{Op: FEEDBACK_OP}, Action: NORMAL, } diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 48cefee8..8096ef50 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -1013,9 +1013,10 @@ func authMfa(out *json.Encoder, fingerprint string, code string) { /* }*/ } +// when the log level is updated through command line, the message is broadcasted to UI and update service as well func sendLogLevelAndNotify(enc *json.Encoder, loglevel string) { events.broadcast <- dto.LogLevelEvent{ - ActionEvent: LOGLEVEL_CHANGED, + ActionEvent: dto.LOGLEVEL_CHANGED, LogLevel: loglevel, } message := fmt.Sprintf("Loglevel %s is sent to the events channel", loglevel) @@ -1024,11 +1025,12 @@ func sendLogLevelAndNotify(enc *json.Encoder, loglevel string) { respond(enc, resp) } +// when the identity status is updated through command line, the message is sent to UI as well func sendIdentityAndNotifyUI(enc *json.Encoder, fingerprint string) { for _, id := range rts.ids { if id.FingerPrint == fingerprint { events.broadcast <- dto.IdentityEvent{ - ActionEvent: IDENTITY_ADDED, + ActionEvent: dto.IDENTITY_ADDED, Id: id.Identity, } message := fmt.Sprintf("Identity %s - %s updated message is sent to the events channel", id.Identity.Name, id.Identity.FingerPrint) From e2e6577eadda6b1341b9aa4316fe36b2d79cdfa4 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Fri, 26 Mar 2021 19:47:33 +0530 Subject: [PATCH 12/24] revering the formatting changes --- DesktopEdge/MainWindow.xaml.cs | 2622 ++++++++++++++------------------ 1 file changed, 1162 insertions(+), 1460 deletions(-) diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index 8b8244a5..9de45d69 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -25,755 +25,631 @@ using Microsoft.Win32; using System.Windows.Interop; -namespace ZitiDesktopEdge -{ +namespace ZitiDesktopEdge { - public partial class MainWindow : Window - { - private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + public partial class MainWindow : Window { + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); - public string RECOVER = "RECOVER"; - public System.Windows.Forms.NotifyIcon notifyIcon; - public string Position = "Bottom"; - private DateTime _startDate; - private System.Windows.Forms.Timer _tunnelUptimeTimer; - private DataClient serviceClient = null; - MonitorClient monitorClient = null; - private bool _isAttached = true; - private bool _isServiceInError = false; - private int _right = 75; - private int _left = 75; - private int _top = 30; - private double _maxHeight = 800d; - private string[] suffixes = { "Bps", "kBps", "mBps", "gBps", "tBps", "pBps" }; + public string RECOVER = "RECOVER"; + public System.Windows.Forms.NotifyIcon notifyIcon; + public string Position = "Bottom"; + private DateTime _startDate; + private System.Windows.Forms.Timer _tunnelUptimeTimer; + private DataClient serviceClient = null; + MonitorClient monitorClient = null; + private bool _isAttached = true; + private bool _isServiceInError = false; + private int _right = 75; + private int _left = 75; + private int _top = 30; + private double _maxHeight = 800d; + private string[] suffixes = { "Bps", "kBps", "mBps", "gBps", "tBps", "pBps" }; - private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1); + private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1); - static System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly(); + static System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly(); - public static string ThisAssemblyName; - public static string ExecutionDirectory; - public static string ExpectedLogPathRoot; - public static string ExpectedLogPathUI; - public static string ExpectedLogPathServices; + public static string ThisAssemblyName; + public static string ExecutionDirectory; + public static string ExpectedLogPathRoot; + public static string ExpectedLogPathUI; + public static string ExpectedLogPathServices; - static MainWindow() - { - asm = System.Reflection.Assembly.GetExecutingAssembly(); - ThisAssemblyName = asm.GetName().Name; + static MainWindow() { + asm = System.Reflection.Assembly.GetExecutingAssembly(); + ThisAssemblyName = asm.GetName().Name; #if DEBUG ExecutionDirectory = @"C:\Program Files (x86)\NetFoundry, Inc\Ziti Desktop Edge"; #else - ExecutionDirectory = Path.GetDirectoryName(asm.Location); + ExecutionDirectory = Path.GetDirectoryName(asm.Location); #endif - ExpectedLogPathRoot = Path.Combine(ExecutionDirectory, "logs"); - ExpectedLogPathUI = Path.Combine(ExpectedLogPathRoot, "UI", $"{ThisAssemblyName}.log"); - ExpectedLogPathServices = Path.Combine(ExpectedLogPathRoot, "service", $"ziti-tunneler.log"); - } + ExpectedLogPathRoot = Path.Combine(ExecutionDirectory, "logs"); + ExpectedLogPathUI = Path.Combine(ExpectedLogPathRoot, "UI", $"{ThisAssemblyName}.log"); + ExpectedLogPathServices = Path.Combine(ExpectedLogPathRoot, "service", $"ziti-tunneler.log"); + } - private void IdentityMenu_OnMessage(string message) - { - ShowBlurbAsync(message, ""); - } + private void IdentityMenu_OnMessage(string message) { + ShowBlurbAsync(message, ""); + } - private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) - { - LoadIdentities(true); - } + private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) { + LoadIdentities(true); + } - private List identities - { - get - { - return (List)Application.Current.Properties["Identities"]; - } - } + private List identities { + get { + return (List)Application.Current.Properties["Identities"]; + } + } - /// - /// The MFA Toggle was toggled - /// - /// True if the toggle was on - private async void MFAToggled(bool isOn) - { - if (isOn) - { - ShowLoad("Generating MFA", "MFA Setup Commencing, please wait"); + /// + /// The MFA Toggle was toggled + /// + /// True if the toggle was on + private async void MFAToggled(bool isOn) { + if (isOn) { + ShowLoad("Generating MFA", "MFA Setup Commencing, please wait"); - await serviceClient.EnableMFA(this.IdentityMenu.Identity.Fingerprint); - } - else - { - this.ShowMFA(IdentityMenu.Identity, 3); - } + await serviceClient.EnableMFA(this.IdentityMenu.Identity.Fingerprint); + } else { + this.ShowMFA(IdentityMenu.Identity, 3); + } - HideLoad(); - } + HideLoad(); + } - /// - /// When a Service Client is ready to setup the MFA Authorization - /// - /// The service client - /// The MFA Event - private void ServiceClient_OnMfaEvent(object sender, MfaEvent mfa) - { - HideLoad(); - this.Dispatcher.Invoke(() => - { - if (mfa.Action == "enrollment_challenge") - { - string url = HttpUtility.UrlDecode(mfa.ProvisioningUrl); - string secret = HttpUtility.ParseQueryString(url)["secret"]; - this.IdentityMenu.Identity.MFAInfo.RecoveryCodes = mfa?.RecoveryCodes?.ToArray(); - SetupMFA(this.IdentityMenu.Identity, url, secret); - } - else if (mfa.Action == "auth_challenge") - { - ShowBlurbAsync("Setting Up auth_challenge", ""); - } - else if (mfa.Action == "enrollment_verification") - { - if (mfa.Successful) - { - ShowMFARecoveryCodes(this.IdentityMenu.Identity); - if (this.IdentityMenu.Identity.Fingerprint == mfa.Fingerprint) - { - this.IdentityMenu.Identity.IsMFAEnabled = true; - this.IdentityMenu.Identity.MFAInfo.IsAuthenticated = mfa.Successful; - this.IdentityMenu.UpdateView(); - } - } - else - { - // ShowBlurb("Provided code could not be verified", ""); - This blurbs on remove MFA and it shouldnt - } - } - else if (mfa.Action == "enrollment_remove") - { - // ShowBlurb("removed mfa: " + mfa.Successful, ""); - } - else - { - ShowBlurbAsync("Unexpected error when processing MFA", ""); - logger.Error("unexpected action: " + mfa.Action); - } - LoadIdentities(true); - }); - } + /// + /// When a Service Client is ready to setup the MFA Authorization + /// + /// The service client + /// The MFA Event + private void ServiceClient_OnMfaEvent(object sender, MfaEvent mfa) { + HideLoad(); + this.Dispatcher.Invoke(() => { + if (mfa.Action == "enrollment_challenge") { + string url = HttpUtility.UrlDecode(mfa.ProvisioningUrl); + string secret = HttpUtility.ParseQueryString(url)["secret"]; + this.IdentityMenu.Identity.MFAInfo.RecoveryCodes = mfa?.RecoveryCodes?.ToArray(); + SetupMFA(this.IdentityMenu.Identity, url, secret); + } else if (mfa.Action == "auth_challenge") { + ShowBlurbAsync("Setting Up auth_challenge", ""); + } else if (mfa.Action == "enrollment_verification") { + if (mfa.Successful) { + ShowMFARecoveryCodes(this.IdentityMenu.Identity); + if (this.IdentityMenu.Identity.Fingerprint == mfa.Fingerprint) { + this.IdentityMenu.Identity.IsMFAEnabled = true; + this.IdentityMenu.Identity.MFAInfo.IsAuthenticated = mfa.Successful; + this.IdentityMenu.UpdateView(); + } + } else { + // ShowBlurb("Provided code could not be verified", ""); - This blurbs on remove MFA and it shouldnt + } + } else if (mfa.Action == "enrollment_remove") { + // ShowBlurb("removed mfa: " + mfa.Successful, ""); + } else { + ShowBlurbAsync("Unexpected error when processing MFA", ""); + logger.Error("unexpected action: " + mfa.Action); + } + LoadIdentities(true); + }); + } - /// - /// Show the MFA Setup Modal - /// - /// The Ziti Identity to Setup - public void SetupMFA(ZitiIdentity identity, string url, string secret) - { - MFASetup.Opacity = 0; - MFASetup.Visibility = Visibility.Visible; - MFASetup.Margin = new Thickness(0, 0, 0, 0); - MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); - MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); - MFASetup.ShowSetup(identity, url, secret); - ShowModal(); - } + /// + /// Show the MFA Setup Modal + /// + /// The Ziti Identity to Setup + public void SetupMFA(ZitiIdentity identity, string url, string secret) { + MFASetup.Opacity = 0; + MFASetup.Visibility = Visibility.Visible; + MFASetup.Margin = new Thickness(0, 0, 0, 0); + MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); + MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); + MFASetup.ShowSetup(identity, url, secret); + ShowModal(); + } - /// - /// Show the MFA Authentication Screen when it is time to authenticate - /// - /// The Ziti Identity to Authenticate - public void MFAAuthenticate(ZitiIdentity identity) - { - this.ShowMFA(identity, 1); - } + /// + /// Show the MFA Authentication Screen when it is time to authenticate + /// + /// The Ziti Identity to Authenticate + public void MFAAuthenticate(ZitiIdentity identity) { + this.ShowMFA(identity, 1); + } - private void ShowMFA(ZitiIdentity identity, int type) - { - MFASetup.Opacity = 0; - MFASetup.Visibility = Visibility.Visible; - MFASetup.Margin = new Thickness(0, 0, 0, 0); - MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); - MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); + private void ShowMFA(ZitiIdentity identity, int type) { + MFASetup.Opacity = 0; + MFASetup.Visibility = Visibility.Visible; + MFASetup.Margin = new Thickness(0, 0, 0, 0); + MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); + MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); - MFASetup.ShowMFA(identity, type); + MFASetup.ShowMFA(identity, type); - ShowModal(); - } + ShowModal(); + } - /// - /// Show the MFA Recovery Codes - /// - /// The Ziti Identity to Authenticate - public void ShowMFARecoveryCodes(ZitiIdentity identity) - { - if (identity.MFAInfo != null) - { - if (identity.MFAInfo.RecoveryCodes?.Length > 0) - { - MFASetup.Opacity = 0; - MFASetup.Visibility = Visibility.Visible; - MFASetup.Margin = new Thickness(0, 0, 0, 0); - MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); - MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); + /// + /// Show the MFA Recovery Codes + /// + /// The Ziti Identity to Authenticate + public void ShowMFARecoveryCodes(ZitiIdentity identity) { + if (identity.MFAInfo!=null) { + if (identity.MFAInfo.RecoveryCodes?.Length > 0) { + MFASetup.Opacity = 0; + MFASetup.Visibility = Visibility.Visible; + MFASetup.Margin = new Thickness(0, 0, 0, 0); + MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3))); + MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3))); - MFASetup.ShowRecovery(identity.MFAInfo.RecoveryCodes, identity); + MFASetup.ShowRecovery(identity.MFAInfo.RecoveryCodes, identity); - ShowModal(); - } - else - { - this.ShowMFA(IdentityMenu.Identity, 2); - } - } - else - { - ShowBlurbAsync("MFA is not setup on this Identity", ""); - } - } + ShowModal(); + } else { + this.ShowMFA(IdentityMenu.Identity, 2); + } + } else { + ShowBlurbAsync("MFA is not setup on this Identity", ""); + } + } - /// - /// Show the modal, aniimating opacity - /// - private void ShowModal() - { - ModalBg.Visibility = Visibility.Visible; - ModalBg.Opacity = 0; - DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3)); - ModalBg.BeginAnimation(Grid.OpacityProperty, animation); - } + /// + /// Show the modal, aniimating opacity + /// + private void ShowModal() { + ModalBg.Visibility = Visibility.Visible; + ModalBg.Opacity = 0; + DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3)); + ModalBg.BeginAnimation(Grid.OpacityProperty, animation); + } - /// - /// Close the various MFA windows - /// - /// The close button - /// The event arguments - private void CloseComplete(object sender, EventArgs e) - { - MFASetup.Visibility = Visibility.Collapsed; - } + /// + /// Close the various MFA windows + /// + /// The close button + /// The event arguments + private void CloseComplete(object sender, EventArgs e) { + MFASetup.Visibility = Visibility.Collapsed; + } - /// - /// Hide the modal animating the opacity - /// - private void HideModal() - { - DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); - animation.Completed += ModalHideComplete; - ModalBg.BeginAnimation(Grid.OpacityProperty, animation); - } + /// + /// Hide the modal animating the opacity + /// + private void HideModal() { + DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); + animation.Completed += ModalHideComplete; + ModalBg.BeginAnimation(Grid.OpacityProperty, animation); + } - /// - /// When the animation completes, set the visibility to avoid UI object conflicts - /// - /// The animation - /// The event - private void ModalHideComplete(object sender, EventArgs e) - { - ModalBg.Visibility = Visibility.Collapsed; - } + /// + /// When the animation completes, set the visibility to avoid UI object conflicts + /// + /// The animation + /// The event + private void ModalHideComplete(object sender, EventArgs e) { + ModalBg.Visibility = Visibility.Collapsed; + } - /// - /// Close the MFA Screen with animation - /// - private void DoClose(bool isComplete) - { - DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); - ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3)); - animation.Completed += CloseComplete; - MFASetup.BeginAnimation(Grid.OpacityProperty, animation); - MFASetup.BeginAnimation(Grid.MarginProperty, animateThick); - HideModal(); - LoadIdentities(true); - if (isComplete) - { - if (MFASetup.Type == 1) - { - for (int i = 0; i < identities.Count; i++) - { - if (identities[i].Fingerprint == MFASetup.Identity.Fingerprint) - { - identities[i] = MFASetup.Identity; - } - } - } - } - if (IdentityMenu.IsVisible) - { - if (isComplete) - { - if (MFASetup.Type == 2) - { - if (IdentityMenu.Identity.MFAInfo.RecoveryCodes.Length == 0) ShowBlurbAsync("You do not have anymore recovery codes", this.RECOVER); - else ShowRecovery(IdentityMenu.Identity); - } - else if (MFASetup.Type == 3) - { - IdentityMenu.Identity.IsMFAEnabled = false; - IdentityMenu.Identity.MFAInfo.IsAuthenticated = false; - ShowBlurbAsync("MFA Disabled, Service Access Can Be Limited", ""); - } - else if (MFASetup.Type == 4) - { - ShowRecovery(IdentityMenu.Identity); - } - } - IdentityMenu.UpdateView(); - } - } + /// + /// Close the MFA Screen with animation + /// + private void DoClose(bool isComplete) { + DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); + ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3)); + animation.Completed += CloseComplete; + MFASetup.BeginAnimation(Grid.OpacityProperty, animation); + MFASetup.BeginAnimation(Grid.MarginProperty, animateThick); + HideModal(); + LoadIdentities(true); + if (isComplete) { + if (MFASetup.Type == 1) { + for (int i=0; i id.Fingerprint == i.Fingerprint)) - { - identities.Add(id); - } - semaphoreSlim.Release(); - } + private void AddIdentity(ZitiIdentity id) { + semaphoreSlim.Wait(); + if (!identities.Any(i => id.Fingerprint == i.Fingerprint)) { + identities.Add(id); + } + semaphoreSlim.Release(); + } - private System.Windows.Forms.ContextMenu contextMenu; - private System.Windows.Forms.MenuItem contextMenuItem; - private System.ComponentModel.IContainer components; - public MainWindow() - { - InitializeComponent(); - SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged; - string nlogFile = Path.Combine(ExecutionDirectory, ThisAssemblyName + "-log.config"); + private System.Windows.Forms.ContextMenu contextMenu; + private System.Windows.Forms.MenuItem contextMenuItem; + private System.ComponentModel.IContainer components; + public MainWindow() { + InitializeComponent(); + SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged; + string nlogFile = Path.Combine(ExecutionDirectory, ThisAssemblyName + "-log.config"); - bool byFile = false; - if (File.Exists(nlogFile)) - { - LogManager.Configuration = new XmlLoggingConfiguration(nlogFile); - byFile = true; - } - else - { - var config = new LoggingConfiguration(); - // Targets where to log to: File and Console - var logfile = new FileTarget("logfile") - { - FileName = ExpectedLogPathUI, - ArchiveEvery = FileArchivePeriod.Day, - ArchiveNumbering = ArchiveNumberingMode.Rolling, - MaxArchiveFiles = 7, - Layout = "[${date:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}", - }; - var logconsole = new ConsoleTarget("logconsole"); + bool byFile = false; + if (File.Exists(nlogFile)) { + LogManager.Configuration = new XmlLoggingConfiguration(nlogFile); + byFile = true; + } else { + var config = new LoggingConfiguration(); + // Targets where to log to: File and Console + var logfile = new FileTarget("logfile") { + FileName = ExpectedLogPathUI, + ArchiveEvery = FileArchivePeriod.Day, + ArchiveNumbering = ArchiveNumberingMode.Rolling, + MaxArchiveFiles = 7, + Layout = "[${date:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}", + }; + var logconsole = new ConsoleTarget("logconsole"); - // Rules for mapping loggers to targets - config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole); - config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile); + // Rules for mapping loggers to targets + config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole); + config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile); - // Apply config - LogManager.Configuration = config; - } - logger.Info("============================== UI started =============================="); - logger.Info("logger initialized"); - logger.Info(" - version : {0}", asm.GetName().Version.ToString()); - logger.Info(" - using file: {0}", byFile); - logger.Info("========================================================================"); + // Apply config + LogManager.Configuration = config; + } + logger.Info("============================== UI started =============================="); + logger.Info("logger initialized"); + logger.Info(" - version : {0}", asm.GetName().Version.ToString()); + logger.Info(" - using file: {0}", byFile); + logger.Info("========================================================================"); - App.Current.MainWindow.WindowState = WindowState.Normal; - App.Current.MainWindow.Deactivated += MainWindow_Deactivated; - App.Current.MainWindow.Activated += MainWindow_Activated; - App.Current.Exit += Current_Exit; + App.Current.MainWindow.WindowState = WindowState.Normal; + App.Current.MainWindow.Deactivated += MainWindow_Deactivated; + App.Current.MainWindow.Activated += MainWindow_Activated; + App.Current.Exit += Current_Exit; - this.components = new System.ComponentModel.Container(); - this.contextMenu = new System.Windows.Forms.ContextMenu(); - this.contextMenuItem = new System.Windows.Forms.MenuItem(); - this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.contextMenuItem }); + this.components = new System.ComponentModel.Container(); + this.contextMenu = new System.Windows.Forms.ContextMenu(); + this.contextMenuItem = new System.Windows.Forms.MenuItem(); + this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.contextMenuItem }); - this.contextMenuItem.Index = 0; - this.contextMenuItem.Text = "&Close UI"; - this.contextMenuItem.Click += new System.EventHandler(this.contextMenuItem_Click); + this.contextMenuItem.Index = 0; + this.contextMenuItem.Text = "&Close UI"; + this.contextMenuItem.Click += new System.EventHandler(this.contextMenuItem_Click); - notifyIcon = new System.Windows.Forms.NotifyIcon(); - notifyIcon.Visible = true; - notifyIcon.Click += TargetNotifyIcon_Click; - notifyIcon.Visible = true; - notifyIcon.BalloonTipClosed += NotifyIcon_BalloonTipClosed; - notifyIcon.MouseClick += NotifyIcon_MouseClick; - notifyIcon.ContextMenu = this.contextMenu; + notifyIcon = new System.Windows.Forms.NotifyIcon(); + notifyIcon.Visible = true; + notifyIcon.Click += TargetNotifyIcon_Click; + notifyIcon.Visible = true; + notifyIcon.BalloonTipClosed += NotifyIcon_BalloonTipClosed; + notifyIcon.MouseClick += NotifyIcon_MouseClick; + notifyIcon.ContextMenu = this.contextMenu; - IdentityMenu.OnDetach += OnDetach; - MainMenu.OnDetach += OnDetach; + IdentityMenu.OnDetach += OnDetach; + MainMenu.OnDetach += OnDetach; - this.MainMenu.MainWindow = this; - this.IdentityMenu.MainWindow = this; - SetNotifyIcon("white"); + this.MainMenu.MainWindow = this; + this.IdentityMenu.MainWindow = this; + SetNotifyIcon("white"); - IdentityMenu.OnMessage += IdentityMenu_OnMessage; - } + IdentityMenu.OnMessage += IdentityMenu_OnMessage; + } - private void Current_Exit(object sender, ExitEventArgs e) - { - if (notifyIcon != null) - { - notifyIcon.Visible = false; - notifyIcon.Icon.Dispose(); - notifyIcon.Dispose(); - notifyIcon = null; - } - } + private void Current_Exit(object sender, ExitEventArgs e) { + if (notifyIcon != null) { + notifyIcon.Visible = false; + notifyIcon.Icon.Dispose(); + notifyIcon.Dispose(); + notifyIcon = null; + } + } - private void contextMenuItem_Click(object Sender, EventArgs e) - { - this.Close(); - } + private void contextMenuItem_Click(object Sender, EventArgs e) { + this.Close(); + } - private void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Left) - { - System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e; - this.Show(); - this.Activate(); - //Do the awesome left clickness - } - else if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - //Do the wickedy right clickness - } - else - { - //Some other button from the enum :) - } - } + private void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { + if (e.Button == System.Windows.Forms.MouseButtons.Left) { + System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e; + this.Show(); + this.Activate(); + //Do the awesome left clickness + } else if (e.Button == System.Windows.Forms.MouseButtons.Right) { + //Do the wickedy right clickness + } else { + //Some other button from the enum :) + } + } - private void NotifyIcon_BalloonTipClosed(object sender, EventArgs e) - { - var thisIcon = (System.Windows.Forms.NotifyIcon)sender; - thisIcon.Visible = false; - thisIcon.Dispose(); - } + private void NotifyIcon_BalloonTipClosed(object sender, EventArgs e) { + var thisIcon = (System.Windows.Forms.NotifyIcon)sender; + thisIcon.Visible = false; + thisIcon.Dispose(); + } - private void Window_MouseDown(object sender, MouseButtonEventArgs e) - { - OnDetach(e); - } + private void Window_MouseDown(object sender, MouseButtonEventArgs e) { + OnDetach(e); + } - private void OnDetach(MouseButtonEventArgs e) - { - if (e.ChangedButton == MouseButton.Left) - { - _isAttached = false; - IdentityMenu.Arrow.Visibility = Visibility.Collapsed; - Arrow.Visibility = Visibility.Collapsed; - MainMenu.Detach(); - this.DragMove(); - } - } + private void OnDetach(MouseButtonEventArgs e) { + if (e.ChangedButton == MouseButton.Left) { + _isAttached = false; + IdentityMenu.Arrow.Visibility = Visibility.Collapsed; + Arrow.Visibility = Visibility.Collapsed; + MainMenu.Detach(); + this.DragMove(); + } + } - private void MainWindow_Activated(object sender, EventArgs e) - { - this.Visibility = Visibility.Visible; - Placement(); - } + private void MainWindow_Activated(object sender, EventArgs e) { + this.Visibility = Visibility.Visible; + Placement(); + } - private void MainWindow_Deactivated(object sender, EventArgs e) - { - if (this._isAttached) - { + private void MainWindow_Deactivated(object sender, EventArgs e) { + if (this._isAttached) { #if DEBUG logger.Debug("debug is enabled - windows pinned"); this.Visibility = Visibility.Collapsed; #else - this.Visibility = Visibility.Collapsed; + this.Visibility = Visibility.Collapsed; #endif - } - } + } + } - private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) - { - if (notifyIcon != null) - { - notifyIcon.Visible = false; - notifyIcon.Icon.Dispose(); - notifyIcon.Dispose(); - notifyIcon = null; - } - Application.Current.Shutdown(); - } + private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { + if (notifyIcon != null) { + notifyIcon.Visible = false; + notifyIcon.Icon.Dispose(); + notifyIcon.Dispose(); + notifyIcon = null; + } + Application.Current.Shutdown(); + } - private void SetCantDisplay(string title, string detailMessage, Visibility closeButtonVisibility) - { - this.Dispatcher.Invoke(() => - { - NoServiceView.Visibility = Visibility.Visible; - CloseErrorButton.IsEnabled = true; - CloseErrorButton.Visibility = closeButtonVisibility; - ErrorMsg.Content = title; - ErrorMsgDetail.Content = detailMessage; - SetNotifyIcon("red"); - _isServiceInError = true; - UpdateServiceView(); - }); - } + private void SetCantDisplay(string title, string detailMessage, Visibility closeButtonVisibility) { + this.Dispatcher.Invoke(() => { + NoServiceView.Visibility = Visibility.Visible; + CloseErrorButton.IsEnabled = true; + CloseErrorButton.Visibility = closeButtonVisibility; + ErrorMsg.Content = title; + ErrorMsgDetail.Content = detailMessage; + SetNotifyIcon("red"); + _isServiceInError = true; + UpdateServiceView(); + }); + } - private void TargetNotifyIcon_Click(object sender, EventArgs e) - { - // this.Show(); - // System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e; - /*if (mea.cli mea.RightButton) { + private void TargetNotifyIcon_Click(object sender, EventArgs e) { +// this.Show(); +// System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e; + /*if (mea.cli mea.RightButton) { } else { }*/ - // this.Activate(); - } +// this.Activate(); + } - private void UpdateServiceView() - { - if (_isServiceInError) - { - AddIdAreaButton.Opacity = 0.1; - AddIdAreaButton.IsEnabled = false; - AddIdButton.Opacity = 0.1; - AddIdButton.IsEnabled = false; - ConnectButton.Opacity = 0.1; - StatArea.Opacity = 0.1; - } - else - { - AddIdAreaButton.Opacity = 1.0; - AddIdAreaButton.IsEnabled = true; - AddIdButton.Opacity = 1.0; - AddIdButton.IsEnabled = true; - StatArea.Opacity = 1.0; - ConnectButton.Opacity = 1.0; - } - TunnelConnected(!_isServiceInError); - } + private void UpdateServiceView() { + if (_isServiceInError) { + AddIdAreaButton.Opacity = 0.1; + AddIdAreaButton.IsEnabled = false; + AddIdButton.Opacity = 0.1; + AddIdButton.IsEnabled = false; + ConnectButton.Opacity = 0.1; + StatArea.Opacity = 0.1; + } else { + AddIdAreaButton.Opacity = 1.0; + AddIdAreaButton.IsEnabled = true; + AddIdButton.Opacity = 1.0; + AddIdButton.IsEnabled = true; + StatArea.Opacity = 1.0; + ConnectButton.Opacity = 1.0; + } + TunnelConnected(!_isServiceInError); + } - private void App_ReceiveString(string obj) - { - Console.WriteLine(obj); - this.Show(); - this.Activate(); - } + private void App_ReceiveString(string obj) { + Console.WriteLine(obj); + this.Show(); + this.Activate(); + } - async private void MainWindow_Loaded(object sender, RoutedEventArgs e) - { + async private void MainWindow_Loaded(object sender, RoutedEventArgs e) { - Window window = Window.GetWindow(App.Current.MainWindow); - ZitiDesktopEdge.App app = (ZitiDesktopEdge.App)App.Current; - app.ReceiveString += App_ReceiveString; + Window window = Window.GetWindow(App.Current.MainWindow); + ZitiDesktopEdge.App app = (ZitiDesktopEdge.App)App.Current; + app.ReceiveString += App_ReceiveString; - // add a new service client - serviceClient = new DataClient(); - serviceClient.OnClientConnected += ServiceClient_OnClientConnected; - serviceClient.OnClientDisconnected += ServiceClient_OnClientDisconnected; - serviceClient.OnIdentityEvent += ServiceClient_OnIdentityEvent; - serviceClient.OnMetricsEvent += ServiceClient_OnMetricsEvent; - serviceClient.OnServiceEvent += ServiceClient_OnServiceEvent; - serviceClient.OnTunnelStatusEvent += ServiceClient_OnTunnelStatusEvent; + // add a new service client + serviceClient = new DataClient(); + serviceClient.OnClientConnected += ServiceClient_OnClientConnected; + serviceClient.OnClientDisconnected += ServiceClient_OnClientDisconnected; + serviceClient.OnIdentityEvent += ServiceClient_OnIdentityEvent; + serviceClient.OnMetricsEvent += ServiceClient_OnMetricsEvent; + serviceClient.OnServiceEvent += ServiceClient_OnServiceEvent; + serviceClient.OnTunnelStatusEvent += ServiceClient_OnTunnelStatusEvent; + serviceClient.OnMfaEvent += ServiceClient_OnMfaEvent; serviceClient.OnLogLevelEvent += ServiceClient_OnLogLevelEvent; - serviceClient.OnMfaEvent += ServiceClient_OnMfaEvent; - Application.Current.Properties.Add("ServiceClient", serviceClient); + Application.Current.Properties.Add("ServiceClient", serviceClient); - monitorClient = new MonitorClient(); - monitorClient.OnClientConnected += MonitorClient_OnClientConnected; + monitorClient = new MonitorClient(); + monitorClient.OnClientConnected += MonitorClient_OnClientConnected; monitorClient.OnServiceStatusEvent += MonitorClient_OnServiceStatusEvent; monitorClient.OnShutdownEvent += MonitorClient_OnShutdownEvent; monitorClient.OnReconnectFailure += MonitorClient_OnReconnectFailure; - Application.Current.Properties.Add("MonitorClient", monitorClient); + Application.Current.Properties.Add("MonitorClient", monitorClient); - Application.Current.Properties.Add("Identities", new List()); - MainMenu.OnAttachmentChange += AttachmentChanged; - MainMenu.OnLogLevelChanged += LogLevelChanged; - IdentityMenu.OnError += IdentityMenu_OnError; + Application.Current.Properties.Add("Identities", new List()); + MainMenu.OnAttachmentChange += AttachmentChanged; + MainMenu.OnLogLevelChanged += LogLevelChanged; + IdentityMenu.OnError += IdentityMenu_OnError; - try - { - await serviceClient.ConnectAsync(); - await serviceClient.WaitForConnectionAsync(); - } - catch /*ignored for now (Exception ex) */ - { - ShowServiceNotStarted(); - serviceClient.Reconnect(); - } + try { + await serviceClient.ConnectAsync(); + await serviceClient.WaitForConnectionAsync(); + } catch /*ignored for now (Exception ex) */{ + ShowServiceNotStarted(); + serviceClient.Reconnect(); + } - try - { - await monitorClient.ConnectAsync(); - await monitorClient.WaitForConnectionAsync(); - } - catch /*ignored for now (Exception ex) */ - { - monitorClient.Reconnect(); - } + try { + await monitorClient.ConnectAsync(); + await monitorClient.WaitForConnectionAsync(); + } catch /*ignored for now (Exception ex) */{ + monitorClient.Reconnect(); + } - IdentityMenu.OnForgot += IdentityForgotten; - Placement(); + IdentityMenu.OnForgot += IdentityForgotten; + Placement(); + } + + string nextVersionStr = null; + private void MonitorClient_OnReconnectFailure(object sender, object e) { + if (nextVersionStr == null) { + // check for the current version + nextVersionStr = "checking for update"; + Version nextVersion = VersionUtil.NormalizeVersion(GithubAPI.GetVersion(GithubAPI.GetJson(GithubAPI.ProdUrl))); + nextVersionStr = nextVersion.ToString(); + Version currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; //fetch from ziti? + + int compare = currentVersion.CompareTo(nextVersion); + if (compare < 0) { + MainMenu.SetAppUpgradeAvailableText("Upgrade available: " + nextVersionStr); + logger.Info("upgrade is available. Published version: {} is newer than the current version: {}", nextVersion, currentVersion); + //UpgradeAvailable(); + } else if (compare > 0) { + logger.Info("the version installed: {0} is newer than the released version: {1}", currentVersion, nextVersion); + MainMenu.SetAppIsNewer("This version is newer than the latest: " + nextVersionStr); + } else { + logger.Info("Current version installed: {0} is the same as the latest released version {1}", currentVersion, nextVersion); + MainMenu.SetAppUpgradeAvailableText(""); + } + } } - string nextVersionStr = null; - private void MonitorClient_OnReconnectFailure(object sender, object e) - { - if (nextVersionStr == null) - { - // check for the current version - nextVersionStr = "checking for update"; - Version nextVersion = VersionUtil.NormalizeVersion(GithubAPI.GetVersion(GithubAPI.GetJson(GithubAPI.ProdUrl))); - nextVersionStr = nextVersion.ToString(); - Version currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; //fetch from ziti? + private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e) { + Application.Current.Shutdown(); + } - int compare = currentVersion.CompareTo(nextVersion); - if (compare < 0) - { - MainMenu.SetAppUpgradeAvailableText("Upgrade available: " + nextVersionStr); - logger.Info("upgrade is available. Published version: {} is newer than the current version: {}", nextVersion, currentVersion); - //UpgradeAvailable(); - } - else if (compare > 0) - { - logger.Info("the version installed: {0} is newer than the released version: {1}", currentVersion, nextVersion); - MainMenu.SetAppIsNewer("This version is newer than the latest: " + nextVersionStr); - } - else - { - logger.Info("Current version installed: {0} is the same as the latest released version {1}", currentVersion, nextVersion); - MainMenu.SetAppUpgradeAvailableText(""); - } - } - } + private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceStatusEvent evt) { + try { + if (evt.Message?.ToLower() == "upgrading") { + logger.Info("The monitor has indicated an upgrade is in progress. Shutting down the UI"); + notifyIcon.Visible = false; + notifyIcon.Icon.Dispose(); + notifyIcon.Dispose(); + Application.Current.Shutdown(); + } + logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status); + Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream; + ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status); - private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e) - { - Application.Current.Shutdown(); - } + switch (status) { + case ServiceControllerStatus.Running: + logger.Info("Service is started"); + break; + case ServiceControllerStatus.Stopped: + logger.Info("Service is stopped"); + ShowServiceNotStarted(); + break; + case ServiceControllerStatus.StopPending: + logger.Info("Service is stopping..."); - private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceStatusEvent evt) - { - try - { - if (evt.Message?.ToLower() == "upgrading") - { - logger.Info("The monitor has indicated an upgrade is in progress. Shutting down the UI"); - notifyIcon.Visible = false; - notifyIcon.Icon.Dispose(); - notifyIcon.Dispose(); - Application.Current.Shutdown(); - } - logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status); - Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream; - ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status); + this.Dispatcher.Invoke(async () => { + SetCantDisplay("The Service is Stopping", "Please wait while the service stops", Visibility.Hidden); + await WaitForServiceToStop(DateTime.Now + TimeSpan.FromSeconds(30)); + }); + break; + case ServiceControllerStatus.StartPending: + logger.Info("Service is starting..."); + break; + case ServiceControllerStatus.PausePending: + logger.Warn("UNEXPECTED STATUS: PausePending"); + break; + case ServiceControllerStatus.Paused: + logger.Warn("UNEXPECTED STATUS: Paused"); + break; + default: + logger.Warn("UNEXPECTED STATUS: {0}", evt.Status); + break; + } + } catch (Exception ex) { + logger.Warn(ex, "unexpected exception in MonitorClient_OnShutdownEvent? {0}", ex.Message); + } + } - switch (status) - { - case ServiceControllerStatus.Running: - logger.Info("Service is started"); - break; - case ServiceControllerStatus.Stopped: - logger.Info("Service is stopped"); - ShowServiceNotStarted(); - break; - case ServiceControllerStatus.StopPending: - logger.Info("Service is stopping..."); + async private Task WaitForServiceToStop(DateTime until) { + //continually poll for the service to stop. If it is stuck - ask the user if they want to try to force + //close the service + while (DateTime.Now < until) { + await Task.Delay(2000); + MonitorServiceStatusEvent resp = await monitorClient.StatusAsync(); + if (resp.IsStopped()) { + // good - that's what we are waiting for... + return; + } else { + // bad - not stopped yet... + logger.Debug("Waiting for service to stop... Still not stopped yet. Status: {0}", resp.Status); + } + } + // real bad - means it's stuck probably. Ask the user if they want to try to force it... + logger.Warn("Waiting for service to stop... Service did not reach stopped state in the expected amount of time."); + SetCantDisplay("The Service Appears Stuck", "Would you like to try to force close the service?", Visibility.Visible); + CloseErrorButton.Content = "Force Quit"; + CloseErrorButton.Click -= CloseError; + CloseErrorButton.Click += ForceQuitButtonClick; + } - this.Dispatcher.Invoke(async () => - { - SetCantDisplay("The Service is Stopping", "Please wait while the service stops", Visibility.Hidden); - await WaitForServiceToStop(DateTime.Now + TimeSpan.FromSeconds(30)); - }); - break; - case ServiceControllerStatus.StartPending: - logger.Info("Service is starting..."); - break; - case ServiceControllerStatus.PausePending: - logger.Warn("UNEXPECTED STATUS: PausePending"); - break; - case ServiceControllerStatus.Paused: - logger.Warn("UNEXPECTED STATUS: Paused"); - break; - default: - logger.Warn("UNEXPECTED STATUS: {0}", evt.Status); - break; - } - } - catch (Exception ex) - { - logger.Warn(ex, "unexpected exception in MonitorClient_OnShutdownEvent? {0}", ex.Message); - } - } + async private void ForceQuitButtonClick(object sender, RoutedEventArgs e) { + MonitorServiceStatusEvent status = await monitorClient.ForceTerminateAsync(); + if (status.IsStopped()) { + //good + CloseErrorButton.Click += CloseError; //reset the close button... + CloseErrorButton.Click -= ForceQuitButtonClick; + } else { + //bad... + SetCantDisplay("The Service Is Still Running", "Current status is: " + status.Status, Visibility.Visible); + } + } - async private Task WaitForServiceToStop(DateTime until) - { - //continually poll for the service to stop. If it is stuck - ask the user if they want to try to force - //close the service - while (DateTime.Now < until) - { - await Task.Delay(2000); - MonitorServiceStatusEvent resp = await monitorClient.StatusAsync(); - if (resp.IsStopped()) - { - // good - that's what we are waiting for... - return; - } - else - { - // bad - not stopped yet... - logger.Debug("Waiting for service to stop... Still not stopped yet. Status: {0}", resp.Status); - } - } - // real bad - means it's stuck probably. Ask the user if they want to try to force it... - logger.Warn("Waiting for service to stop... Service did not reach stopped state in the expected amount of time."); - SetCantDisplay("The Service Appears Stuck", "Would you like to try to force close the service?", Visibility.Visible); - CloseErrorButton.Content = "Force Quit"; - CloseErrorButton.Click -= CloseError; - CloseErrorButton.Click += ForceQuitButtonClick; - } + async private void StartZitiService(object sender, RoutedEventArgs e) { + try { + ShowLoad("Starting", "Starting the data service"); + logger.Info("StartZitiService"); + var r = await monitorClient.StartServiceAsync(); + if (r.Code != 0) { + logger.Debug("ERROR: {0} : {1}", r.Message, r.Error); + } else { + logger.Info("Service started!"); + //no longer used: startZitiButtonVisible = false; + CloseErrorButton.Click -= StartZitiService; + CloseError(null, null); + } + } catch (Exception ex) { + logger.Info(ex, "UNEXPECTED ERROR!"); + //no longer used: startZitiButtonVisible = false; + //CloseErrorButton.Click += StartZitiService; + CloseErrorButton.IsEnabled = true; + } + CloseErrorButton.IsEnabled = true; + HideLoad(); + } - async private void ForceQuitButtonClick(object sender, RoutedEventArgs e) - { - MonitorServiceStatusEvent status = await monitorClient.ForceTerminateAsync(); - if (status.IsStopped()) - { - //good - CloseErrorButton.Click += CloseError; //reset the close button... - CloseErrorButton.Click -= ForceQuitButtonClick; - } - else - { - //bad... - SetCantDisplay("The Service Is Still Running", "Current status is: " + status.Status, Visibility.Visible); - } - } - - async private void StartZitiService(object sender, RoutedEventArgs e) - { - try - { - ShowLoad("Starting", "Starting the data service"); - logger.Info("StartZitiService"); - var r = await monitorClient.StartServiceAsync(); - if (r.Code != 0) - { - logger.Debug("ERROR: {0} : {1}", r.Message, r.Error); - } - else - { - logger.Info("Service started!"); - //no longer used: startZitiButtonVisible = false; - CloseErrorButton.Click -= StartZitiService; - CloseError(null, null); - } - } - catch (Exception ex) - { - logger.Info(ex, "UNEXPECTED ERROR!"); - //no longer used: startZitiButtonVisible = false; - //CloseErrorButton.Click += StartZitiService; - CloseErrorButton.IsEnabled = true; - } - CloseErrorButton.IsEnabled = true; - HideLoad(); - } - - private void ShowServiceNotStarted() - { - TunnelConnected(false); - LoadIdentities(true); - /* + private void ShowServiceNotStarted() { + TunnelConnected(false); + LoadIdentities(true); + /* this.Dispatcher.Invoke(() => { semaphoreSlim.Wait(); //make sure the event is only added to the button once CloseErrorButton.Click -= CloseError; @@ -786,867 +662,693 @@ namespace ZitiDesktopEdge SetCantDisplay("Service Not Started", "Do you want to start the data service now?", Visibility.Visible); }); */ - } + } - private void MonitorClient_OnClientConnected(object sender, object e) - { - logger.Debug("MonitorClient_OnClientConnected"); - MainMenu.SetAppUpgradeAvailableText(""); - } + private void MonitorClient_OnClientConnected(object sender, object e) { + logger.Debug("MonitorClient_OnClientConnected"); + MainMenu.SetAppUpgradeAvailableText(""); + } - async private void LogLevelChanged(string level) - { - await serviceClient.SetLogLevelAsync(level); - await monitorClient.SetLogLevelAsync(level); - Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level); - } + async private void LogLevelChanged(string level) { + await serviceClient.SetLogLevelAsync(level); + await monitorClient.SetLogLevelAsync(level); + Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level); + } - private void IdentityMenu_OnError(string message) - { - ShowError("Identity Error", message); - } + private void IdentityMenu_OnError(string message) { + ShowError("Identity Error", message); + } - private void ServiceClient_OnClientConnected(object sender, object e) - { - this.Dispatcher.Invoke(() => - { - //e is _ALWAYS_ null at this time use this to display something if you want - NoServiceView.Visibility = Visibility.Collapsed; - _isServiceInError = false; - UpdateServiceView(); - SetNotifyIcon("white"); - LoadIdentities(true); - }); - } + private void ServiceClient_OnClientConnected(object sender, object e) { + this.Dispatcher.Invoke(() => { + //e is _ALWAYS_ null at this time use this to display something if you want + NoServiceView.Visibility = Visibility.Collapsed; + _isServiceInError = false; + UpdateServiceView(); + SetNotifyIcon("white"); + LoadIdentities(true); + }); + } - private void ServiceClient_OnClientDisconnected(object sender, object e) - { - this.Dispatcher.Invoke(() => - { - IdList.Children.Clear(); - if (e != null) - { - logger.Debug(e.ToString()); - } - //SetCantDisplay("Start the Ziti Tunnel Service to continue"); - ShowServiceNotStarted(); - }); - } + private void ServiceClient_OnClientDisconnected(object sender, object e) { + this.Dispatcher.Invoke(() => { + IdList.Children.Clear(); + if (e != null) { + logger.Debug(e.ToString()); + } + //SetCantDisplay("Start the Ziti Tunnel Service to continue"); + ShowServiceNotStarted(); + }); + } - private void ServiceClient_OnIdentityEvent(object sender, IdentityEvent e) - { - if (e == null) return; + private void ServiceClient_OnIdentityEvent(object sender, IdentityEvent e) { + if (e == null) return; - ZitiIdentity zid = ZitiIdentity.FromClient(e.Id); - logger.Debug($"==== IdentityEvent : action:{e.Action} fingerprint:{e.Id.FingerPrint} name:{e.Id.Name} "); + ZitiIdentity zid = ZitiIdentity.FromClient(e.Id); + logger.Debug($"==== IdentityEvent : action:{e.Action} fingerprint:{e.Id.FingerPrint} name:{e.Id.Name} "); - this.Dispatcher.Invoke(async () => - { - if (e.Action == "added") - { - var found = identities.Find(i => i.Fingerprint == e.Id.FingerPrint); - if (found == null) - { - AddIdentity(zid); + this.Dispatcher.Invoke(async () => { + if (e.Action == "added") { + var found = identities.Find(i => i.Fingerprint == e.Id.FingerPrint); + if (found == null) { + AddIdentity(zid); + LoadIdentities(true); + } else { + // means we likely are getting an update for some reason. compare the identities and use the latest info + found.Name = zid.Name; + found.ControllerUrl = zid.ControllerUrl; + found.IsEnabled = zid.IsEnabled; LoadIdentities(true); - } - else - { - // means we likely are getting an update for some reason. compare the identities and use the latest info - found.Name = zid.Name; - found.ControllerUrl = zid.ControllerUrl; - found.IsEnabled = zid.IsEnabled; - LoadIdentities(true); - return; - } - } - else if (e.Action == "updated") - { - //this indicates that all updates have been sent to the UI... wait for 2 seconds then trigger any ui updates needed - await Task.Delay(2000); + return; + } + } else if (e.Action == "updated") { + //this indicates that all updates have been sent to the UI... wait for 2 seconds then trigger any ui updates needed + await Task.Delay(2000); + + } else { + IdentityForgotten(ZitiIdentity.FromClient(e.Id)); + } + }); + logger.Debug($"IDENTITY EVENT. Action: {e.Action} fingerprint: {zid.Fingerprint}"); + } - } - else - { - IdentityForgotten(ZitiIdentity.FromClient(e.Id)); - } - }); - logger.Debug($"IDENTITY EVENT. Action: {e.Action} fingerprint: {zid.Fingerprint}"); - } + private void ServiceClient_OnMetricsEvent(object sender, List ids) { + if (ids != null) { + long totalUp = 0; + long totalDown = 0; + foreach (var id in ids) { + //logger.Debug($"==== MetricsEvent : id {id.Name} down: {id.Metrics.Down} up:{id.Metrics.Up}"); + if (id?.Metrics != null) { + totalDown += id.Metrics.Down; + totalUp += id.Metrics.Up; + } + } + this.Dispatcher.Invoke(() => { + SetSpeed(totalUp, UploadSpeed, UploadSpeedLabel); + SetSpeed(totalDown, DownloadSpeed, DownloadSpeedLabel); + }); + } + } - private void ServiceClient_OnMetricsEvent(object sender, List ids) - { - if (ids != null) - { - long totalUp = 0; - long totalDown = 0; - foreach (var id in ids) - { - //logger.Debug($"==== MetricsEvent : id {id.Name} down: {id.Metrics.Down} up:{id.Metrics.Up}"); - if (id?.Metrics != null) - { - totalDown += id.Metrics.Down; - totalUp += id.Metrics.Up; - } - } - this.Dispatcher.Invoke(() => - { - SetSpeed(totalUp, UploadSpeed, UploadSpeedLabel); - SetSpeed(totalDown, DownloadSpeed, DownloadSpeedLabel); - }); - } - } + public void SetSpeed(decimal bytes, Label speed, Label speedLabel) { + int counter = 0; + while (Math.Round(bytes / 1024) >= 1) { + bytes = bytes / 1024; + counter++; + } + speed.Content = bytes.ToString("0.0"); + speedLabel.Content = suffixes[counter]; + } - public void SetSpeed(decimal bytes, Label speed, Label speedLabel) - { - int counter = 0; - while (Math.Round(bytes / 1024) >= 1) - { - bytes = bytes / 1024; - counter++; - } - speed.Content = bytes.ToString("0.0"); - speedLabel.Content = suffixes[counter]; - } + private void ServiceClient_OnServiceEvent(object sender, ServiceEvent e) { + if (e == null) return; - private void ServiceClient_OnServiceEvent(object sender, ServiceEvent e) - { - if (e == null) return; + Debug.WriteLine($"==== ServiceEvent : action:{e.Action} fingerprint:{e.Fingerprint} name:{e.Service.Name} "); + this.Dispatcher.Invoke(() => { + var found = identities.Find(id => id.Fingerprint == e.Fingerprint); - Debug.WriteLine($"==== ServiceEvent : action:{e.Action} fingerprint:{e.Fingerprint} name:{e.Service.Name} "); - this.Dispatcher.Invoke(() => - { - var found = identities.Find(id => id.Fingerprint == e.Fingerprint); + if (found == null) { + Debug.WriteLine($"{e.Action} service event for {e.Service.Name} but the provided identity fingerprint {e.Fingerprint} is not found!"); + return; + } - if (found == null) - { - Debug.WriteLine($"{e.Action} service event for {e.Service.Name} but the provided identity fingerprint {e.Fingerprint} is not found!"); - return; - } + if (e.Action == "added") { + ZitiService zs = new ZitiService(e.Service); + var svc = found.Services.Find(s => s.Name == zs.Name); + if (svc == null) { + found.Services.Add(zs); + if (zs.HasFailingPostureCheck()) { + found.HasServiceFailingPostureCheck = true; + if (zs.PostureChecks.Any(p => !p.IsPassing && p.QueryType == "MFA")) { + found.MFAInfo.IsAuthenticated = false; + } + } + } else { + logger.Debug("the service named " + zs.Name + " is already accounted for on this identity."); + } + } else { + logger.Debug("removing the service named: " + e.Service.Name); + found.Services.RemoveAll(s => s.Name == e.Service.Name); + } + LoadIdentities(false); + IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu; + if (deets.IsVisible) { + deets.UpdateView(); + } + }); + } - if (e.Action == "added") - { - ZitiService zs = new ZitiService(e.Service); - var svc = found.Services.Find(s => s.Name == zs.Name); - if (svc == null) - { - found.Services.Add(zs); - if (zs.HasFailingPostureCheck()) - { - found.HasServiceFailingPostureCheck = true; - if (zs.PostureChecks.Any(p => !p.IsPassing && p.QueryType == "MFA")) - { - found.MFAInfo.IsAuthenticated = false; - } - } - } - else - { - logger.Debug("the service named " + zs.Name + " is already accounted for on this identity."); - } - } - else - { - logger.Debug("removing the service named: " + e.Service.Name); - found.Services.RemoveAll(s => s.Name == e.Service.Name); - } - LoadIdentities(false); - IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu; - if (deets.IsVisible) - { - deets.UpdateView(); - } - }); - } + private void ServiceClient_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) { + if (e == null) return; //just skip it for now... + logger.Debug($"==== TunnelStatusEvent: "); + Application.Current.Properties.Remove("CurrentTunnelStatus"); + Application.Current.Properties.Add("CurrentTunnelStatus", e.Status); + e.Status.Dump(Console.Out); + this.Dispatcher.Invoke(() => { + if (e.ApiVersion != DataClient.EXPECTED_API_VERSION) { + SetCantDisplay("Version mismatch!", "The version of the Service is not compatible", Visibility.Visible); + return; + } + this.MainMenu.LogLevel = e.Status.LogLevel; + Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.Status.LogLevel); - private void ServiceClient_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) - { - if (e == null) return; //just skip it for now... - logger.Debug($"==== TunnelStatusEvent: "); - Application.Current.Properties.Remove("CurrentTunnelStatus"); - Application.Current.Properties.Add("CurrentTunnelStatus", e.Status); - e.Status.Dump(Console.Out); - this.Dispatcher.Invoke(() => - { - if (e.ApiVersion != DataClient.EXPECTED_API_VERSION) - { - SetCantDisplay("Version mismatch!", "The version of the Service is not compatible", Visibility.Visible); - return; - } - this.MainMenu.LogLevel = e.Status.LogLevel; - Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.Status.LogLevel); + InitializeTimer((int)e.Status.Duration); + LoadStatusFromService(e.Status); + LoadIdentities(true); + IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu; + if (deets.IsVisible) { + deets.UpdateView(); + } + }); + } + + private void ServiceClient_OnLogLevelEvent(object sender, LogLevelEvent e) { +            if (e.LogLevel != null) { +                SetLogLevel_monitor(e.LogLevel); +                this.Dispatcher.Invoke(() =>  { +                    this.MainMenu.LogLevel = e.LogLevel; +                    Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.LogLevel); +                }); +            } +        } - InitializeTimer((int)e.Status.Duration); - LoadStatusFromService(e.Status); - LoadIdentities(true); - IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu; - if (deets.IsVisible) - { - deets.UpdateView(); - } - }); - } +        async private void SetLogLevel_monitor(string loglevel)  { +            await monitorClient.SetLogLevelAsync(loglevel); +        } - private void ServiceClient_OnLogLevelEvent(object sender, LogLevelEvent e) - { - if (e.LogLevel != null) - { - SetLogLevel_monitor(e.LogLevel); - this.Dispatcher.Invoke(() => - { - this.MainMenu.LogLevel = e.LogLevel; - Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.LogLevel); - }); - } - } + private void IdentityForgotten(ZitiIdentity forgotten) { + ZitiIdentity idToRemove = null; + foreach (var id in identities) { + if (id.Fingerprint == forgotten.Fingerprint) { + idToRemove = id; + break; + } + } + identities.Remove(idToRemove); + LoadIdentities(false); + } - async private void SetLogLevel_monitor(string loglevel) - { - await monitorClient.SetLogLevelAsync(loglevel); - } + private void AttachmentChanged(bool attached) { + _isAttached = attached; + if (!_isAttached) { + SetLocation(); + } + Placement(); + MainMenu.Visibility = Visibility.Collapsed; + } - private void IdentityForgotten(ZitiIdentity forgotten) - { - ZitiIdentity idToRemove = null; - foreach (var id in identities) - { - if (id.Fingerprint == forgotten.Fingerprint) - { - idToRemove = id; - break; - } - } - identities.Remove(idToRemove); - LoadIdentities(false); - } + private void LoadStatusFromService(TunnelStatus status) { + //clear any identities + this.identities.Clear(); - private void AttachmentChanged(bool attached) - { - _isAttached = attached; - if (!_isAttached) - { - SetLocation(); - } - Placement(); - MainMenu.Visibility = Visibility.Collapsed; - } + if (status != null) { + _isServiceInError = false; + UpdateServiceView(); + NoServiceView.Visibility = Visibility.Collapsed; + if (status.Active) { + SetNotifyIcon("green"); + } else { + SetNotifyIcon("white"); + } + if (!Application.Current.Properties.Contains("ip")) { + Application.Current.Properties.Add("ip", status?.IpInfo?.Ip); + } + if (!Application.Current.Properties.Contains("subnet")) { + Application.Current.Properties.Add("subnet", status?.IpInfo?.Subnet); + } + if (!Application.Current.Properties.Contains("mtu")) { + Application.Current.Properties.Add("mtu", status?.IpInfo?.MTU); + } + if (!Application.Current.Properties.Contains("dns")) { + Application.Current.Properties.Add("dns", status?.IpInfo?.DNS); + } - private void LoadStatusFromService(TunnelStatus status) - { - //clear any identities - this.identities.Clear(); + foreach (var id in status.Identities) { + updateViewWithIdentity(id); + } + LoadIdentities(true); + } else { + ShowServiceNotStarted(); + } + } - if (status != null) - { - _isServiceInError = false; - UpdateServiceView(); - NoServiceView.Visibility = Visibility.Collapsed; - if (status.Active) - { - SetNotifyIcon("green"); - } - else - { - SetNotifyIcon("white"); - } - if (!Application.Current.Properties.Contains("ip")) - { - Application.Current.Properties.Add("ip", status?.IpInfo?.Ip); - } - if (!Application.Current.Properties.Contains("subnet")) - { - Application.Current.Properties.Add("subnet", status?.IpInfo?.Subnet); - } - if (!Application.Current.Properties.Contains("mtu")) - { - Application.Current.Properties.Add("mtu", status?.IpInfo?.MTU); - } - if (!Application.Current.Properties.Contains("dns")) - { - Application.Current.Properties.Add("dns", status?.IpInfo?.DNS); - } + private void updateViewWithIdentity(Identity id) { + var zid = ZitiIdentity.FromClient(id); + foreach (var i in identities) { + if (i.Fingerprint == zid.Fingerprint) { + identities.Remove(i); + break; + } + } + identities.Add(zid); + } + private void SetNotifyIcon(string iconPrefix) { + var iconUri = new Uri("pack://application:,,/Assets/Images/ziti-" + iconPrefix + ".ico"); + Stream iconStream = Application.GetResourceStream(iconUri).Stream; + notifyIcon.Icon = new Icon(iconStream); - foreach (var id in status.Identities) - { - updateViewWithIdentity(id); - } - LoadIdentities(true); - } - else - { - ShowServiceNotStarted(); - } - } + Application.Current.MainWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri); + } - private void updateViewWithIdentity(Identity id) - { - var zid = ZitiIdentity.FromClient(id); - foreach (var i in identities) - { - if (i.Fingerprint == zid.Fingerprint) - { - identities.Remove(i); - break; - } - } - identities.Add(zid); - } - private void SetNotifyIcon(string iconPrefix) - { - var iconUri = new Uri("pack://application:,,/Assets/Images/ziti-" + iconPrefix + ".ico"); - Stream iconStream = Application.GetResourceStream(iconUri).Stream; - notifyIcon.Icon = new Icon(iconStream); + private void LoadIdentities(Boolean repaint) { + this.Dispatcher.Invoke(() => { + IdList.Children.Clear(); + IdList.Height = 0; + var desktopWorkingArea = SystemParameters.WorkArea; + if (_maxHeight > (desktopWorkingArea.Height - 10)) _maxHeight = desktopWorkingArea.Height - 10; + if (_maxHeight < 100) _maxHeight = 100; + IdList.MaxHeight = _maxHeight - 520; + ZitiIdentity[] ids = identities.OrderBy(i => i.Name.ToLower()).ToArray(); + MainMenu.SetupIdList(ids); - Application.Current.MainWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri); - } + if (ids.Length > 0 && serviceClient.Connected) { + double height = 490 + (ids.Length * 60); + if (height > _maxHeight) height = _maxHeight; + this.Height = height; + IdentityMenu.SetHeight(this.Height - 160); + MainMenu.IdentitiesButton.Visibility = Visibility.Visible; + foreach (var id in ids) { + IdentityItem idItem = new IdentityItem(); - private void LoadIdentities(Boolean repaint) - { - this.Dispatcher.Invoke(() => - { - IdList.Children.Clear(); - IdList.Height = 0; - var desktopWorkingArea = SystemParameters.WorkArea; - if (_maxHeight > (desktopWorkingArea.Height - 10)) _maxHeight = desktopWorkingArea.Height - 10; - if (_maxHeight < 100) _maxHeight = 100; - IdList.MaxHeight = _maxHeight - 520; - ZitiIdentity[] ids = identities.OrderBy(i => i.Name.ToLower()).ToArray(); - MainMenu.SetupIdList(ids); + idItem.ToggleStatus.IsEnabled = id.IsEnabled; + if (id.IsEnabled) { + idItem.ToggleStatus.Content = "ENABLED"; + } else { + idItem.ToggleStatus.Content = "DISABLED"; + } + idItem.Authenticate += IdItem_Authenticate; + idItem.OnStatusChanged += Id_OnStatusChanged; + idItem.Identity = id; + IdList.Children.Add(idItem); + if (IdentityMenu.Visibility==Visibility.Visible) { + if (id.Fingerprint==IdentityMenu.Identity.Fingerprint) { + IdentityMenu.Identity = id; + } + } + } + //IdList.Height = ; + DoubleAnimation animation = new DoubleAnimation((double)(ids.Length * 64), TimeSpan.FromSeconds(.3)); + IdList.BeginAnimation(FrameworkElement.HeightProperty, animation); + IdListScroller.Visibility = Visibility.Visible; + } else { + this.Height = 490; + MainMenu.IdentitiesButton.Visibility = Visibility.Collapsed; + IdListScroller.Visibility = Visibility.Collapsed; + } + AddIdButton.Visibility = Visibility.Visible; + AddIdAreaButton.Visibility = Visibility.Visible; - if (ids.Length > 0 && serviceClient.Connected) - { - double height = 490 + (ids.Length * 60); - if (height > _maxHeight) height = _maxHeight; - this.Height = height; - IdentityMenu.SetHeight(this.Height - 160); - MainMenu.IdentitiesButton.Visibility = Visibility.Visible; - foreach (var id in ids) - { - IdentityItem idItem = new IdentityItem(); + Placement(); + }); + } - idItem.ToggleStatus.IsEnabled = id.IsEnabled; - if (id.IsEnabled) - { - idItem.ToggleStatus.Content = "ENABLED"; - } - else - { - idItem.ToggleStatus.Content = "DISABLED"; - } - idItem.Authenticate += IdItem_Authenticate; - idItem.OnStatusChanged += Id_OnStatusChanged; - idItem.Identity = id; - IdList.Children.Add(idItem); - if (IdentityMenu.Visibility == Visibility.Visible) - { - if (id.Fingerprint == IdentityMenu.Identity.Fingerprint) - { - IdentityMenu.Identity = id; - } - } - } - //IdList.Height = ; - DoubleAnimation animation = new DoubleAnimation((double)(ids.Length * 64), TimeSpan.FromSeconds(.3)); - IdList.BeginAnimation(FrameworkElement.HeightProperty, animation); - IdListScroller.Visibility = Visibility.Visible; - } - else - { - this.Height = 490; - MainMenu.IdentitiesButton.Visibility = Visibility.Collapsed; - IdListScroller.Visibility = Visibility.Collapsed; - } - AddIdButton.Visibility = Visibility.Visible; - AddIdAreaButton.Visibility = Visibility.Visible; + private void IdItem_Authenticate(ZitiIdentity identity) { + ShowAuthenticate(identity); + } - Placement(); - }); - } + private void Id_OnStatusChanged(bool attached) { + for (int i = 0; i < IdList.Children.Count; i++) { + IdentityItem item = IdList.Children[i] as IdentityItem; + if (item.ToggleSwitch.Enabled) { + break; + } + } + } - private void IdItem_Authenticate(ZitiIdentity identity) - { - ShowAuthenticate(identity); - } + private void TunnelConnected(bool isConnected) { + this.Dispatcher.Invoke(() => { + if (isConnected) { + ConnectButton.Visibility = Visibility.Collapsed; + DisconnectButton.Visibility = Visibility.Visible; + } else { + ConnectButton.Visibility = Visibility.Visible; + DisconnectButton.Visibility = Visibility.Collapsed; + IdentityMenu.Visibility = Visibility.Collapsed; + MainMenu.Visibility = Visibility.Collapsed; + HideBlurb(); + } + }); + } - private void Id_OnStatusChanged(bool attached) - { - for (int i = 0; i < IdList.Children.Count; i++) - { - IdentityItem item = IdList.Children[i] as IdentityItem; - if (item.ToggleSwitch.Enabled) - { - break; - } - } - } + private void SetLocation() { + var desktopWorkingArea = SystemParameters.WorkArea; - private void TunnelConnected(bool isConnected) - { - this.Dispatcher.Invoke(() => - { - if (isConnected) - { - ConnectButton.Visibility = Visibility.Collapsed; - DisconnectButton.Visibility = Visibility.Visible; - } - else - { - ConnectButton.Visibility = Visibility.Visible; - DisconnectButton.Visibility = Visibility.Collapsed; - IdentityMenu.Visibility = Visibility.Collapsed; - MainMenu.Visibility = Visibility.Collapsed; - HideBlurb(); - } - }); - } + var height = MainView.ActualHeight; + IdentityMenu.MainHeight = MainView.ActualHeight; + MainMenu.MainHeight = MainView.ActualHeight; - private void SetLocation() - { - var desktopWorkingArea = SystemParameters.WorkArea; + Rectangle trayRectangle = WinAPI.GetTrayRectangle(); + if (trayRectangle.Top < 20) { + this.Position = "Top"; + this.Top = desktopWorkingArea.Top + _top; + this.Left = desktopWorkingArea.Right - this.Width - _right; + Arrow.SetValue(Canvas.TopProperty, (double)0); + Arrow.SetValue(Canvas.LeftProperty, (double)185); + MainMenu.Arrow.SetValue(Canvas.TopProperty, (double)0); + MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); + IdentityMenu.Arrow.SetValue(Canvas.TopProperty, (double)0); + IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); + } else if (trayRectangle.Left < 20) { + this.Position = "Left"; + this.Left = _left; + this.Top = desktopWorkingArea.Bottom - this.ActualHeight - 75; + Arrow.SetValue(Canvas.TopProperty, height - 200); + Arrow.SetValue(Canvas.LeftProperty, (double)0); + MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 200); + MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0); + IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 200); + IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0); + } else if (desktopWorkingArea.Right == (double)trayRectangle.Left) { + this.Position = "Right"; + this.Left = desktopWorkingArea.Right - this.Width - 20; + this.Top = desktopWorkingArea.Bottom - height - 75; + Arrow.SetValue(Canvas.TopProperty, height - 100); + Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); + MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 100); + MainMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); + IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 100); + IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); + } else { + this.Position = "Bottom"; + this.Left = desktopWorkingArea.Right - this.Width - 75; + this.Top = desktopWorkingArea.Bottom - height; + Arrow.SetValue(Canvas.TopProperty, height - 35); + Arrow.SetValue(Canvas.LeftProperty, (double)185); + MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 35); + MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); + IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 35); + IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); + } + } + public void Placement() { + if (_isAttached) { + Arrow.Visibility = Visibility.Visible; + IdentityMenu.Arrow.Visibility = Visibility.Visible; + SetLocation(); + } else { + IdentityMenu.Arrow.Visibility = Visibility.Collapsed; + Arrow.Visibility = Visibility.Collapsed; + } + } - var height = MainView.ActualHeight; - IdentityMenu.MainHeight = MainView.ActualHeight; - MainMenu.MainHeight = MainView.ActualHeight; + private void OpenIdentity(ZitiIdentity identity) { + IdentityMenu.Identity = identity; - Rectangle trayRectangle = WinAPI.GetTrayRectangle(); - if (trayRectangle.Top < 20) - { - this.Position = "Top"; - this.Top = desktopWorkingArea.Top + _top; - this.Left = desktopWorkingArea.Right - this.Width - _right; - Arrow.SetValue(Canvas.TopProperty, (double)0); - Arrow.SetValue(Canvas.LeftProperty, (double)185); - MainMenu.Arrow.SetValue(Canvas.TopProperty, (double)0); - MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); - IdentityMenu.Arrow.SetValue(Canvas.TopProperty, (double)0); - IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); - } - else if (trayRectangle.Left < 20) - { - this.Position = "Left"; - this.Left = _left; - this.Top = desktopWorkingArea.Bottom - this.ActualHeight - 75; - Arrow.SetValue(Canvas.TopProperty, height - 200); - Arrow.SetValue(Canvas.LeftProperty, (double)0); - MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 200); - MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0); - IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 200); - IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0); - } - else if (desktopWorkingArea.Right == (double)trayRectangle.Left) - { - this.Position = "Right"; - this.Left = desktopWorkingArea.Right - this.Width - 20; - this.Top = desktopWorkingArea.Bottom - height - 75; - Arrow.SetValue(Canvas.TopProperty, height - 100); - Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); - MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 100); - MainMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); - IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 100); - IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30); - } - else - { - this.Position = "Bottom"; - this.Left = desktopWorkingArea.Right - this.Width - 75; - this.Top = desktopWorkingArea.Bottom - height; - Arrow.SetValue(Canvas.TopProperty, height - 35); - Arrow.SetValue(Canvas.LeftProperty, (double)185); - MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 35); - MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); - IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 35); - IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185); - } - } - public void Placement() - { - if (_isAttached) - { - Arrow.Visibility = Visibility.Visible; - IdentityMenu.Arrow.Visibility = Visibility.Visible; - SetLocation(); - } - else - { - IdentityMenu.Arrow.Visibility = Visibility.Collapsed; - Arrow.Visibility = Visibility.Collapsed; - } - } + } - private void OpenIdentity(ZitiIdentity identity) - { - IdentityMenu.Identity = identity; + private void ShowMenu(object sender, MouseButtonEventArgs e) { + MainMenu.Visibility = Visibility.Visible; + } - } + async private void AddIdentity(object sender, MouseButtonEventArgs e) { + UIModel.HideOnLostFocus = false; + Microsoft.Win32.OpenFileDialog jwtDialog = new Microsoft.Win32.OpenFileDialog(); + UIModel.HideOnLostFocus = true; + jwtDialog.DefaultExt = ".jwt"; + jwtDialog.Filter = "Ziti Identities (*.jwt)|*.jwt"; + if (jwtDialog.ShowDialog() == true) { + ShowLoad("Adding Identity", "Please wait while the identity is added"); + string fileContent = File.ReadAllText(jwtDialog.FileName); - private void ShowMenu(object sender, MouseButtonEventArgs e) - { - MainMenu.Visibility = Visibility.Visible; - } + try { + Identity createdId = await serviceClient.AddIdentityAsync(System.IO.Path.GetFileName(jwtDialog.FileName), false, fileContent); - async private void AddIdentity(object sender, MouseButtonEventArgs e) - { - UIModel.HideOnLostFocus = false; - Microsoft.Win32.OpenFileDialog jwtDialog = new Microsoft.Win32.OpenFileDialog(); - UIModel.HideOnLostFocus = true; - jwtDialog.DefaultExt = ".jwt"; - jwtDialog.Filter = "Ziti Identities (*.jwt)|*.jwt"; - if (jwtDialog.ShowDialog() == true) - { - ShowLoad("Adding Identity", "Please wait while the identity is added"); - string fileContent = File.ReadAllText(jwtDialog.FileName); + if (createdId != null) { + var zid = ZitiIdentity.FromClient(createdId); + AddIdentity(zid); + LoadIdentities(true); + } else { + ShowError("Identity Error", "Identity Id was null, please try again"); + } + await serviceClient.IdentityOnOffAsync(createdId.FingerPrint, true); + } catch (ServiceException se) { + ShowError(se.Message, se.AdditionalInfo); + } catch (Exception ex) { + ShowError("Unexpected Error", "Code 2:" + ex.Message); + } + HideLoad(); + } + } - try - { - Identity createdId = await serviceClient.AddIdentityAsync(System.IO.Path.GetFileName(jwtDialog.FileName), false, fileContent); + private void OnTimedEvent(object sender, EventArgs e) { + TimeSpan span = (DateTime.Now - _startDate); + int hours = span.Hours; + int minutes = span.Minutes; + int seconds = span.Seconds; + var hoursString = (hours > 9) ? hours.ToString() : "0" + hours; + var minutesString = (minutes > 9) ? minutes.ToString() : "0" + minutes; + var secondsString = (seconds > 9) ? seconds.ToString() : "0" + seconds; + ConnectedTime.Content = hoursString + ":" + minutesString + ":" + secondsString; + } - if (createdId != null) - { - var zid = ZitiIdentity.FromClient(createdId); - AddIdentity(zid); - LoadIdentities(true); - } - else - { - ShowError("Identity Error", "Identity Id was null, please try again"); - } - await serviceClient.IdentityOnOffAsync(createdId.FingerPrint, true); - } - catch (ServiceException se) - { - ShowError(se.Message, se.AdditionalInfo); - } - catch (Exception ex) - { - ShowError("Unexpected Error", "Code 2:" + ex.Message); - } - HideLoad(); - } - } + private void InitializeTimer(int millisAgoStarted) { + _startDate = DateTime.Now.Subtract(new TimeSpan(0, 0, 0, 0, millisAgoStarted)); + _tunnelUptimeTimer = new System.Windows.Forms.Timer(); + _tunnelUptimeTimer.Interval = 100; + _tunnelUptimeTimer.Tick += OnTimedEvent; + _tunnelUptimeTimer.Enabled = true; + _tunnelUptimeTimer.Start(); + } - private void OnTimedEvent(object sender, EventArgs e) - { - TimeSpan span = (DateTime.Now - _startDate); - int hours = span.Hours; - int minutes = span.Minutes; - int seconds = span.Seconds; - var hoursString = (hours > 9) ? hours.ToString() : "0" + hours; - var minutesString = (minutes > 9) ? minutes.ToString() : "0" + minutes; - var secondsString = (seconds > 9) ? seconds.ToString() : "0" + seconds; - ConnectedTime.Content = hoursString + ":" + minutesString + ":" + secondsString; - } + async private Task DoConnectAsync() { + try { + SetNotifyIcon("green"); + TunnelConnected(true); - private void InitializeTimer(int millisAgoStarted) - { - _startDate = DateTime.Now.Subtract(new TimeSpan(0, 0, 0, 0, millisAgoStarted)); - _tunnelUptimeTimer = new System.Windows.Forms.Timer(); - _tunnelUptimeTimer.Interval = 100; - _tunnelUptimeTimer.Tick += OnTimedEvent; - _tunnelUptimeTimer.Enabled = true; - _tunnelUptimeTimer.Start(); - } + for (int i = 0; i < identities.Count; i++) { + await serviceClient.IdentityOnOffAsync(identities[i].Fingerprint, true); + } + for (int i = 0; i < IdList.Children.Count; i++) { + IdentityItem item = IdList.Children[i] as IdentityItem; + item._identity.IsEnabled = true; + item.RefreshUI(); + } + } catch (ServiceException se) { + ShowError("Error Occurred", se.Message + " " + se.AdditionalInfo); + } catch (Exception ex) { + ShowError("Unexpected Error", "Code 3:" + ex.Message); + } + } - async private Task DoConnectAsync() - { - try - { - SetNotifyIcon("green"); - TunnelConnected(true); + async private void Disconnect(object sender, RoutedEventArgs e) { + try { + ShowLoad("Disabling Service", "Please wait for the service to stop."); + var r = await monitorClient.StopServiceAsync(); + if (r.Code != 0) { + logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message); + } else { + logger.Info("Service stopped!"); + } + } catch(Exception ex) { + logger.Error(ex, "unexpected error: {0}", ex.Message); + ShowError("Erorr Disabling Service", "An error occurred while trying to disable the data service. Is the monitor service running?"); + } + HideLoad(); + } - for (int i = 0; i < identities.Count; i++) - { - await serviceClient.IdentityOnOffAsync(identities[i].Fingerprint, true); - } - for (int i = 0; i < IdList.Children.Count; i++) - { - IdentityItem item = IdList.Children[i] as IdentityItem; - item._identity.IsEnabled = true; - item.RefreshUI(); - } - } - catch (ServiceException se) - { - ShowError("Error Occurred", se.Message + " " + se.AdditionalInfo); - } - catch (Exception ex) - { - ShowError("Unexpected Error", "Code 3:" + ex.Message); - } - } + internal void ShowLoad(string title, string msg) { + this.Dispatcher.Invoke(() => { + LoadingDetails.Text = msg; + LoadingTitle.Content = title; + LoadProgress.IsIndeterminate = true; + LoadingScreen.Visibility = Visibility.Visible; + UpdateLayout(); + }); + } - async private void Disconnect(object sender, RoutedEventArgs e) - { - try - { - ShowLoad("Disabling Service", "Please wait for the service to stop."); - var r = await monitorClient.StopServiceAsync(); - if (r.Code != 0) - { - logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message); - } - else - { - logger.Info("Service stopped!"); - } - } - catch (Exception ex) - { - logger.Error(ex, "unexpected error: {0}", ex.Message); - ShowError("Erorr Disabling Service", "An error occurred while trying to disable the data service. Is the monitor service running?"); - } - HideLoad(); - } + internal void HideLoad() { + this.Dispatcher.Invoke(() => { + LoadingScreen.Visibility = Visibility.Collapsed; + LoadProgress.IsIndeterminate = false; + }); + } - internal void ShowLoad(string title, string msg) - { - this.Dispatcher.Invoke(() => - { - LoadingDetails.Text = msg; - LoadingTitle.Content = title; - LoadProgress.IsIndeterminate = true; - LoadingScreen.Visibility = Visibility.Visible; - UpdateLayout(); - }); - } + private void FormFadeOut_Completed(object sender, EventArgs e) { + closeCompleted = true; + } + private bool closeCompleted = false; + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { + if (!closeCompleted) { + FormFadeOut.Begin(); + e.Cancel = true; + } + } - internal void HideLoad() - { - this.Dispatcher.Invoke(() => - { - LoadingScreen.Visibility = Visibility.Collapsed; - LoadProgress.IsIndeterminate = false; - }); - } + public void ShowError(String title, String message) { + this.Dispatcher.Invoke(() => { + ErrorTitle.Content = title; + ErrorDetails.Text = message; + ErrorView.Visibility = Visibility.Visible; + }); + } - private void FormFadeOut_Completed(object sender, EventArgs e) - { - closeCompleted = true; - } - private bool closeCompleted = false; - private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) - { - if (!closeCompleted) - { - FormFadeOut.Begin(); - e.Cancel = true; - } - } + private void CloseError(object sender, RoutedEventArgs e) { + this.Dispatcher.Invoke(() => { + ErrorView.Visibility = Visibility.Collapsed; + NoServiceView.Visibility = Visibility.Collapsed; + CloseErrorButton.IsEnabled = true; + }); + } - public void ShowError(String title, String message) - { - this.Dispatcher.Invoke(() => - { - ErrorTitle.Content = title; - ErrorDetails.Text = message; - ErrorView.Visibility = Visibility.Visible; - }); - } + private void CloseApp(object sender, RoutedEventArgs e) { + Application.Current.Shutdown(); + } - private void CloseError(object sender, RoutedEventArgs e) - { - this.Dispatcher.Invoke(() => - { - ErrorView.Visibility = Visibility.Collapsed; - NoServiceView.Visibility = Visibility.Collapsed; - CloseErrorButton.IsEnabled = true; - }); - } - - private void CloseApp(object sender, RoutedEventArgs e) - { - Application.Current.Shutdown(); - } - - private void MainUI_Deactivated(object sender, EventArgs e) - { - if (this._isAttached) - { + private void MainUI_Deactivated(object sender, EventArgs e) { + if (this._isAttached) { #if DEBUG logger.Debug("debug is enabled - windows pinned"); #else - this.Visibility = Visibility.Collapsed; + this.Visibility = Visibility.Collapsed; #endif + } + } + + private void Label_MouseDoubleClick(object sender, MouseButtonEventArgs e) { + Placement(); + } + + int cur = 0; + LogLevelEnum[] levels = new LogLevelEnum[] { LogLevelEnum.FATAL, LogLevelEnum.ERROR, LogLevelEnum.WARN, LogLevelEnum.INFO, LogLevelEnum.DEBUG, LogLevelEnum.TRACE, LogLevelEnum.VERBOSE }; + public LogLevelEnum NextLevel() { + cur++; + if (cur > 6) { + cur = 0; + } + return levels[cur]; + } + + private void IdList_LayoutUpdated(object sender, EventArgs e) { + Placement(); + } + + async private void CollectLogFileClick(object sender, RoutedEventArgs e) { + await CollectLogFiles(); + } + async private Task CollectLogFiles() { + MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync(); + if (resp != null) { + + logger.Info("response: {0}", resp.Message); + } else { + ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback. Is the monitor service running?"); } - } + } - private void Label_MouseDoubleClick(object sender, MouseButtonEventArgs e) - { - Placement(); - } + private string _blurbUrl = ""; - int cur = 0; - LogLevelEnum[] levels = new LogLevelEnum[] { LogLevelEnum.FATAL, LogLevelEnum.ERROR, LogLevelEnum.WARN, LogLevelEnum.INFO, LogLevelEnum.DEBUG, LogLevelEnum.TRACE, LogLevelEnum.VERBOSE }; - public LogLevelEnum NextLevel() - { - cur++; - if (cur > 6) - { - cur = 0; + /// + /// Show the blurb as a growler notification + /// + /// The message to show + /// The url or action name to execute + public async Task ShowBlurbAsync(string message, string url) { + Blurb.Content = message; + _blurbUrl = url; + BlurbArea.Visibility = Visibility.Visible; + BlurbArea.Opacity = 0; + BlurbArea.Margin = new Thickness(0, 0, 0, 0); + DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3)); + ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(15, 0, 15, 15), TimeSpan.FromSeconds(.3)); + BlurbArea.BeginAnimation(Grid.OpacityProperty, animation); + BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick); + await Task.Delay(5000); + HideBlurb(); + } + + /// + /// Execute the hide operation wihout an action from the growler + /// + /// The object that was clicked + /// The click event + private void DoHideBlurb(object sender, MouseButtonEventArgs e) { + HideBlurb(); + } + + /// + /// Hide the blurb area + /// + private void HideBlurb() { + DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); + ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3)); + animation.Completed += HideComplete; + BlurbArea.BeginAnimation(Grid.OpacityProperty, animation); + BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick); + } + + /// + /// Hide the blurb area after the animation fades out + /// + /// The animation object + /// The completion event + private void HideComplete(object sender, EventArgs e) { + BlurbArea.Visibility = Visibility.Collapsed; + } + + /// + /// Execute a predefined action or url when the pop up is clicked + /// + /// The object that was clicked + /// The click event + private void BlurbAction(object sender, MouseButtonEventArgs e) { + if (_blurbUrl.Length>0) { + // So this simply execute a url but you could do like if (_blurbUrl=="DoSomethingNifty") CallNifyFunction(); + if (_blurbUrl== this.RECOVER) { + this.ShowMFA(IdentityMenu.Identity, 4); + } else { + Process.Start(new ProcessStartInfo(_blurbUrl) { UseShellExecute = true }); + } + HideBlurb(); + } else { + HideBlurb(); + } + } + + private void ShowAuthenticate(ZitiIdentity identity) { + MFAAuthenticate(identity); + } + + private void ShowRecovery(ZitiIdentity identity) { + ShowMFARecoveryCodes(identity); + } + + + + + + private ICommand someCommand; + public ICommand SomeCommand { + get { + return someCommand + ?? (someCommand = new ActionCommand(() => { + if (DebugForm.Visibility == Visibility.Hidden) { + DebugForm.Visibility = Visibility.Visible; + } else { + DebugForm.Visibility = Visibility.Hidden; + } + })); + } + set { + someCommand = value; } - return levels[cur]; - } + } + } - private void IdList_LayoutUpdated(object sender, EventArgs e) - { - Placement(); - } + public class ActionCommand : ICommand { + private readonly Action _action; - async private void CollectLogFileClick(object sender, RoutedEventArgs e) - { - await CollectLogFiles(); - } - async private Task CollectLogFiles() - { - MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync(); - if (resp != null) - { + public ActionCommand(Action action) { + _action = action; + } - logger.Info("response: {0}", resp.Message); - } - else - { - ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback. Is the monitor service running?"); - } - } + public void Execute(object parameter) { + _action(); + } - private string _blurbUrl = ""; + public bool CanExecute(object parameter) { + return true; + } - /// - /// Show the blurb as a growler notification - /// - /// The message to show - /// The url or action name to execute - public async Task ShowBlurbAsync(string message, string url) - { - Blurb.Content = message; - _blurbUrl = url; - BlurbArea.Visibility = Visibility.Visible; - BlurbArea.Opacity = 0; - BlurbArea.Margin = new Thickness(0, 0, 0, 0); - DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3)); - ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(15, 0, 15, 15), TimeSpan.FromSeconds(.3)); - BlurbArea.BeginAnimation(Grid.OpacityProperty, animation); - BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick); - await Task.Delay(5000); - HideBlurb(); - } - - /// - /// Execute the hide operation wihout an action from the growler - /// - /// The object that was clicked - /// The click event - private void DoHideBlurb(object sender, MouseButtonEventArgs e) - { - HideBlurb(); - } - - /// - /// Hide the blurb area - /// - private void HideBlurb() - { - DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3)); - ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3)); - animation.Completed += HideComplete; - BlurbArea.BeginAnimation(Grid.OpacityProperty, animation); - BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick); - } - - /// - /// Hide the blurb area after the animation fades out - /// - /// The animation object - /// The completion event - private void HideComplete(object sender, EventArgs e) - { - BlurbArea.Visibility = Visibility.Collapsed; - } - - /// - /// Execute a predefined action or url when the pop up is clicked - /// - /// The object that was clicked - /// The click event - private void BlurbAction(object sender, MouseButtonEventArgs e) - { - if (_blurbUrl.Length > 0) - { - // So this simply execute a url but you could do like if (_blurbUrl=="DoSomethingNifty") CallNifyFunction(); - if (_blurbUrl == this.RECOVER) - { - this.ShowMFA(IdentityMenu.Identity, 4); - } - else - { - Process.Start(new ProcessStartInfo(_blurbUrl) { UseShellExecute = true }); - } - HideBlurb(); - } - else - { - HideBlurb(); - } - } - - private void ShowAuthenticate(ZitiIdentity identity) - { - MFAAuthenticate(identity); - } - - private void ShowRecovery(ZitiIdentity identity) - { - ShowMFARecoveryCodes(identity); - } - - - - - - private ICommand someCommand; - public ICommand SomeCommand - { - get - { - return someCommand - ?? (someCommand = new ActionCommand(() => - { - if (DebugForm.Visibility == Visibility.Hidden) - { - DebugForm.Visibility = Visibility.Visible; - } - else - { - DebugForm.Visibility = Visibility.Hidden; - } - })); - } - set - { - someCommand = value; - } - } - } - - public class ActionCommand : ICommand - { - private readonly Action _action; - - public ActionCommand(Action action) - { - _action = action; - } - - public void Execute(object parameter) - { - _action(); - } - - public bool CanExecute(object parameter) - { - return true; - } - - public event EventHandler CanExecuteChanged; - } + public event EventHandler CanExecuteChanged; + } } From c1d3b3d0a977723789573d505f73f2d5cd9343ea Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 6 Apr 2021 16:31:20 -0400 Subject: [PATCH 13/24] one big commit - nothing but go fmt ./... --- service/cziti/ctun.go | 2 +- service/cziti/mfa.go | 16 +- service/cziti/sdk.go | 2 +- service/ziti-tunnel/cli/constants.go | 110 ++-- service/ziti-tunnel/cli/ipcClient.go | 516 +++++++++--------- service/ziti-tunnel/cli/responseGenerator.go | 458 ++++++++-------- service/ziti-tunnel/cli/service.go | 110 ++-- service/ziti-tunnel/constants/consts.go | 8 +- service/ziti-tunnel/dto/clidtos.go | 94 ++-- service/ziti-tunnel/dto/events.go | 12 +- service/ziti-tunnel/service/debug.go | 10 +- service/ziti-tunnel/service/install.go | 8 +- .../service/orphaned-identities.go | 202 +++---- service/ziti-tunnel/service/permissions.go | 2 +- service/ziti-tunnel/service/pkg-vars.go | 4 +- service/ziti-tunnel/service/service.go | 2 +- service/ziti-tunnel/service/state.go | 6 +- service/ziti-tunnel/service/topic.go | 12 +- service/ziti-tunnel/service/types.go | 2 +- service/ziti-tunnel/util/detect-ip-changes.go | 10 +- service/ziti-tunnel/util/iputil/iputil.go | 2 +- service/ziti-tunnel/util/logging/loghelper.go | 15 +- 22 files changed, 801 insertions(+), 802 deletions(-) diff --git a/service/cziti/ctun.go b/service/cziti/ctun.go index 4a700e90..09c082cd 100644 --- a/service/cziti/ctun.go +++ b/service/cziti/ctun.go @@ -321,4 +321,4 @@ Set-NetIPInterface -InterfaceIndex $i.ifIndex -InterfaceMetric %d`, interfaceNam if err != nil { log.Errorf("ERROR setting interface metric: %v", err) } -} \ No newline at end of file +} diff --git a/service/cziti/mfa.go b/service/cziti/mfa.go index bf8ddcc0..ee8ab036 100644 --- a/service/cziti/mfa.go +++ b/service/cziti/mfa.go @@ -113,9 +113,9 @@ func ziti_mfa_cb_verify_go(_ C.ziti_context, status C.int, cFingerprint *C.char) fp := C.GoString(cFingerprint) log.Debugf("ziti_mfa_cb_verify_go called for %s. status: %d for ", fp, int(status)) var m = dto.MfaEvent{ - ActionEvent: dto.MFAEnrollmentVerificationEvent, - Fingerprint: fp, - Successful: false, + ActionEvent: dto.MFAEnrollmentVerificationEvent, + Fingerprint: fp, + Successful: false, RecoveryCodes: nil, } @@ -135,6 +135,7 @@ func ziti_mfa_cb_verify_go(_ C.ziti_context, status C.int, cFingerprint *C.char) } var rtnCodes = make(chan mfaCodes) + func ReturnMfaCodes(id *ZIdentity, code string) ([]string, error) { ccode := C.CString(code) defer C.free(unsafe.Pointer(ccode)) @@ -179,6 +180,7 @@ func ziti_mfa_recovery_codes_cb_return(_ C.ziti_context, status C.int, recoveryC } var genCodes = make(chan mfaCodes) + func GenerateMfaCodes(id *ZIdentity, code string) ([]string, error) { ccode := C.CString(code) defer C.free(unsafe.Pointer(ccode)) @@ -292,9 +294,9 @@ func ziti_mfa_cb_remove_go(_ C.ziti_context, status C.int, cFingerprint *C.char) log.Debugf("ziti_mfa_cb_remove_go called for %s. status: %d for ", fp, int(status)) var m = dto.MfaEvent{ - ActionEvent: dto.MFAEnrollmentRemovedEvent, - Fingerprint: fp, - Successful: false, + ActionEvent: dto.MFAEnrollmentRemovedEvent, + Fingerprint: fp, + Successful: false, RecoveryCodes: nil, } @@ -311,4 +313,4 @@ func ziti_mfa_cb_remove_go(_ C.ziti_context, status C.int, cFingerprint *C.char) log.Debugf("sending ziti_mfa_verify response back to UI for %s. verified: %t. error: %s", fp, m.Successful, m.Error) goapi.BroadcastEvent(m) -} \ No newline at end of file +} diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index 975fac58..503820a8 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -453,7 +453,7 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { var m = dto.IdentityEvent{ ActionEvent: dto.IdentityUpdateComplete, - Id: dto.Identity{ + Id: dto.Identity{ FingerPrint: zid.Fingerprint, }, } diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index 3c9f4be5..8191fe45 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -1,55 +1,55 @@ -package cli - -/* - * Copyright NetFoundry, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import ( - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/logging" -) - -var GET_STATUS = dto.CommandMsg{ - Function: "Status", -} - -var ONOFF_IDENTITY = dto.CommandMsg{ - Function: "IdentityOnOff", -} - -var SET_LOGLEVEL = dto.CommandMsg{ - Function: "SetLogLevel", -} - -var NOTIFY_LOGLEVEL_UI_MONITOR = dto.CommandMsg{ - Function: "NotifyLogLevelUIAndUpdateService", -} - -var NOTIFY_IDENTITY_UI = dto.CommandMsg{ - Function: "NotifyIdentityUI", -} - -var monitorIpcPipe = `\\.\pipe\OpenZiti\ziti-monitor\ipc` - -var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} -{{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} -{{end}}` - -var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%9s" "Protocols"}} | {{printf "%14s" "Ports"}} | {{printf "%40s" "Addresses"}} | {{"OwnsIntercept"}} -{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%9s" .Protocols}} | {{printf "%14s" .Ports}} | {{printf "%40s" .Addresses}} | {{.OwnsIntercept}} -{{end}}` - -var log = logging.Logger() +package cli + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/logging" +) + +var GET_STATUS = dto.CommandMsg{ + Function: "Status", +} + +var ONOFF_IDENTITY = dto.CommandMsg{ + Function: "IdentityOnOff", +} + +var SET_LOGLEVEL = dto.CommandMsg{ + Function: "SetLogLevel", +} + +var NOTIFY_LOGLEVEL_UI_MONITOR = dto.CommandMsg{ + Function: "NotifyLogLevelUIAndUpdateService", +} + +var NOTIFY_IDENTITY_UI = dto.CommandMsg{ + Function: "NotifyIdentityUI", +} + +var monitorIpcPipe = `\\.\pipe\OpenZiti\ziti-monitor\ipc` + +var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}} +{{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} +{{end}}` + +var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%9s" "Protocols"}} | {{printf "%14s" "Ports"}} | {{printf "%40s" "Addresses"}} | {{"OwnsIntercept"}} +{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%9s" .Protocols}} | {{printf "%14s" .Ports}} | {{printf "%40s" .Addresses}} | {{.OwnsIntercept}} +{{end}}` + +var log = logging.Logger() diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index 3a395e66..ef621083 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -1,258 +1,258 @@ -package cli - -/* - * Copyright NetFoundry, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import ( - "bufio" - "encoding/json" - "io" - "net" - "strings" - "time" - - "github.com/Microsoft/go-winio" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" -) - -type fetchStatusFromRTS func([]string, *dto.TunnelStatus, map[string]bool) dto.Response -type fetchResponseFromRTS func([]string, dto.Response, map[string]bool) dto.Response - -func sendMessagetoPipe(ipcPipeConn net.Conn, commandMsg *dto.CommandMsg, args []string) error { - writer := bufio.NewWriter(ipcPipeConn) - enc := json.NewEncoder(writer) - - err := enc.Encode(commandMsg) - if err != nil { - log.Error("could not encode or writer list identities message, %v", err) - return err - } - - log.Debug("Message sent to ipc pipe") - - writer.Flush() - - return nil -} - -func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan bool, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { - - reader := bufio.NewReader(ipcPipeConn) - msg, err := reader.ReadString('\n') - - if err != nil { - log.Error(err) - readDone <- false - return - } - - if len(args) == 0 { - args = append(args, "all") - } - - dec := json.NewDecoder(strings.NewReader(msg)) - - if fn != nil { - var tunnelStatus dto.ZitiTunnelStatus - if err := dec.Decode(&tunnelStatus); err == io.EOF { - readDone <- false - return - } else if err != nil { - log.Fatal(err) - readDone <- false - return - } - - if tunnelStatus.Status != nil { - responseMsg := fn(args, tunnelStatus.Status, flags) - if responseMsg.Code == service.SUCCESS { - log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) - readDone <- true - return - } else { - if responseMsg.Error != "" { - log.Info(responseMsg.Error) - } else { - log.Info(responseMsg.Message) - } - } - } else { - log.Errorf("Ziti tunnel retuned nil status") - } - } - - if responseFn != nil { - var response dto.Response - if err := dec.Decode(&response); err == io.EOF { - readDone <- false - return - } else if err != nil { - log.Fatal(err) - readDone <- false - return - } - - if response.Message != "" { - responseMsg := responseFn(args, response, flags) - if responseMsg.Code == service.SUCCESS { - if responseMsg.Payload != nil { - log.Infof("Payload : %v", responseMsg.Payload) - } - log.Infof("Message : %s", responseMsg.Message) - readDone <- true - return - } else { - if responseMsg.Error != "" { - log.Info(responseMsg.Error) - } else { - log.Info(responseMsg.Message) - } - } - } else { - log.Errorf("Ziti tunnel retuned nil response") - } - } - - readDone <- false - return -} - -func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) bool { - log.Infof("Command %s with args %s", commandMsg.Function, args) - - log.Debug("Connecting to pipe") - timeout := 2000 * time.Millisecond - ipcPipeConn, err := winio.DialPipe(service.IpcPipeName(), &timeout) - defer closeConn(ipcPipeConn) - - if err != nil { - log.Errorf("Connection to ipc pipe is not established, %v", err) - log.Errorf("Ziti Desktop Edge app may not be running") - return false - } - readDone := make(chan bool) - defer close(readDone) // ensure that goroutine exits - - go readMessageFromPipe(ipcPipeConn, readDone, fn, responseFn, args, flags) - - err = sendMessagetoPipe(ipcPipeConn, commandMsg, args) - if err != nil { - log.Errorf("Message is not sent to ipc pipe, %v", err) - return false - } - - log.Debugf("Connection to ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) - - status := <-readDone - log.Debug("read finished normally") - return status -} - -// monitor ipc messages - -func GetDataFromMonitorIpcPipe(actionMessage *dto.ActionEvent, args []string, flags map[string]bool) bool { - log.Infof("Command %s with args %s", actionMessage.StatusEvent.Op, args) - - log.Debug("Connecting to pipe") - timeout := 2000 * time.Millisecond - ipcPipeConn, err := winio.DialPipe(monitorIpcPipe, &timeout) - defer closeConn(ipcPipeConn) - - if err != nil { - log.Errorf("Connection to monitor ipc pipe is not established, %v", err) - log.Errorf("Ziti Update service may not be running") - return false - } - readDone := make(chan bool) - defer close(readDone) // ensure that goroutine exits - - go readMessageFromMonitorPipe(ipcPipeConn, readDone, args, flags) - - err = sendMessageToMonitorPipe(ipcPipeConn, actionMessage, args) - if err != nil { - log.Errorf("Message is not sent to monitor ipc pipe, %v", err) - return false - } - - log.Debugf("Connection to monitor ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) - - status := <-readDone - log.Debug("read finished normally") - return status -} - -func sendMessageToMonitorPipe(ipcPipeConn net.Conn, actionMessage *dto.ActionEvent, args []string) error { - writer := bufio.NewWriter(ipcPipeConn) - enc := json.NewEncoder(writer) - - err := enc.Encode(actionMessage) - if err != nil { - log.Error("could not encode or write response message, %v", err) - return err - } - - log.Debug("Message sent to monitor ipc pipe") - - writer.Flush() - - return nil -} - -func readMessageFromMonitorPipe(ipcPipeConn net.Conn, readDone chan bool, args []string, flags map[string]bool) { - - reader := bufio.NewReader(ipcPipeConn) - msg, err := reader.ReadString('\n') - - if err != nil { - log.Error(err) - readDone <- false - return - } - - dec := json.NewDecoder(strings.NewReader(msg)) - - var monitorServiceResponse dto.MonitorServiceResponse - if err := dec.Decode(&monitorServiceResponse); err == io.EOF { - readDone <- false - return - } else if err != nil { - log.Fatal(err) - readDone <- false - return - } - - if monitorServiceResponse.Code == service.SUCCESS { - log.Infof("Feedback file %s is created", monitorServiceResponse.Message) - readDone <- true - return - } else { - log.Info(monitorServiceResponse.Error) - } - - readDone <- false - return -} - -func closeConn(conn net.Conn) { - if conn != nil { - err := conn.Close() - if err != nil { - log.Warnf("abnormal error while closing connection. %v", err) - } - } -} +package cli + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "bufio" + "encoding/json" + "io" + "net" + "strings" + "time" + + "github.com/Microsoft/go-winio" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" +) + +type fetchStatusFromRTS func([]string, *dto.TunnelStatus, map[string]bool) dto.Response +type fetchResponseFromRTS func([]string, dto.Response, map[string]bool) dto.Response + +func sendMessagetoPipe(ipcPipeConn net.Conn, commandMsg *dto.CommandMsg, args []string) error { + writer := bufio.NewWriter(ipcPipeConn) + enc := json.NewEncoder(writer) + + err := enc.Encode(commandMsg) + if err != nil { + log.Error("could not encode or writer list identities message, %v", err) + return err + } + + log.Debug("Message sent to ipc pipe") + + writer.Flush() + + return nil +} + +func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan bool, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) { + + reader := bufio.NewReader(ipcPipeConn) + msg, err := reader.ReadString('\n') + + if err != nil { + log.Error(err) + readDone <- false + return + } + + if len(args) == 0 { + args = append(args, "all") + } + + dec := json.NewDecoder(strings.NewReader(msg)) + + if fn != nil { + var tunnelStatus dto.ZitiTunnelStatus + if err := dec.Decode(&tunnelStatus); err == io.EOF { + readDone <- false + return + } else if err != nil { + log.Fatal(err) + readDone <- false + return + } + + if tunnelStatus.Status != nil { + responseMsg := fn(args, tunnelStatus.Status, flags) + if responseMsg.Code == service.SUCCESS { + log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) + readDone <- true + return + } else { + if responseMsg.Error != "" { + log.Info(responseMsg.Error) + } else { + log.Info(responseMsg.Message) + } + } + } else { + log.Errorf("Ziti tunnel retuned nil status") + } + } + + if responseFn != nil { + var response dto.Response + if err := dec.Decode(&response); err == io.EOF { + readDone <- false + return + } else if err != nil { + log.Fatal(err) + readDone <- false + return + } + + if response.Message != "" { + responseMsg := responseFn(args, response, flags) + if responseMsg.Code == service.SUCCESS { + if responseMsg.Payload != nil { + log.Infof("Payload : %v", responseMsg.Payload) + } + log.Infof("Message : %s", responseMsg.Message) + readDone <- true + return + } else { + if responseMsg.Error != "" { + log.Info(responseMsg.Error) + } else { + log.Info(responseMsg.Message) + } + } + } else { + log.Errorf("Ziti tunnel retuned nil response") + } + } + + readDone <- false + return +} + +func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, responseFn fetchResponseFromRTS, args []string, flags map[string]bool) bool { + log.Infof("Command %s with args %s", commandMsg.Function, args) + + log.Debug("Connecting to pipe") + timeout := 2000 * time.Millisecond + ipcPipeConn, err := winio.DialPipe(service.IpcPipeName(), &timeout) + defer closeConn(ipcPipeConn) + + if err != nil { + log.Errorf("Connection to ipc pipe is not established, %v", err) + log.Errorf("Ziti Desktop Edge app may not be running") + return false + } + readDone := make(chan bool) + defer close(readDone) // ensure that goroutine exits + + go readMessageFromPipe(ipcPipeConn, readDone, fn, responseFn, args, flags) + + err = sendMessagetoPipe(ipcPipeConn, commandMsg, args) + if err != nil { + log.Errorf("Message is not sent to ipc pipe, %v", err) + return false + } + + log.Debugf("Connection to ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) + + status := <-readDone + log.Debug("read finished normally") + return status +} + +// monitor ipc messages + +func GetDataFromMonitorIpcPipe(actionMessage *dto.ActionEvent, args []string, flags map[string]bool) bool { + log.Infof("Command %s with args %s", actionMessage.StatusEvent.Op, args) + + log.Debug("Connecting to pipe") + timeout := 2000 * time.Millisecond + ipcPipeConn, err := winio.DialPipe(monitorIpcPipe, &timeout) + defer closeConn(ipcPipeConn) + + if err != nil { + log.Errorf("Connection to monitor ipc pipe is not established, %v", err) + log.Errorf("Ziti Update service may not be running") + return false + } + readDone := make(chan bool) + defer close(readDone) // ensure that goroutine exits + + go readMessageFromMonitorPipe(ipcPipeConn, readDone, args, flags) + + err = sendMessageToMonitorPipe(ipcPipeConn, actionMessage, args) + if err != nil { + log.Errorf("Message is not sent to monitor ipc pipe, %v", err) + return false + } + + log.Debugf("Connection to monitor ipc pipe is established - %s and remote address %s", ipcPipeConn.LocalAddr().String(), ipcPipeConn.RemoteAddr().String()) + + status := <-readDone + log.Debug("read finished normally") + return status +} + +func sendMessageToMonitorPipe(ipcPipeConn net.Conn, actionMessage *dto.ActionEvent, args []string) error { + writer := bufio.NewWriter(ipcPipeConn) + enc := json.NewEncoder(writer) + + err := enc.Encode(actionMessage) + if err != nil { + log.Error("could not encode or write response message, %v", err) + return err + } + + log.Debug("Message sent to monitor ipc pipe") + + writer.Flush() + + return nil +} + +func readMessageFromMonitorPipe(ipcPipeConn net.Conn, readDone chan bool, args []string, flags map[string]bool) { + + reader := bufio.NewReader(ipcPipeConn) + msg, err := reader.ReadString('\n') + + if err != nil { + log.Error(err) + readDone <- false + return + } + + dec := json.NewDecoder(strings.NewReader(msg)) + + var monitorServiceResponse dto.MonitorServiceResponse + if err := dec.Decode(&monitorServiceResponse); err == io.EOF { + readDone <- false + return + } else if err != nil { + log.Fatal(err) + readDone <- false + return + } + + if monitorServiceResponse.Code == service.SUCCESS { + log.Infof("Feedback file %s is created", monitorServiceResponse.Message) + readDone <- true + return + } else { + log.Info(monitorServiceResponse.Error) + } + + readDone <- false + return +} + +func closeConn(conn net.Conn) { + if conn != nil { + err := conn.Close() + if err != nil { + log.Warnf("abnormal error while closing connection. %v", err) + } + } +} diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index 83ca8355..fd06eeda 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -1,229 +1,229 @@ -package cli - -/* - * Copyright NetFoundry, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" - "text/template" - - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" -) - -func convertToIdentityCli(id *dto.Identity) dto.IdentityCli { - return dto.IdentityCli{ - Name: id.Name, - FingerPrint: id.FingerPrint, - Active: id.Active, - Config: id.Config.ZtAPI, - Status: id.Status, - } -} - -func convertToServiceCli(svc dto.Service) dto.ServiceCli { - cliPorts := "" - for _, val := range svc.Ports { - if len(cliPorts) != 0 { - cliPorts = fmt.Sprintf("%s, %d-%d", cliPorts, val.Low, val.High) - } else { - cliPorts = fmt.Sprintf("%d-%d", val.Low, val.High) - } - } - cliAddresses := "" - for _, val := range svc.Addresses { - if len(cliAddresses) != 0 { - cliAddresses = cliAddresses + ", " + val.HostName + "/" + val.IP - } else { - cliAddresses = val.HostName + "/" + val.IP - } - } - - return dto.ServiceCli{ - Name: svc.Name, - Id: svc.Id, - Protocols: strings.Join(svc.Protocols, ","), - Ports: cliPorts, - Addresses: cliAddresses, - OwnsIntercept: svc.OwnsIntercept, - } -} - -// GetIdentitiesFromRTS is to get identities from the RTS -func GetIdentitiesFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { - - var filteredIdentities []dto.IdentityCli - - if flags["services"] { - return filterServicesByIdentity(args, status, flags) - } - - for _, val := range args { - if val == "all" { - for _, id := range status.Identities { - filteredIdentities = append(filteredIdentities, convertToIdentityCli(id)) - } - break - } else { - for _, id := range status.Identities { - if strings.Compare(id.Name, val) == 0 { - filteredIdentities = append(filteredIdentities, convertToIdentityCli(id)) - } - } - } - } - - if len(filteredIdentities) == 0 { - errMsg := fmt.Sprintf("Could not find identities matching %s", args) - return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} - } - message := fmt.Sprintf("Got %d identities - %s", len(filteredIdentities), args) - return generateResponse("identities", message, filteredIdentities, flags, templateIdentity) -} - -func filterServicesByIdentity(identity []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { - var filteredServices []dto.ServiceCli - - for _, id := range status.Identities { - for _, filterID := range identity { - if (filterID == "all" || id.Name == filterID) && len(id.Services) > 0 { - for _, svc := range id.Services { - filteredServices = append(filteredServices, convertToServiceCli(*svc)) - } - // if the filterId array has all or matching string, then fetch all the services and break from the filter loop - break - } - } - - } - - if len(filteredServices) == 0 { - errMsg := fmt.Sprintf("Could not find services for identity %s", identity) - return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} - } - message := fmt.Sprintf("Got %d services for identity - %s", len(filteredServices), identity) - return generateResponse("services", message, filteredServices, flags, templateService) - -} - -func GetServicesFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { - - var filteredServices []dto.ServiceCli - - for _, val := range args { - if val == "all" { - for _, id := range status.Identities { - if len(id.Services) > 0 { - for _, svc := range id.Services { - filteredServices = append(filteredServices, convertToServiceCli(*svc)) - } - } - } - break - } else { - for _, id := range status.Identities { - if len(id.Services) > 0 { - for _, svc := range id.Services { - if strings.Compare(val, svc.Name) == 0 { - filteredServices = append(filteredServices, convertToServiceCli(*svc)) - } - } - } - } - } - } - - if len(filteredServices) == 0 { - errMsg := fmt.Sprintf("Could not find services matching %s", args) - return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} - } - message := fmt.Sprintf("Got %d services - %s", len(filteredServices), args) - - return generateResponse("services", message, filteredServices, flags, templateService) - -} - -func generateResponse(dataType string, message string, filteredData interface{}, flags map[string]bool, templateStr string) dto.Response { - - var bytesData []byte - var err error - var responseBuffer bytes.Buffer - var responseStr string - - if flags["prettyJSON"] == true { - bytesData, err = json.MarshalIndent(filteredData, "", " ") - - if err != nil { - log.Error(err) - return dto.Response{Message: message, Code: service.ERROR, Error: "Could not fetch " + dataType + " from Runtime", Payload: nil} - } - responseStr = string(bytesData) - - } else { - it, err := template.New("filteredData").Parse(templateStr) - - if err != nil { - log.Error(err) - return dto.Response{Message: message, Code: service.ERROR, Error: "Could not parse " + dataType + " from Runtime", Payload: nil} - } - - err = it.Execute(&responseBuffer, filteredData) - - if err != nil { - log.Error(err) - return dto.Response{Message: message, Code: service.ERROR, Error: "Could not print " + dataType + " from Runtime", Payload: nil} - } - responseStr = responseBuffer.String() - } - - return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: responseStr} -} - -func GetLogLevelFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { - - if flags["query"] == true { - message := fmt.Sprintf("Loglevel is currently set to %s", status.LogLevel) - return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: ""} - } - errMsg := fmt.Sprintf("Unknown error: args %s flag %v", args, flags) - return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: ""} - -} - -// GetIdentityResponseObjectFromRTS is to get identity info from the RTS -func GetIdentityResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { - log.Debugf("Message from ziti-tunnel : %v", status.Message) - if status.Error == "" && status.Payload != nil { - log.Debugf("Payload from RTS %v", status.Payload) - payloadData := status.Payload.(map[string]interface{}) - identityStatus := make(map[string]interface{}) - identityStatus["FingerPrint"] = payloadData["FingerPrint"] - identityStatus["Active"] = payloadData["Active"] - identityStatus["Name"] = payloadData["Name"] - return dto.Response{Message: status.Message, Code: service.SUCCESS, Error: "", Payload: identityStatus} - } else { - return status - } -} - -// GetResponseObjectFromRTS is to get response object info from the RTS -func GetResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { - return status -} +package cli + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" + "text/template" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" +) + +func convertToIdentityCli(id *dto.Identity) dto.IdentityCli { + return dto.IdentityCli{ + Name: id.Name, + FingerPrint: id.FingerPrint, + Active: id.Active, + Config: id.Config.ZtAPI, + Status: id.Status, + } +} + +func convertToServiceCli(svc dto.Service) dto.ServiceCli { + cliPorts := "" + for _, val := range svc.Ports { + if len(cliPorts) != 0 { + cliPorts = fmt.Sprintf("%s, %d-%d", cliPorts, val.Low, val.High) + } else { + cliPorts = fmt.Sprintf("%d-%d", val.Low, val.High) + } + } + cliAddresses := "" + for _, val := range svc.Addresses { + if len(cliAddresses) != 0 { + cliAddresses = cliAddresses + ", " + val.HostName + "/" + val.IP + } else { + cliAddresses = val.HostName + "/" + val.IP + } + } + + return dto.ServiceCli{ + Name: svc.Name, + Id: svc.Id, + Protocols: strings.Join(svc.Protocols, ","), + Ports: cliPorts, + Addresses: cliAddresses, + OwnsIntercept: svc.OwnsIntercept, + } +} + +// GetIdentitiesFromRTS is to get identities from the RTS +func GetIdentitiesFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { + + var filteredIdentities []dto.IdentityCli + + if flags["services"] { + return filterServicesByIdentity(args, status, flags) + } + + for _, val := range args { + if val == "all" { + for _, id := range status.Identities { + filteredIdentities = append(filteredIdentities, convertToIdentityCli(id)) + } + break + } else { + for _, id := range status.Identities { + if strings.Compare(id.Name, val) == 0 { + filteredIdentities = append(filteredIdentities, convertToIdentityCli(id)) + } + } + } + } + + if len(filteredIdentities) == 0 { + errMsg := fmt.Sprintf("Could not find identities matching %s", args) + return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} + } + message := fmt.Sprintf("Got %d identities - %s", len(filteredIdentities), args) + return generateResponse("identities", message, filteredIdentities, flags, templateIdentity) +} + +func filterServicesByIdentity(identity []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { + var filteredServices []dto.ServiceCli + + for _, id := range status.Identities { + for _, filterID := range identity { + if (filterID == "all" || id.Name == filterID) && len(id.Services) > 0 { + for _, svc := range id.Services { + filteredServices = append(filteredServices, convertToServiceCli(*svc)) + } + // if the filterId array has all or matching string, then fetch all the services and break from the filter loop + break + } + } + + } + + if len(filteredServices) == 0 { + errMsg := fmt.Sprintf("Could not find services for identity %s", identity) + return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} + } + message := fmt.Sprintf("Got %d services for identity - %s", len(filteredServices), identity) + return generateResponse("services", message, filteredServices, flags, templateService) + +} + +func GetServicesFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { + + var filteredServices []dto.ServiceCli + + for _, val := range args { + if val == "all" { + for _, id := range status.Identities { + if len(id.Services) > 0 { + for _, svc := range id.Services { + filteredServices = append(filteredServices, convertToServiceCli(*svc)) + } + } + } + break + } else { + for _, id := range status.Identities { + if len(id.Services) > 0 { + for _, svc := range id.Services { + if strings.Compare(val, svc.Name) == 0 { + filteredServices = append(filteredServices, convertToServiceCli(*svc)) + } + } + } + } + } + } + + if len(filteredServices) == 0 { + errMsg := fmt.Sprintf("Could not find services matching %s", args) + return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: nil} + } + message := fmt.Sprintf("Got %d services - %s", len(filteredServices), args) + + return generateResponse("services", message, filteredServices, flags, templateService) + +} + +func generateResponse(dataType string, message string, filteredData interface{}, flags map[string]bool, templateStr string) dto.Response { + + var bytesData []byte + var err error + var responseBuffer bytes.Buffer + var responseStr string + + if flags["prettyJSON"] == true { + bytesData, err = json.MarshalIndent(filteredData, "", " ") + + if err != nil { + log.Error(err) + return dto.Response{Message: message, Code: service.ERROR, Error: "Could not fetch " + dataType + " from Runtime", Payload: nil} + } + responseStr = string(bytesData) + + } else { + it, err := template.New("filteredData").Parse(templateStr) + + if err != nil { + log.Error(err) + return dto.Response{Message: message, Code: service.ERROR, Error: "Could not parse " + dataType + " from Runtime", Payload: nil} + } + + err = it.Execute(&responseBuffer, filteredData) + + if err != nil { + log.Error(err) + return dto.Response{Message: message, Code: service.ERROR, Error: "Could not print " + dataType + " from Runtime", Payload: nil} + } + responseStr = responseBuffer.String() + } + + return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: responseStr} +} + +func GetLogLevelFromRTS(args []string, status *dto.TunnelStatus, flags map[string]bool) dto.Response { + + if flags["query"] == true { + message := fmt.Sprintf("Loglevel is currently set to %s", status.LogLevel) + return dto.Response{Message: message, Code: service.SUCCESS, Error: "", Payload: ""} + } + errMsg := fmt.Sprintf("Unknown error: args %s flag %v", args, flags) + return dto.Response{Message: "", Code: service.ERROR, Error: errMsg, Payload: ""} + +} + +// GetIdentityResponseObjectFromRTS is to get identity info from the RTS +func GetIdentityResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { + log.Debugf("Message from ziti-tunnel : %v", status.Message) + if status.Error == "" && status.Payload != nil { + log.Debugf("Payload from RTS %v", status.Payload) + payloadData := status.Payload.(map[string]interface{}) + identityStatus := make(map[string]interface{}) + identityStatus["FingerPrint"] = payloadData["FingerPrint"] + identityStatus["Active"] = payloadData["Active"] + identityStatus["Name"] = payloadData["Name"] + return dto.Response{Message: status.Message, Code: service.SUCCESS, Error: "", Payload: identityStatus} + } else { + return status + } +} + +// GetResponseObjectFromRTS is to get response object info from the RTS +func GetResponseObjectFromRTS(args []string, status dto.Response, flags map[string]bool) dto.Response { + return status +} diff --git a/service/ziti-tunnel/cli/service.go b/service/ziti-tunnel/cli/service.go index ebc1b290..ae695c88 100644 --- a/service/ziti-tunnel/cli/service.go +++ b/service/ziti-tunnel/cli/service.go @@ -1,55 +1,55 @@ -package cli - -import ( - "strings" - - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" -) - -//GetIdentities is to fetch identities through cmdline -func GetIdentities(args []string, flags map[string]bool) { - GetDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, nil, args, flags) -} - -//GetServices is to fetch services through cmdline -func GetServices(args []string, flags map[string]bool) { - GetDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, nil, args, flags) -} - -//OnOffIdentity is to enable or disable the identity through cmdline -func OnOffIdentity(args []string, flags map[string]bool) { - identityPayload := make(map[string]interface{}) - identityPayload["OnOff"] = strings.EqualFold(args[1], "on") - identityPayload["Fingerprint"] = args[0] - ONOFF_IDENTITY.Payload = identityPayload - log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) - status := GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityResponseObjectFromRTS, args, flags) - if status { - NOTIFY_IDENTITY_UI.Payload = identityPayload - log.Infof("Notifying the Identity Status to UI %v", identityPayload) - GetDataFromIpcPipe(&NOTIFY_IDENTITY_UI, nil, GetResponseObjectFromRTS, args, flags) - } -} - -//SetLogLevel is to change the loglevel through cmdline -func SetLogLevel(args []string, flags map[string]bool) { - if flags["query"] == true { - GetDataFromIpcPipe(&GET_STATUS, GetLogLevelFromRTS, nil, args, flags) - } else { - loglevelPayload := make(map[string]interface{}) - loglevelPayload["Level"] = args[0] - SET_LOGLEVEL.Payload = loglevelPayload - log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) - status := GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) - if status { - NOTIFY_LOGLEVEL_UI_MONITOR.Payload = loglevelPayload - log.Infof("Notifying the LogLevel to UI and Ziti monitor service %v", loglevelPayload) - GetDataFromIpcPipe(&NOTIFY_LOGLEVEL_UI_MONITOR, nil, GetResponseObjectFromRTS, args, flags) - } - } -} - -//GetFeedback is to create logs zip through cmdline -func GetFeedback(args []string, flags map[string]bool) { - GetDataFromMonitorIpcPipe(&dto.FEEDBACK_REQUEST, args, flags) -} +package cli + +import ( + "strings" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" +) + +//GetIdentities is to fetch identities through cmdline +func GetIdentities(args []string, flags map[string]bool) { + GetDataFromIpcPipe(&GET_STATUS, GetIdentitiesFromRTS, nil, args, flags) +} + +//GetServices is to fetch services through cmdline +func GetServices(args []string, flags map[string]bool) { + GetDataFromIpcPipe(&GET_STATUS, GetServicesFromRTS, nil, args, flags) +} + +//OnOffIdentity is to enable or disable the identity through cmdline +func OnOffIdentity(args []string, flags map[string]bool) { + identityPayload := make(map[string]interface{}) + identityPayload["OnOff"] = strings.EqualFold(args[1], "on") + identityPayload["Fingerprint"] = args[0] + ONOFF_IDENTITY.Payload = identityPayload + log.Debugf("OnOffIdentity Payload %v", ONOFF_IDENTITY) + status := GetDataFromIpcPipe(&ONOFF_IDENTITY, nil, GetIdentityResponseObjectFromRTS, args, flags) + if status { + NOTIFY_IDENTITY_UI.Payload = identityPayload + log.Infof("Notifying the Identity Status to UI %v", identityPayload) + GetDataFromIpcPipe(&NOTIFY_IDENTITY_UI, nil, GetResponseObjectFromRTS, args, flags) + } +} + +//SetLogLevel is to change the loglevel through cmdline +func SetLogLevel(args []string, flags map[string]bool) { + if flags["query"] == true { + GetDataFromIpcPipe(&GET_STATUS, GetLogLevelFromRTS, nil, args, flags) + } else { + loglevelPayload := make(map[string]interface{}) + loglevelPayload["Level"] = args[0] + SET_LOGLEVEL.Payload = loglevelPayload + log.Debugf("LogLevel Payload %v", SET_LOGLEVEL) + status := GetDataFromIpcPipe(&SET_LOGLEVEL, nil, GetResponseObjectFromRTS, args, flags) + if status { + NOTIFY_LOGLEVEL_UI_MONITOR.Payload = loglevelPayload + log.Infof("Notifying the LogLevel to UI and Ziti monitor service %v", loglevelPayload) + GetDataFromIpcPipe(&NOTIFY_LOGLEVEL_UI_MONITOR, nil, GetResponseObjectFromRTS, args, flags) + } + } +} + +//GetFeedback is to create logs zip through cmdline +func GetFeedback(args []string, flags map[string]bool) { + GetDataFromMonitorIpcPipe(&dto.FEEDBACK_REQUEST, args, flags) +} diff --git a/service/ziti-tunnel/constants/consts.go b/service/ziti-tunnel/constants/consts.go index 02961102..cc1c95ea 100644 --- a/service/ziti-tunnel/constants/consts.go +++ b/service/ziti-tunnel/constants/consts.go @@ -17,9 +17,9 @@ package constants -const( +const ( Ipv4ip = "100.64.0.1" - Ipv4MaxMask = 8 - Ipv4MinMask = 16 + Ipv4MaxMask = 8 + Ipv4MinMask = 16 Ipv4DefaultMask = 10 -) \ No newline at end of file +) diff --git a/service/ziti-tunnel/dto/clidtos.go b/service/ziti-tunnel/dto/clidtos.go index 030cdce8..8f3166f5 100644 --- a/service/ziti-tunnel/dto/clidtos.go +++ b/service/ziti-tunnel/dto/clidtos.go @@ -1,47 +1,47 @@ -package dto - -/* - * Copyright NetFoundry, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -type IdentityCli struct { - Name string - FingerPrint string - Active bool - Config string - ControllerVersion string - Status string -} - -type ServiceCli struct { - Name string - Id string - Protocols string - Ports string - Addresses string - OwnsIntercept bool -} - -type IdentityOnOffPayload struct { - OnOff string - Fingerprint string -} - -type MonitorServiceResponse struct { - Code int - Message string - Error string -} +package dto + +/* + * Copyright NetFoundry, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +type IdentityCli struct { + Name string + FingerPrint string + Active bool + Config string + ControllerVersion string + Status string +} + +type ServiceCli struct { + Name string + Id string + Protocols string + Ports string + Addresses string + OwnsIntercept bool +} + +type IdentityOnOffPayload struct { + OnOff string + Fingerprint string +} + +type MonitorServiceResponse struct { + Code int + Message string + Error string +} diff --git a/service/ziti-tunnel/dto/events.go b/service/ziti-tunnel/dto/events.go index 1971a1b0..c216ced3 100644 --- a/service/ziti-tunnel/dto/events.go +++ b/service/ziti-tunnel/dto/events.go @@ -21,8 +21,8 @@ const ( REMOVED = "removed" ERROR = "error" UPDATED = "updated" - CHANGED = "changed" - NORMAL = "Normal" + CHANGED = "changed" + NORMAL = "Normal" SERVICE_OP = "service" IDENTITY_OP = "identity" @@ -30,11 +30,11 @@ const ( FEEDBACK_OP = "CaptureLogs" MFA_OP = "mfa" - MFAEnrollmentChallengAtion = "enrollment_challenge" - MFAEnrollmentVerificationAction = "enrollment_verification" - MFAEnrollmentRemovedAction = "enrollment_remove" + MFAEnrollmentChallengAtion = "enrollment_challenge" + MFAEnrollmentVerificationAction = "enrollment_verification" + MFAEnrollmentRemovedAction = "enrollment_remove" - MFA_AUTH_CHALLENGE_ACTION = "auth_challenge" + MFA_AUTH_CHALLENGE_ACTION = "auth_challenge" ) var SERVICE_ADDED = ActionEvent{ diff --git a/service/ziti-tunnel/service/debug.go b/service/ziti-tunnel/service/debug.go index 6da5bdd4..47f87435 100644 --- a/service/ziti-tunnel/service/debug.go +++ b/service/ziti-tunnel/service/debug.go @@ -18,8 +18,8 @@ package service import ( - idcfg "github.com/openziti/sdk-golang/ziti/config" "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" + idcfg "github.com/openziti/sdk-golang/ziti/config" ) func dbg() { @@ -28,15 +28,15 @@ func dbg() { events.broadcast <- dto.TunnelStatusEvent{ StatusEvent: dto.StatusEvent{Op: "status"}, Status: r, - ApiVersion: API_VERSION, + ApiVersion: API_VERSION, } svcs := make([]*dto.Service, 2) svcs[0] = &dto.Service{ - Name: "FakeService1", + Name: "FakeService1", } svcs[1] = &dto.Service{ - Name: "Second Fake Service", + Name: "Second Fake Service", } events.broadcast <- dto.IdentityEvent{ @@ -57,7 +57,7 @@ func dbg() { events.broadcast <- dto.ServiceEvent{ ActionEvent: dto.SERVICE_ADDED, Service: &dto.Service{ - Name: "New Service", + Name: "New Service", }, Fingerprint: "new_id_fingerprint", } diff --git a/service/ziti-tunnel/service/install.go b/service/ziti-tunnel/service/install.go index 65910e42..7ec0c3db 100644 --- a/service/ziti-tunnel/service/install.go +++ b/service/ziti-tunnel/service/install.go @@ -52,9 +52,9 @@ func InstallService() error { log.Infof("service installed using path: %s", fullPath) s, err = m.CreateService(SvcStartName, fullPath, mgr.Config{ - StartType: mgr.StartAutomatic, - DisplayName: SvcName, - Description: SvcNameLong, + StartType: mgr.StartAutomatic, + DisplayName: SvcName, + Description: SvcNameLong, }) if err != nil { return err @@ -89,4 +89,4 @@ func RemoveService() error { return fmt.Errorf("RemoveEventLogSource() failed: %s", err) } return nil -} \ No newline at end of file +} diff --git a/service/ziti-tunnel/service/orphaned-identities.go b/service/ziti-tunnel/service/orphaned-identities.go index af6f5c10..470d1863 100644 --- a/service/ziti-tunnel/service/orphaned-identities.go +++ b/service/ziti-tunnel/service/orphaned-identities.go @@ -1,101 +1,101 @@ -package service - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/config" -) - -// After System update, the identity files are not getting copied to the config path -// So we are adding a function to scan for identities in the backtup location -func scanForIdentitiesPostWindowsUpdate() error { - srcBackUpPaths := [2]string{"Windows.~BT\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry", - "Windows.old\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry"} - systemDrivePath := os.Getenv("SystemDrive") - if systemDrivePath == "" { - return nil - } - for _, srcPath := range srcBackUpPaths { - sourcePath := filepath.Join(systemDrivePath, string(os.PathSeparator), srcPath) - _, err := os.Stat(sourcePath) - if err != nil { - log.Debugf("Folder %s does not exist", sourcePath) - continue - } - err = searchAndCopyFilesFromBackup(sourcePath) - if err != nil { - log.Debugf("Copy files from %s failed, %v", sourcePath, err) - } - } - return nil -} - -func searchAndCopyFilesFromBackup(srcPath string) error { - err := filepath.Walk(srcPath, copyFilesFromBackUp) - if err != nil { - return err - } - return nil -} - -func copyFilesFromBackUp(path string, f os.FileInfo, err error) error { - if !f.IsDir() { - log.Infof("Found: %s", path) - destinationFile := filepath.Join(config.Path(), string(os.PathSeparator), f.Name()) - //check if the file is present in the destination folder - _, err := os.Stat(destinationFile) - if err == nil && !strings.Contains(f.Name(), ConfigFileName) { - log.Debugf("File %s is already present in the config path and it is not %s, So not transfering", f.Name(), ConfigFileName) - deleteFile(path) - return nil - } - _, err = copy(path, destinationFile) - if err != nil { - log.Errorf("Error occurred while copying the Windows backup folder %s --> %s %v", f.Name(), destinationFile, err) - return nil - } else { - log.Infof("Found backup file at %s. Restored this file to %s", path, destinationFile) - deleteFile(path) - } - } - return nil -} -func deleteFile(path string) { - log.Infof("Removing file %s", path) - err := os.Remove(path) - if err != nil { - log.Errorf("Error occured while removing the file %s, %v", path, err) - } else { - log.Infof("Removed file %s", path) - } -} - -func copy(src, dst string) (int64, error) { - sourceFileStat, err := os.Stat(src) - if err != nil { - return 0, err - } - - if !sourceFileStat.Mode().IsRegular() { - return 0, errors.New(fmt.Sprintf("%s is not a regular file", src)) - } - - source, err := os.Open(src) - if err != nil { - return 0, err - } - defer source.Close() - - destination, err := os.Create(dst) - if err != nil { - return 0, err - } - defer destination.Close() - nBytes, err := io.Copy(destination, source) - return nBytes, err -} +package service + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/config" +) + +// After System update, the identity files are not getting copied to the config path +// So we are adding a function to scan for identities in the backtup location +func scanForIdentitiesPostWindowsUpdate() error { + srcBackUpPaths := [2]string{"Windows.~BT\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry", + "Windows.old\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry"} + systemDrivePath := os.Getenv("SystemDrive") + if systemDrivePath == "" { + return nil + } + for _, srcPath := range srcBackUpPaths { + sourcePath := filepath.Join(systemDrivePath, string(os.PathSeparator), srcPath) + _, err := os.Stat(sourcePath) + if err != nil { + log.Debugf("Folder %s does not exist", sourcePath) + continue + } + err = searchAndCopyFilesFromBackup(sourcePath) + if err != nil { + log.Debugf("Copy files from %s failed, %v", sourcePath, err) + } + } + return nil +} + +func searchAndCopyFilesFromBackup(srcPath string) error { + err := filepath.Walk(srcPath, copyFilesFromBackUp) + if err != nil { + return err + } + return nil +} + +func copyFilesFromBackUp(path string, f os.FileInfo, err error) error { + if !f.IsDir() { + log.Infof("Found: %s", path) + destinationFile := filepath.Join(config.Path(), string(os.PathSeparator), f.Name()) + //check if the file is present in the destination folder + _, err := os.Stat(destinationFile) + if err == nil && !strings.Contains(f.Name(), ConfigFileName) { + log.Debugf("File %s is already present in the config path and it is not %s, So not transfering", f.Name(), ConfigFileName) + deleteFile(path) + return nil + } + _, err = copy(path, destinationFile) + if err != nil { + log.Errorf("Error occurred while copying the Windows backup folder %s --> %s %v", f.Name(), destinationFile, err) + return nil + } else { + log.Infof("Found backup file at %s. Restored this file to %s", path, destinationFile) + deleteFile(path) + } + } + return nil +} +func deleteFile(path string) { + log.Infof("Removing file %s", path) + err := os.Remove(path) + if err != nil { + log.Errorf("Error occured while removing the file %s, %v", path, err) + } else { + log.Infof("Removed file %s", path) + } +} + +func copy(src, dst string) (int64, error) { + sourceFileStat, err := os.Stat(src) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, errors.New(fmt.Sprintf("%s is not a regular file", src)) + } + + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + nBytes, err := io.Copy(destination, source) + return nBytes, err +} diff --git a/service/ziti-tunnel/service/permissions.go b/service/ziti-tunnel/service/permissions.go index 8525a1d6..39fe8846 100644 --- a/service/ziti-tunnel/service/permissions.go +++ b/service/ziti-tunnel/service/permissions.go @@ -53,4 +53,4 @@ func EnsurePermissions(group string) string { } return sid -} \ No newline at end of file +} diff --git a/service/ziti-tunnel/service/pkg-vars.go b/service/ziti-tunnel/service/pkg-vars.go index 264a08c3..e081df8b 100644 --- a/service/ziti-tunnel/service/pkg-vars.go +++ b/service/ziti-tunnel/service/pkg-vars.go @@ -59,8 +59,8 @@ const ( IDENTITY_NOT_FOUND = 1000 MFA_FAILED_TO_GENERATE_CODES = 200 - MFA_FAILED_TO_RETURN_CODES = 201 - MFA_FINGERPRINT_NOT_FOUND = 202 + MFA_FAILED_TO_RETURN_CODES = 201 + MFA_FINGERPRINT_NOT_FOUND = 202 DEFAULT_REFRESH_INTERVAL = 10 diff --git a/service/ziti-tunnel/service/service.go b/service/ziti-tunnel/service/service.go index fbf72ca4..3ddd42d0 100644 --- a/service/ziti-tunnel/service/service.go +++ b/service/ziti-tunnel/service/service.go @@ -87,7 +87,7 @@ loop: changes <- svc.Status{State: svc.StopPending} log.Infof("waiting for shutdown to complete") - <- control + <-control log.Infof("normal shutdown complete") return } diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index 0c5dfd6e..26933a70 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -152,9 +152,9 @@ func (t *RuntimeState) ToMetrics() dto.TunnelStatus { Name: id.Name, FingerPrint: id.FingerPrint, Metrics: id.Metrics, - Active: id.Active, - MfaEnabled: id.MfaEnabled, - MfaNeeded: id.MfaNeeded, + Active: id.Active, + MfaEnabled: id.MfaEnabled, + MfaNeeded: id.MfaNeeded, } i++ } diff --git a/service/ziti-tunnel/service/topic.go b/service/ziti-tunnel/service/topic.go index de09edab..c6d95897 100644 --- a/service/ziti-tunnel/service/topic.go +++ b/service/ziti-tunnel/service/topic.go @@ -19,8 +19,8 @@ package service type topic struct { broadcast chan interface{} - channels map[int]chan interface{} - done chan bool + channels map[int]chan interface{} + done chan bool } func newTopic(cap int16) topic { @@ -31,19 +31,19 @@ func newTopic(cap int16) topic { } } -func(t *topic) register(id int, c chan interface{}) { +func (t *topic) register(id int, c chan interface{}) { t.channels[id] = c } -func(t *topic) unregister(id int) { +func (t *topic) unregister(id int) { delete(t.channels, id) } -func(t *topic) shutdown() { +func (t *topic) shutdown() { t.done <- true } -func(t *topic) run() { +func (t *topic) run() { go func() { for { select { diff --git a/service/ziti-tunnel/service/types.go b/service/ziti-tunnel/service/types.go index 97365273..67ec1495 100644 --- a/service/ziti-tunnel/service/types.go +++ b/service/ziti-tunnel/service/types.go @@ -8,4 +8,4 @@ import ( type Id struct { dto.Identity CId *cziti.ZIdentity -} \ No newline at end of file +} diff --git a/service/ziti-tunnel/util/detect-ip-changes.go b/service/ziti-tunnel/util/detect-ip-changes.go index 9044090e..077d21e5 100644 --- a/service/ziti-tunnel/util/detect-ip-changes.go +++ b/service/ziti-tunnel/util/detect-ip-changes.go @@ -29,10 +29,10 @@ var ( modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") - procWSACreateEvent = modws2_32.NewProc("WSACreateEvent") - procNotifyAddrChange = modiphlpapi.NewProc("NotifyAddrChange") + procWSACreateEvent = modws2_32.NewProc("WSACreateEvent") + procNotifyAddrChange = modiphlpapi.NewProc("NotifyAddrChange") procNotifyRouteChange = modiphlpapi.NewProc("NotifyRouteChange") - log = logging.Logger() + log = logging.Logger() ) func OnIPChange(callback func()) { @@ -43,7 +43,7 @@ func OnIPChange(callback func()) { log.Debugf("Symbol [NotifyAddrChange] loaded at %#v", procNotifyAddrChange.Addr()) var ( - err error + err error overlap *windows.Overlapped = &windows.Overlapped{} ) @@ -84,4 +84,4 @@ func WSACreateEvent() (windows.Handle, error) { } else { return windows.Handle(handlePtr), nil } -} \ No newline at end of file +} diff --git a/service/ziti-tunnel/util/iputil/iputil.go b/service/ziti-tunnel/util/iputil/iputil.go index 838664de..b9ad861c 100644 --- a/service/ziti-tunnel/util/iputil/iputil.go +++ b/service/ziti-tunnel/util/iputil/iputil.go @@ -35,7 +35,7 @@ func Ipv4Inc(ip net.IP, maskBits int) net.IP { newIpAsInt := ipAsInt + 1 - return Uint32ToIpv4(baseIp + newIpAsInt & uint32(ipMask)) + return Uint32ToIpv4(baseIp + newIpAsInt&uint32(ipMask)) } func Ipv4ToUint32(ip net.IP) uint32 { if len(ip) == 16 { diff --git a/service/ziti-tunnel/util/logging/loghelper.go b/service/ziti-tunnel/util/logging/loghelper.go index d2981f25..8005ead8 100644 --- a/service/ziti-tunnel/util/logging/loghelper.go +++ b/service/ziti-tunnel/util/logging/loghelper.go @@ -48,16 +48,13 @@ func init() { setConsoleModeProc := kernel32DLL.NewProc("SetConsoleMode") setConsoleModeProc.Call(uintptr(handle), 0x0001|0x0002|0x0004) - - with := &dateFormatterNoFilename{ - } + with := &dateFormatterNoFilename{} /*with := &dateFormatterWithFilename{ }*/ with.dateFormatter.timeFormat = UTCFormat() withFilenameLogger.SetFormatter(with) - without := &dateFormatterNoFilename{ - } + without := &dateFormatterNoFilename{} without.dateFormatter.timeFormat = UTCFormat() noFilenamelogger.SetFormatter(without) } @@ -70,7 +67,7 @@ func NoFilenameLogger() *logrus.Logger { return noFilenamelogger } -func SetLoggingLevel(goLevel logrus.Level){ +func SetLoggingLevel(goLevel logrus.Level) { withFilenameLogger.SetLevel(goLevel) noFilenamelogger.SetLevel(goLevel) } @@ -84,8 +81,8 @@ func initLogger(logger *logrus.Logger, level logrus.Level) { logger.SetReportCaller(true) - rl, _ := rotatelogs.New(config.LogFile() + ".%Y%m%d%H%M.log", - rotatelogs.WithRotationTime(24 * time.Hour), + rl, _ := rotatelogs.New(config.LogFile()+".%Y%m%d%H%M.log", + rotatelogs.WithRotationTime(24*time.Hour), rotatelogs.WithRotationCount(7), rotatelogs.WithLinkName(config.LogFile())) @@ -205,4 +202,4 @@ var errorColor = ansi.Red + "ERROR" + ansi.DefaultFG var warnColor = ansi.Yellow + " WARN" + ansi.DefaultFG var infoColor = ansi.White + " INFO" + ansi.DefaultFG var debugColor = ansi.Blue + "DEBUG" + ansi.DefaultFG -var traceColor = ansi.LightBlack + "TRACE" + ansi.DefaultFG \ No newline at end of file +var traceColor = ansi.LightBlack + "TRACE" + ansi.DefaultFG From 6ebc4d15135e155d33bad4599319b466cb6fb636 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Wed, 7 Apr 2021 14:04:00 +0530 Subject: [PATCH 14/24] remove ownIntercept from the list services option --- service/ziti-tunnel/cli/constants.go | 4 ++-- service/ziti-tunnel/cli/responseGenerator.go | 1 - service/ziti-tunnel/dto/clidtos.go | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/service/ziti-tunnel/cli/constants.go b/service/ziti-tunnel/cli/constants.go index 8191fe45..3c21a278 100644 --- a/service/ziti-tunnel/cli/constants.go +++ b/service/ziti-tunnel/cli/constants.go @@ -48,8 +48,8 @@ var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint" {{range .}}{{printf "%40s" .Name}} | {{printf "%41s" .FingerPrint}} | {{printf "%6t" .Active}} | {{printf "%30s" .Config}} | {{.Status}} {{end}}` -var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%9s" "Protocols"}} | {{printf "%14s" "Ports"}} | {{printf "%40s" "Addresses"}} | {{"OwnsIntercept"}} -{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%9s" .Protocols}} | {{printf "%14s" .Ports}} | {{printf "%40s" .Addresses}} | {{.OwnsIntercept}} +var templateService = `{{printf "%40s" "Name"}} | {{printf "%15s" "Id"}} | {{printf "%9s" "Protocols"}} | {{printf "%14s" "Ports"}} | {{printf "%60s" "Addresses"}} +{{range .}}{{printf "%40s" .Name}} | {{printf "%15s" .Id}} | {{printf "%9s" .Protocols}} | {{printf "%14s" .Ports}} | {{printf "%60s" .Addresses}} {{end}}` var log = logging.Logger() diff --git a/service/ziti-tunnel/cli/responseGenerator.go b/service/ziti-tunnel/cli/responseGenerator.go index fd06eeda..f0143d26 100644 --- a/service/ziti-tunnel/cli/responseGenerator.go +++ b/service/ziti-tunnel/cli/responseGenerator.go @@ -62,7 +62,6 @@ func convertToServiceCli(svc dto.Service) dto.ServiceCli { Protocols: strings.Join(svc.Protocols, ","), Ports: cliPorts, Addresses: cliAddresses, - OwnsIntercept: svc.OwnsIntercept, } } diff --git a/service/ziti-tunnel/dto/clidtos.go b/service/ziti-tunnel/dto/clidtos.go index 8f3166f5..6f7e840d 100644 --- a/service/ziti-tunnel/dto/clidtos.go +++ b/service/ziti-tunnel/dto/clidtos.go @@ -32,7 +32,6 @@ type ServiceCli struct { Protocols string Ports string Addresses string - OwnsIntercept bool } type IdentityOnOffPayload struct { From 3fa72adefc3a86c2521c4dbedc76e771f16e395f Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Wed, 7 Apr 2021 14:05:56 +0530 Subject: [PATCH 15/24] updating version --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 9ab8337f..8fdcf386 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.9.1 +1.9.2 From 9c4d1295ff50516885bd3165c72c9d23600eb8dd Mon Sep 17 00:00:00 2001 From: Jeremy Tellier - ROG Date: Wed, 7 Apr 2021 13:01:19 +0100 Subject: [PATCH 16/24] Fix the search for service query --- DesktopEdge/Views/Screens/IdentityDetails.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs b/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs index f7fd423d..f15ce065 100644 --- a/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs +++ b/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs @@ -119,7 +119,7 @@ namespace ZitiDesktopEdge { ServiceList.Children.Clear(); if (_identity.Services.Count>0) { foreach(var zitiSvc in _identity.Services.OrderBy(s => s.Name.ToLower())) { - if (zitiSvc.Name.ToLower().IndexOf(filter)>=0||zitiSvc.ToString().ToLower().IndexOf(filter)>=0) { + if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >=0||zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >=0) { Logger.Trace("painting: " + zitiSvc.Name); ServiceInfo info = new ServiceInfo(); info.Info = zitiSvc; From 5a0bc732263800dc9d7c365d63431190f0c79145 Mon Sep 17 00:00:00 2001 From: Mary Lincy Dcouto Date: Wed, 7 Apr 2021 22:16:49 +0530 Subject: [PATCH 17/24] fixing code review comments --- service/ziti-tunnel/cli/ipcClient.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/service/ziti-tunnel/cli/ipcClient.go b/service/ziti-tunnel/cli/ipcClient.go index ef621083..c2316fe3 100644 --- a/service/ziti-tunnel/cli/ipcClient.go +++ b/service/ziti-tunnel/cli/ipcClient.go @@ -18,6 +18,7 @@ package cli */ import ( + "fmt" "bufio" "encoding/json" "io" @@ -81,18 +82,19 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan bool, fn fetchStatu if tunnelStatus.Status != nil { responseMsg := fn(args, tunnelStatus.Status, flags) if responseMsg.Code == service.SUCCESS { - log.Info("\n" + responseMsg.Payload.(string) + "\n" + responseMsg.Message) + fmt.Println(responseMsg.Payload.(string)) + fmt.Println(responseMsg.Message) readDone <- true return } else { if responseMsg.Error != "" { - log.Info(responseMsg.Error) + log.Error(responseMsg.Error) } else { log.Info(responseMsg.Message) } } } else { - log.Errorf("Ziti tunnel retuned nil status") + log.Errorf("Ziti tunnel retuned status, %v", tunnelStatus) } } @@ -118,13 +120,13 @@ func readMessageFromPipe(ipcPipeConn net.Conn, readDone chan bool, fn fetchStatu return } else { if responseMsg.Error != "" { - log.Info(responseMsg.Error) + log.Error(responseMsg.Error) } else { log.Info(responseMsg.Message) } } } else { - log.Errorf("Ziti tunnel retuned nil response") + log.Errorf("Ziti tunnel retuned nil response message, %v", response) } } @@ -142,7 +144,7 @@ func GetDataFromIpcPipe(commandMsg *dto.CommandMsg, fn fetchStatusFromRTS, respo if err != nil { log.Errorf("Connection to ipc pipe is not established, %v", err) - log.Errorf("Ziti Desktop Edge app may not be running") + log.Fatal("Ziti Desktop Edge app may not be running") return false } readDone := make(chan bool) @@ -241,7 +243,7 @@ func readMessageFromMonitorPipe(ipcPipeConn net.Conn, readDone chan bool, args [ readDone <- true return } else { - log.Info(monitorServiceResponse.Error) + log.Error(monitorServiceResponse.Error) } readDone <- false From d73d66a4a633d81aaf3dd1dab9b433fa1a340759 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 7 Apr 2021 12:59:03 -0400 Subject: [PATCH 18/24] initial stab at chunking nrpt rules --- service/windns/windns.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/service/windns/windns.go b/service/windns/windns.go index f342f845..384c9e95 100644 --- a/service/windns/windns.go +++ b/service/windns/windns.go @@ -121,11 +121,31 @@ func AddNrptRules(domainsToMap map[string]bool, dnsServer string) { log.Debug("no domains to map specified to AddNrptRules. exiting early") return } + + blockSize := 250 + if len(domainsToMap) > blockSize { + log.Debugf("domainsToMap is too long [%d] and may fail on some systems. splitting the requested entries into blocks of %d", len(domainsToMap), blockSize) + } + currentSize := 0 + hostnames := make([]string, blockSize) + for hostname := range domainsToMap { + hostnames[currentSize] = hostname + currentSize ++ + if currentSize >= blockSize { + log.Debugf("sending chunk of domains to be added to NRPT") + chunkedAddNrptRules(hostnames, dnsServer) + hostnames = make([]string, blockSize) + currentSize = 0 + } + } +} + +func chunkedAddNrptRules(domainsToAdd []string, dnsServer string) { sb := strings.Builder{} sb.WriteString(`$Rules = @( `) - for hostname := range domainsToMap { + for _, hostname := range domainsToAdd { sb.WriteString(fmt.Sprintf(`@{ Namespace ="%s"; NameServers = @("%s"); Comment = "Added by ziti-tunnel"; DisplayName = "ziti-tunnel:%s"; }%s`, hostname, dnsServer, hostname, "\n")) } @@ -136,7 +156,7 @@ ForEach ($Rule in $Rules) { }`)) script := sb.String() - log.Debugf("Executing NRPT script:\n%s", script) + log.Debugf("Executing NRPT script containing %d domains:\n%s", len(domainsToAdd), script) cmd := exec.Command("powershell", "-Command", script) cmd.Stderr = os.Stdout @@ -148,6 +168,7 @@ ForEach ($Rule in $Rules) { } } + func RemoveNrptRules(domainsToMap map[string]bool) { if len(domainsToMap) == 0 { log.Debug("no domains to map specified to RemoveNrptRules. exiting early") From 4b18db7cd1918b65957475e324560459d7fc8216 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:55:37 -0400 Subject: [PATCH 19/24] make sure we add the final chunk of rules to the NRPT. also update the .gitignore with logs --- service/.gitignore | 1 + service/windns/windns.go | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/service/.gitignore b/service/.gitignore index da9d6160..879e2457 100644 --- a/service/.gitignore +++ b/service/.gitignore @@ -7,3 +7,4 @@ NFWintunInstaller.msi wintun.dll gdb.txt +logs diff --git a/service/windns/windns.go b/service/windns/windns.go index 384c9e95..e35f9ddb 100644 --- a/service/windns/windns.go +++ b/service/windns/windns.go @@ -122,7 +122,7 @@ func AddNrptRules(domainsToMap map[string]bool, dnsServer string) { return } - blockSize := 250 + blockSize := 50 if len(domainsToMap) > blockSize { log.Debugf("domainsToMap is too long [%d] and may fail on some systems. splitting the requested entries into blocks of %d", len(domainsToMap), blockSize) } @@ -138,6 +138,10 @@ func AddNrptRules(domainsToMap map[string]bool, dnsServer string) { currentSize = 0 } } + if currentSize > 0 { + //means there's a chunk still to add.... + chunkedAddNrptRules(hostnames[:currentSize], dnsServer) + } } func chunkedAddNrptRules(domainsToAdd []string, dnsServer string) { From f757977dd889190265d8f0866d18fd8f71e3319d Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:57:15 -0400 Subject: [PATCH 20/24] fix two bugs - first don't add IPs to NRPT. dispatch service updates in a go routine just in case something ends up blocking the dispatch channel --- service/cziti/sdk.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index 503820a8..28b01c73 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -340,7 +340,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, z } zid.Services.Store(svcId, &added) - ServiceChanges <- se + go func() {ServiceChanges <- se}() //do this in a go routine just in case it gets blocked so the uv loop doesn't block } return addresses } @@ -411,7 +411,9 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { } addys := serviceCB(ztx, removed, C.ZITI_SERVICE_UNAVAILABLE, zid) for _, toRemove := range addys { - hostnamesToRemove[toRemove.HostName] = true + if toRemove.IsHost { + hostnamesToRemove[toRemove.HostName] = true + } } } for i := 0; true; i++ { @@ -422,12 +424,16 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { log.Info("service changed remove the service then add it back immediately", C.GoString(changed.name)) addys := serviceCB(ztx, changed, C.ZITI_SERVICE_UNAVAILABLE, zid) for _, toRemove := range addys { - hostnamesToRemove[toRemove.HostName] = true + if toRemove.IsHost { + hostnamesToRemove[toRemove.HostName] = true + } } addys = serviceCB(ztx, changed, C.ZITI_OK, zid) for _, toAdd := range addys { - hostnamesToAdd[toAdd.HostName] = true + if toAdd.IsHost { + hostnamesToAdd[toAdd.HostName] = true + } } } for i := 0; true; i++ { @@ -437,7 +443,9 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { } addys := serviceCB(ztx, added, C.ZITI_OK, zid) for _, toAdd := range addys { - hostnamesToAdd[toAdd.HostName] = true + if toAdd.IsHost { + hostnamesToAdd[toAdd.HostName] = true + } } } From 5a4687771a3b10a81de65c0fbced674dd71d9230 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 7 Apr 2021 15:39:49 -0400 Subject: [PATCH 21/24] output the NRPT policy/rule on feedback --- ZitiUpdateService/UpdateService.cs | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs index 5b678107..57fdf030 100644 --- a/ZitiUpdateService/UpdateService.cs +++ b/ZitiUpdateService/UpdateService.cs @@ -199,6 +199,7 @@ namespace ZitiUpdateService { outputTasklist(destinationLocation); outputRouteInfo(destinationLocation); outputNetstatInfo(destinationLocation); + outputNrpt(destinationLocation); Task.Delay(500).Wait(); @@ -340,6 +341,37 @@ namespace ZitiUpdateService { } } + private void outputNrpt(string destinationFolder) { + Logger.Info("outputting NRPT rules"); + try { + Logger.Info("outputting NRPT DnsClientNrptRule"); + string nrptRuleOutput = Path.Combine(destinationFolder, "NrptRule.txt"); + Process nrptRuleProcess = new Process(); + ProcessStartInfo nrptRuleStartInfo = new ProcessStartInfo(); + nrptRuleStartInfo.WindowStyle = ProcessWindowStyle.Hidden; + nrptRuleStartInfo.FileName = "cmd.exe"; + nrptRuleStartInfo.Arguments = $"/C powershell \"Get-DnsClientNrptRule | sort -Property Namespace\" > \"{nrptRuleOutput}\""; + Logger.Info("Running: {0}", nrptRuleStartInfo.Arguments); + nrptRuleProcess.StartInfo = nrptRuleStartInfo; + nrptRuleProcess.Start(); + nrptRuleProcess.WaitForExit(); + + Logger.Info("outputting NRPT DnsClientNrptPolicy"); + string nrptOutput = Path.Combine(destinationFolder, "NrptPolicy.txt"); + Process process = new Process(); + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + startInfo.FileName = "cmd.exe"; + startInfo.Arguments = $"/C powershell \"Get-DnsClientNrptPolicy | sort -Property Namespace\" > \"{nrptOutput}\""; + Logger.Info("Running: {0}", startInfo.Arguments); + process.StartInfo = startInfo; + process.Start(); + process.WaitForExit(); + } catch (Exception ex) { + Logger.Error(ex, "Unexpected error {0}", ex.Message); + } + } + public void Debug() { OnStart(null);// new string[] { "FilesystemCheck" }); } From d9a55ffa25dad6c0789b92c8864567b17a64e3be Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 7 Apr 2021 16:20:00 -0400 Subject: [PATCH 22/24] update release-notes --- release-notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release-notes.md b/release-notes.md index eb763f10..d291aec5 100644 --- a/release-notes.md +++ b/release-notes.md @@ -7,7 +7,9 @@ * none ## Bugs fixed: -* none +* [#346](https://github.com/openziti/desktop-edge-win/issues/346) Fixed the UI filtering of services on the Identity detail screen +* [#348](https://github.com/openziti/desktop-edge-win/issues/348) IP addresses do not need to be added to the NRPT +* [#349](https://github.com/openziti/desktop-edge-win/issues/349) Too many services can cause the NRPT update to fail ## Dependency Updates * none From 8ec6cb18b56bd71fb9a02ca12fbd9369c962752d Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Thu, 8 Apr 2021 06:31:27 -0400 Subject: [PATCH 23/24] fix race condition at startup --- service/ziti-tunnel/service/ipc.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index ecac534a..04aca3fd 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -1037,7 +1037,15 @@ func handleEvents(isInitialized chan struct{}) { //Removes the Config from the provided identity and returns a 'cleaned' id func Clean(src *Id) dto.Identity { - log.Tracef("cleaning identity: %s %v %v", src.Name, src.CId.MfaNeeded, src.CId.MfaEnabled) + mfaNeeded := false + mfaEnabled := false + + if src.CId != nil { + mfaNeeded = src.CId.MfaNeeded + mfaEnabled = src.CId.MfaEnabled + } + + log.Tracef("cleaning identity: %s", src.Name, mfaNeeded, mfaEnabled) AddMetrics(src) nid := dto.Identity{ Name: src.Name, @@ -1046,8 +1054,8 @@ func Clean(src *Id) dto.Identity { Config: idcfg.Config{}, ControllerVersion: src.ControllerVersion, Status: "", - MfaNeeded: src.CId.MfaNeeded, - MfaEnabled: src.CId.MfaEnabled, + MfaNeeded: mfaNeeded, + MfaEnabled: mfaEnabled, Services: make([]*dto.Service, 0), Metrics: src.Metrics, Tags: nil, From cc3220de4551603c97f1118fad06b0b689134e8d Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Thu, 8 Apr 2021 06:53:37 -0400 Subject: [PATCH 24/24] try to fix the off by one issue --- service/windns/windns.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/service/windns/windns.go b/service/windns/windns.go index e35f9ddb..54dd0cbf 100644 --- a/service/windns/windns.go +++ b/service/windns/windns.go @@ -129,14 +129,14 @@ func AddNrptRules(domainsToMap map[string]bool, dnsServer string) { currentSize := 0 hostnames := make([]string, blockSize) for hostname := range domainsToMap { - hostnames[currentSize] = hostname - currentSize ++ if currentSize >= blockSize { log.Debugf("sending chunk of domains to be added to NRPT") chunkedAddNrptRules(hostnames, dnsServer) hostnames = make([]string, blockSize) currentSize = 0 } + hostnames[currentSize] = hostname + currentSize++ } if currentSize > 0 { //means there's a chunk still to add.... @@ -172,7 +172,6 @@ ForEach ($Rule in $Rules) { } } - func RemoveNrptRules(domainsToMap map[string]bool) { if len(domainsToMap) == 0 { log.Debug("no domains to map specified to RemoveNrptRules. exiting early")