| /* |
| * 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 models |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "fmt" |
| "io" |
| "os" |
| "reflect" |
| "strconv" |
| "strings" |
| |
| "github.com/apache/brooklyn-client/cli/terminal" |
| "github.com/urfave/cli" |
| "k8s.io/client-go/util/jsonpath" |
| ) |
| |
| type IdentityDetails struct { |
| Id string `json:"id"` |
| Name string `json:"name"` |
| SymbolicName string `json:"symbolicName"` |
| Version string `json:"version"` |
| Description string `json:"description"` |
| } |
| |
| type CatalogItemSummary struct { |
| IdentityDetails |
| JavaType string `json:"javaType"` |
| PlanYaml string `json:"planYaml"` |
| Deprecated bool `json:"deprecated"` |
| Config []ConfigSummary `json:"config"` |
| Tags []interface{} `json:"tags"` |
| Links map[string]interface{} `json:"links"` |
| Type string `json:"type"` |
| } |
| |
| type CatalogEntitySummary struct { |
| CatalogItemSummary |
| IconUrl string `json:"iconUrl"` |
| Effectors []EffectorSummary `json:"effectors"` |
| Sensors []SensorSummary `json:"sensors"` |
| } |
| |
| type CatalogBundleAddResult struct { |
| Message string `json:"message"` |
| Bundle string `json:"bundle"` |
| Code string `json:"code"` |
| Types map[string]CatalogItemSummary `json:"types"` |
| } |
| |
| func createTableWithIdentityDetails(item IdentityDetails) terminal.Table { |
| table := terminal.NewTable([]string{"Id:", item.Id}) |
| table.Add("Version:", item.Version) |
| table.Add("Name:", item.Name) |
| table.Add("Symbolic Name:", item.SymbolicName) |
| table.Add("Description:", item.Description) |
| return table |
| } |
| |
| func (summary *CatalogItemSummary) Display(c *cli.Context) error { |
| |
| if jsonFlag := c.GlobalString("json"); jsonFlag != "" { |
| raw := c.GlobalBool("raw-output") |
| err := displayAsJson(summary, jsonFlag, raw) |
| if err != nil { |
| return fmt.Errorf("display error: %s", err) |
| } |
| } else { |
| summary.displayAsTable() |
| } |
| return nil |
| } |
| |
| func (summary *CatalogEntitySummary) Display(c *cli.Context) error { |
| |
| if jsonFlag := c.GlobalString("json"); jsonFlag != "" { |
| raw := c.GlobalBool("raw-output") |
| err := displayAsJson(summary, jsonFlag, raw) |
| if err != nil { |
| return fmt.Errorf("display error: %s\n", err) |
| } |
| } else { |
| summary.displayAsTable() |
| } |
| return nil |
| } |
| |
| func (summary *CatalogItemSummary) displayAsTable() { |
| |
| table := createTableWithIdentityDetails(summary.IdentityDetails) |
| if summary.Deprecated { |
| table.Add("Deprecated:", "true") |
| } |
| table.Add("Java Type:", summary.JavaType) |
| table.Print() |
| } |
| |
| func (summary *CatalogEntitySummary) displayAsTable() { |
| |
| table := createTableWithIdentityDetails(summary.IdentityDetails) |
| if summary.Deprecated { |
| table.Add("Deprecated:", "true") |
| } |
| table.Add("Java Type:", summary.JavaType) |
| table.Add("Icon URL:", summary.IconUrl) |
| |
| for c, conf := range summary.Config { |
| if c == 0 { |
| table.Add("", "") // helps distinguish entries from one another |
| table.Add("Config:", "") |
| } |
| table.Add("Name:", conf.Name) |
| table.Add("Type:", conf.Type) |
| table.Add("Description:", conf.Description) |
| table.Add("Default Value:", fmt.Sprintf("%v", conf.DefaultValue)) |
| table.Add("Reconfigurable:", strconv.FormatBool(conf.Reconfigurable)) |
| table.Add("Label:", conf.Label) |
| table.Add("Priority:", strconv.FormatFloat(conf.Priority, 'f', -1, 64)) |
| table.Add("Pinned:", strconv.FormatBool(conf.Pinned)) |
| |
| if len(conf.PossibleValues) > 0 { |
| var values bytes.Buffer |
| for i, pv := range conf.PossibleValues { |
| if i > 0 { |
| values.WriteString(", ") |
| } |
| values.WriteString(pv["value"]) |
| if pv["value"] != pv["description"] { |
| values.WriteString(" (" + pv["description"] + ")") |
| } |
| } |
| table.Add("Possible Values:", values.String()) |
| } |
| table.Add("", "") // helps distinguish entries from one another |
| } |
| |
| for t, tag := range summary.Tags { |
| if t == 0 { |
| table.Add("", "") // helps distinguish entries from one another |
| table.Add("Tags:", "") |
| } |
| if asJson, erj := json.Marshal(tag); nil == erj { |
| table.Add("tag:", string(asJson)) |
| } else { |
| table.Add("tag:", fmt.Sprintf("%v", tag)) |
| } |
| } |
| |
| table.Print() |
| } |
| |
| func resultsBackToJson(wr io.Writer, values []reflect.Value, raw bool) error { |
| for i, r := range values { |
| object := r.Interface() |
| |
| jsonText, err := json.Marshal(object) |
| if err != nil { |
| return fmt.Errorf("error converting object to JSON: %s", err) |
| } |
| |
| if r.Kind() == reflect.String && raw { |
| stringWithQuotes := string(jsonText) |
| trimLeft := strings.TrimPrefix(stringWithQuotes, `"`) |
| withoutQuotes := strings.TrimSuffix(trimLeft, `"`) |
| jsonText = []byte(withoutQuotes) |
| } |
| |
| if i != len(values)-1 { |
| jsonText = append(jsonText, ' ') |
| } |
| if _, err := wr.Write(jsonText); err != nil { |
| return err |
| } |
| } |
| return nil |
| } |
| |
| func displayAsJson(v interface{}, displayPath string, raw bool) error { |
| j := jsonpath.New("displayer") |
| j.AllowMissingKeys(true) |
| |
| // wrap the path with k8s.io's conventional {} braces for convenience |
| err := j.Parse(fmt.Sprintf("{%s}", displayPath)) |
| if err != nil { |
| return fmt.Errorf("could not parse JSONPath expression (%s)", err) |
| } |
| |
| allResults, err := j.FindResults(v) |
| if err != nil { |
| return fmt.Errorf("error evaluating JSONPath expression: %s", err) |
| } |
| for ix := range allResults { |
| if err = resultsBackToJson(os.Stdout, allResults[ix], raw); err != nil { |
| return fmt.Errorf("display error: %s", err) |
| } |
| } |
| return nil |
| } |