Skip to content

Commit

Permalink
fabric-ca-client command plumbing with cobra/viper
Browse files Browse the repository at this point in the history
This is the plumbing work for the cobra/viper-based fabric-ca-client command.

See https://jira.hyperledger.org/browse/FAB-2012

To build this command: "make fabric-ca-client".

Its usage message is as follows:

Hyperledger Fabric Certificate Authority Client

Usage:
  fabric-ca-client [command]

Available Commands:
  enroll        Enroll user with fabric-ca server
  reenroll      Reenroll user with fabric-ca server
  register      Register user with fabric-ca server
  revoke        Revoke user with fabric-ca server

Flags:
  -c, --config string   Configuration file (default "fabric-ca-client-config.yaml")
  -s, --server string   URL of the Fabric-ca server

Use "fabric-ca-client [command] --help" for more information about a command.

Change-Id: I3807465756113be209f3a345acd7be112d8be6dd
Signed-off-by: Saad Karim <[email protected]>
  • Loading branch information
Saad Karim committed Feb 9, 2017
1 parent 0bdea4a commit c4e83c1
Show file tree
Hide file tree
Showing 13 changed files with 751 additions and 4 deletions.
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# - license - check all go files for license headers
# - fabric-ca - builds the fabric-ca executable
# - fabric-ca-server - builds the fabric-ca-server executable
# - fabric-ca-client - builds the fabric-ca-client executable
# - unit-tests - Performs checks first and runs the go-test based unit tests
# - checks - runs all check conditions (license, format, imports, lint and vet)
# - ldap-tests - runs the LDAP tests
Expand Down Expand Up @@ -87,6 +88,11 @@ fabric-ca-server:
@mkdir -p bin && go build -o bin/fabric-ca-server ./cmd/fabric-ca-server
@echo "Built bin/fabric-ca-server"

fabric-ca-client:
@echo "Building fabric-ca-client in bin directory ..."
@mkdir -p bin && go build -o bin/fabric-ca-client ./cmd/fabric-ca-client
@echo "Built bin/fabric-ca-client"

# We (re)build a package within a docker context but persist the $GOPATH/pkg
# directory so that subsequent builds are faster
build/docker/bin/fabric-ca:
Expand Down Expand Up @@ -133,7 +139,7 @@ build/image/%/$(DUMMY): Makefile build/image/%/payload
build/sampleconfig.tar.bz2: $(SAMPLECONFIG)
tar -jc -C images/fabric-ca/config $(patsubst images/fabric-ca/config/%,%,$(SAMPLECONFIG)) > $@

unit-tests: checks fabric-ca fabric-ca-server
unit-tests: checks fabric-ca fabric-ca-server fabric-ca-client
@scripts/run_tests

container-tests: ldap-tests
Expand Down
1 change: 1 addition & 0 deletions cmd/fabric-ca-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fabric-ca-client
198 changes: 198 additions & 0 deletions cmd/fabric-ca-client/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"

"github.com/cloudflare/cfssl/log"
"github.com/hyperledger/fabric-ca/util"
"github.com/spf13/viper"
)

const (
longName = "Hyperledger Fabric Certificate Authority Client"
shortName = "fabric-ca client"
cmdName = "fabric-ca-client"
envVarPrefix = "FABRIC_CA_CLIENT"
homeEnvVar = "FABRIC_CA_CLIENT_HOME"
)

const (
defaultCfgTemplate = `
#############################################################################
# This is a configuration file for the fabric-ca-client command.
#
# COMMAND LINE ARGUMENTS AND ENVIRONMENT VARIABLES
# ------------------------------------------------
# Each configuration element can be overridden via command line
# arguments or environment variables. The precedence for determining
# the value of each element is as follows:
# 1) command line argument
# Examples:
# a) --url https://localhost:7054
# To set the fabric-ca server url
# 2) environment variable
# Examples:
# a) FABRIC_CA_CLIENT_URL=https://localhost:7054
# To set the fabric-ca server url
# 3) configuration file
# 4) default value (if there is one)
# All default values are shown beside each element below.
#
# FILE NAME ELEMENTS
# ------------------
# All filename elements below end with the word "file".
# For example, see "certfile" and "keyfile" in the "ca" section.
# The value of each filename element can be a simple filename, a
# relative path, or an absolute path. If the value is not an
# absolute path, it is interpretted as being relative to the location
# of this configuration file.
#
#############################################################################
#############################################################################
# Client Configuration
#############################################################################
# URL of the Fabric-ca-server (default: http://localhost:7054)
serverURL: <<<URL>>>
#############################################################################
# TLS section for the client's listenting port
#############################################################################
tls:
# Enable TLS (default: false)
enabled: false
# TLS for the client's listenting port (default: false)
caFile:
certFile:
keyFile:
#############################################################################
# Certificate Signing Request section for generating the CSR for
# an enrollment certificate (ECert)
#############################################################################
csr:
cn: <<<ENROLLMENT_ID>>>
names:
- C: US
ST: "North Carolina"
L:
O: Hyperledger
OU: Fabric
hosts:
- <<<MYHOST>>>
ca:
pathlen:
pathlenzero:
expiry:
`
)

var (
// cfgFileName is the name of the client's config file
cfgFileName string
)

func configInit() error {

var err error

// Make the config file name absolute
if !filepath.IsAbs(cfgFileName) {
cfgFileName, err = filepath.Abs(cfgFileName)
if err != nil {
return fmt.Errorf("Failed to get full path of config file: %s", err)
}
}

// If the config file doesn't exist, create a default one
if !util.FileExists(cfgFileName) {
err = createDefaultConfigFile()
if err != nil {
return fmt.Errorf("Failed to create default configuration file: %s", err)
}
log.Infof("Created a default configuration file at %s", cfgFileName)
} else {
log.Infof("Configuration file location: %s", cfgFileName)
}

// Call viper to read the config
viper.SetConfigFile(cfgFileName)
viper.AutomaticEnv() // read in environment variables that match
err = viper.ReadInConfig()
if err != nil {
return fmt.Errorf("Failed to read config file: %s", err)
}

return nil

}

// Get the default path for the config file to display in usage message
func getDefaultConfigFile() string {
var fname = fmt.Sprintf("%s-config.yaml", cmdName)
// First check home env variables
home := "."
envs := []string{"FABRIC_CA_CLIENT_HOME", "FABRIC_CA_HOME", "HOME"}
for _, env := range envs {
envVal := os.Getenv(env)
if envVal != "" {
home = envVal
break
}
}
return path.Join(home, ".fabric-ca-client", fname)
}

func createDefaultConfigFile() error {
var err error
// Create a default config, if URL provided via CLI or envar update config files
url := viper.GetString("url")
if url == "" {
url = util.GetServerURL()
}

enrollID := viper.GetString("enrollid")

host := viper.GetString("host")
if host == "" {
host, err = os.Hostname()
if err != nil {
log.Error(err)
}
}

// Do string subtitution to get the default config
cfg := strings.Replace(defaultCfgTemplate, "<<<URL>>>", url, 1)
cfg = strings.Replace(defaultCfgTemplate, "<<<ENROLLMENT_ID>>>", enrollID, 1)
cfg = strings.Replace(defaultCfgTemplate, "<<<MYHOST>>>", host, 1)

// Now write the file
err = os.MkdirAll(filepath.Dir(cfgFileName), 0755)
if err != nil {
return err
}
// Now write the file
return ioutil.WriteFile(cfgFileName, []byte(cfg), 0755)
}
75 changes: 75 additions & 0 deletions cmd/fabric-ca-client/enroll.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"github.com/cloudflare/cfssl/log"
"github.com/hyperledger/fabric-ca/api"
"github.com/hyperledger/fabric-ca/util"
"github.com/spf13/cobra"
)

var (
csrFile string
)

// initCmd represents the init command
var enrollCmd = &cobra.Command{
Use: "enroll",
Short: "Enroll user",
Long: "Enroll user with fabric-ca server",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
cmd.Help()
return nil
}

err := runEnroll()
if err != nil {
return err
}

return nil
},
}

func init() {
rootCmd.AddCommand(enrollCmd)
enrollFlags := enrollCmd.Flags()
util.FlagString(enrollFlags, "user", "u", "", "user:pass for user being enrolled")
}

// The client enroll main logic
func runEnroll() error {
log.Debug("Entered Enroll")

user, pass, err := util.GetUser()
if err != nil {
return err
}

req := &api.EnrollmentRequest{
Name: user,
Secret: pass,
}

_ = req

log.Infof("User Enrolled")

return nil
}
Loading

0 comments on commit c4e83c1

Please sign in to comment.