diff --git a/pkg/ctl/bk/autorecovery/autorecovery.go b/pkg/ctl/bk/autorecovery/autorecovery.go new file mode 100644 index 000000000..87b886642 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/autorecovery.go @@ -0,0 +1,46 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + + "github.com/spf13/cobra" +) + +func Commands(flagGrouping *cmdutils.FlagGrouping) *cobra.Command { + resourceCmd := cmdutils.NewResourceCmd( + "auto-recovery", + "Operations about ledger", + "", + "") + + commands := []func(*cmdutils.VerbCmd){ + RecoverBookieCmd, + ListUnderReplicatedLedgerCmd, + WhoIsAuditorCmd, + TriggerAuditCmd, + SetLostBookieRecoveryDelayCmd, + GetLostBookieRecoveryDelayCmd, + DecommissionCmd, + } + + cmdutils.AddVerbCmds(flagGrouping, resourceCmd, commands...) + + return resourceCmd +} diff --git a/pkg/ctl/bk/autorecovery/decommission.go b/pkg/ctl/bk/autorecovery/decommission.go new file mode 100644 index 000000000..de7594740 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/decommission.go @@ -0,0 +1,70 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" +) + +func DecommissionCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for decommission a bookie." + desc.CommandPermission = "none" + + var examples []pulsar.Example + c := pulsar.Example{ + Desc: "Decommission a bookie", + Command: "pulsarctl bk auto-recovery (bk-ip:bk-port)", + } + examples = append(examples, c) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: "Successfully decommission the bookie (bookie-ip:bookie-port)", + } + + argError := pulsar.Output{ + Desc: "the bookie address is not specified or the bookie address is specified more than one", + Out: "[✖] the bookie address is not specified or the bookie address is specified more than one", + } + out = append(out, successOut, argError) + desc.CommandOutput = out + + vc.SetDescription( + "decommission", + "Decommission a bookie", + desc.ToString(), + desc.ExampleToString()) + + vc.SetRunFuncWithNameArg(func() error { + return doDecommission(vc) + }, "the bookie address is not specified or the bookie address is specified more than one") +} + +func doDecommission(vc *cmdutils.VerbCmd) error { + admin := cmdutils.NewBookieClient() + err := admin.AutoRecovery().Decommission(vc.NameArg) + if err == nil { + vc.Command.Printf("Successfully decommission the bookie %s\n", vc.NameArg) + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/get_lost_bookie_recovery_delay.go b/pkg/ctl/bk/autorecovery/get_lost_bookie_recovery_delay.go new file mode 100644 index 000000000..9d4b34c01 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/get_lost_bookie_recovery_delay.go @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" +) + +func GetLostBookieRecoveryDelayCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for getting the lost bookie recovery delay in second of a bookie." + desc.CommandPermission = "none" + + var examples []pulsar.Example + get := pulsar.Example{ + Desc: "Get the lost Bookie Recovery Delay of a bookie", + Command: "pulsarctl bk auto-recovery get-delay", + } + examples = append(examples, get) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: "lostBookieRecoveryDelay value: (delay)", + } + out = append(out, successOut) + desc.CommandOutput = out + + vc.SetDescription( + "get-delay", + "Get the lost bookie recovery delay of a bookie", + desc.ToString(), + desc.ExampleToString()) + + vc.SetRunFunc(func() error { + return doGetLostBookieRecoveryDelay(vc) + }) +} + +func doGetLostBookieRecoveryDelay(vc *cmdutils.VerbCmd) error { + admin := cmdutils.NewBookieClient() + out, err := admin.AutoRecovery().GetLostBookieRecoveryDelay() + if err == nil { + vc.Command.Println(out) + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/list_under_replicated_ledger.go b/pkg/ctl/bk/autorecovery/list_under_replicated_ledger.go new file mode 100644 index 000000000..1e30f85c7 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/list_under_replicated_ledger.go @@ -0,0 +1,97 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" + + "github.com/spf13/pflag" +) + +func ListUnderReplicatedLedgerCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for listing all the underreplicated ledgers which have been marked " + + "for rereplication." + desc.CommandPermission = "none" + + var examples []pulsar.Example + list := pulsar.Example{ + Desc: "List all the underreplicated ledgers which have been marked for rereplication", + Command: "pulsarctl bk auto-recovery list-under-replicated-ledger", + } + + li := pulsar.Example{ + Desc: "List all the underreplicated ledgers of a bookie which have been marked for rereplication", + Command: "pulsarctl bk auto-recovery list-under-replicated-ledger --include (bookie-ip:bookie-port)", + } + + le := pulsar.Example{ + Desc: "List all the underreplicated ledgers except a bookie which have been marked for rereplication", + Command: "pulsarctl bk auto-recovery list-under-replicated-ledger --exclude (bookie-ip:bookie-port)", + } + examples = append(examples, list, li, le) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: `{ + [ledgerId1, ledgerId2...] +}`, + } + out = append(out, successOut) + desc.CommandOutput = out + + vc.SetDescription( + "list-under-replicated-ledger", + "List all the underreplicated ledgers which have been marked for rereplication", + desc.ToString(), + desc.ExampleToString()) + + var include string + var exclude string + var show bool + + vc.SetRunFunc(func() error { + return doListUnderReplicatedLedger(vc, include, exclude, show) + }) + + vc.FlagSetGroup.InFlagSet("List Under Replicated Ledger", func(set *pflag.FlagSet) { + set.StringVar(&include, "include", "", "show the underreplicated ledger of the bookie") + set.StringVar(&exclude, "exclude", "", "show the underreplicated ledger exclude the bookie") + set.BoolVar(&show, "show", false, "show the ledgers replica list") + }) +} + +func doListUnderReplicatedLedger(vc *cmdutils.VerbCmd, include, exclude string, print bool) error { + admin := cmdutils.NewBookieClient() + var l interface{} + var err error + if print { + l, err = admin.AutoRecovery().PrintListUnderReplicatedLedger(include, exclude) + } else { + l, err = admin.AutoRecovery().ListUnderReplicatedLedger(include, exclude) + } + + if err == nil { + cmdutils.PrintJSON(vc.Command.OutOrStdout(), l) + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/recover_bookie.go b/pkg/ctl/bk/autorecovery/recover_bookie.go new file mode 100644 index 000000000..0d79690b1 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/recover_bookie.go @@ -0,0 +1,79 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" + + "github.com/spf13/pflag" +) + +func RecoverBookieCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for recovering the ledger data of a failed bookie." + desc.CommandPermission = "none" + + var examples []pulsar.Example + rb := pulsar.Example{ + Desc: "Recover the ledger data of a failed bookie", + Command: "pulsarctl bk auto-recovery recover-bookie (bookie-1) (bookie-2)", + } + examples = append(examples, rb) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: "Successfully recover the bookies (bookie-1) (bookie-2)", + } + out = append(out, successOut) + desc.CommandOutput = out + + vc.SetDescription( + "recover-bookie", + "Recover the ledger data of a failed bookie", + desc.ToString(), + desc.ExampleToString()) + + var deleteCookie bool + + vc.SetRunFuncWithMultiNameArgs(func() error { + return doRecoverBookie(vc, deleteCookie) + }, func(args []string) error { + return nil + }) + + vc.FlagSetGroup.InFlagSet("Recover Bookie", func(set *pflag.FlagSet) { + set.BoolVar(&deleteCookie, "delelte-cookie", false, "delete cookie") + }) +} + +func doRecoverBookie(vc *cmdutils.VerbCmd, deleteCookie bool) error { + admin := cmdutils.NewBookieClient() + err := admin.AutoRecovery().RecoverBookie(vc.NameArgs, deleteCookie) + if err == nil { + if deleteCookie { + vc.Command.Printf("Successfully recover the bookies %v and delete the cookie\n", vc.NameArgs) + } else { + vc.Command.Printf("Successfully recover the bookie %v\n", vc.NameArgs) + } + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/set_lost_bookie_recovery_delay.go b/pkg/ctl/bk/autorecovery/set_lost_bookie_recovery_delay.go new file mode 100644 index 000000000..4545a5d43 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/set_lost_bookie_recovery_delay.go @@ -0,0 +1,79 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "strconv" + + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" + + "github.com/pkg/errors" +) + +func SetLostBookieRecoveryDelayCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for setting the lost bookie recovery delay in second." + desc.CommandPermission = "none" + + var examples []pulsar.Example + set := pulsar.Example{ + Desc: "Set the lost Bookie Recovery Delay", + Command: "pulsarctl bk auto-recovery set-delay (delay)", + } + examples = append(examples, set) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: "Successfully set the lost bookie recovery delay to (delay)(second)", + } + + argError := pulsar.Output{ + Desc: "the specified delay time is not specified or the delay time is specified more than one", + Out: "[✖] the specified delay time is not specified or the delay time is specified more than one", + } + out = append(out, successOut, argError) + desc.CommandOutput = out + + vc.SetDescription( + "set-delay", + "Set the lost bookie recovery delay", + desc.ToString(), + desc.ExampleToString()) + + vc.SetRunFuncWithNameArg(func() error { + return doLostBookieRecoveryDelay(vc) + }, "the delay time is not specified or the delay time is specified more than one") +} + +func doLostBookieRecoveryDelay(vc *cmdutils.VerbCmd) error { + delay, err := strconv.Atoi(vc.NameArg) + if err != nil { + return errors.Errorf("invalid delay times %s", vc.NameArg) + } + + admin := cmdutils.NewBookieClient() + err = admin.AutoRecovery().SetLostBookieRecoveryDelay(delay) + if err == nil { + vc.Command.Printf("Successfully set the lost bookie recovery delay to %d(second)\n", delay) + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/trigger_audit.go b/pkg/ctl/bk/autorecovery/trigger_audit.go new file mode 100644 index 000000000..04d02220b --- /dev/null +++ b/pkg/ctl/bk/autorecovery/trigger_audit.go @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" +) + +func TriggerAuditCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for triggering audit by resetting the lostBookieRecoveryDelay." + desc.CommandPermission = "none" + + var examples []pulsar.Example + trigger := pulsar.Example{ + Desc: "Trigger audit by resetting the lostBookieRecoveryDelay", + Command: "pulsarctl bk auto-recovery trigger-audit", + } + examples = append(examples, trigger) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: "Successfully trigger audit by resetting the lostBookieRecoveryDelay", + } + out = append(out, successOut) + desc.CommandOutput = out + + vc.SetDescription( + "trigger-audit", + "Trigger audit by resetting the lostBookieRecoveryDelay", + desc.ToString(), + desc.ExampleToString()) + + vc.SetRunFunc(func() error { + return doTriggerAudit(vc) + }) +} + +func doTriggerAudit(vc *cmdutils.VerbCmd) error { + admin := cmdutils.NewBookieClient() + err := admin.AutoRecovery().TriggerAudit() + if err == nil { + vc.Command.Println("Successfully trigger audit by resetting the lostBookieRecoveryDelay") + } + + return err +} diff --git a/pkg/ctl/bk/autorecovery/who_is_auditor.go b/pkg/ctl/bk/autorecovery/who_is_auditor.go new file mode 100644 index 000000000..f5b05e508 --- /dev/null +++ b/pkg/ctl/bk/autorecovery/who_is_auditor.go @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 autorecovery + +import ( + "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/pulsar" +) + +func WhoIsAuditorCmd(vc *cmdutils.VerbCmd) { + var desc pulsar.LongDescription + desc.CommandUsedFor = "This command is used for getting who is the auditor." + desc.CommandPermission = "none" + + var examples []pulsar.Example + get := pulsar.Example{ + Desc: "Get who is the auditor", + Command: "pulsarctl bk auto-recovery who-is-auditor", + } + examples = append(examples, get) + desc.CommandExamples = examples + + var out []pulsar.Output + successOut := pulsar.Output{ + Desc: "normal output", + Out: `{ + "Auditor": "hostname/hostAddress:Port" +}`, + } + out = append(out, successOut) + desc.CommandOutput = out + + vc.SetDescription( + "who-is-auditor", + "Get who is the auditor", + desc.ToString(), + desc.ExampleToString()) + + vc.SetRunFunc(func() error { + return doWhoIsAuditor(vc) + }) +} + +func doWhoIsAuditor(vc *cmdutils.VerbCmd) error { + admin := cmdutils.NewBookieClient() + auditor, err := admin.AutoRecovery().WhoIsAuditor() + if err == nil { + cmdutils.PrintJSON(vc.Command.OutOrStdout(), auditor) + } + + return err +} diff --git a/pkg/ctl/bk/bk.go b/pkg/ctl/bk/bk.go index 976551ff0..69c01f650 100644 --- a/pkg/ctl/bk/bk.go +++ b/pkg/ctl/bk/bk.go @@ -19,6 +19,7 @@ package bk import ( "github.com/streamnative/pulsarctl/pkg/cmdutils" + "github.com/streamnative/pulsarctl/pkg/ctl/bk/autorecovery" "github.com/streamnative/pulsarctl/pkg/ctl/bk/ledger" "github.com/spf13/cobra" @@ -33,6 +34,7 @@ func Command(flagGrouping *cmdutils.FlagGrouping) *cobra.Command { ) resourceCmd.AddCommand(ledger.Command(flagGrouping)) + resourceCmd.AddCommand(autorecovery.Commands(flagGrouping)) return resourceCmd } diff --git a/pkg/pulsar/admin.go b/pkg/pulsar/admin.go index 186db971d..cc00cf31c 100644 --- a/pkg/pulsar/admin.go +++ b/pkg/pulsar/admin.go @@ -90,6 +90,7 @@ type Client interface { // BookieClient provides a client to the BookKeeper Restful API type BookieClient interface { Ledger() Ledger + AutoRecovery() AutoRecovery } type client struct { diff --git a/pkg/pulsar/autorecovery.go b/pkg/pulsar/autorecovery.go new file mode 100644 index 000000000..92a3849a0 --- /dev/null +++ b/pkg/pulsar/autorecovery.go @@ -0,0 +1,124 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 pulsar + +type AutoRecovery interface { + // RecoverBookie is used to recovering ledger data for a failed bookie + RecoverBookie([]string, bool) error + + // ListUnderReplicatedLedger is used to listing all the underreplicated ledgers + // which have been marked for rereplication + ListUnderReplicatedLedger(string, string) ([]int64, error) + + // PrintListUnderReplicatedLedger is used to printing the replicate list of the replicated ledgers + PrintListUnderReplicatedLedger(string, string) (map[int64][]string, error) + + // WhoIsAuditor is used to getting which bookie is the auditor + WhoIsAuditor() (map[string]string, error) + + // TriggerAudit is used to triggering audit by resetting the lostBookieRecoveryDelay + TriggerAudit() error + + // GetLostBookieRecoveryDelay is used to getting the lostBookieRecoveryDelay of a bookie + GetLostBookieRecoveryDelay() (string, error) + + // SetLostBookieRecoveryDelay is used to setting the lastBookieRecoverDelay of a bookie + SetLostBookieRecoveryDelay(int) error + + // Decommission is used to decommissioning a bookie + Decommission(string) error +} + +type autoRecovery struct { + client *bookieClient + request *client + basePath string + params map[string]string +} + +func (c *bookieClient) AutoRecovery() AutoRecovery { + return &autoRecovery{ + client: c, + request: c.client, + basePath: "/autorecovery", + params: make(map[string]string), + } +} + +func (a *autoRecovery) RecoverBookie(src []string, deleteCookie bool) error { + endpoint := a.client.bookieEndpoint(a.basePath, "/bookie") + request := RecoveryRequest{ + BookieSrc: src, + DeleteCookie: deleteCookie, + } + return a.request.put(endpoint, &request) +} + +func (a *autoRecovery) ListUnderReplicatedLedger(missingReplica, excludingMissingReplica string) ([]int64, error) { + endpoint := a.client.bookieEndpoint(a.basePath, "/list_under_replicated_ledger") + a.params["missingreplica"] = missingReplica + a.params["excludingmissingreplica"] = excludingMissingReplica + resp := make([]int64, 0) + _, err := a.request.getWithQueryParams(endpoint, &resp, a.params, true) + return resp, err +} + +func (a *autoRecovery) PrintListUnderReplicatedLedger(missingReplica, + excludingMissingReplica string) (map[int64][]string, error) { + + endpoint := a.client.bookieEndpoint(a.basePath, "/list_under_replicated_ledger") + a.params["missingreplica"] = missingReplica + a.params["excludingmissingreplica"] = excludingMissingReplica + a.params["printmissingreplica"] = "true" + resp := make(map[int64][]string) + _, err := a.request.getWithQueryParams(endpoint, &resp, a.params, true) + return resp, err +} + +func (a *autoRecovery) WhoIsAuditor() (map[string]string, error) { + endpoint := a.client.bookieEndpoint(a.basePath, "/who_is_auditor") + resp := make(map[string]string) + return resp, a.request.get(endpoint, &resp) +} + +func (a *autoRecovery) TriggerAudit() error { + endpoint := a.client.bookieEndpoint(a.basePath, "/trigger_audit") + return a.request.put(endpoint, nil) +} + +func (a *autoRecovery) GetLostBookieRecoveryDelay() (string, error) { + endpoint := a.client.bookieEndpoint(a.basePath, "/lost_bookie_recovery_delay") + resp, err := a.request.getWithQueryParams(endpoint, nil, nil, false) + return string(resp), err +} + +func (a *autoRecovery) SetLostBookieRecoveryDelay(delay int) error { + endpoint := a.client.bookieEndpoint(a.basePath, "/lost_bookie_recovery_delay") + req := LostBookieRecoverDelayRequest{ + DelaySeconds: delay, + } + return a.request.put(endpoint, &req) +} + +func (a *autoRecovery) Decommission(src string) error { + endpoint := a.client.bookieEndpoint(a.basePath, "/decommission") + req := DecommissionRequest{ + BookieSrc: src, + } + return a.request.put(endpoint, &req) +} diff --git a/pkg/pulsar/bookie_data.go b/pkg/pulsar/bookie_data.go index c9cab8b9a..4c98c992c 100644 --- a/pkg/pulsar/bookie_data.go +++ b/pkg/pulsar/bookie_data.go @@ -40,3 +40,16 @@ type LedgerMetadata struct { Password []byte `json:"password"` CustomMetadata map[string][]byte `json:"customMetadata"` } + +type RecoveryRequest struct { + BookieSrc []string `json:"bookie_src"` + DeleteCookie bool `json:"delete_cookie"` +} + +type LostBookieRecoverDelayRequest struct { + DelaySeconds int `json:"delay_seconds"` +} + +type DecommissionRequest struct { + BookieSrc string `json:"bookie_src"` +}