diff --git a/glide.lock b/glide.lock index a76531064..22e0fa576 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 24fb3930c21a13fb6a30885bc622c54c76ecceee4bada0ffe79ae51b38c6d97e -updated: 2017-12-04T13:00:55.781717355+06:00 +hash: c62900e577b0cace4ec04c14d8c636c2ed62732562a2ed1b790ee52d2387b6d7 +updated: 2017-12-04T18:52:53.450682025+06:00 imports: - name: cloud.google.com/go version: fe3d41e1ecb2ce36ad3a979037c9b9a2b726226f @@ -263,6 +263,10 @@ imports: version: 378c27f9b1e552b1cadd2bfbe704bcdb46a3f0e7 subpackages: - pkg/validator +- name: github.com/k8sdb/memcached + version: c52892815af3ca91f21f5187e69d21bf77749d1a + subpackages: + - pkg/validator - name: github.com/k8sdb/mongodb version: a4a9d663de1fa2df52844d90ab03ea3eb9c9612a subpackages: @@ -275,6 +279,10 @@ imports: version: 45137f3723943902a343cf6befb71345aa6d52f6 subpackages: - pkg/validator +- name: github.com/k8sdb/redis + version: 1a608fca03e79a6bf6bbe2ab4579e0349e59bd40 + subpackages: + - pkg/validator - name: github.com/mailru/easyjson version: d5b7844b561a7bc640052f1b935f7b800330d7e0 subpackages: @@ -339,7 +347,7 @@ imports: - name: github.com/sirupsen/logrus version: f006c2ac4710855cf0f916dd6b77acf6b048dc6e - name: github.com/spf13/cobra - version: 86783686cade7a5ea7f5306d461d91841c7a6b3d + version: 3a5f27b046057b8b1bc8301159a31635aa68d0d5 subpackages: - doc - name: github.com/spf13/pflag diff --git a/glide.yaml b/glide.yaml index feb5f460c..e052878dd 100644 --- a/glide.yaml +++ b/glide.yaml @@ -15,6 +15,10 @@ import: version: master - package: github.com/k8sdb/mongodb version: master +- package: github.com/k8sdb/redis + version: master +- package: github.com/k8sdb/memcached + version: master - package: github.com/spf13/cobra - package: github.com/yudai/gojsondiff version: 1.0.0 diff --git a/pkg/cmds/get.go b/pkg/cmds/get.go index 9b719fa3f..ed9bcf850 100644 --- a/pkg/cmds/get.go +++ b/pkg/cmds/get.go @@ -71,6 +71,8 @@ const ( * postgres * mysql * mongodb + * redis + * memcached * snapshot * dormantdatabase ` diff --git a/pkg/cmds/summarize.go b/pkg/cmds/summarize.go index 3627f7f50..d7663242a 100644 --- a/pkg/cmds/summarize.go +++ b/pkg/cmds/summarize.go @@ -48,6 +48,8 @@ const ( * postgreses * mysqls * mongodbs + * redises + * memcacheds ` ) diff --git a/pkg/decoder/decode.go b/pkg/decoder/decode.go index ede4fc5c5..ad535707c 100644 --- a/pkg/decoder/decode.go +++ b/pkg/decoder/decode.go @@ -34,6 +34,18 @@ func Decode(kind string, data []byte) (runtime.Object, error) { return nil, err } return mongodb, nil + case tapi.ResourceKindRedis: + var redis *tapi.Redis + if err := yaml.Unmarshal(data, &redis); err != nil { + return nil, err + } + return redis, nil + case tapi.ResourceKindMemcached: + var memcached *tapi.Memcached + if err := yaml.Unmarshal(data, &memcached); err != nil { + return nil, err + } + return memcached, nil case tapi.ResourceKindSnapshot: var snapshot *tapi.Snapshot if err := yaml.Unmarshal(data, &snapshot); err != nil { diff --git a/pkg/describer/describer.go b/pkg/describer/describer.go index 0676fbd3d..ebb1fd1c3 100644 --- a/pkg/describer/describer.go +++ b/pkg/describer/describer.go @@ -50,6 +50,8 @@ func (h *humanReadableDescriber) addDefaultHandlers() { h.Handler(h.describePostgres) h.Handler(h.describeMySQL) h.Handler(h.describeMongoDB) + h.Handler(h.describeRedis) + h.Handler(h.describeMemcached) h.Handler(h.describeSnapshot) h.Handler(h.describeDormantDatabase) } diff --git a/pkg/describer/k8sdb_describer.go b/pkg/describer/k8sdb_describer.go index 604ff7427..5e67beb9c 100644 --- a/pkg/describer/k8sdb_describer.go +++ b/pkg/describer/k8sdb_describer.go @@ -63,7 +63,7 @@ func (d *humanReadableDescriber) describeElastic(item *api.Elasticsearch, descri describeStorage(item.Spec.Storage, out) - statefulSetName := fmt.Sprintf("%v-%v", item.Name, item.ResourceCode()) + statefulSetName := fmt.Sprintf("%v", item.Name) d.describeStatefulSet(item.Namespace, statefulSetName, out) d.describeService(item.Namespace, item.Name, out) @@ -128,7 +128,7 @@ func (d *humanReadableDescriber) describePostgres(item *api.Postgres, describerS describeStorage(item.Spec.Storage, out) - statefulSetName := fmt.Sprintf("%v-%v", item.Name, item.ResourceCode()) + statefulSetName := fmt.Sprintf("%v", item.Name) d.describeStatefulSet(item.Namespace, statefulSetName, out) d.describeService(item.Namespace, item.Name, out) @@ -196,7 +196,7 @@ func (d *humanReadableDescriber) describeMySQL(item *api.MySQL, describerSetting describeStorage(item.Spec.Storage, out) - statefulSetName := fmt.Sprintf("%v-%v", item.Name, item.ResourceCode()) + statefulSetName := fmt.Sprintf("%v", item.Name) d.describeStatefulSet(item.Namespace, statefulSetName, out) d.describeService(item.Namespace, item.Name, out) @@ -264,7 +264,7 @@ func (d *humanReadableDescriber) describeMongoDB(item *api.MongoDB, describerSet describeStorage(item.Spec.Storage, out) - statefulSetName := fmt.Sprintf("%v-%v", item.Name, item.ResourceCode()) + statefulSetName := fmt.Sprintf("%v", item.Name) d.describeStatefulSet(item.Namespace, statefulSetName, out) d.describeService(item.Namespace, item.Name, out) @@ -286,6 +286,102 @@ func (d *humanReadableDescriber) describeMongoDB(item *api.MongoDB, describerSet }) } +func (d *humanReadableDescriber) describeRedis(item *api.Redis, describerSettings *printers.DescriberSettings) (string, error) { + clientSet, err := d.ClientSet() + if err != nil { + return "", err + } + + var events *kapi.EventList + if describerSettings.ShowEvents { + item.Kind = api.ResourceKindRedis + events, err = clientSet.Core().Events(item.Namespace).Search(scheme.Scheme, item) + if err != nil { + return "", err + } + } + + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", item.Name) + fmt.Fprintf(out, "Namespace:\t%s\n", item.Namespace) + fmt.Fprintf(out, "StartTimestamp:\t%s\n", timeToString(&item.CreationTimestamp)) + if item.Labels != nil { + printLabelsMultiline(out, "Labels", item.Labels) + } + fmt.Fprintf(out, "Status:\t%s\n", string(item.Status.Phase)) + if len(item.Status.Reason) > 0 { + fmt.Fprintf(out, "Reason:\t%s\n", item.Status.Reason) + } + if item.Annotations != nil { + printLabelsMultiline(out, "Annotations", item.Annotations) + } + + describeStorage(item.Spec.Storage, out) + + statefulSetName := fmt.Sprintf("%v", item.Name) + + d.describeStatefulSet(item.Namespace, statefulSetName, out) + d.describeService(item.Namespace, item.Name, out) + + if item.Spec.Monitor != nil { + describeMonitor(item.Spec.Monitor, out) + } + + if events != nil { + describeEvents(events, out) + } + + return nil + }) +} + +func (d *humanReadableDescriber) describeMemcached(item *api.Memcached, describerSettings *printers.DescriberSettings) (string, error) { + clientSet, err := d.ClientSet() + if err != nil { + return "", err + } + + var events *kapi.EventList + if describerSettings.ShowEvents { + item.Kind = api.ResourceKindMemcached + events, err = clientSet.Core().Events(item.Namespace).Search(scheme.Scheme, item) + if err != nil { + return "", err + } + } + + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", item.Name) + fmt.Fprintf(out, "Namespace:\t%s\n", item.Namespace) + fmt.Fprintf(out, "StartTimestamp:\t%s\n", timeToString(&item.CreationTimestamp)) + if item.Labels != nil { + printLabelsMultiline(out, "Labels", item.Labels) + } + fmt.Fprintf(out, "Status:\t%s\n", string(item.Status.Phase)) + if len(item.Status.Reason) > 0 { + fmt.Fprintf(out, "Reason:\t%s\n", item.Status.Reason) + } + if item.Annotations != nil { + printLabelsMultiline(out, "Annotations", item.Annotations) + } + + deploymentName := fmt.Sprintf("%v", item.Name) + + d.describeDeployments(item.Namespace, deploymentName, out) + d.describeService(item.Namespace, item.Name, out) + + if item.Spec.Monitor != nil { + describeMonitor(item.Spec.Monitor, out) + } + + if events != nil { + describeEvents(events, out) + } + + return nil + }) +} + func (d *humanReadableDescriber) describeSnapshot(item *api.Snapshot, describerSettings *printers.DescriberSettings) (string, error) { clientSet, err := d.ClientSet() if err != nil { diff --git a/pkg/describer/kube_describer.go b/pkg/describer/kube_describer.go index 5175d4749..82bccca41 100644 --- a/pkg/describer/kube_describer.go +++ b/pkg/describer/kube_describer.go @@ -46,6 +46,36 @@ func (d *humanReadableDescriber) describeStatefulSet(namespace, name string, out fmt.Fprintf(out, " Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed) } +func (d *humanReadableDescriber) describeDeployments(namespace, name string, out io.Writer) { + clientSet, err := d.ClientSet() + if err != nil { + return + } + + ps, err := clientSet.Extensions().Deployments(namespace).Get(name, metav1.GetOptions{}) + if err != nil { + return + } + pc := clientSet.Core().Pods(namespace) + + selector, err := metav1.LabelSelectorAsSelector(ps.Spec.Selector) + if err != nil { + return + } + + running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector) + if err != nil { + return + } + + fmt.Fprint(out, "\n") + fmt.Fprint(out, "Deployment:\t\n") + fmt.Fprintf(out, " Name:\t%s\n", ps.Name) + fmt.Fprintf(out, " Replicas:\t%d current / %d desired\n", ps.Status.Replicas, ps.Spec.Replicas) + fmt.Fprintf(out, " CreationTimestamp:\t%s\n", timeToString(&ps.CreationTimestamp)) + fmt.Fprintf(out, " Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed) +} + func getPodStatusForController(c coreclient.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) { options := metav1.ListOptions{LabelSelector: selector.String()} rcPods, err := c.List(options) diff --git a/pkg/printer/resource_printer.go b/pkg/printer/resource_printer.go index c14d5c58d..e9ffde9f7 100644 --- a/pkg/printer/resource_printer.go +++ b/pkg/printer/resource_printer.go @@ -85,6 +85,10 @@ func (h *HumanReadablePrinter) addDefaultHandlers() { h.Handler(h.printMySQL) h.Handler(h.printMongoDBList) h.Handler(h.printMongoDB) + h.Handler(h.printRedisList) + h.Handler(h.printRedis) + h.Handler(h.printMemcachedList) + h.Handler(h.printMemcached) h.Handler(h.printSnapshotList) h.Handler(h.printSnapshot) h.Handler(h.printDormantDatabaseList) @@ -152,6 +156,10 @@ func getColumns(options PrintOptions, t reflect.Type) []string { if options.Wide { columns = append(columns, "VERSION") } + case "*v1alpha1.Redis", "*v1alpha1.RedisList": + if options.Wide { + columns = append(columns, "VERSION") + } case "*v1alpha1.Snapshot", "*v1alpha1.SnapshotList": columns = append(columns, "DATABASE") if options.Wide { @@ -339,6 +347,92 @@ func (h *HumanReadablePrinter) printMongoDBList(itemList *tapi.MongoDBList, w io return nil } +func (h *HumanReadablePrinter) printRedis(item *tapi.Redis, w io.Writer, options PrintOptions) error { + name := formatResourceName(options.Kind, item.Name, options.WithKind) + + namespace := item.Namespace + + if options.WithNamespace { + if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { + return err + } + } + + status := item.Status.Phase + if status == "" { + status = statusUnknown + } + if _, err := fmt.Fprintf(w, "%s\t", name); err != nil { + return err + } + + if options.Wide { + if _, err := fmt.Fprintf(w, "%s\t", item.Spec.Version); err != nil { + return err + } + } + + if _, err := fmt.Fprintf(w, "%s\t%s", status, TranslateTimestamp(item.CreationTimestamp)); err != nil { + return err + } + + _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels)) + + return err +} + +func (h *HumanReadablePrinter) printRedisList(itemList *tapi.RedisList, w io.Writer, options PrintOptions) error { + for _, item := range itemList.Items { + if err := h.printRedis(&item, w, options); err != nil { + return err + } + } + return nil +} + +func (h *HumanReadablePrinter) printMemcached(item *tapi.Memcached, w io.Writer, options PrintOptions) error { + name := formatResourceName(options.Kind, item.Name, options.WithKind) + + namespace := item.Namespace + + if options.WithNamespace { + if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { + return err + } + } + + status := item.Status.Phase + if status == "" { + status = statusUnknown + } + if _, err := fmt.Fprintf(w, "%s\t", name); err != nil { + return err + } + + if options.Wide { + if _, err := fmt.Fprintf(w, "%s\t", item.Spec.Version); err != nil { + return err + } + } + + if _, err := fmt.Fprintf(w, "%s\t%s", status, TranslateTimestamp(item.CreationTimestamp)); err != nil { + return err + } + + _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels)) + + return err +} + +func (h *HumanReadablePrinter) printMemcachedList(itemList *tapi.MemcachedList, w io.Writer, options PrintOptions) error { + for _, item := range itemList.Items { + if err := h.printMemcached(&item, w, options); err != nil { + return err + } + } + return nil +} + func (h *HumanReadablePrinter) printSnapshot(item *tapi.Snapshot, w io.Writer, options PrintOptions) error { name := formatResourceName(options.Kind, item.Name, options.WithKind) diff --git a/pkg/util/resource.go b/pkg/util/resource.go index 6f7226113..0553c0343 100644 --- a/pkg/util/resource.go +++ b/pkg/util/resource.go @@ -39,6 +39,16 @@ func GetSupportedResource(resource string) (string, error) { strings.ToLower(tapi.ResourceCodeMongoDB), strings.ToLower(tapi.ResourceNameMongoDB): return tapi.ResourceTypeMongoDB + "." + tapi.SchemeGroupVersion.Group, nil + case strings.ToLower(tapi.ResourceKindRedis), + strings.ToLower(tapi.ResourceTypeRedis), + strings.ToLower(tapi.ResourceCodeRedis), + strings.ToLower(tapi.ResourceNameRedis): + return tapi.ResourceTypeRedis + "." + tapi.SchemeGroupVersion.Group, nil + case strings.ToLower(tapi.ResourceKindMemcached), + strings.ToLower(tapi.ResourceTypeMemcached), + strings.ToLower(tapi.ResourceCodeMemcached), + strings.ToLower(tapi.ResourceNameMemcached): + return tapi.ResourceTypeMemcached + "." + tapi.SchemeGroupVersion.Group, nil case strings.ToLower(tapi.ResourceKindSnapshot), strings.ToLower(tapi.ResourceTypeSnapshot), strings.ToLower(tapi.ResourceCodeSnapshot), @@ -76,6 +86,16 @@ func GetResourceType(resource string) (string, error) { strings.ToLower(tapi.ResourceCodeMongoDB), strings.ToLower(tapi.ResourceNameMongoDB): return tapi.ResourceTypeMongoDB, nil + case strings.ToLower(tapi.ResourceKindRedis), + strings.ToLower(tapi.ResourceTypeRedis), + strings.ToLower(tapi.ResourceCodeRedis), + strings.ToLower(tapi.ResourceNameRedis): + return tapi.ResourceTypeRedis, nil + case strings.ToLower(tapi.ResourceKindMemcached), + strings.ToLower(tapi.ResourceTypeMemcached), + strings.ToLower(tapi.ResourceCodeMemcached), + strings.ToLower(tapi.ResourceNameMemcached): + return tapi.ResourceTypeMemcached, nil case strings.ToLower(tapi.ResourceKindSnapshot), strings.ToLower(tapi.ResourceTypeSnapshot), strings.ToLower(tapi.ResourceCodeSnapshot), @@ -97,6 +117,8 @@ func CheckSupportedResource(kind string) error { tapi.ResourceKindPostgres, tapi.ResourceKindMySQL, tapi.ResourceKindMongoDB, + tapi.ResourceKindRedis, + tapi.ResourceKindMemcached, tapi.ResourceKindSnapshot, tapi.ResourceKindDormantDatabase: return nil @@ -112,6 +134,8 @@ func GetAllSupportedResources(f cmdutil.Factory) ([]string, error) { tapi.ResourceTypePostgres + "." + tapi.SchemeGroupVersion.Group, tapi.ResourceTypeMySQL + "." + tapi.SchemeGroupVersion.Group, tapi.ResourceTypeMongoDB + "." + tapi.SchemeGroupVersion.Group, + tapi.ResourceTypeRedis + "." + tapi.SchemeGroupVersion.Group, + tapi.ResourceTypeMemcached + "." + tapi.SchemeGroupVersion.Group, tapi.ResourceTypeSnapshot + "." + tapi.SchemeGroupVersion.Group, tapi.ResourceTypeDormantDatabase + "." + tapi.SchemeGroupVersion.Group, } @@ -146,6 +170,8 @@ var ShortForms = map[string]string{ tapi.ResourceCodePostgres: tapi.ResourceTypePostgres, tapi.ResourceCodeMySQL: tapi.ResourceTypeMySQL, tapi.ResourceCodeMongoDB: tapi.ResourceTypeMongoDB, + tapi.ResourceCodeRedis: tapi.ResourceTypeRedis, + tapi.ResourceCodeMemcached: tapi.ResourceTypeMemcached, tapi.ResourceCodeSnapshot: tapi.ResourceTypeSnapshot, tapi.ResourceCodeDormantDatabase: tapi.ResourceTypeDormantDatabase, } @@ -242,6 +268,15 @@ var PreconditionSpecField = map[string][]string{ "spec.nodeSelector", "spec.init", }, + tapi.ResourceKindRedis: { + "spec.version", + "spec.storage", + "spec.nodeSelector", + }, + tapi.ResourceKindMemcached: { + "spec.version", + "spec.nodeSelector", + }, tapi.ResourceKindDormantDatabase: { "spec.origin", }, @@ -276,7 +311,12 @@ func CheckResourceExists(client internalclientset.Interface, kind, name, namespa case tapi.ResourceKindMongoDB: statefulSetName := fmt.Sprintf("%v-%v", name, tapi.ResourceCodeMongoDB) _, err = client.Apps().StatefulSets(namespace).Get(statefulSetName, metav1.GetOptions{}) - + case tapi.ResourceKindRedis: + statefulSetName := fmt.Sprintf("%v-%v", name, tapi.ResourceCodeRedis) + _, err = client.Apps().StatefulSets(namespace).Get(statefulSetName, metav1.GetOptions{}) + case tapi.ResourceKindMemcached: + deploymentName := fmt.Sprintf("%v-%v", name, tapi.ResourceCodeMemcached) + _, err = client.Extensions().Deployments(namespace).Get(deploymentName, metav1.GetOptions{}) } if err != nil { diff --git a/pkg/validator/validate.go b/pkg/validator/validate.go index 9663d4f64..790109dea 100644 --- a/pkg/validator/validate.go +++ b/pkg/validator/validate.go @@ -8,9 +8,11 @@ import ( amv "github.com/k8sdb/apimachinery/pkg/validator" "github.com/k8sdb/cli/pkg/encoder" esv "github.com/k8sdb/elasticsearch/pkg/validator" + memv "github.com/k8sdb/memcached/pkg/validator" mgv "github.com/k8sdb/mongodb/pkg/validator" msv "github.com/k8sdb/mysql/pkg/validator" pgv "github.com/k8sdb/postgres/pkg/validator" + rdv "github.com/k8sdb/redis/pkg/validator" "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/pkg/kubectl/resource" ) @@ -47,6 +49,18 @@ func Validate(client kubernetes.Interface, info *resource.Info) error { return err } return mgv.ValidateMongoDB(client, mongodb) + case tapi.ResourceKindRedis: + var redis *tapi.Redis + if err := yaml.Unmarshal(objByte, &redis); err != nil { + return err + } + return rdv.ValidateRedis(client, redis) + case tapi.ResourceKindMemcached: + var memcached *tapi.Memcached + if err := yaml.Unmarshal(objByte, &memcached); err != nil { + return err + } + return memv.ValidateMemcached(client, memcached) case tapi.ResourceKindSnapshot: var snapshot *tapi.Snapshot if err := yaml.Unmarshal(objByte, &snapshot); err != nil { @@ -97,7 +111,22 @@ func ValidateDeletion(info *resource.Info) error { if mongodb.Spec.DoNotPause { return fmt.Errorf(`MongoDB "%v" can't be paused. To continue delete, unset spec.doNotPause and retry.`, mongodb.Name) } - + case tapi.ResourceKindRedis: + var redis *tapi.Redis + if err := yaml.Unmarshal(objByte, &redis); err != nil { + return err + } + if redis.Spec.DoNotPause { + return fmt.Errorf(`Redis "%v" can't be paused. To continue delete, unset spec.doNotPause and retry.`, redis.Name) + } + case tapi.ResourceKindMemcached: + var memcached *tapi.Memcached + if err := yaml.Unmarshal(objByte, &memcached); err != nil { + return err + } + if memcached.Spec.DoNotPause { + return fmt.Errorf(`Memcached "%v" can't be paused. To continue delete, unset spec.doNotPause and retry.`, memcached.Name) + } } return nil } diff --git a/vendor/github.com/k8sdb/memcached/LICENSE b/vendor/github.com/k8sdb/memcached/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/github.com/k8sdb/memcached/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/vendor/github.com/k8sdb/memcached/pkg/validator/validate.go b/vendor/github.com/k8sdb/memcached/pkg/validator/validate.go new file mode 100644 index 000000000..12710f76d --- /dev/null +++ b/vendor/github.com/k8sdb/memcached/pkg/validator/validate.go @@ -0,0 +1,31 @@ +package validator + +import ( + "fmt" + + api "github.com/k8sdb/apimachinery/apis/kubedb/v1alpha1" + "github.com/k8sdb/apimachinery/pkg/docker" + amv "github.com/k8sdb/apimachinery/pkg/validator" + "k8s.io/client-go/kubernetes" +) + +func ValidateMemcached(client kubernetes.Interface, memcached *api.Memcached) error { + if memcached.Spec.Version == "" { + return fmt.Errorf(`Object 'Version' is missing in '%v'`, memcached.Spec) + } + + // Set Database Image version + version := string(memcached.Spec.Version) + if err := docker.CheckDockerImageVersion(docker.ImageMemcached, version); err != nil { + return fmt.Errorf(`Image %v:%v not found`, docker.ImageMemcached, version) + } + + monitorSpec := memcached.Spec.Monitor + if monitorSpec != nil { + if err := amv.ValidateMonitorSpec(monitorSpec); err != nil { + return err + } + + } + return nil +} diff --git a/vendor/github.com/k8sdb/redis/LICENSE b/vendor/github.com/k8sdb/redis/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/vendor/github.com/k8sdb/redis/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed 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. diff --git a/vendor/github.com/k8sdb/redis/pkg/validator/validate.go b/vendor/github.com/k8sdb/redis/pkg/validator/validate.go new file mode 100644 index 000000000..71a2b0288 --- /dev/null +++ b/vendor/github.com/k8sdb/redis/pkg/validator/validate.go @@ -0,0 +1,38 @@ +package validator + +import ( + "fmt" + + api "github.com/k8sdb/apimachinery/apis/kubedb/v1alpha1" + "github.com/k8sdb/apimachinery/pkg/docker" + amv "github.com/k8sdb/apimachinery/pkg/validator" + "k8s.io/client-go/kubernetes" +) + +func ValidateRedis(client kubernetes.Interface, redis *api.Redis) error { + if redis.Spec.Version == "" { + return fmt.Errorf(`Object 'Version' is missing in '%v'`, redis.Spec) + } + + // Set Database Image version + version := string(redis.Spec.Version) + if err := docker.CheckDockerImageVersion(docker.ImageRedis, version); err != nil { + return fmt.Errorf(`Image %v:%v not found`, docker.ImageRedis, version) + } + + if redis.Spec.Storage != nil { + var err error + if err = amv.ValidateStorage(client, redis.Spec.Storage); err != nil { + return err + } + } + + monitorSpec := redis.Spec.Monitor + if monitorSpec != nil { + if err := amv.ValidateMonitorSpec(monitorSpec); err != nil { + return err + } + + } + return nil +} diff --git a/vendor/github.com/spf13/cobra/doc/md_docs.go b/vendor/github.com/spf13/cobra/doc/md_docs.go index 68cf5bf64..d7a2c2b62 100644 --- a/vendor/github.com/spf13/cobra/doc/md_docs.go +++ b/vendor/github.com/spf13/cobra/doc/md_docs.go @@ -67,7 +67,7 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) buf.WriteString("## " + name + "\n\n") buf.WriteString(short + "\n\n") buf.WriteString("### Synopsis\n\n") - buf.WriteString("\n" + long + "\n\n") + buf.WriteString(long + "\n\n") if cmd.Runnable() { buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine())) @@ -82,7 +82,7 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) return err } if hasSeeAlso(cmd) { - buf.WriteString("### SEE ALSO\n") + buf.WriteString("### SEE ALSO\n\n") if cmd.HasParent() { parent := cmd.Parent() pname := parent.CommandPath()