From dbe413c59442033787342306b0b3f41714503906 Mon Sep 17 00:00:00 2001 From: Priyansu Rout Date: Thu, 13 Jun 2024 23:53:29 +0530 Subject: [PATCH 1/5] Implement 'osnadmin channel info' subcommand and update tests Signed-off-by: Priyansu Rout --- cmd/osnadmin/main.go | 15 ++-- cmd/osnadmin/main_test.go | 185 ++++++++++++++++++++++++++++++-------- 2 files changed, 157 insertions(+), 43 deletions(-) diff --git a/cmd/osnadmin/main.go b/cmd/osnadmin/main.go index 464293ae515..b93e98c49c7 100644 --- a/cmd/osnadmin/main.go +++ b/cmd/osnadmin/main.go @@ -52,7 +52,10 @@ func executeForArgs(args []string) (output string, exit int, err error) { configBlockPath := join.Flag("config-block", "Path to the file containing an up-to-date config block for the channel").Short('b').Required().String() list := channel.Command("list", "List channel information for an Ordering Service Node (OSN). If the channelID flag is set, more detailed information will be provided for that channel.") - listChannelID := list.Flag("channelID", "Channel ID").Short('c').String() + // listChannelID := list.Flag("channelID", "Channel ID").Short('c').String() + // Define the new info subcommand + info := channel.Command("info", "Get detailed information about a specific channel.") + infoChannelID := info.Flag("channelID", "Channel ID").Short('c').Required().String() remove := channel.Command("remove", "Remove a channel from an Ordering Service Node (OSN).") removeChannelID := remove.Flag("channelID", "Channel ID").Short('c').Required().String() @@ -113,11 +116,13 @@ func executeForArgs(args []string) (output string, exit int, err error) { case join.FullCommand(): resp, err = osnadmin.Join(osnURL, marshaledConfigBlock, caCertPool, tlsClientCert) case list.FullCommand(): - if *listChannelID != "" { - resp, err = osnadmin.ListSingleChannel(osnURL, *listChannelID, caCertPool, tlsClientCert) - break - } + // if *listChannelID != "" { + // resp, err = osnadmin.ListSingleChannel(osnURL, *listChannelID, caCertPool, tlsClientCert) + // break + // } resp, err = osnadmin.ListAllChannels(osnURL, caCertPool, tlsClientCert) + case info.FullCommand(): + resp, err = osnadmin.ListSingleChannel(osnURL, *infoChannelID, caCertPool, tlsClientCert) case remove.FullCommand(): resp, err = osnadmin.Remove(osnURL, *removeChannelID, caCertPool, tlsClientCert) } diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index 325341fdcc3..e5987fe876a 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -118,13 +118,20 @@ var _ = Describe("osnadmin", func() { Name: "fight-the-system", }, }) + }) - mockChannelManagement.ChannelInfoReturns(types.ChannelInfo{ - Name: "asparagus", - ConsensusRelation: "broccoli", - Status: "carrot", - Height: 987, - }, nil) + It("returns an error when channelID flag is not provided", func() { + args := []string{ + "channel", + "info", + "--orderer-address", ordererURL, + "--ca-file", ordererCACert, + "--client-cert", clientCert, + "--client-key", clientKey, + } + output, exit, err := executeForArgs(args) + expectedErrorMessage := "required flag(s) \"channelID\" not set" + checkCLIError(output, exit, err, expectedErrorMessage) }) It("uses the channel participation API to list all application channels and the system channel (when it exists)", func() { @@ -156,10 +163,70 @@ var _ = Describe("osnadmin", func() { checkStatusOutput(output, exit, err, 200, 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", + }, + } + checkStatusOutput(output, exit, err, 200, expectedOutput) + }) + }) + }) + + Describe("Info", func() { + BeforeEach(func() { + mockChannelManagement.ChannelListReturns(types.ChannelList{ + Channels: []types.ChannelInfoShort{ + { + Name: "participation-trophy", + }, + { + Name: "another-participation-trophy", + }, + }, + SystemChannel: &types.ChannelInfoShort{ + Name: "fight-the-system", + }, + }) + + mockChannelManagement.ChannelInfoReturns(types.ChannelInfo{ + Name: "asparagus", + ConsensusRelation: "broccoli", + Status: "carrot", + Height: 987, + }, nil) + }) + It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", - "list", + "info", "--orderer-address", ordererURL, "--channelID", "tell-me-your-secrets", "--ca-file", ordererCACert, @@ -185,7 +252,7 @@ var _ = Describe("osnadmin", func() { It("returns 404 not found", func() { args := []string{ "channel", - "list", + "info", "--orderer-address", ordererURL, "--channelID", "tell-me-your-secrets", "--ca-file", ordererCACert, @@ -205,39 +272,10 @@ var _ = Describe("osnadmin", 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", - }, - } - checkStatusOutput(output, exit, err, 200, expectedOutput) - }) - It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", - "list", + "info", "--orderer-address", ordererURL, "--channelID", "tell-me-your-secrets", } @@ -254,6 +292,26 @@ var _ = Describe("osnadmin", func() { } checkStatusOutput(output, exit, err, 200, expectedOutput) }) + Context("when the channel does not exist", func() { + BeforeEach(func() { + mockChannelManagement.ChannelInfoReturns(types.ChannelInfo{}, errors.New("eat-your-peas")) + }) + + It("returns 404 not found with the info subcommand", func() { + args := []string{ + "channel", + "info", + "--orderer-address", ordererURL, + "--channelID", "tell-me-your-secrets", + } + output, exit, err := executeForArgs(args) + expectedOutput := types.ErrorResponse{ + Error: "eat-your-peas", + } + checkStatusOutput(output, exit, err, 404, expectedOutput) + }) + }) + }) }) @@ -581,6 +639,18 @@ var _ = Describe("osnadmin", func() { }) }) + Context("when an unknown flag is used with the info subcommand", func() { + It("returns an error for long flags", func() { + _, _, err := executeForArgs([]string{"channel", "info", "--bad-flag"}) + Expect(err).To(MatchError("unknown long flag '--bad-flag'")) + }) + + It("returns an error for short flags", func() { + _, _, err := executeForArgs([]string{"channel", "info", "-z"}) + Expect(err).To(MatchError("unknown short flag '-z'")) + }) + }) + Context("when the ca cert cannot be read", func() { BeforeEach(func() { ordererCACert = "not-the-ca-cert-youre-looking-for" @@ -591,6 +661,25 @@ var _ = Describe("osnadmin", func() { "channel", "list", "--orderer-address", ordererURL, + "--ca-file", ordererCACert, + "--client-cert", clientCert, + "--client-key", clientKey, + } + output, exit, err := executeForArgs(args) + checkFlagError(output, exit, err, "reading orderer CA certificate: open not-the-ca-cert-youre-looking-for: no such file or directory") + }) + }) + + Context("when the ca cert cannot be read with the info subcommand", func() { + BeforeEach(func() { + ordererCACert = "not-the-ca-cert-youre-looking-for" + }) + + It("returns with exit code 1 and prints the error with the info subcommand", func() { + args := []string{ + "channel", + "info", + "--orderer-address", ordererURL, "--channelID", channelID, "--ca-file", ordererCACert, "--client-cert", clientCert, @@ -640,6 +729,26 @@ var _ = Describe("osnadmin", func() { }) }) + Context("when the client cert/key pair fail to load with the info subcommand", func() { + BeforeEach(func() { + clientKey = "brussel-sprouts" + }) + + It("returns with exit code 1 and prints the error with the info subcommand", func() { + args := []string{ + "channel", + "info", + "--orderer-address", ordererURL, + "--channelID", channelID, + "--ca-file", ordererCACert, + "--client-cert", clientCert, + "--client-key", clientKey, + } + output, exit, err := executeForArgs(args) + checkFlagError(output, exit, err, "loading client cert/key pair: open brussel-sprouts: no such file or directory") + }) + }) + Context("when the config block cannot be read", func() { var configBlockPath string From 8d97bcffb75dbc6546273dbc2490483f51896f1a Mon Sep 17 00:00:00 2001 From: Priyansu Rout Date: Fri, 14 Jun 2024 00:26:23 +0530 Subject: [PATCH 2/5] Implement 'osnadmin channel info' subcommand and update tests Signed-off-by: Priyansu Rout --- cmd/osnadmin/main.go | 2 +- cmd/osnadmin/main_test.go | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/cmd/osnadmin/main.go b/cmd/osnadmin/main.go index b93e98c49c7..54a2730392e 100644 --- a/cmd/osnadmin/main.go +++ b/cmd/osnadmin/main.go @@ -58,7 +58,7 @@ func executeForArgs(args []string) (output string, exit int, err error) { infoChannelID := info.Flag("channelID", "Channel ID").Short('c').Required().String() remove := channel.Command("remove", "Remove a channel from an Ordering Service Node (OSN).") - removeChannelID := remove.Flag("channelID", "Channel ID").Short('c').Required().String() + removeChannelID := remove.Flag("channelID", "Channel ID").Short('c').String() command, err := app.Parse(args) if err != nil { diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index e5987fe876a..68dac159476 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -120,20 +120,6 @@ var _ = Describe("osnadmin", func() { }) }) - It("returns an error when channelID flag is not provided", func() { - args := []string{ - "channel", - "info", - "--orderer-address", ordererURL, - "--ca-file", ordererCACert, - "--client-cert", clientCert, - "--client-key", clientKey, - } - output, exit, err := executeForArgs(args) - expectedErrorMessage := "required flag(s) \"channelID\" not set" - checkCLIError(output, exit, err, expectedErrorMessage) - }) - It("uses the channel participation API to list all application channels and the system channel (when it exists)", func() { args := []string{ "channel", @@ -223,6 +209,20 @@ var _ = Describe("osnadmin", func() { }, nil) }) + // It("returns an error when channelID flag is not provided", func() { + // args := []string{ + // "channel", + // "info", + // "--orderer-address", ordererURL, + // "--ca-file", ordererCACert, + // "--client-cert", clientCert, + // "--client-key", clientKey, + // } + // output, exit, err := executeForArgs(args) + // expectedErrorMessage := "required flag(s) \"channelID\" not set" + // checkCLIError(output, exit, err, expectedErrorMessage) + // }) + It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", From e95740aeb70f027f997d3ade3e131444f579ea96 Mon Sep 17 00:00:00 2001 From: Priyansu Rout Date: Fri, 14 Jun 2024 00:31:27 +0530 Subject: [PATCH 3/5] Implement osnadmin channel info' subcommand and update tests Signed-off-by: Priyansu Rout --- cmd/osnadmin/main_test.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index 68dac159476..f11a66d4da5 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -209,20 +209,6 @@ var _ = Describe("osnadmin", func() { }, nil) }) - // It("returns an error when channelID flag is not provided", func() { - // args := []string{ - // "channel", - // "info", - // "--orderer-address", ordererURL, - // "--ca-file", ordererCACert, - // "--client-cert", clientCert, - // "--client-key", clientKey, - // } - // output, exit, err := executeForArgs(args) - // expectedErrorMessage := "required flag(s) \"channelID\" not set" - // checkCLIError(output, exit, err, expectedErrorMessage) - // }) - It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", From f88783dfa1421e01e85cd6d3e353a2aefc3fa0da Mon Sep 17 00:00:00 2001 From: Priyansu Rout Date: Fri, 14 Jun 2024 00:41:10 +0530 Subject: [PATCH 4/5] Implement 'osnadmin channel info' subcommand and update tests Signed-off-by: Priyansu Rout --- cmd/osnadmin/main.go | 2 +- cmd/osnadmin/main_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cmd/osnadmin/main.go b/cmd/osnadmin/main.go index 54a2730392e..b93e98c49c7 100644 --- a/cmd/osnadmin/main.go +++ b/cmd/osnadmin/main.go @@ -58,7 +58,7 @@ func executeForArgs(args []string) (output string, exit int, err error) { infoChannelID := info.Flag("channelID", "Channel ID").Short('c').Required().String() remove := channel.Command("remove", "Remove a channel from an Ordering Service Node (OSN).") - removeChannelID := remove.Flag("channelID", "Channel ID").Short('c').String() + removeChannelID := remove.Flag("channelID", "Channel ID").Short('c').Required().String() command, err := app.Parse(args) if err != nil { diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index f11a66d4da5..f24f90cb7f2 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -209,6 +209,20 @@ var _ = Describe("osnadmin", func() { }, nil) }) + It("returns an error when channelID flag is not provided", func() { + args := []string{ + "channel", + "info", + "--orderer-address", ordererURL, + "--ca-file", ordererCACert, + "--client-cert", clientCert, + "--client-key", clientKey, + } + output, exit, err := executeForArgs(args) + expectedErrorMessage := "required flag(s) \"channelID\" not set" + checkCLIError(output, exit, err, expectedErrorMessage) + }) + It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", From ebc72d5959e07dbffab6e78d208d4c58458a5b2f Mon Sep 17 00:00:00 2001 From: Priyansu Rout Date: Fri, 14 Jun 2024 00:45:15 +0530 Subject: [PATCH 5/5] Implement 'osnadmin channel info' subcommand and update tests Signed-off-by: Priyansu Rout --- cmd/osnadmin/main.go | 2 -- cmd/osnadmin/main_test.go | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/cmd/osnadmin/main.go b/cmd/osnadmin/main.go index b93e98c49c7..b63834223d6 100644 --- a/cmd/osnadmin/main.go +++ b/cmd/osnadmin/main.go @@ -52,8 +52,6 @@ func executeForArgs(args []string) (output string, exit int, err error) { configBlockPath := join.Flag("config-block", "Path to the file containing an up-to-date config block for the channel").Short('b').Required().String() list := channel.Command("list", "List channel information for an Ordering Service Node (OSN). If the channelID flag is set, more detailed information will be provided for that channel.") - // listChannelID := list.Flag("channelID", "Channel ID").Short('c').String() - // Define the new info subcommand info := channel.Command("info", "Get detailed information about a specific channel.") infoChannelID := info.Flag("channelID", "Channel ID").Short('c').Required().String() diff --git a/cmd/osnadmin/main_test.go b/cmd/osnadmin/main_test.go index f24f90cb7f2..4005dba2604 100644 --- a/cmd/osnadmin/main_test.go +++ b/cmd/osnadmin/main_test.go @@ -209,20 +209,6 @@ var _ = Describe("osnadmin", func() { }, nil) }) - It("returns an error when channelID flag is not provided", func() { - args := []string{ - "channel", - "info", - "--orderer-address", ordererURL, - "--ca-file", ordererCACert, - "--client-cert", clientCert, - "--client-key", clientKey, - } - output, exit, err := executeForArgs(args) - expectedErrorMessage := "required flag(s) \"channelID\" not set" - checkCLIError(output, exit, err, expectedErrorMessage) - }) - It("uses the channel participation API to list the details of a single channel", func() { args := []string{ "channel", @@ -311,7 +297,6 @@ var _ = Describe("osnadmin", func() { checkStatusOutput(output, exit, err, 404, expectedOutput) }) }) - }) })