diff --git a/apis/monitoring/v1alpha1/crd.go b/apis/monitoring/v1alpha1/crd.go new file mode 100644 index 000000000..48ab653bb --- /dev/null +++ b/apis/monitoring/v1alpha1/crd.go @@ -0,0 +1,69 @@ +package v1alpha1 + +import ( + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a ClusterAlert) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: ResourceTypeClusterAlert + "." + SchemeGroupVersion.Group, + Labels: map[string]string{ + "app": "searchlight", + }, + }, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: SchemeGroupVersion.Group, + Version: SchemeGroupVersion.Version, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: ResourceTypeClusterAlert, + Kind: ResourceKindClusterAlert, + ShortNames: []string{"ca"}, + }, + }, + } +} + +func (a NodeAlert) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: ResourceTypeNodeAlert + "." + SchemeGroupVersion.Group, + Labels: map[string]string{ + "app": "searchlight", + }, + }, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: SchemeGroupVersion.Group, + Version: SchemeGroupVersion.Version, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: ResourceTypeNodeAlert, + Kind: ResourceKindNodeAlert, + ShortNames: []string{"noa"}, + }, + }, + } +} + +func (a PodAlert) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return &apiextensions.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: ResourceTypePodAlert + "." + SchemeGroupVersion.Group, + Labels: map[string]string{ + "app": "searchlight", + }, + }, + Spec: apiextensions.CustomResourceDefinitionSpec{ + Group: SchemeGroupVersion.Group, + Version: SchemeGroupVersion.Version, + Scope: apiextensions.NamespaceScoped, + Names: apiextensions.CustomResourceDefinitionNames{ + Plural: ResourceTypePodAlert, + Kind: ResourceKindPodAlert, + ShortNames: []string{"poa"}, + }, + }, + } +} diff --git a/glide.lock b/glide.lock index 73589738b..f71820af5 100644 --- a/glide.lock +++ b/glide.lock @@ -1,10 +1,10 @@ hash: d4e0fa4fe10ae0446a7bd192707a80af444bed38241dae17ed724523aa973c88 -updated: 2017-10-09T09:20:15.826749492-07:00 +updated: 2017-10-14T10:07:10.812045545-07:00 imports: - name: github.com/appscode/envconfig version: 183bbe643a2875eaa69c85627ac6b25813983203 - name: github.com/appscode/go - version: b2ff0c0b3293cc848d781d1efb57ffda5fa0226e + version: f719fe83ed5dd094e07c4456dc68e1227131d581 subpackages: - context - crypto/rand @@ -109,7 +109,7 @@ imports: - name: github.com/go-macaron/toolbox version: 6766b8f16d1b135b250f09ba4dc4e24ab65b1107 - name: github.com/go-ole/go-ole - version: 2ca6d5950a178eae0d0b51e0993facc42f3cefe2 + version: 2ecd927eaf828c4fc088fae349b28eed1480ff56 subpackages: - oleutil - name: github.com/go-openapi/analysis @@ -208,7 +208,7 @@ imports: - name: github.com/nlopes/slack version: 5cde21b8b96a43fc3435a1f514123d14fd7eabdc - name: github.com/olekukonko/tablewriter - version: a7a4c189eb47ed33ce7b35f2880070a0c82a67d4 + version: cca8bbc0798408af109aaaa239cbd2634846b340 - name: github.com/onsi/gomega version: c893efa28eb45626cdaa76c9f653b62488858837 subpackages: @@ -224,7 +224,7 @@ imports: - matchers/support/goraph/util - types - name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d + version: a22138067af1c4942683050411a841ade67fe1eb - name: github.com/prometheus/client_golang version: c5b7fccd204277076155f10851dad72b76a49317 subpackages: @@ -266,7 +266,7 @@ imports: - name: github.com/shurcooL/sanitized_anchor_name version: 10ef21a441db47d8b13ebcc5fd2310f636973c77 - name: github.com/spf13/cobra - version: 50204810fdb5010baae72e4f41b303689cbdcc9f + version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b subpackages: - doc - name: github.com/spf13/pflag diff --git a/pkg/operator/controller.go b/pkg/operator/controller.go index f7f23d1d1..6f7b74eeb 100644 --- a/pkg/operator/controller.go +++ b/pkg/operator/controller.go @@ -6,14 +6,14 @@ import ( "time" "github.com/appscode/go/log" + "github.com/appscode/kutil" "github.com/appscode/pat" - aci "github.com/appscode/searchlight/apis/monitoring/v1alpha1" api "github.com/appscode/searchlight/apis/monitoring/v1alpha1" cs "github.com/appscode/searchlight/client/typed/monitoring/v1alpha1" "github.com/appscode/searchlight/pkg/eventer" "github.com/appscode/searchlight/pkg/icinga" "github.com/prometheus/client_golang/prometheus/promhttp" - extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -33,10 +33,10 @@ type Options struct { } type Operator struct { - KubeClient clientset.Interface - ApiExtKubeClient apiextensionsclient.Interface - ExtClient cs.MonitoringV1alpha1Interface - IcingaClient *icinga.Client // TODO: init + KubeClient clientset.Interface + CRDClient apiextensionsclient.Interface + ExtClient cs.MonitoringV1alpha1Interface + IcingaClient *icinga.Client // TODO: init Opt Options clusterHost *icinga.ClusterHost @@ -45,63 +45,40 @@ type Operator struct { recorder record.EventRecorder } -func New(kubeClient clientset.Interface, apiExtKubeClient apiextensionsclient.Interface, extClient cs.MonitoringV1alpha1Interface, icingaClient *icinga.Client, opt Options) *Operator { +func New(kubeClient clientset.Interface, crdClient apiextensionsclient.Interface, extClient cs.MonitoringV1alpha1Interface, icingaClient *icinga.Client, opt Options) *Operator { return &Operator{ - KubeClient: kubeClient, - ApiExtKubeClient: apiExtKubeClient, - ExtClient: extClient, - IcingaClient: icingaClient, - Opt: opt, - clusterHost: icinga.NewClusterHost(kubeClient, extClient, icingaClient), - nodeHost: icinga.NewNodeHost(kubeClient, extClient, icingaClient), - podHost: icinga.NewPodHost(kubeClient, extClient, icingaClient), - recorder: eventer.NewEventRecorder(kubeClient, "Searchlight operator"), + KubeClient: kubeClient, + CRDClient: crdClient, + ExtClient: extClient, + IcingaClient: icingaClient, + Opt: opt, + clusterHost: icinga.NewClusterHost(kubeClient, extClient, icingaClient), + nodeHost: icinga.NewNodeHost(kubeClient, extClient, icingaClient), + podHost: icinga.NewPodHost(kubeClient, extClient, icingaClient), + recorder: eventer.NewEventRecorder(kubeClient, "Searchlight operator"), } } func (op *Operator) Setup() error { - log.Infoln("Ensuring CustomResourceDefinition") - - if err := op.ensureCustomResourceDefinition(aci.ResourceKindClusterAlert, aci.ResourceTypeClusterAlert, "ca"); err != nil { - return err - } - if err := op.ensureCustomResourceDefinition(aci.ResourceKindNodeAlert, aci.ResourceTypeNodeAlert, "noa"); err != nil { - return err - } - if err := op.ensureCustomResourceDefinition(aci.ResourceKindPodAlert, aci.ResourceTypePodAlert, "poa"); err != nil { - return err - } - return nil + return op.ensureCustomResourceDefinitions() } -func (op *Operator) ensureCustomResourceDefinition(resourceKind, resourceType, shortName string) error { - name := resourceType + "." + api.SchemeGroupVersion.Group - _, err := op.ApiExtKubeClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) - if !kerr.IsNotFound(err) { - return err +func (op *Operator) ensureCustomResourceDefinitions() error { + crds := []*apiextensions.CustomResourceDefinition{ + api.ClusterAlert{}.CustomResourceDefinition(), + api.NodeAlert{}.CustomResourceDefinition(), + api.PodAlert{}.CustomResourceDefinition(), } - - crd := &extensionsobj.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "app": "searchlight", - }, - }, - Spec: extensionsobj.CustomResourceDefinitionSpec{ - Group: api.SchemeGroupVersion.Group, - Version: api.SchemeGroupVersion.Version, - Scope: extensionsobj.NamespaceScoped, - Names: extensionsobj.CustomResourceDefinitionNames{ - Plural: resourceType, - Kind: resourceKind, - ShortNames: []string{shortName}, - }, - }, + for _, crd := range crds { + _, err := op.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}) + if kerr.IsNotFound(err) { + _, err = op.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd) + if err != nil { + return err + } + } } - - _, err = op.ApiExtKubeClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd) - return err + return kutil.WaitForCRDReady(op.KubeClient.CoreV1().RESTClient(), crds) } func (op *Operator) RunAPIServer() { diff --git a/vendor/github.com/go-ole/go-ole/LICENSE b/vendor/github.com/go-ole/go-ole/LICENSE new file mode 100644 index 000000000..623ec06f9 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2013-2017 Yasuhiro Matsumoto, + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/olekukonko/tablewriter/table.go b/vendor/github.com/olekukonko/tablewriter/table.go index 4d0725120..d2db51909 100644 --- a/vendor/github.com/olekukonko/tablewriter/table.go +++ b/vendor/github.com/olekukonko/tablewriter/table.go @@ -9,7 +9,6 @@ package tablewriter import ( - "bytes" "fmt" "io" "regexp" @@ -21,120 +20,87 @@ const ( ) const ( - CENTER = "+" - ROW = "-" - COLUMN = "|" - SPACE = " " - NEWLINE = "\n" + CENTRE = "+" + ROW = "-" + COLUMN = "|" + SPACE = " " ) const ( ALIGN_DEFAULT = iota - ALIGN_CENTER + ALIGN_CENTRE ALIGN_RIGHT ALIGN_LEFT ) var ( - decimal = regexp.MustCompile(`^-*\d*\.?\d*$`) - percent = regexp.MustCompile(`^-*\d*\.?\d*$%$`) + decimal = regexp.MustCompile(`^\d*\.?\d*$`) + percent = regexp.MustCompile(`^\d*\.?\d*$%$`) ) -type Border struct { - Left bool - Right bool - Top bool - Bottom bool -} - type Table struct { - out io.Writer - rows [][]string - lines [][][]string - cs map[int]int - rs map[int]int - headers []string - footers []string - caption bool - captionText string - autoFmt bool - autoWrap bool - mW int - pCenter string - pRow string - pColumn string - tColumn int - tRow int - hAlign int - fAlign int - align int - newLine string - rowLine bool - autoMergeCells bool - hdrLine bool - borders Border - colSize int - headerParams []string - columnsParams []string - footerParams []string - columnsAlign []int + out io.Writer + rows [][]string + lines [][][]string + cs map[int]int + rs map[int]int + headers []string + footers []string + autoFmt bool + autoWrap bool + mW int + pCenter string + pRow string + pColumn string + tColumn int + tRow int + align int + rowLine bool + hdrLine bool + border bool + colSize int } // Start New Table // Take io.Writer Directly func NewWriter(writer io.Writer) *Table { t := &Table{ - out: writer, - rows: [][]string{}, - lines: [][][]string{}, - cs: make(map[int]int), - rs: make(map[int]int), - headers: []string{}, - footers: []string{}, - caption: false, - captionText: "Table caption.", - autoFmt: true, - autoWrap: true, - mW: MAX_ROW_WIDTH, - pCenter: CENTER, - pRow: ROW, - pColumn: COLUMN, - tColumn: -1, - tRow: -1, - hAlign: ALIGN_DEFAULT, - fAlign: ALIGN_DEFAULT, - align: ALIGN_DEFAULT, - newLine: NEWLINE, - rowLine: false, - hdrLine: true, - borders: Border{Left: true, Right: true, Bottom: true, Top: true}, - colSize: -1, - headerParams: []string{}, - columnsParams: []string{}, - footerParams: []string{}, - columnsAlign: []int{}} + out: writer, + rows: [][]string{}, + lines: [][][]string{}, + cs: make(map[int]int), + rs: make(map[int]int), + headers: []string{}, + footers: []string{}, + autoFmt: true, + autoWrap: true, + mW: MAX_ROW_WIDTH, + pCenter: CENTRE, + pRow: ROW, + pColumn: COLUMN, + tColumn: -1, + tRow: -1, + align: ALIGN_DEFAULT, + rowLine: false, + hdrLine: true, + border: true, + colSize: -1} return t } // Render table output -func (t *Table) Render() { - if t.borders.Top { +func (t Table) Render() { + if t.border { t.printLine(true) } t.printHeading() - if t.autoMergeCells { - t.printRowsMergeCells() - } else { - t.printRows() - } - if !t.rowLine && t.borders.Bottom { + t.printRows() + + if !t.rowLine && t.border { t.printLine(true) } t.printFooter() - if t.caption { - t.printCaption() - } } // Set table header @@ -155,14 +121,6 @@ func (t *Table) SetFooter(keys []string) { } } -// Set table Caption -func (t *Table) SetCaption(caption bool, captionText ...string) { - t.caption = caption - if len(captionText) == 1 { - t.captionText = captionText[0] - } -} - // Turn header autoformatting on/off. Default is on (true). func (t *Table) SetAutoFormatHeaders(auto bool) { t.autoFmt = auto @@ -178,11 +136,6 @@ func (t *Table) SetColWidth(width int) { t.mW = width } -// Set the minimal width for a column -func (t *Table) SetColMinWidth(column int, width int) { - t.cs[column] = width -} - // Set the Column Separator func (t *Table) SetColumnSeparator(sep string) { t.pColumn = sep @@ -198,42 +151,11 @@ func (t *Table) SetCenterSeparator(sep string) { t.pCenter = sep } -// Set Header Alignment -func (t *Table) SetHeaderAlignment(hAlign int) { - t.hAlign = hAlign -} - -// Set Footer Alignment -func (t *Table) SetFooterAlignment(fAlign int) { - t.fAlign = fAlign -} - // Set Table Alignment func (t *Table) SetAlignment(align int) { t.align = align } -func (t *Table) SetColumnAlignment(keys []int) { - for _, v := range keys { - switch v { - case ALIGN_CENTER: - break - case ALIGN_LEFT: - break - case ALIGN_RIGHT: - break - default: - v = ALIGN_DEFAULT - } - t.columnsAlign = append(t.columnsAlign, v) - } -} - -// Set New Line -func (t *Table) SetNewLine(nl string) { - t.newLine = nl -} - // Set Header Line // This would enable / disable a line after the header func (t *Table) SetHeaderLine(line bool) { @@ -246,20 +168,10 @@ func (t *Table) SetRowLine(line bool) { t.rowLine = line } -// Set Auto Merge Cells -// This would enable / disable the merge of cells with identical values -func (t *Table) SetAutoMergeCells(auto bool) { - t.autoMergeCells = auto -} - // Set Table Border // This would enable / disable line around the table func (t *Table) SetBorder(border bool) { - t.SetBorders(Border{border, border, border, border}) -} - -func (t *Table) SetBorders(border Border) { - t.borders = border + t.border = border } // Append row to table @@ -292,18 +204,8 @@ func (t *Table) AppendBulk(rows [][]string) { } } -// Clear rows -func (t *Table) ClearRows() { - t.lines = [][][]string{} -} - -// Clear footer -func (t *Table) ClearFooter() { - t.footers = []string{} -} - // Print line based on row width -func (t *Table) printLine(nl bool) { +func (t Table) printLine(nl bool) { fmt.Fprint(t.out, t.pCenter) for i := 0; i < len(t.cs); i++ { v := t.cs[i] @@ -314,49 +216,12 @@ func (t *Table) printLine(nl bool) { t.pCenter) } if nl { - fmt.Fprint(t.out, t.newLine) + fmt.Fprintln(t.out) } } -// Print line based on row width with our without cell separator -func (t *Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) { - fmt.Fprint(t.out, t.pCenter) - for i := 0; i < len(t.cs); i++ { - v := t.cs[i] - if i > len(displayCellSeparator) || displayCellSeparator[i] { - // Display the cell separator - fmt.Fprintf(t.out, "%s%s%s%s", - t.pRow, - strings.Repeat(string(t.pRow), v), - t.pRow, - t.pCenter) - } else { - // Don't display the cell separator for this cell - fmt.Fprintf(t.out, "%s%s", - strings.Repeat(" ", v+2), - t.pCenter) - } - } - if nl { - fmt.Fprint(t.out, t.newLine) - } -} - -// Return the PadRight function if align is left, PadLeft if align is right, -// and Pad by default -func pad(align int) func(string, string, int) string { - padFunc := Pad - switch align { - case ALIGN_LEFT: - padFunc = PadRight - case ALIGN_RIGHT: - padFunc = PadLeft - } - return padFunc -} - // Print heading information -func (t *Table) printHeading() { +func (t Table) printHeading() { // Check if headers is available if len(t.headers) < 1 { return @@ -364,77 +229,48 @@ func (t *Table) printHeading() { // Check if border is set // Replace with space if not set - fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) + fmt.Fprint(t.out, ConditionString(t.border, t.pColumn, SPACE)) // Identify last column end := len(t.cs) - 1 - // Get pad function - padFunc := pad(t.hAlign) - - // Checking for ANSI escape sequences for header - is_esc_seq := false - if len(t.headerParams) > 0 { - is_esc_seq = true - } - // Print Heading column for i := 0; i <= end; i++ { v := t.cs[i] - h := "" - if i < len(t.headers) { - h = t.headers[i] - } + h := t.headers[i] if t.autoFmt { h = Title(h) } - pad := ConditionString((i == end && !t.borders.Left), SPACE, t.pColumn) - - if is_esc_seq { - fmt.Fprintf(t.out, " %s %s", - format(padFunc(h, SPACE, v), - t.headerParams[i]), pad) - } else { - fmt.Fprintf(t.out, " %s %s", - padFunc(h, SPACE, v), - pad) - } - + pad := ConditionString((i == end && !t.border), SPACE, t.pColumn) + fmt.Fprintf(t.out, " %s %s", + Pad(h, SPACE, v), + pad) } // Next line - fmt.Fprint(t.out, t.newLine) + fmt.Fprintln(t.out) if t.hdrLine { t.printLine(true) } } // Print heading information -func (t *Table) printFooter() { +func (t Table) printFooter() { // Check if headers is available if len(t.footers) < 1 { return } // Only print line if border is not set - if !t.borders.Bottom { + if !t.border { t.printLine(true) } // Check if border is set // Replace with space if not set - fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE)) + fmt.Fprint(t.out, ConditionString(t.border, t.pColumn, SPACE)) // Identify last column end := len(t.cs) - 1 - // Get pad function - padFunc := pad(t.fAlign) - - // Checking for ANSI escape sequences for header - is_esc_seq := false - if len(t.footerParams) > 0 { - is_esc_seq = true - } - // Print Heading column for i := 0; i <= end; i++ { v := t.cs[i] @@ -442,28 +278,17 @@ func (t *Table) printFooter() { if t.autoFmt { f = Title(f) } - pad := ConditionString((i == end && !t.borders.Top), SPACE, t.pColumn) + pad := ConditionString((i == end && !t.border), SPACE, t.pColumn) if len(t.footers[i]) == 0 { pad = SPACE } - - if is_esc_seq { - fmt.Fprintf(t.out, " %s %s", - format(padFunc(f, SPACE, v), - t.footerParams[i]), pad) - } else { - fmt.Fprintf(t.out, " %s %s", - padFunc(f, SPACE, v), - pad) - } - - //fmt.Fprintf(t.out, " %s %s", - // padFunc(f, SPACE, v), - // pad) + fmt.Fprintf(t.out, " %s %s", + Pad(f, SPACE, v), + pad) } // Next line - fmt.Fprint(t.out, t.newLine) + fmt.Fprintln(t.out) //t.printLine(true) hasPrinted := false @@ -479,7 +304,7 @@ func (t *Table) printFooter() { } // Set center to be space if length is 0 - if length == 0 && !t.borders.Right { + if length == 0 && !t.border { center = SPACE } @@ -493,7 +318,7 @@ func (t *Table) printFooter() { pad = SPACE } // Ignore left space of it has printed before - if hasPrinted || t.borders.Left { + if hasPrinted || t.border { pad = t.pRow center = t.pCenter } @@ -514,52 +339,21 @@ func (t *Table) printFooter() { } - fmt.Fprint(t.out, t.newLine) -} + fmt.Fprintln(t.out) -// Print caption text -func (t Table) printCaption() { - width := t.getTableWidth() - paragraph, _ := WrapString(t.captionText, width) - for linecount := 0; linecount < len(paragraph); linecount++ { - fmt.Fprintln(t.out, paragraph[linecount]) - } -} - -// Calculate the total number of characters in a row -func (t Table) getTableWidth() int { - var chars int - for _, v := range t.cs { - chars += v - } - - // Add chars, spaces, seperators to calculate the total width of the table. - // ncols := t.colSize - // spaces := ncols * 2 - // seps := ncols + 1 - - return (chars + (3 * t.colSize) + 2) } func (t Table) printRows() { for i, lines := range t.lines { t.printRow(lines, i) } -} -func (t *Table) fillAlignment(num int) { - if len(t.columnsAlign) < num { - t.columnsAlign = make([]int, num) - for i := range t.columnsAlign { - t.columnsAlign[i] = t.align - } - } } // Print Row Information // Adjust column alignment based on type -func (t *Table) printRow(columns [][]string, colKey int) { +func (t Table) printRow(columns [][]string, colKey int) { // Get Maximum Height max := t.rs[colKey] total := len(columns) @@ -576,13 +370,6 @@ func (t *Table) printRow(columns [][]string, colKey int) { // pads := []int{} pads := []int{} - // Checking for ANSI escape sequences for columns - is_esc_seq := false - if len(t.columnsParams) > 0 { - is_esc_seq = true - } - t.fillAlignment(total) - for i, line := range columns { length := len(line) pad := max - length @@ -596,20 +383,15 @@ func (t *Table) printRow(columns [][]string, colKey int) { for y := 0; y < total; y++ { // Check if border is set - fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) + fmt.Fprint(t.out, ConditionString((!t.border && y == 0), SPACE, t.pColumn)) fmt.Fprintf(t.out, SPACE) str := columns[y][x] - // Embedding escape sequence with column value - if is_esc_seq { - str = format(str, t.columnsParams[y]) - } - // This would print alignment // Default alignment would use multiple configuration - switch t.columnsAlign[y] { - case ALIGN_CENTER: // + switch t.align { + case ALIGN_CENTRE: // fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y])) case ALIGN_RIGHT: fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y])) @@ -634,112 +416,14 @@ func (t *Table) printRow(columns [][]string, colKey int) { } // Check if border is set // Replace with space if not set - fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) - fmt.Fprint(t.out, t.newLine) - } - - if t.rowLine { - t.printLine(true) + fmt.Fprint(t.out, ConditionString(t.border, t.pColumn, SPACE)) + fmt.Fprintln(t.out) } -} -// Print the rows of the table and merge the cells that are identical -func (t *Table) printRowsMergeCells() { - var previousLine []string - var displayCellBorder []bool - var tmpWriter bytes.Buffer - for i, lines := range t.lines { - // We store the display of the current line in a tmp writer, as we need to know which border needs to be print above - previousLine, displayCellBorder = t.printRowMergeCells(&tmpWriter, lines, i, previousLine) - if i > 0 { //We don't need to print borders above first line - if t.rowLine { - t.printLineOptionalCellSeparators(true, displayCellBorder) - } - } - tmpWriter.WriteTo(t.out) - } - //Print the end of the table if t.rowLine { t.printLine(true) } -} -// Print Row Information to a writer and merge identical cells. -// Adjust column alignment based on type - -func (t *Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey int, previousLine []string) ([]string, []bool) { - // Get Maximum Height - max := t.rs[colKey] - total := len(columns) - - // Pad Each Height - pads := []int{} - - for i, line := range columns { - length := len(line) - pad := max - length - pads = append(pads, pad) - for n := 0; n < pad; n++ { - columns[i] = append(columns[i], " ") - } - } - - var displayCellBorder []bool - t.fillAlignment(total) - for x := 0; x < max; x++ { - for y := 0; y < total; y++ { - - // Check if border is set - fmt.Fprint(writer, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) - - fmt.Fprintf(writer, SPACE) - - str := columns[y][x] - - if t.autoMergeCells { - //Store the full line to merge mutli-lines cells - fullLine := strings.Join(columns[y], " ") - if len(previousLine) > y && fullLine == previousLine[y] && fullLine != "" { - // If this cell is identical to the one above but not empty, we don't display the border and keep the cell empty. - displayCellBorder = append(displayCellBorder, false) - str = "" - } else { - // First line or different content, keep the content and print the cell border - displayCellBorder = append(displayCellBorder, true) - } - } - - // This would print alignment - // Default alignment would use multiple configuration - switch t.columnsAlign[y] { - case ALIGN_CENTER: // - fmt.Fprintf(writer, "%s", Pad(str, SPACE, t.cs[y])) - case ALIGN_RIGHT: - fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) - case ALIGN_LEFT: - fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) - default: - if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) { - fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) - } else { - fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) - } - } - fmt.Fprintf(writer, SPACE) - } - // Check if border is set - // Replace with space if not set - fmt.Fprint(writer, ConditionString(t.borders.Left, t.pColumn, SPACE)) - fmt.Fprint(writer, t.newLine) - } - - //The new previous line is the current one - previousLine = make([]string, total) - for y := 0; y < total; y++ { - previousLine[y] = strings.Join(columns[y], " ") //Store the full line for multi-lines cells - } - //Returns the newly added line and wether or not a border should be displayed above. - return previousLine, displayCellBorder } func (t *Table) parseDimension(str string, colKey, rowKey int) []string { diff --git a/vendor/github.com/olekukonko/tablewriter/table_with_color.go b/vendor/github.com/olekukonko/tablewriter/table_with_color.go deleted file mode 100644 index 5a4a53ec2..000000000 --- a/vendor/github.com/olekukonko/tablewriter/table_with_color.go +++ /dev/null @@ -1,134 +0,0 @@ -package tablewriter - -import ( - "fmt" - "strconv" - "strings" -) - -const ESC = "\033" -const SEP = ";" - -const ( - BgBlackColor int = iota + 40 - BgRedColor - BgGreenColor - BgYellowColor - BgBlueColor - BgMagentaColor - BgCyanColor - BgWhiteColor -) - -const ( - FgBlackColor int = iota + 30 - FgRedColor - FgGreenColor - FgYellowColor - FgBlueColor - FgMagentaColor - FgCyanColor - FgWhiteColor -) - -const ( - BgHiBlackColor int = iota + 100 - BgHiRedColor - BgHiGreenColor - BgHiYellowColor - BgHiBlueColor - BgHiMagentaColor - BgHiCyanColor - BgHiWhiteColor -) - -const ( - FgHiBlackColor int = iota + 90 - FgHiRedColor - FgHiGreenColor - FgHiYellowColor - FgHiBlueColor - FgHiMagentaColor - FgHiCyanColor - FgHiWhiteColor -) - -const ( - Normal = 0 - Bold = 1 - UnderlineSingle = 4 - Italic -) - -type Colors []int - -func startFormat(seq string) string { - return fmt.Sprintf("%s[%sm", ESC, seq) -} - -func stopFormat() string { - return fmt.Sprintf("%s[%dm", ESC, Normal) -} - -// Making the SGR (Select Graphic Rendition) sequence. -func makeSequence(codes []int) string { - codesInString := []string{} - for _, code := range codes { - codesInString = append(codesInString, strconv.Itoa(code)) - } - return strings.Join(codesInString, SEP) -} - -// Adding ANSI escape sequences before and after string -func format(s string, codes interface{}) string { - var seq string - - switch v := codes.(type) { - - case string: - seq = v - case []int: - seq = makeSequence(v) - default: - return s - } - - if len(seq) == 0 { - return s - } - return startFormat(seq) + s + stopFormat() -} - -// Adding header colors (ANSI codes) -func (t *Table) SetHeaderColor(colors ...Colors) { - if t.colSize != len(colors) { - panic("Number of header colors must be equal to number of headers.") - } - for i := 0; i < len(colors); i++ { - t.headerParams = append(t.headerParams, makeSequence(colors[i])) - } -} - -// Adding column colors (ANSI codes) -func (t *Table) SetColumnColor(colors ...Colors) { - if t.colSize != len(colors) { - panic("Number of column colors must be equal to number of headers.") - } - for i := 0; i < len(colors); i++ { - t.columnsParams = append(t.columnsParams, makeSequence(colors[i])) - } -} - -// Adding column colors (ANSI codes) -func (t *Table) SetFooterColor(colors ...Colors) { - if len(t.footers) != len(colors) { - panic("Number of footer colors must be equal to number of footer.") - } - for i := 0; i < len(colors); i++ { - t.footerParams = append(t.footerParams, makeSequence(colors[i])) - } -} - -func Color(colors ...int) []int { - return colors -} diff --git a/vendor/github.com/olekukonko/tablewriter/wrap.go b/vendor/github.com/olekukonko/tablewriter/wrap.go index 9ef69e904..f3747d9f3 100644 --- a/vendor/github.com/olekukonko/tablewriter/wrap.go +++ b/vendor/github.com/olekukonko/tablewriter/wrap.go @@ -10,8 +10,7 @@ package tablewriter import ( "math" "strings" - - "github.com/mattn/go-runewidth" + "unicode/utf8" ) var ( @@ -24,11 +23,11 @@ const defaultPenalty = 1e5 // Wrap wraps s into a paragraph of lines of length lim, with minimal // raggedness. func WrapString(s string, lim int) ([]string, int) { - words := strings.Split(strings.Replace(s, nl, sp, -1), sp) + words := strings.Split(strings.Replace(strings.TrimSpace(s), nl, sp, -1), sp) var lines []string max := 0 for _, v := range words { - max = runewidth.StringWidth(v) + max = len(v) if max > lim { lim = max } @@ -56,9 +55,9 @@ func WrapWords(words []string, spc, lim, pen int) [][]string { length := make([][]int, n) for i := 0; i < n; i++ { length[i] = make([]int, n) - length[i][i] = runewidth.StringWidth(words[i]) + length[i][i] = utf8.RuneCountInString(words[i]) for j := i + 1; j < n; j++ { - length[i][j] = length[i][j-1] + spc + runewidth.StringWidth(words[j]) + length[i][j] = length[i][j-1] + spc + utf8.RuneCountInString(words[j]) } } nbrk := make([]int, n) @@ -97,7 +96,7 @@ func WrapWords(words []string, spc, lim, pen int) [][]string { func getLines(s string) []string { var lines []string - for _, line := range strings.Split(s, nl) { + for _, line := range strings.Split(strings.TrimSpace(s), nl) { lines = append(lines, line) } return lines diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go index 842ee8045..75780c991 100644 --- a/vendor/github.com/pkg/errors/errors.go +++ b/vendor/github.com/pkg/errors/errors.go @@ -14,18 +14,13 @@ // Adding context to an error // // The errors.Wrap function returns a new error that adds context to the -// original error by recording a stack trace at the point Wrap is called, -// and the supplied message. For example +// original error. For example // // _, err := ioutil.ReadAll(r) // if err != nil { // return errors.Wrap(err, "read failed") // } // -// If additional control is required the errors.WithStack and errors.WithMessage -// functions destructure errors.Wrap into its component operations of annotating -// an error with a stack trace and an a message, respectively. -// // Retrieving the cause of an error // // Using errors.Wrap constructs a stack of errors, adding context to the @@ -132,22 +127,8 @@ func (f *fundamental) Format(s fmt.State, verb rune) { return } fallthrough - case 's': + case 's', 'q': io.WriteString(s, f.msg) - case 'q': - fmt.Fprintf(s, "%q", f.msg) - } -} - -// WithStack annotates err with a stack trace at the point WithStack was called. -// If err is nil, WithStack returns nil. -func WithStack(err error) error { - if err == nil { - return nil - } - return &withStack{ - err, - callers(), } } @@ -174,8 +155,7 @@ func (w *withStack) Format(s fmt.State, verb rune) { } } -// Wrap returns an error annotating err with a stack trace -// at the point Wrap is called, and the supplied message. +// Wrap returns an error annotating err with message. // If err is nil, Wrap returns nil. func Wrap(err error, message string) error { if err == nil { @@ -191,8 +171,7 @@ func Wrap(err error, message string) error { } } -// Wrapf returns an error annotating err with a stack trace -// at the point Wrapf is call, and the format specifier. +// Wrapf returns an error annotating err with the format specifier. // If err is nil, Wrapf returns nil. func Wrapf(err error, format string, args ...interface{}) error { if err == nil { @@ -208,18 +187,6 @@ func Wrapf(err error, format string, args ...interface{}) error { } } -// WithMessage annotates err with a new message. -// If err is nil, WithMessage returns nil. -func WithMessage(err error, message string) error { - if err == nil { - return nil - } - return &withMessage{ - cause: err, - msg: message, - } -} - type withMessage struct { cause error msg string diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go index e402065dd..c19fe7a06 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.go +++ b/vendor/github.com/spf13/cobra/bash_completions.go @@ -92,7 +92,7 @@ __handle_reply() cur="${cur#*=}" ${flags_completion[${index}]} if [ -n "${ZSH_VERSION}" ]; then - # zfs completion needs --flag= prefix + # zsh completion needs --flag= prefix eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )" fi fi diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index a23bb6d90..58e6ceb07 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -128,8 +128,6 @@ type Command struct { // TraverseChildren parses flags on all parents before executing child command. TraverseChildren bool - // name is the command name, usually the executable's name. - name string // commands is the list of commands supported by this program. commands []*Command // parent is a parent command for this command. @@ -693,6 +691,9 @@ func (c *Command) execute(a []string) (err error) { c.PreRun(c, argWoFlags) } + if err := c.validateRequiredFlags(); err != nil { + return err + } if c.RunE != nil { if err := c.RunE(c, argWoFlags); err != nil { return err @@ -810,6 +811,25 @@ func (c *Command) ValidateArgs(args []string) error { return c.Args(c, args) } +func (c *Command) validateRequiredFlags() error { + flags := c.Flags() + missingFlagNames := []string{} + flags.VisitAll(func(pflag *flag.Flag) { + requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag] + if !found { + return + } + if (requiredAnnotation[0] == "true") && !pflag.Changed { + missingFlagNames = append(missingFlagNames, pflag.Name) + } + }) + + if len(missingFlagNames) > 0 { + return fmt.Errorf(`Required flag(s) "%s" have/has not been set`, strings.Join(missingFlagNames, `", "`)) + } + return nil +} + // InitDefaultHelpFlag adds default help flag to c. // It is called automatically by executing the c or by calling help and usage. // If c already has help flag, it will do nothing. @@ -1025,15 +1045,12 @@ func (c *Command) DebugFlags() { // Name returns the command's name: the first word in the use line. func (c *Command) Name() string { - if c.name == "" { - name := c.Use - i := strings.Index(name, " ") - if i >= 0 { - name = name[:i] - } - c.name = name + name := c.Use + i := strings.Index(name, " ") + if i >= 0 { + name = name[:i] } - return c.name + return name } // HasAlias determines if a given string is an alias of the command. @@ -1343,6 +1360,9 @@ func (c *Command) ParseFlags(args []string) error { return nil } + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } beforeErrorBufLen := c.flagErrorBuf.Len() c.mergePersistentFlags() err := c.Flags().Parse(args)