NOISSUE - Rename bashflux to cli and fix cert path (#349)

* NOISSUE - rename bashflux to cli and fix cert path

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix pkg name

Signed-off-by: drasko <drasko.draskovic@gmail.com>
This commit is contained in:
Drasko DRASKOVIC
2018-08-16 13:41:27 +02:00
committed by GitHub
parent 455fedf075
commit 2c988c19b0
11 changed files with 113 additions and 61 deletions
+87
View File
@@ -0,0 +1,87 @@
# Mainflux CLI
## Build
From the project root:
```
make cli
```
## Usage
### Service
#### Get the service verison
```
mainflux-cli version
```
### User management
#### Create User
```
mainflux-cli users create john.doe@email.com password
```
#### Login User
```
mainflux-cli users token john.doe@email.com password
```
### System Provisioning
#### Provision Device
```
mainflux-cli things create '{"type":"device", "name":"nyDevice"}' <user_auth_token>
```
#### Provision Application
```
mainflux-cli things create '{"type":"app", "name":"nyDevice"}' <user_auth_token>
```
#### Retrieve All Things
```
mainflux-cli things get all --offset=1 --limit=5 <user_auth_token>
```
#### Retrieve Thing By ID
```
mainflux-cli things get <thing_id> --offset=1 --limit=5 <user_auth_token>
```
#### Remove Thing
```
mainflux-cli things delete <thing_id> <user_auth_token>
```
#### Provision Channel
```
mainflux-cli channels create '{"name":"nyChannel"}' <user_auth_token>
```
#### Retrieve All Channels
```
mainflux-cli channels get all --offset=1 --limit=5 <user_auth_token>
```
#### Retrievie Channel By ID
```
mainflux-cli channels get <channel_id> --offset=1 --limit=5 <user_auth_token>
```
#### Remove Channel
```
mainflux-cli channels delete <channel_id> <user_auth_token>
```
### Access control
#### Connect Thing to a Channel
```
mainflux-cli things connect <thing_id> <channel_id> <user_auth_token>
```
#### Disconnect Things from a Channel
```
mainflux-cli things disconnect <thing_id> <channel_id> <user_auth_token>
```
### Messaging
#### Send a message over HTTP
```
mainflux-cli msg send <channel_id> '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' <thing_auth_token>
```
+120
View File
@@ -0,0 +1,120 @@
package cli
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/spf13/cobra"
)
const channelsEP = "channels"
var cmdChannels = []cobra.Command{
cobra.Command{
Use: "create",
Short: "create <JSON_channel> <user_auth_token>",
Long: `Creates new channel and generates it's UUID`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
CreateChannel(args[0], args[1])
},
},
cobra.Command{
Use: "get",
Short: "get all/<channel_id> <user_auth_token>",
Long: `Gets list of all channels or gets channel by id`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
if args[0] == "all" {
GetChannels(args[1])
return
}
GetChannel(args[0], args[1])
},
},
cobra.Command{
Use: "update",
Short: "update <channel_id> <JSON_string> <user_auth_token>",
Long: `Updates channel record`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 3 {
LogUsage(cmd.Short)
return
}
UpdateChannel(args[0], args[1], args[2])
},
},
cobra.Command{
Use: "delete",
Short: "delete <channel_id> <user_auth_token>",
Long: `Delete channel by ID`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
DeleteChannel(args[0], args[1])
},
},
}
func NewChannelsCmd() *cobra.Command {
cmd := cobra.Command{
Use: "channels",
Short: "Manipulation with channels",
Long: `Manipulation with channels: create, delete or update channels`,
Run: func(cmd *cobra.Command, args []string) {
LogUsage(cmd.Short)
},
}
for i, _ := range cmdChannels {
cmd.AddCommand(&cmdChannels[i])
}
return &cmd
}
// CreateChannel - creates new channel and generates UUID
func CreateChannel(data, token string) {
url := fmt.Sprintf("%s/%s", serverAddr, channelsEP)
req, err := http.NewRequest("POST", url, strings.NewReader(data))
SendRequest(req, token, err)
}
// GetChannels - gets all channels
func GetChannels(token string) {
url := fmt.Sprintf("%s/%s?offset=%s&limit=%s",
serverAddr, channelsEP, strconv.Itoa(Offset), strconv.Itoa(Limit))
req, err := http.NewRequest("GET", url, nil)
SendRequest(req, token, err)
}
// GetChannel - gets channel by ID
func GetChannel(id, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, channelsEP, id)
req, err := http.NewRequest("GET", url, nil)
SendRequest(req, token, err)
}
// UpdateChannel - update a channel
func UpdateChannel(id, data, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, channelsEP, id)
req, err := http.NewRequest("PUT", url, strings.NewReader(data))
SendRequest(req, token, err)
}
// DeleteChannel - removes channel
func DeleteChannel(id, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, channelsEP, id)
req, err := http.NewRequest("DELETE", url, nil)
SendRequest(req, token, err)
}
+69
View File
@@ -0,0 +1,69 @@
package cli
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"github.com/mainflux/mainflux"
)
const (
defCertsPath = "/src/github.com/mainflux/mainflux/docker/ssl/certs/"
envCertFile = "MF_CERT_FILE"
envKeyFile = "MF_KEY_FILE"
envCaFile = "MF_CA_FILE"
)
var (
httpClient = &http.Client{}
serverAddr = fmt.Sprintf("https://%s", "localhost")
defCertFile = fmt.Sprintf("%s%s%s", os.Getenv("GOPATH"), defCertsPath, "mainflux-server.crt")
defKeyFile = fmt.Sprintf("%s%s%s", os.Getenv("GOPATH"), defCertsPath, "mainflux-server.key")
defCaFile = fmt.Sprintf("%s%s%s", os.Getenv("GOPATH"), defCertsPath, "ca.crt")
)
// SetServerAddr - set addr using host and port
func SetServerAddr(host string, port int) {
serverAddr = fmt.Sprintf("https://%s", host)
if port != 0 {
serverAddr = fmt.Sprintf("%s:%s", serverAddr, strconv.Itoa(port))
}
}
func SetCerts() {
// Set certificates paths
certFile := mainflux.Env(envCertFile, defCertFile)
keyFile := mainflux.Env(envKeyFile, defKeyFile)
caFile := mainflux.Env(envCaFile, defCaFile)
// Load client cert
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal(err)
}
// Load CA cert
caCert, err := ioutil.ReadFile(caFile)
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Setup HTTPS client
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient = &http.Client{Transport: transport}
}
+52
View File
@@ -0,0 +1,52 @@
package cli
import (
"net/http"
"strings"
"github.com/spf13/cobra"
)
const contentTypeSenml = "application/senml+json"
var cmdMessages = []cobra.Command{
cobra.Command{
Use: "send",
Short: "send <channel_id> <JSON_string> <client_token>",
Long: `Sends message on the channel`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 3 {
LogUsage(cmd.Short)
return
}
SendMsg(args[0], args[1], args[2])
},
},
}
func NewMessagesCmd() *cobra.Command {
cmd := cobra.Command{
Use: "msg",
Short: "Send or retrieve messages",
Long: `Send or retrieve messages: control message flow on the channel`,
}
for i, _ := range cmdMessages {
cmd.AddCommand(&cmdMessages[i])
}
return &cmd
}
// SendMsg - publishes SenML message on the channel
func SendMsg(id, msg, token string) {
url := serverAddr + "/http/channels/" + id + "/messages"
req, err := http.NewRequest("POST", url, strings.NewReader(msg))
LogError(err)
req.Header.Set("Authorization", token)
req.Header.Add("Content-Type", contentTypeSenml)
resp, err := httpClient.Do(req)
FormatResLog(resp, err)
}
+160
View File
@@ -0,0 +1,160 @@
package cli
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/spf13/cobra"
)
const thingsEP = "things"
var cmdThings = []cobra.Command{
cobra.Command{
Use: "create",
Short: "create <JSON_thing> <user_auth_token>",
Long: `Create new thing, generate his UUID and store it`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
CreateThing(args[0], args[1])
},
},
cobra.Command{
Use: "get",
Short: "get all/<thing_id> <user_auth_token>",
Long: `Get all thingss or thing by id`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
if args[0] == "all" {
GetThings(args[1])
return
}
GetThing(args[0], args[1])
},
},
cobra.Command{
Use: "delete",
Short: "delete <thing_id> <user_auth_token>",
Long: `Removes thing from database`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
DeleteThing(args[0], args[1])
},
},
cobra.Command{
Use: "update",
Short: "update <thing_id> <JSON_string> <user_auth_token>",
Long: `Update thing record`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 3 {
LogUsage(cmd.Short)
return
}
UpdateThing(args[0], args[1], args[2])
},
},
cobra.Command{
Use: "connect",
Short: "connect <thing_id> <channel_id> <user_auth_token>",
Long: `Connect thing to the channel`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 3 {
LogUsage(cmd.Short)
return
}
ConnectThing(args[0], args[1], args[2])
},
},
cobra.Command{
Use: "disconnect",
Short: "disconnect <thing_id> <channel_id> <user_auth_token>",
Long: `Disconnect thing to the channel`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 3 {
LogUsage(cmd.Short)
return
}
DisconnectThing(args[0], args[1], args[2])
},
},
}
func NewThingsCmd() *cobra.Command {
cmd := cobra.Command{
Use: "things",
Short: "things <options>",
Long: `Things handling: create, delete or update things.`,
Run: func(cmd *cobra.Command, args []string) {
LogUsage(cmd.Short)
},
}
for i, _ := range cmdThings {
cmd.AddCommand(&cmdThings[i])
}
return &cmd
}
// CreateThing - creates new thing and generates thing UUID
func CreateThing(data, token string) {
url := fmt.Sprintf("%s/%s", serverAddr, thingsEP)
req, err := http.NewRequest("POST", url, strings.NewReader(data))
SendRequest(req, token, err)
}
// GetThings - gets all things
func GetThings(token string) {
url := fmt.Sprintf("%s/%s?offset=%s&limit=%s",
serverAddr, thingsEP, strconv.Itoa(Offset), strconv.Itoa(Limit))
req, err := http.NewRequest("GET", url, nil)
SendRequest(req, token, err)
}
// GetThing - gets thing by ID
func GetThing(id, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, thingsEP, id)
req, err := http.NewRequest("GET", url, nil)
SendRequest(req, token, err)
}
// UpdateThing - updates thing by ID
func UpdateThing(id, data, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, thingsEP, id)
req, err := http.NewRequest("PUT", url, strings.NewReader(data))
SendRequest(req, token, err)
}
// DeleteThing - removes thing
func DeleteThing(id, token string) {
url := fmt.Sprintf("%s/%s/%s", serverAddr, thingsEP, id)
req, err := http.NewRequest("DELETE", url, nil)
SendRequest(req, token, err)
}
// ConnectThing - connect thing to a channel
func ConnectThing(cliId, chanId, token string) {
url := fmt.Sprintf("%s/%s/%s/%s/%s", serverAddr, channelsEP,
chanId, thingsEP, cliId)
req, err := http.NewRequest("PUT", url, nil)
SendRequest(req, token, err)
}
// DisconnectThing - connect thing to a channel
func DisconnectThing(cliId, chanId, token string) {
url := fmt.Sprintf("%s/%s/%s/%s/%s", serverAddr, channelsEP,
chanId, thingsEP, cliId)
req, err := http.NewRequest("DELETE", url, nil)
SendRequest(req, token, err)
}
+68
View File
@@ -0,0 +1,68 @@
package cli
import (
"fmt"
"strings"
"github.com/spf13/cobra"
)
var cmdUsers = []cobra.Command{
cobra.Command{
Use: "create",
Short: "create <username> <password>",
Long: `Creates new user`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
CreateUser(args[0], args[1])
},
},
cobra.Command{
Use: "token",
Short: "token <username> <password>",
Long: `Creates new token`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
LogUsage(cmd.Short)
return
}
CreateToken(args[0], args[1])
},
},
}
func NewUsersCmd() *cobra.Command {
cmd := cobra.Command{
Use: "users",
Short: "users create/token <email> <password>",
Long: `Manages users in the system (create account or token)`,
Run: func(cmd *cobra.Command, args []string) {
LogUsage(cmd.Short)
},
}
for i, _ := range cmdUsers {
cmd.AddCommand(&cmdUsers[i])
}
return &cmd
}
// CreateUser - create user
func CreateUser(user, pwd string) {
msg := fmt.Sprintf(`{"email": "%s", "password": "%s"}`, user, pwd)
url := fmt.Sprintf("%s/users", serverAddr)
resp, err := httpClient.Post(url, contentType, strings.NewReader(msg))
FormatResLog(resp, err)
}
// CreateToken - create user token
func CreateToken(user, pwd string) {
msg := fmt.Sprintf(`{"email": "%s", "password": "%s"}`, user, pwd)
url := fmt.Sprintf("%s/tokens", serverAddr)
resp, err := httpClient.Post(url, contentType, strings.NewReader(msg))
FormatResLog(resp, err)
}
+68
View File
@@ -0,0 +1,68 @@
package cli
import (
"fmt"
"io/ioutil"
"net/http"
"github.com/fatih/color"
"github.com/hokaccha/go-prettyjson"
)
const contentType = "application/json"
var Limit = 10
var Offset = 0
func SendRequest(req *http.Request, token string, e error) {
req.Header.Set("Authorization", token)
req.Header.Add("Content-Type", contentType)
if e != nil {
LogError(e)
return
}
resp, err := httpClient.Do(req)
FormatResLog(resp, err)
}
// FormatResLog - format http response
func FormatResLog(resp *http.Response, err error) {
if err != nil {
LogError(err)
return
}
defer resp.Body.Close()
fmt.Printf(color.CyanString("%s %s\nContent-Length: %v\n\n"),
resp.Proto, resp.Status, resp.ContentLength)
if len(resp.Header.Get("Location")) != 0 {
fmt.Printf(color.BlueString("Resource location: %s\n\n"),
resp.Header.Get("Location"))
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
LogError(err)
return
}
if len(body) != 0 {
pj, err := prettyjson.Format([]byte(body))
if err != nil {
fmt.Printf("%s\n\n", color.BlueString(string(body)))
return
}
fmt.Printf("%s\n\n", string(pj))
}
}
func LogUsage(u string) {
fmt.Printf(color.YellowString("Usage: %s\n\n"), u)
}
func LogError(err error) {
fmt.Printf("%s\n\n", color.RedString(err.Error()))
}
+24
View File
@@ -0,0 +1,24 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
)
func NewVersionCmd() *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Get version of Mainflux Things Service",
Long: `Mainflux server health checkt.`,
Run: func(cmd *cobra.Command, args []string) {
Version()
},
}
}
// Version - server health check
func Version() {
url := fmt.Sprintf("%s/version", serverAddr)
FormatResLog(httpClient.Get(url))
}