Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cluster: need support clean up audit log #1644

Merged
merged 14 commits into from
Dec 2, 2021
6 changes: 4 additions & 2 deletions components/cluster/command/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ You can retain some nodes and roles data when cleanup the cluster, eg:
$ tiup cluster clean <cluster-name> --all
$ tiup cluster clean <cluster-name> --log
$ tiup cluster clean <cluster-name> --data
$ tiup cluster clean <cluster-name> --audit-log
$ tiup cluster clean <cluster-name> --all --ignore-role prometheus
$ tiup cluster clean <cluster-name> --all --ignore-node 172.16.13.11:9000
$ tiup cluster clean <cluster-name> --all --ignore-node 172.16.13.12`,
Expand All @@ -50,7 +51,7 @@ You can retain some nodes and roles data when cleanup the cluster, eg:
cleanOpt.CleanupLog = true
}

if !(cleanOpt.CleanupData || cleanOpt.CleanupLog) {
if !(cleanOpt.CleanupData || cleanOpt.CleanupLog || cleanOpt.CleanupAuditLog) {
return cmd.Help()
}

Expand All @@ -62,7 +63,8 @@ You can retain some nodes and roles data when cleanup the cluster, eg:
cmd.Flags().StringArrayVar(&cleanOpt.RetainDataRoles, "ignore-role", nil, "Specify the roles whose data will be retained")
cmd.Flags().BoolVar(&cleanOpt.CleanupData, "data", false, "Cleanup data")
cmd.Flags().BoolVar(&cleanOpt.CleanupLog, "log", false, "Cleanup log")
cmd.Flags().BoolVar(&cleanALl, "all", false, "Cleanup both log and data")
cmd.Flags().BoolVar(&cleanOpt.CleanupAuditLog, "audit-log", false, "Cleanup TiDB-server audit log")
cmd.Flags().BoolVar(&cleanALl, "all", false, "Cleanup both log and data (not include audit log)")

return cmd
}
101 changes: 68 additions & 33 deletions pkg/cluster/manager/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,42 +58,16 @@ func (m *Manager) CleanCluster(name string, gOpt operator.Options, cleanOpt oper

// calculate file paths to be deleted before the prompt
delFileMap := getCleanupFiles(topo,
cleanOpt.CleanupData, cleanOpt.CleanupLog, false, cleanOpt.RetainDataRoles, cleanOpt.RetainDataNodes)
cleanOpt.CleanupData, cleanOpt.CleanupLog, false, cleanOpt.CleanupAuditLog, cleanOpt.RetainDataRoles, cleanOpt.RetainDataNodes)

if !skipConfirm {
target := ""
switch {
case cleanOpt.CleanupData && cleanOpt.CleanupLog:
target = "data and log"
case cleanOpt.CleanupData:
target = "data"
case cleanOpt.CleanupLog:
target = "log"
}

// build file list string
delFileList := ""
for host, fileList := range delFileMap {
delFileList += fmt.Sprintf("\n%s:", color.CyanString(host))
for _, dfp := range fileList.Slice() {
delFileList += fmt.Sprintf("\n %s", dfp)
}
}

if err := tui.PromptForConfirmOrAbortError(
"This operation will stop %s %s cluster %s and clean its' %s.\nNodes will be ignored: %s\nRoles will be ignored: %s\nFiles to be deleted are: %s\nDo you want to continue? [y/N]:",
m.sysName,
color.HiYellowString(base.Version),
color.HiYellowString(name),
target,
cleanOpt.RetainDataNodes,
cleanOpt.RetainDataRoles,
delFileList); err != nil {
if err := cleanupConfirm(name, m.sysName, base.Version, cleanOpt, delFileMap); err != nil {
return err
}
log.Infof("Cleanup cluster...")
}

log.Infof("Cleanup cluster...")

b, err := m.sshTaskBuilder(name, topo, base.User, gOpt)
if err != nil {
return err
Expand All @@ -115,27 +89,76 @@ func (m *Manager) CleanCluster(name string, gOpt operator.Options, cleanOpt oper
return perrs.Trace(err)
}

log.Infof("Cleanup cluster `%s` successfully", name)
log.Infof("Cleanup%s in cluster `%s` successfully", cleanTarget(cleanOpt), name)
return nil
}

// checkConfirm
func cleanupConfirm(clusterName, sysName, version string, cleanOpt operator.Options, delFileMap map[string]set.StringSet) error {
log.Warnf("The clean operation will %s %s %s cluster `%s`",
color.HiYellowString("stop"), sysName, version, color.HiYellowString(clusterName))
if err := tui.PromptForConfirmOrAbortError("Do you want to continue? [y/N]:"); err != nil {
return err
}

// build file list string
delFileList := ""
for host, fileList := range delFileMap {
// target host has no files to delete
if len(fileList) == 0 {
continue
}

delFileList += fmt.Sprintf("\n%s:", color.CyanString(host))
for _, dfp := range fileList.Slice() {
delFileList += fmt.Sprintf("\n %s", dfp)
}
}

log.Warnf("Clean the clutser %s's%s.\nNodes will be ignored: %s\nRoles will be ignored: %s\nFiles to be deleted are: %s",
color.HiYellowString(clusterName), cleanTarget(cleanOpt), cleanOpt.RetainDataNodes,
cleanOpt.RetainDataRoles,
delFileList)
return tui.PromptForConfirmOrAbortError("Do you want to continue? [y/N]:")
}

func cleanTarget(cleanOpt operator.Options) string {
target := ""

if cleanOpt.CleanupData {
target += " data"
}

if cleanOpt.CleanupLog {
target += (" log")
}

if cleanOpt.CleanupAuditLog {
target += (" audit-log")
}

return color.HiYellowString(target)
}

// cleanupFiles record the file that needs to be cleaned up
type cleanupFiles struct {
cleanupData bool // whether to clean up the data
cleanupLog bool // whether to clean up the log
cleanupTLS bool // whether to clean up the tls files
cleanupAuditLog bool // whether to clean up the tidb server audit log
retainDataRoles []string // roles that don't clean up
retainDataNodes []string // roles that don't clean up
delFileMap map[string]set.StringSet
}

// getCleanupFiles get the files that need to be deleted
func getCleanupFiles(topo spec.Topology,
cleanupData, cleanupLog, cleanupTLS bool, retainDataRoles, retainDataNodes []string) map[string]set.StringSet {
cleanupData, cleanupLog, cleanupTLS, cleanupAuditLog bool, retainDataRoles, retainDataNodes []string) map[string]set.StringSet {
c := &cleanupFiles{
cleanupData: cleanupData,
cleanupLog: cleanupLog,
cleanupTLS: cleanupTLS,
cleanupAuditLog: cleanupAuditLog,
retainDataRoles: retainDataRoles,
retainDataNodes: retainDataNodes,
delFileMap: make(map[string]set.StringSet),
Expand Down Expand Up @@ -187,7 +210,19 @@ func (c *cleanupFiles) instanceCleanupFiles(topo spec.Topology) {

if c.cleanupLog && len(ins.LogDir()) > 0 {
for _, logDir := range strings.Split(ins.LogDir(), ",") {
logPaths.Insert(path.Join(logDir, "*.log"))
// need to judge the audit log of tidb server
if ins.ComponentName() == spec.ComponentTiDB {
logPaths.Insert(path.Join(logDir, "tidb?[!audit]*.log"))
logPaths.Insert(path.Join(logDir, "tidb.log")) // maybe no need deleted
} else {
logPaths.Insert(path.Join(logDir, "*.log"))
}
}
}

if c.cleanupAuditLog && ins.ComponentName() == spec.ComponentTiDB {
for _, logDir := range strings.Split(ins.LogDir(), ",") {
logPaths.Insert(path.Join(logDir, "tidb-audit*.log"))
}
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/cluster/operation/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ type Options struct {
SSHProxyTimeout uint64 // timeout in seconds when connecting the proxy host

// What type of things should we cleanup in clean command
CleanupData bool // should we cleanup data
CleanupLog bool // should we clenaup log
CleanupData bool // should we cleanup data
CleanupLog bool // should we clenaup log
CleanupAuditLog bool // should we clenaup tidb server auit log

// Some data will be retained when destroying instances
RetainDataRoles []string
Expand Down