Compare commits
4 commits
c799dc7838
...
277de43a02
| Author | SHA1 | Date | |
|---|---|---|---|
| 277de43a02 | |||
| bdd85b01ff | |||
| 2112e7eefd | |||
| eac73ada69 |
11 changed files with 311 additions and 72 deletions
21
README.md
21
README.md
|
|
@ -207,14 +207,12 @@ On the other hand, profiles are simply objects that contain data used to populat
|
|||
type Profile struct {
|
||||
ID string `json:"id"` // profile ID
|
||||
Description string `json:"description,omitempty"` // profile description
|
||||
Tags []string `json:"tags,omitempty"` // tags used for ...
|
||||
Paths []string `json:"paths,omitempty"` // paths to download
|
||||
Plugins []string `json:"plugins,omitempty"` // plugins to run
|
||||
Tags []string `json:"tags,omitempty"` // tags used for filtering (not implemented yet)
|
||||
Data map[string]any `json:"data,omitempty"` // include render data
|
||||
}
|
||||
```
|
||||
|
||||
Profiles can be created using JSON. See the example in `$MAKESHIFT_ROOT/profiles/default.json`.
|
||||
Profiles can be created using JSON and only require an `id` with optional `data`. See the example in `$MAKESHIFT_ROOT/profiles/default.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -235,12 +233,9 @@ Profiles can be created using JSON. See the example in `$MAKESHIFT_ROOT/profiles
|
|||
|
||||
There are some features still missing that will be added later.
|
||||
|
||||
1. Uploading files and directories
|
||||
2. Uploading new profiles and plugins
|
||||
3. Running `makeshift` locally with profiles and plugins
|
||||
4. Plugin to add user data for one-time use without creating a profile
|
||||
5. Optionally build plugins directly into the main driver
|
||||
6. Protected routes that require authentication
|
||||
7. Configuration file for persistent runs
|
||||
8. `Dockerfile` and `docker-compose.yml` files to build containers
|
||||
9. Including certs with requests
|
||||
1. Running `makeshift` locally with profiles and plugins
|
||||
2. Plugin to add user data for one-time use without creating a profile
|
||||
3. Optionally build plugins directly into the main driver
|
||||
4. Protected routes that require authentication
|
||||
5. Configuration file for persistent runs
|
||||
6. `Dockerfile` and `docker-compose.yml` files to build containers
|
||||
0
bin/compile-plugins.sh
Normal file → Executable file
0
bin/compile-plugins.sh
Normal file → Executable file
|
|
@ -24,17 +24,29 @@ var deleteCmd = &cobra.Command{
|
|||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
setenv(cmd, "host", "MAKESHIFT_HOST")
|
||||
setenv(cmd, "path", "MAKESHIFT_PATH")
|
||||
setenv(cmd, "cacert", "MAKESHIFT_CACERT")
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
paths, _ = cmd.Flags().GetStringSlice("path")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
paths, _ = cmd.Flags().GetStringSlice("path")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
query string
|
||||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if path == "" {
|
||||
log.Warn().Msg("skipping empty path")
|
||||
|
|
@ -61,7 +73,8 @@ var deleteProfilesCmd = &cobra.Command{
|
|||
Short: "Delete profile(s)",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -69,6 +82,14 @@ var deleteProfilesCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
for _, profileID := range args {
|
||||
if profileID == "default" {
|
||||
log.Warn().Msg("cannot delete the default profile")
|
||||
|
|
@ -95,7 +116,8 @@ var deletePluginsCmd = &cobra.Command{
|
|||
Short: "Delete plugin(s)",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -103,6 +125,15 @@ var deletePluginsCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
for _, pluginName := range args {
|
||||
query = fmt.Sprintf("/plugins/%s", pluginName)
|
||||
res, _, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
|
|
@ -116,6 +147,7 @@ var deletePluginsCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
deleteCmd.PersistentFlags().String("host", "http://localhost:5050", "Set the makeshift server host (can be set with MAKESHIFT_HOST)")
|
||||
deleteCmd.PersistentFlags().String("cacert", "", "Set the CA certificate path to load")
|
||||
deleteCmd.Flags().StringSliceP("path", "p", []string{}, "Set the paths to delete files and directories")
|
||||
deleteCmd.AddCommand(deleteProfilesCmd, deletePluginsCmd)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,12 +37,14 @@ var downloadCmd = cobra.Command{
|
|||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
setenv(cmd, "host", "MAKESHIFT_HOST")
|
||||
setenv(cmd, "path", "MAKESHIFT_PATH")
|
||||
setenv(cmd, "cacert", "MAKESHIFT_CACERT")
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
path, _ = cmd.Flags().GetString("path")
|
||||
outputPath, _ = cmd.Flags().GetString("output")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
pluginNames, _ = cmd.Flags().GetStringSlice("plugins")
|
||||
profileIDs, _ = cmd.Flags().GetStringSlice("profiles")
|
||||
extract, _ = cmd.Flags().GetBool("extract")
|
||||
|
|
@ -72,6 +74,10 @@ var downloadCmd = cobra.Command{
|
|||
Strs("plugins", pluginNames).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
Path: query,
|
||||
Method: http.MethodGet,
|
||||
|
|
@ -163,6 +169,7 @@ var downloadProfileCmd = &cobra.Command{
|
|||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
outputPath, _ = cmd.Flags().GetString("output")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -176,6 +183,10 @@ var downloadProfileCmd = &cobra.Command{
|
|||
Str("output", outputPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
for _, profileID := range args {
|
||||
query = fmt.Sprintf("/profiles/%s", profileID)
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
|
|
@ -219,6 +230,7 @@ var downloadPluginCmd = &cobra.Command{
|
|||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
outputPath, _ = cmd.Flags().GetString("output")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -232,6 +244,10 @@ var downloadPluginCmd = &cobra.Command{
|
|||
Str("output", outputPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
for _, pluginName := range args {
|
||||
query = fmt.Sprintf("/plugins/%s/raw", pluginName)
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
|
|
@ -267,6 +283,7 @@ var downloadPluginCmd = &cobra.Command{
|
|||
func init() {
|
||||
downloadCmd.PersistentFlags().String("host", "http://localhost:5050", "Set the makeshift remote host (can be set with MAKESHIFT_HOST)")
|
||||
downloadCmd.PersistentFlags().StringP("output", "o", "", "Set the output path to write files")
|
||||
downloadCmd.PersistentFlags().String("cacert", "", "Set the CA certificate path to load")
|
||||
downloadCmd.Flags().StringP("path", "p", ".", "Set the path to list files (can be set with MAKESHIFT_PATH)")
|
||||
downloadCmd.Flags().StringSlice("profiles", []string{}, "Set the profile(s) to use to populate data store")
|
||||
downloadCmd.Flags().StringSlice("plugins", []string{}, "Set the plugin(s) to run before downloading files")
|
||||
|
|
|
|||
49
cmd/list.go
49
cmd/list.go
|
|
@ -24,14 +24,16 @@ var listCmd = &cobra.Command{
|
|||
`,
|
||||
Args: cobra.NoArgs,
|
||||
Short: "List all files in a remote data directory",
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
setenv(cmd, "host", "MAKESHIFT_HOST")
|
||||
setenv(cmd, "path", "MAKESHIFT_PATH")
|
||||
setenv(cmd, "cacert", "MAKESHIFT_CACERT")
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
path, _ = cmd.Flags().GetString("path")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
path, _ = cmd.Flags().GetString("path")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
body []byte
|
||||
|
|
@ -42,8 +44,13 @@ var listCmd = &cobra.Command{
|
|||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("path", path).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
// make request to /list endpoint
|
||||
_, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
Path: fmt.Sprintf("/list/%s", path),
|
||||
|
|
@ -80,7 +87,8 @@ var listPluginsCmd = &cobra.Command{
|
|||
Short: "Show plugins information",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -90,6 +98,15 @@ var listPluginsCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
// make request to /list endpoint
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
|
|
@ -121,11 +138,19 @@ var listPluginsCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
var listProfilesCmd = &cobra.Command{
|
||||
Use: "profiles",
|
||||
Use: "profiles",
|
||||
Example: `
|
||||
# list all profiles
|
||||
makeshift list profiles
|
||||
|
||||
# live individual profiles
|
||||
makeshift list profiles default custom
|
||||
`,
|
||||
Short: "Show all available profiles",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -135,6 +160,15 @@ var listProfilesCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
// make request to /list endpoint
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
|
|
@ -154,7 +188,7 @@ var listProfilesCmd = &cobra.Command{
|
|||
// make request to /list endpoint
|
||||
query = fmt.Sprintf("/profiles/%s", profileID)
|
||||
res, body, err = c.MakeRequest(client.HTTPEnvelope{
|
||||
Path: fmt.Sprintf(query),
|
||||
Path: query,
|
||||
Method: http.MethodGet,
|
||||
})
|
||||
handleResponseError(res, host, query, err)
|
||||
|
|
@ -174,6 +208,7 @@ var listProfilesCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
listCmd.PersistentFlags().String("host", "http://localhost:5050", "Set the configurator remote host (can be set with MAKESHIFT_HOST)")
|
||||
listCmd.PersistentFlags().String("cacert", "", "Set the CA certificate path to load")
|
||||
listCmd.Flags().StringP("path", "p", ".", "Set the path to list files (can be set with MAKESHIFT_PATH)")
|
||||
|
||||
listCmd.AddCommand(listPluginsCmd, listProfilesCmd)
|
||||
|
|
|
|||
18
cmd/serve.go
18
cmd/serve.go
|
|
@ -23,12 +23,16 @@ var serveCmd = &cobra.Command{
|
|||
setenv(cmd, "host", "MAKESHIFT_HOST")
|
||||
setenv(cmd, "root", "MAKESHIFT_ROOT")
|
||||
setenv(cmd, "timeout", "MAKESHIFT_TIMEOUT")
|
||||
setenv(cmd, "cacert", "MAKESHIFT_CACERT")
|
||||
setenv(cmd, "keyfile", "MAKESHIFT_KEYFILE")
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
rootPath, _ = cmd.Flags().GetString("root")
|
||||
timeout, _ = cmd.Flags().GetInt("timeout")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
rootPath, _ = cmd.Flags().GetString("root")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
keyfile, _ = cmd.Flags().GetString("keyfile")
|
||||
timeout, _ = cmd.Flags().GetInt("timeout")
|
||||
|
||||
parsed *url.URL
|
||||
server *service.Service
|
||||
|
|
@ -47,6 +51,8 @@ var serveCmd = &cobra.Command{
|
|||
server = service.New()
|
||||
server.Addr = parsed.Host
|
||||
server.RootPath = rootPath
|
||||
server.CACertFile = cacertPath
|
||||
server.CACertKeyfile = keyfile
|
||||
server.Timeout = time.Duration(timeout) * time.Second
|
||||
|
||||
// show some debugging information
|
||||
|
|
@ -54,6 +60,8 @@ var serveCmd = &cobra.Command{
|
|||
Str("host", parsed.Host).
|
||||
Any("paths", map[string]string{
|
||||
"root": rootPath,
|
||||
"cacert": cacertPath,
|
||||
"keyfile": keyfile,
|
||||
"data": server.PathForData(),
|
||||
"profiles": server.PathForProfiles(),
|
||||
"plugins": server.PathForPlugins(),
|
||||
|
|
@ -84,6 +92,10 @@ func init() {
|
|||
serveCmd.Flags().String("host", "localhost:5050", "Set the configurator server host (can be set with MAKESHIFT_HOST)")
|
||||
serveCmd.Flags().String("root", "./", "Set the root path to serve files (can be set with MAKESHIFT_ROOT)")
|
||||
serveCmd.Flags().IntP("timeout", "t", 60, "Set the timeout in seconds for requests (can be set with MAKESHIFT_TIMEOUT)")
|
||||
serveCmd.Flags().String("cacert", "", "Set the CA certificate path to load (can be set with MAKESHIFT_CACERT)")
|
||||
serveCmd.Flags().String("keyfile", "", "Set the CA key file to use (can be set with MAKESHIFT_KEYFILE)")
|
||||
|
||||
serveCmd.MarkFlagsRequiredTogether("cacert", "keyfile")
|
||||
|
||||
rootCmd.AddCommand(serveCmd)
|
||||
}
|
||||
|
|
|
|||
176
cmd/upload.go
176
cmd/upload.go
|
|
@ -4,6 +4,8 @@ import (
|
|||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"maps"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -41,12 +43,14 @@ var uploadCmd = &cobra.Command{
|
|||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
setenv(cmd, "host", "MAKESHIFT_HOST")
|
||||
setenv(cmd, "path", "MAKESHIFT_PATH")
|
||||
setenv(cmd, "cacert", "MAKESHIFT_CACERT")
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
path, _ = cmd.Flags().GetString("path")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
path, _ = cmd.Flags().GetString("path")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
|
||||
inputData = processFiles(dataArgs)
|
||||
useDirectoryPath = len(inputData) > 1
|
||||
|
|
@ -55,8 +59,21 @@ var uploadCmd = &cobra.Command{
|
|||
query string
|
||||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("path", path).
|
||||
Str("query", query).
|
||||
Str("cacert", cacertPath).
|
||||
Any("input", inputData).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
for inputPath, contents := range inputData {
|
||||
log.Info().Str("path", path).Int("size", len(contents)).Send()
|
||||
log.Debug().Str("path", path).Int("size", len(contents)).Send()
|
||||
if useDirectoryPath {
|
||||
query = path + "/" + filepath.Clean(inputPath)
|
||||
} else {
|
||||
|
|
@ -92,9 +109,10 @@ var uploadProfilesCmd = &cobra.Command{
|
|||
Short: "Upload a new profile",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
profiles = processProfiles(dataArgs)
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
profiles = processProfiles(dataArgs)
|
||||
|
||||
c = client.New(host)
|
||||
res *http.Response
|
||||
|
|
@ -103,6 +121,16 @@ var uploadProfilesCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("query", query).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
// load files from args
|
||||
for i, path := range args {
|
||||
body, err = os.ReadFile(path)
|
||||
|
|
@ -160,8 +188,9 @@ var uploadPluginsCmd = &cobra.Command{
|
|||
// make one request be host positional argument (restricted to 1 for now)
|
||||
// temp := append(handleArgs(args), processDataArgs(dataArgs)...)
|
||||
var (
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
host, _ = cmd.Flags().GetString("host")
|
||||
dataArgs, _ = cmd.Flags().GetStringArray("data")
|
||||
cacertPath, _ = cmd.Flags().GetString("cacert")
|
||||
|
||||
plugins = processFiles(dataArgs)
|
||||
c = client.New(host)
|
||||
|
|
@ -172,6 +201,16 @@ var uploadPluginsCmd = &cobra.Command{
|
|||
err error
|
||||
)
|
||||
|
||||
log.Debug().
|
||||
Str("host", host).
|
||||
Str("query", query).
|
||||
Str("cacert", cacertPath).
|
||||
Send()
|
||||
|
||||
if cacertPath != "" {
|
||||
c.LoadCertificateFromPath(cacertPath)
|
||||
}
|
||||
|
||||
// load files from args
|
||||
for i, path := range args {
|
||||
body, err = os.ReadFile(path)
|
||||
|
|
@ -208,6 +247,8 @@ var uploadPluginsCmd = &cobra.Command{
|
|||
func init() {
|
||||
uploadCmd.PersistentFlags().String("host", "http://localhost:5050", "Set the makeshift remote host (can be set with MAKESHIFT_HOST)")
|
||||
uploadCmd.PersistentFlags().StringArrayP("data", "d", []string{}, "Set the data to send to specified host (prepend @ for files)")
|
||||
uploadCmd.PersistentFlags().String("cacert", "", "Set the CA certificate path to load")
|
||||
|
||||
uploadCmd.Flags().StringP("path", "p", ".", "Set the path to list files (can be set with MAKESHIFT_PATH)")
|
||||
|
||||
uploadProfilesCmd.Flags().VarP(&inputFormat, "format", "F", "Set the input format for profile")
|
||||
|
|
@ -220,31 +261,27 @@ func processFiles(args []string) map[string][]byte {
|
|||
// load data either from file or directly from args
|
||||
var collection = make(map[string][]byte, len(args))
|
||||
for _, arg := range args {
|
||||
// if arg is empty string, then skip and continue
|
||||
// skip empty string args
|
||||
if len(arg) > 0 {
|
||||
// determine if we're reading from file to load contents
|
||||
if strings.HasPrefix(arg, "@") {
|
||||
var (
|
||||
path string = strings.TrimLeft(arg, "@")
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
contents, err = os.ReadFile(path)
|
||||
var path string = strings.TrimLeft(arg, "@")
|
||||
|
||||
// process sub-directories recursively
|
||||
newCollection, err := processDir(path)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("path", path).Msg("failed to read file")
|
||||
continue
|
||||
log.Warn().
|
||||
Err(err).
|
||||
Str("path", path).
|
||||
Msg("failed to process directory at path")
|
||||
}
|
||||
log.Trace().
|
||||
Str("path", path).
|
||||
Msg("new collection added at path")
|
||||
maps.Copy(collection, newCollection)
|
||||
|
||||
// skip empty files
|
||||
if len(contents) == 0 {
|
||||
log.Warn().Str("path", path).Msg("file is empty")
|
||||
continue
|
||||
}
|
||||
|
||||
// add loaded data to collection of all data
|
||||
collection[path] = contents
|
||||
} else {
|
||||
log.Warn().Msg("only files can be uploaded (add @ before the path)")
|
||||
log.Warn().Msg("only files can be uploaded (add @ before the path with '--data' flag)")
|
||||
|
||||
continue
|
||||
}
|
||||
|
|
@ -275,20 +312,28 @@ func processProfiles(args []string) []*makeshift.Profile {
|
|||
)
|
||||
contents, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("path", path).Msg("failed to read file")
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("path", path).
|
||||
Msg("failed to read file")
|
||||
continue
|
||||
}
|
||||
|
||||
// skip empty files
|
||||
if len(contents) == 0 {
|
||||
log.Warn().Str("path", path).Msg("file is empty")
|
||||
log.Warn().
|
||||
Str("path", path).
|
||||
Msg("file is empty")
|
||||
continue
|
||||
}
|
||||
|
||||
// convert/validate input data
|
||||
data, err = parseProfile(contents, format.DataFormatFromFileExt(path, inputFormat))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("path", path).Msg("failed to validate input from file")
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("path", path).
|
||||
Msg("failed to validate input from file")
|
||||
}
|
||||
|
||||
// add loaded data to collection of all data
|
||||
|
|
@ -306,7 +351,9 @@ func processProfiles(args []string) []*makeshift.Profile {
|
|||
}
|
||||
err = json.Unmarshal(input, &data)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed to unmarshal input for argument %d", i)
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msgf("failed to unmarshal input for argument %d", i)
|
||||
}
|
||||
return []*makeshift.Profile{data}
|
||||
}
|
||||
|
|
@ -315,6 +362,73 @@ func processProfiles(args []string) []*makeshift.Profile {
|
|||
return collection
|
||||
}
|
||||
|
||||
func processDir(path string) (map[string][]byte, error) {
|
||||
var (
|
||||
collection = map[string][]byte{}
|
||||
fileInfo os.FileInfo
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
// determine if path is directory
|
||||
if fileInfo, err = os.Stat(path); err == nil {
|
||||
if fileInfo.IsDir() {
|
||||
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
||||
if !d.IsDir() {
|
||||
contents, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("path", path).Msg("failed to read file")
|
||||
return nil
|
||||
}
|
||||
|
||||
// skip empty files
|
||||
if len(contents) == 0 {
|
||||
log.Warn().Str("path", path).Msg("file is empty")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("path", path).
|
||||
Msg("file added to collection")
|
||||
|
||||
// add loaded data to collection of all data
|
||||
collection[path] = contents
|
||||
} else {
|
||||
// process sub-directories recursively
|
||||
newCollection, err := processDir(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to process directory at path '%s': %v", path, err)
|
||||
}
|
||||
log.Trace().
|
||||
Str("path", path).
|
||||
Msg("new collection added from nested directory")
|
||||
maps.Copy(collection, newCollection)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
} else {
|
||||
contents, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
return collection, fmt.Errorf("failed to read file at path '%s': %v", path, err)
|
||||
}
|
||||
|
||||
// skip empty files
|
||||
if len(contents) == 0 {
|
||||
return collection, fmt.Errorf("file is empty")
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("path", path).
|
||||
Msg("file added to collection")
|
||||
|
||||
// add loaded data to collection of all data
|
||||
collection[path] = contents
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("failed to stat file: %v", err)
|
||||
}
|
||||
return collection, nil
|
||||
}
|
||||
|
||||
func parseProfile(contents []byte, dataFormat format.DataFormat) (*makeshift.Profile, error) {
|
||||
var (
|
||||
data *makeshift.Profile
|
||||
|
|
|
|||
|
|
@ -133,10 +133,18 @@ func addToArchive(tw *tar.Writer, filename string, hooks []makeshift.Hook) error
|
|||
}
|
||||
hook.Data.Set("file", contents)
|
||||
|
||||
err = hook.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = hook.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = hook.Cleanup()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create temporary file to use to add to archive
|
||||
hook = hooks[len(hooks)-1]
|
||||
|
|
|
|||
|
|
@ -29,10 +29,18 @@ type Hook struct {
|
|||
Plugin Plugin
|
||||
}
|
||||
|
||||
func (h *Hook) Init() error {
|
||||
return h.Plugin.Init()
|
||||
}
|
||||
|
||||
func (h *Hook) Run() error {
|
||||
return h.Plugin.Run(h.Data, h.Args)
|
||||
}
|
||||
|
||||
func (h *Hook) Cleanup() error {
|
||||
return h.Plugin.Cleanup()
|
||||
}
|
||||
|
||||
func PluginToMap(p Plugin) map[string]any {
|
||||
return map[string]any{
|
||||
"name": p.Name(),
|
||||
|
|
|
|||
|
|
@ -142,6 +142,14 @@ func (s *Service) Download() http.HandlerFunc {
|
|||
"version": hook.Plugin.Version(),
|
||||
},
|
||||
}).Send()
|
||||
err = hook.Init()
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("plugin", hook.Plugin.Name()).
|
||||
Msg("failed to initialize plugin")
|
||||
continue
|
||||
}
|
||||
err = hook.Run()
|
||||
if err != nil {
|
||||
log.Error().
|
||||
|
|
@ -150,6 +158,14 @@ func (s *Service) Download() http.HandlerFunc {
|
|||
Msg("failed to run plugin")
|
||||
continue
|
||||
}
|
||||
err = hook.Cleanup()
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("plugin", hook.Plugin.Name()).
|
||||
Msg("failed to cleanup plugin")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// take the contents from the last hook and update files
|
||||
|
|
@ -190,7 +206,9 @@ func (s *Service) Upload() http.HandlerFunc {
|
|||
)
|
||||
|
||||
// show what we're uploading
|
||||
log.Debug().Str("path", path).Msg("Service.Upload()")
|
||||
log.Debug().
|
||||
Str("path", path).
|
||||
Msg("Service.Upload()")
|
||||
|
||||
// take the provided path and store the file contents
|
||||
dirpath = filepath.Dir(path)
|
||||
|
|
@ -296,7 +314,7 @@ func (s *Service) loadProfiles(profileIDs []string, store storage.KVStore, errs
|
|||
profile *makeshift.Profile
|
||||
err error
|
||||
)
|
||||
if i > DEFAULT_PROFILES_MAX_COUNT {
|
||||
if i > s.ProfilesMaxCount {
|
||||
log.Warn().Msg("max profiles count reached...stopping")
|
||||
return errs
|
||||
}
|
||||
|
|
@ -329,7 +347,7 @@ func (s *Service) loadPlugins(pluginNames []string, store storage.KVStore, args
|
|||
plugin makeshift.Plugin
|
||||
err error
|
||||
)
|
||||
if i > DEFAULT_PLUGINS_MAX_COUNT {
|
||||
if i > s.PluginsMaxCount {
|
||||
log.Warn().Msg("max plugins count reached or exceeded...stopping")
|
||||
return hooks, errs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,10 @@ import (
|
|||
)
|
||||
|
||||
type Service struct {
|
||||
Addr string
|
||||
RootPath string `yaml:"root,omitempty"`
|
||||
Environment map[string]string
|
||||
Addr string
|
||||
RootPath string `yaml:"root,omitempty"`
|
||||
CACertFile string `yaml:"cacert,omitempty"`
|
||||
CACertKeyfile string `yaml:"keyfile,omitempty"`
|
||||
|
||||
// max counts
|
||||
PluginsMaxCount int
|
||||
|
|
@ -32,13 +33,8 @@ type Service struct {
|
|||
// New creates a new Service instance with default values
|
||||
func New() *Service {
|
||||
return &Service{
|
||||
Addr: ":5050",
|
||||
RootPath: "./",
|
||||
Environment: map[string]string{
|
||||
"MAKESHIFT_HOST": "",
|
||||
"MAKESHIFT_ROOT": "",
|
||||
"ACCESS_TOKEN": "",
|
||||
},
|
||||
Addr: ":5050",
|
||||
RootPath: "./",
|
||||
PluginsMaxCount: DEFAULT_PLUGINS_MAX_COUNT,
|
||||
ProfilesMaxCount: DEFAULT_PROFILES_MAX_COUNT,
|
||||
Timeout: DEFAULT_TIMEOUT_IN_SECS,
|
||||
|
|
@ -121,7 +117,11 @@ func (s *Service) Serve() error {
|
|||
|
||||
// always available public routes go here
|
||||
router.HandleFunc("/status", s.GetStatus)
|
||||
return http.ListenAndServe(s.Addr, router)
|
||||
if s.CACertFile != "" && s.CACertKeyfile != "" {
|
||||
return http.ListenAndServeTLS(s.Addr, s.CACertFile, s.CACertKeyfile, router)
|
||||
} else {
|
||||
return http.ListenAndServe(s.Addr, router)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) requireAuth() bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue