Skip to content

Commit

Permalink
Add in microfab cli (#143)
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew B White <whitemat@uk.ibm.com>
  • Loading branch information
mbwhite authored Feb 7, 2023
1 parent 7aaef0b commit c85c234
Show file tree
Hide file tree
Showing 11 changed files with 846 additions and 195 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Use Go 1.17
- name: Use Go 1.18
uses: actions/setup-go@v3
with:
go-version: 1.17
go-version: 1.18
- name: Run Go formatters and linters
run: make lint
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@

microfabd

_cfg
_mfcfg

7 changes: 7 additions & 0 deletions cmd/microfab/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "github.com/hyperledger-labs/microfab/pkg/microfab"

func main() {
microfab.Execute()
}
65 changes: 48 additions & 17 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,35 +1,66 @@
module github.com/hyperledger-labs/microfab

go 1.14
go 1.18

require (
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/Shopify/sarama v1.26.4 // indirect
github.com/docker/docker v23.0.0+incompatible
github.com/docker/go-connections v0.4.0
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.2
github.com/gorilla/mux v1.7.4
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/hyperledger/fabric v2.1.0+incompatible
github.com/hyperledger/fabric-amcl v0.0.0-20200424173818-327c9e2cf77a // indirect
github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e
github.com/maxbrunsfeld/counterfeiter/v6 v6.4.1
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.17.0
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.7.1 // indirect
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 // indirect
github.com/stretchr/testify v1.6.1 // indirect
github.com/sykesm/zap-logfmt v0.0.3 // indirect
go.uber.org/zap v1.15.0 // indirect
golang.org/x/lint v0.0.0-20190930215403-16217165b5de
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.27.1 // indirect
github.com/spf13/viper v1.15.0
golang.org/x/exp v0.0.0-20230206171751-46f607a40771
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/net v0.4.0
golang.org/x/sync v0.1.0
google.golang.org/grpc v1.52.0
gopkg.in/yaml.v2 v2.4.0
sourcegraph.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518
)

require (
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Shopify/sarama v1.26.4 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hyperledger/fabric-amcl v0.0.0-20200424173818-327c9e2cf77a // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/sykesm/zap-logfmt v0.0.3 // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/tools v0.2.0 // indirect
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.4.0 // indirect
)
490 changes: 315 additions & 175 deletions go.sum

Large diffs are not rendered by default.

134 changes: 134 additions & 0 deletions pkg/microfab/connect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package microfab

import (
"fmt"
"io"
"log"
"net/url"
"os"
"path"

"github.com/hyperledger-labs/microfab/pkg/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

var connectCmd = &cobra.Command{
Use: "connect",
Short: "Writes out connection details for use by the Peer CLI and SDKs",
RunE: func(cmd *cobra.Command, args []string) error {
return connect()
},
}

func connect() error {

urlStr := "http://console.127-0-0-1.nip.io:8080"
testURL, err := url.Parse(urlStr)
if err != nil {
return errors.Wrapf(err, "Unable to parse URL")
}

rootDir := path.Clean(mspdir)

log.Printf("Connecting to URL '%s'\n", urlStr)
log.Printf("Identity and Configuration '%s'\n", rootDir)

// check to see if the directory exists, and if it does emptry
cfgExists, err := exists(rootDir)
if err != nil {
return err
}

if cfgExists {
empty, err := isEmpty(rootDir)
if err != nil {
return err
}

if !empty && !force {
return errors.Errorf("Config directory '%s' is not empty, use --force to overwrite", rootDir)
}
} else {
os.MkdirAll(rootDir, 0755)
}

mfc, err := client.New(testURL, false)
if err != nil {
return errors.Wrapf(err, "Unable to create client")
}

orgs, err := mfc.GetOrganizations()
if err != nil {
return errors.Wrapf(err, "Unable to get Organizations")
}

for _, org := range orgs {

id, err := mfc.GetIdentity(org)
if err != nil {
return errors.Wrapf(err, "Unable to get Identity")
}

idRoot := path.Join(rootDir, org, id.ID, "msp")
os.MkdirAll(path.Join(idRoot, "admincerts"), 0755)
os.MkdirAll(path.Join(idRoot, "cacerts"), 0755)
os.MkdirAll(path.Join(idRoot, "keystore"), 0755)
os.MkdirAll(path.Join(idRoot, "signcerts"), 0755)

os.WriteFile(path.Join(idRoot, "admincerts", "cert.pem"), id.Certificate, 0644)
os.WriteFile(path.Join(idRoot, "signcerts", "cert.pem"), id.Certificate, 0644)
os.WriteFile(path.Join(idRoot, "keystore", "cert_sk"), id.PrivateKey, 0644)
os.WriteFile(path.Join(idRoot, "cacerts", "cert.pem"), id.CA, 0644)

// get the peers, if there's no peer then move on
peer, err := mfc.GetPeer(org)
if err != nil {
continue
}

u, err := url.Parse(peer.APIURL)
if err != nil {
return errors.Wrapf(err, "Unable to prase APIURL")
}

f, err := os.Create(path.Join(rootDir, fmt.Sprintf("%s.env", org)))
if err != nil {
return errors.Wrapf(err, "Unable to form path for context")
}

f.WriteString(fmt.Sprintf("CORE_PEER_ADDRESS=%s\n", u.Host))
f.WriteString(fmt.Sprintf("CORE_PEER_LOCALMSPID=%s\n", peer.MSPID))
f.WriteString(fmt.Sprintf("CORE_PEER_MSPCONFIGPATH=%s\n", idRoot))
f.Sync()

}
return nil

}

func isEmpty(name string) (bool, error) {
f, err := os.Open(name)
if err != nil {
return false, err
}
defer f.Close()

_, err = f.Readdirnames(1) // Or f.Readdir(1)
if err == io.EOF {
return true, nil
}
return false, err // Either not empty or error, suits both cases
}

// exists returns whether the given file or directory exists
func exists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
38 changes: 38 additions & 0 deletions pkg/microfab/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package microfab

import (
"log"
"net/url"

"github.com/hyperledger-labs/microfab/pkg/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

var pingCmd = &cobra.Command{
Use: "ping",
Short: "Pings the microfab image to see if it's running",
RunE: func(cmd *cobra.Command, args []string) error {
return ping()
},
}

func ping() error {

testURL, err := url.Parse("http://console.127-0-0-1.nip.io:8080")
if err != nil {
return errors.Errorf("Unable to parse URL %s", testURL.String())
}

mfc, err := client.New(testURL, false)
if err != nil {
return errors.Wrapf(err, "Unable to connect create client to connect to Microfab")

}
err = mfc.Ping()
if err != nil {
return errors.Wrapf(err, "Unable to connect to runing microfab")
}
log.Println("Microfab ping successful")
return nil
}
45 changes: 45 additions & 0 deletions pkg/microfab/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package microfab

import (
"log"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var rootCmd = &cobra.Command{
Use: "microfab",
Short: "microfab...",
Long: "Microfab Launch Control",
Version: "c0",
SilenceUsage: true,
SilenceErrors: true,
}

var cfg string
var mspdir string
var force bool

// Execute the microfab command
func Execute() {
viper.AutomaticEnv()
viper.ReadInConfig()

if err := rootCmd.Execute(); err != nil {
log.Fatalf("%s\n", err)
}
}

func init() {
rootCmd.PersistentFlags().StringVar(&cfg, "config", "", "Microfab config")
rootCmd.PersistentFlags().StringVar(&mspdir, "msp", "_mfcfg", "msp output directory")
rootCmd.PersistentFlags().BoolVar(&force, "force", false, "Force overwriting msp directory")

viper.BindPFlag("MICROFAB_CONFIG", rootCmd.PersistentFlags().Lookup("config"))

rootCmd.AddCommand(startCmd)
rootCmd.AddCommand(stopCmd)
rootCmd.AddCommand(connectCmd)
rootCmd.AddCommand(pingCmd)

}
Loading

0 comments on commit c85c234

Please sign in to comment.