/
3n4cli.go
153 lines (130 loc) · 3.5 KB
/
3n4cli.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// 3nigm4 3n4cli package
// Author: Guido Ronchetti <dyst0ni3@gmail.com>
// v1.0 16/06/2016
//
package main
// Golang std libs
import (
"encoding/json"
"fmt"
"os"
"os/user"
"path"
)
// Internal dependencies
import (
ct "github.com/nexocrew/3nigm4/lib/commons"
"github.com/nexocrew/3nigm4/lib/logger"
)
// Third party libs
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/crypto/openpgp"
)
// Logger global instance
var log *logger.LogFacility
// Global PGP private key: it's loaded the first time a command, that
// uses it, is invoked. After that remains in memory until the program
// is close.
var pgpPrivateKey openpgp.EntityList
// Global PGP public key: it's loaded the first time a command, that
// uses it, is invoked. After that remains in memory until the program
// is close.
var pgpPublicKey openpgp.EntityList
// rootAppFolder is the the name of the root folder used by the 3nigm4
// app to store config files, stored data, etc... This folder will be
// located under the user $HOME dir.
var rootAppFolder = ".3nigm4"
// RootCmd is the base command used by cobra in the storageservice
// exec.
var RootCmd = &cobra.Command{
Use: "3n4cli",
Short: "CLI client for the 3nigm4 services",
Long: "Command line client to access 3nigm4 services, it generally requires a network connection to operate.",
RunE: func(cmd *cobra.Command, args []string) error {
// Execution implementation
return fmt.Errorf("undefined command, select a valid one")
},
}
func init() {
cobra.OnInitialize(initConfig)
// global flags
setArgument(RootCmd, "verbose")
viper.BindPFlag(am["verbose"].name, RootCmd.PersistentFlags().Lookup(am["verbose"].name))
}
// checkRequestStatus check request status and if an anomalous
// response status code is present check for the StandardResponse
// error property.
func checkRequestStatus(httpstatus, expected int, body []byte) error {
if httpstatus != expected {
var status ct.StandardResponse
err := json.Unmarshal(body, &status)
if err != nil {
return err
}
return fmt.Errorf(
"service returned wrong status code: having %d expecting %d, cause %s",
httpstatus,
expected,
status.Error)
}
return nil
}
func initConfig() {
usr, err := user.Current()
if err != nil {
log.CriticalLog("Unable to access user home dir cause %s.\n", err.Error())
os.Exit(1)
}
rootDir := path.Join(usr.HomeDir, rootAppFolder)
// init fs if first starting
_, err = os.Stat(rootDir)
if os.IsNotExist(err) {
log.MessageLog("Initialising 3n4 filesystem and config...\n")
err = initfs(usr.Username, rootDir)
if err != nil {
log.CriticalLog("Unable to init filesystem: %s.\n", err.Error())
os.Exit(1)
}
}
// set config file references
viper.SetConfigName("config")
viper.AddConfigPath(rootDir)
// set env reader
viper.SetEnvPrefix("3n4env")
viper.AutomaticEnv()
err = viper.ReadInConfig()
if err != nil {
log.WarningLog("Unable to read config file: %s.\n", err.Error())
}
}
// Execute parsing and execute selected
// command.
func Execute() error {
// execute actual command
_, err := RootCmd.ExecuteC()
if err != nil {
return err
}
return nil
}
func main() {
// start up logging facility
log = logger.NewLogFacility("3n4cli", false, true)
// start up storage singleton
pss = newPersistentStorage()
if pss == nil {
log.CriticalLog("Unable to start persistant storage, cannot procede.\n")
os.Exit(1)
}
err := Execute()
if err != nil {
log.CriticalLog("%s.\n", err.Error())
pss.save()
os.Exit(1)
}
pss.save()
os.Exit(0)
}