diff --git a/cmd/osnadmin/main.go b/cmd/osnadmin/main.go index c13b2775fea..9d331946370 100644 --- a/cmd/osnadmin/main.go +++ b/cmd/osnadmin/main.go @@ -42,9 +42,9 @@ func executeForArgs(args []string) (output string, exit int, err error) { // app := kingpin.New("osnadmin", "Orderer Service Node (OSN) administration") orderer := app.Flag("orderer-address", "Admin endpoint of the OSN").Short('o').Required().String() - caFile := app.Flag("ca-file", "Path to file containing PEM-encoded TLS CA certificate(s) for the OSN").Required().String() - clientCert := app.Flag("client-cert", "Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the OSN").Required().String() - clientKey := app.Flag("client-key", "Path to file containing PEM-encoded private key to use for mutual TLS communication with the OSN").Required().String() + caFile := app.Flag("ca-file", "Path to file containing PEM-encoded TLS CA certificate(s) for the OSN").String() + clientCert := app.Flag("client-cert", "Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the OSN").String() + clientKey := app.Flag("client-key", "Path to file containing PEM-encoded private key to use for mutual TLS communication with the OSN").String() channel := app.Command("channel", "Channel actions") @@ -63,21 +63,31 @@ func executeForArgs(args []string) (output string, exit int, err error) { // // flag validation // - osnURL := fmt.Sprintf("https://%s", *orderer) - - caCertPool := x509.NewCertPool() - caFilePEM, err := ioutil.ReadFile(*caFile) - if err != nil { - return "", 1, fmt.Errorf("reading orderer CA certificate: %s", err) - } - err = comm.AddPemToCertPool(caFilePEM, caCertPool) - if err != nil { - return "", 1, fmt.Errorf("adding ca-file PEM to cert pool: %s", err) - } + var ( + osnURL string + caCertPool *x509.CertPool + tlsClientCert tls.Certificate + ) + // TLS enabled + if *caFile != "" { + osnURL = fmt.Sprintf("https://%s", *orderer) + var err error + caCertPool = x509.NewCertPool() + caFilePEM, err := ioutil.ReadFile(*caFile) + if err != nil { + return "", 1, fmt.Errorf("reading orderer CA certificate: %s", err) + } + err = comm.AddPemToCertPool(caFilePEM, caCertPool) + if err != nil { + return "", 1, fmt.Errorf("adding ca-file PEM to cert pool: %s", err) + } - tlsClientCert, err := tls.LoadX509KeyPair(*clientCert, *clientKey) - if err != nil { - return "", 1, fmt.Errorf("loading client cert/key pair: %s", err) + tlsClientCert, err = tls.LoadX509KeyPair(*clientCert, *clientKey) + if err != nil { + return "", 1, fmt.Errorf("loading client cert/key pair: %s", err) + } + } else { // TLS disabled + osnURL = fmt.Sprintf("http://%s", *orderer) } var marshaledConfigBlock []byte diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index 2fa9ea9cb1a..40840c858fd 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -87,8 +87,12 @@ var _ = Describe("osnadmin", func() { }) JustBeforeEach(func() { - testServer.TLS = tlsConfig - testServer.StartTLS() + if tlsConfig != nil { + testServer.TLS = tlsConfig + testServer.StartTLS() + } else { + testServer.Start() + } u, err := url.Parse(testServer.URL) Expect(err).NotTo(HaveOccurred()) @@ -196,6 +200,62 @@ var _ = Describe("osnadmin", func() { checkOutput(output, exit, err, 404, expectedOutput) }) }) + + Context("when TLS is disabled", func() { + BeforeEach(func() { + tlsConfig = nil + }) + + It("uses the channel participation API to list all channels", func() { + args := []string{ + "channel", + "list", + "--orderer-address", ordererURL, + } + output, exit, err := executeForArgs(args) + Expect(err).NotTo(HaveOccurred()) + Expect(exit).To(Equal(0)) + + expectedOutput := types.ChannelList{ + Channels: []types.ChannelInfoShort{ + { + Name: "participation-trophy", + URL: "/participation/v1/channels/participation-trophy", + }, + { + Name: "another-participation-trophy", + URL: "/participation/v1/channels/another-participation-trophy", + }, + }, + SystemChannel: &types.ChannelInfoShort{ + Name: "fight-the-system", + URL: "/participation/v1/channels/fight-the-system", + }, + } + checkOutput(output, exit, err, 200, expectedOutput) + }) + + It("uses the channel participation API to list the details of a single channel", func() { + args := []string{ + "channel", + "list", + "--orderer-address", ordererURL, + "--channel-id", "tell-me-your-secrets", + } + output, exit, err := executeForArgs(args) + Expect(err).NotTo(HaveOccurred()) + Expect(exit).To(Equal(0)) + + expectedOutput := types.ChannelInfo{ + Name: "asparagus", + URL: "/participation/v1/channels/asparagus", + ConsensusRelation: "broccoli", + Status: "carrot", + Height: 987, + } + checkOutput(output, exit, err, 200, expectedOutput) + }) + }) }) Describe("Remove", func() { @@ -237,6 +297,25 @@ var _ = Describe("osnadmin", func() { checkOutput(output, exit, err, 404, expectedOutput) }) }) + + Context("when TLS is disabled", func() { + BeforeEach(func() { + tlsConfig = nil + }) + + It("uses the channel participation API to remove a channel", func() { + args := []string{ + "channel", + "remove", + "--orderer-address", ordererURL, + "--channel-id", channelID, + } + output, exit, err := executeForArgs(args) + Expect(err).NotTo(HaveOccurred()) + Expect(exit).To(Equal(0)) + Expect(output).To(Equal("Status: 204\n")) + }) + }) }) Describe("Join", func() { @@ -391,6 +470,31 @@ var _ = Describe("osnadmin", func() { checkOutput(output, exit, err, 405, expectedOutput) }) }) + + Context("when TLS is disabled", func() { + BeforeEach(func() { + tlsConfig = nil + }) + + It("uses the channel participation API to join a channel", func() { + args := []string{ + "channel", + "join", + "--orderer-address", ordererURL, + "--channel-id", channelID, + "--config-block", blockPath, + } + output, exit, err := executeForArgs(args) + expectedOutput := types.ChannelInfo{ + Name: "apple", + URL: "/participation/v1/channels/apple", + ConsensusRelation: "banana", + Status: "orange", + Height: 123, + } + checkOutput(output, exit, err, 201, expectedOutput) + }) + }) }) Describe("Flags", func() {