bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/cmd/synsec-cli/lapi.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http/httputil" 8 "net/url" 9 "strings" 10 11 "bitbucket.org/Aishee/synsec/pkg/apiclient" 12 "bitbucket.org/Aishee/synsec/pkg/csconfig" 13 "bitbucket.org/Aishee/synsec/pkg/cwhub" 14 "bitbucket.org/Aishee/synsec/pkg/cwversion" 15 "bitbucket.org/Aishee/synsec/pkg/models" 16 "github.com/go-openapi/strfmt" 17 log "github.com/sirupsen/logrus" 18 "github.com/spf13/cobra" 19 "gopkg.in/yaml.v2" 20 ) 21 22 var LAPIURLPrefix string = "v1" 23 var lapiUser string 24 25 func NewLapiCmd() *cobra.Command { 26 var cmdLapi = &cobra.Command{ 27 Use: "lapi [action]", 28 Short: "Manage interaction with Local API (LAPI)", 29 Args: cobra.MinimumNArgs(1), 30 PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 31 if err := csConfig.LoadAPIClient(); err != nil { 32 return fmt.Errorf("loading api client: %s", err.Error()) 33 } 34 if csConfig.API.Client == nil { 35 log.Fatalln("There is no API->client configuration") 36 } 37 if csConfig.API.Client.Credentials == nil { 38 log.Fatalf("no configuration for synsec API in '%s'", *csConfig.FilePath) 39 } 40 return nil 41 }, 42 } 43 44 var cmdLapiRegister = &cobra.Command{ 45 Use: "register", 46 Short: "Register a machine to Local API (LAPI)", 47 Long: `Register you machine to the Local API (LAPI). 48 Keep in mind the machine needs to be validated by an administrator on LAPI side to be effective.`, 49 Args: cobra.MinimumNArgs(0), 50 Run: func(cmd *cobra.Command, args []string) { 51 var err error 52 if lapiUser == "" { 53 lapiUser, err = generateID() 54 if err != nil { 55 log.Fatalf("unable to generate machine id: %s", err) 56 } 57 } 58 password := strfmt.Password(generatePassword(passwordLength)) 59 if apiURL == "" { 60 if csConfig.API.Client != nil && csConfig.API.Client.Credentials != nil && csConfig.API.Client.Credentials.URL != "" { 61 apiURL = csConfig.API.Client.Credentials.URL 62 } else { 63 log.Fatalf("No Local API URL. Please provide it in your configuration or with the -u parameter") 64 } 65 } 66 /*URL needs to end with /, but user doesn't care*/ 67 if !strings.HasSuffix(apiURL, "/") { 68 apiURL += "/" 69 } 70 /*URL needs to start with http://, but user doesn't care*/ 71 if !strings.HasPrefix(apiURL, "http://") && !strings.HasPrefix(apiURL, "https://") { 72 apiURL = "http://" + apiURL 73 } 74 apiurl, err := url.Parse(apiURL) 75 if err != nil { 76 log.Fatalf("parsing api url: %s", err) 77 } 78 _, err = apiclient.RegisterClient(&apiclient.Config{ 79 MachineID: lapiUser, 80 Password: password, 81 UserAgent: fmt.Sprintf("synsec/%s", cwversion.VersionStr()), 82 URL: apiurl, 83 VersionPrefix: LAPIURLPrefix, 84 }, nil) 85 86 if err != nil { 87 log.Fatalf("api client register: %s", err) 88 } 89 90 log.Printf("Successfully registered to Local API (LAPI)") 91 92 var dumpFile string 93 if outputFile != "" { 94 dumpFile = outputFile 95 } else if csConfig.API.Client.CredentialsFilePath != "" { 96 dumpFile = csConfig.API.Client.CredentialsFilePath 97 } else { 98 dumpFile = "" 99 } 100 apiCfg := csconfig.ApiCredentialsCfg{ 101 Login: lapiUser, 102 Password: password.String(), 103 URL: apiURL, 104 } 105 apiConfigDump, err := yaml.Marshal(apiCfg) 106 if err != nil { 107 log.Fatalf("unable to marshal api credentials: %s", err) 108 } 109 if dumpFile != "" { 110 err = ioutil.WriteFile(dumpFile, apiConfigDump, 0644) 111 if err != nil { 112 log.Fatalf("write api credentials in '%s' failed: %s", dumpFile, err) 113 } 114 log.Printf("Local API credentials dumped to '%s'", dumpFile) 115 } else { 116 fmt.Printf("%s\n", string(apiConfigDump)) 117 } 118 log.Warningf(ReloadMessage()) 119 }, 120 } 121 cmdLapiRegister.Flags().StringVarP(&apiURL, "url", "u", "", "URL of the API (ie. http://127.0.0.1)") 122 cmdLapiRegister.Flags().StringVarP(&outputFile, "file", "f", "", "output file destination") 123 cmdLapiRegister.Flags().StringVar(&lapiUser, "machine", "", "Name of the machine to register with") 124 cmdLapi.AddCommand(cmdLapiRegister) 125 126 var cmdLapiStatus = &cobra.Command{ 127 Use: "status", 128 Short: "Check authentication to Local API (LAPI)", 129 Args: cobra.MinimumNArgs(0), 130 Run: func(cmd *cobra.Command, args []string) { 131 var err error 132 133 password := strfmt.Password(csConfig.API.Client.Credentials.Password) 134 apiurl, err := url.Parse(csConfig.API.Client.Credentials.URL) 135 login := csConfig.API.Client.Credentials.Login 136 if err != nil { 137 log.Fatalf("parsing api url ('%s'): %s", apiurl, err) 138 } 139 if err := csConfig.LoadHub(); err != nil { 140 log.Fatalf(err.Error()) 141 } 142 143 if err := cwhub.GetHubIdx(csConfig.Hub); err != nil { 144 log.Fatalf("Failed to load hub index : %s", err) 145 log.Infoln("Run 'sudo ccscli hub update' to get the hub index") 146 } 147 scenarios, err := cwhub.GetUpstreamInstalledScenariosAsString() 148 if err != nil { 149 log.Fatalf("failed to get scenarios : %s", err.Error()) 150 } 151 152 Client, err = apiclient.NewDefaultClient(apiurl, 153 LAPIURLPrefix, 154 fmt.Sprintf("synsec/%s", cwversion.VersionStr()), 155 nil) 156 if err != nil { 157 log.Fatalf("init default client: %s", err) 158 } 159 t := models.WatcherAuthRequest{ 160 MachineID: &login, 161 Password: &password, 162 Scenarios: scenarios, 163 } 164 log.Infof("Loaded credentials from %s", csConfig.API.Client.CredentialsFilePath) 165 log.Infof("Trying to authenticate with username %s on %s", login, apiurl) 166 resp, err := Client.Auth.AuthenticateWatcher(context.Background(), t) 167 if err != nil { 168 log.Fatalf("Failed to authenticate to Local API (LAPI) : %s", err) 169 } else { 170 log.Infof("You can successfully interact with Local API (LAPI)") 171 } 172 for k, v := range resp.Response.Header { 173 log.Debugf("[headers] %s : %s", k, v) 174 } 175 dump, _ := httputil.DumpResponse(resp.Response, true) 176 log.Debugf("Response: %s", string(dump)) 177 }, 178 } 179 cmdLapi.AddCommand(cmdLapiStatus) 180 return cmdLapi 181 }