From aa9f04e0cec2322006e3f53b1afa20d6f4540bc9 Mon Sep 17 00:00:00 2001 From: tamal Date: Sat, 24 Jun 2017 01:12:06 -0700 Subject: [PATCH 01/18] Support non-default service account to install operator --- pkg/init.go | 6 ++++-- pkg/util/flags.go | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index 34529ff94..ddc3af324 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -50,6 +50,7 @@ func NewCmdInit(out io.Writer, errOut io.Writer) *cobra.Command { func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { upgrade := cmdutil.GetFlagBool(cmd, "upgrade") namespace := cmdutil.GetFlagString(cmd, "operator-namespace") + serviceAccount := cmdutil.GetFlagString(cmd, "operator-service-account") version := cmdutil.GetFlagString(cmd, "version") client, err := kube.NewKubeClient(cmd) @@ -111,7 +112,7 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { return nil } - if err := createOperatorDeployment(client, namespace, version); err != nil { + if err := createOperatorDeployment(client, namespace, version, serviceAccount); err != nil { if kerr.IsAlreadyExists(err) { fmt.Fprintln(errOut, "Operator deployment already exists.") } else { @@ -143,7 +144,7 @@ var operatorLabel = map[string]string{ "app": docker.OperatorName, } -func createOperatorDeployment(client kubernetes.Interface, namespace, version string) error { +func createOperatorDeployment(client kubernetes.Interface, namespace, version, serviceAccount string) error { deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, @@ -188,6 +189,7 @@ func createOperatorDeployment(client kubernetes.Interface, namespace, version st }, }, }, + ServiceAccountName: serviceAccount, }, }, }, diff --git a/pkg/util/flags.go b/pkg/util/flags.go index 54008aafe..5f17e3ee5 100644 --- a/pkg/util/flags.go +++ b/pkg/util/flags.go @@ -44,6 +44,7 @@ func AddEditFlags(cmd *cobra.Command) { func AddInitFlags(cmd *cobra.Command) { cmd.Flags().String("operator-namespace", "kube-system", "Name of namespace where operator will be deployed.") + cmd.Flags().String("operator-service-account", "default", "Service account name used to run operator") cmd.Flags().String("version", "0.2.0", "Operator version") cmd.Flags().Bool("upgrade", false, "If present, Upgrade operator to use provided version") } From 37600a723f5727672c0d3c61f2b217c2c83b595c Mon Sep 17 00:00:00 2001 From: tamal Date: Sat, 24 Jun 2017 01:13:18 -0700 Subject: [PATCH 02/18] added-all --- pkg/init.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index ddc3af324..fc64aa6c1 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -112,7 +112,7 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { return nil } - if err := createOperatorDeployment(client, namespace, version, serviceAccount); err != nil { + if err := createOperatorDeployment(client, namespace, serviceAccount, version); err != nil { if kerr.IsAlreadyExists(err) { fmt.Fprintln(errOut, "Operator deployment already exists.") } else { @@ -144,7 +144,7 @@ var operatorLabel = map[string]string{ "app": docker.OperatorName, } -func createOperatorDeployment(client kubernetes.Interface, namespace, version, serviceAccount string) error { +func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAccount, version string) error { deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, From 0762f7988eba021e327f8a1f479149a7b52dab41 Mon Sep 17 00:00:00 2001 From: tamal Date: Tue, 27 Jun 2017 08:55:19 -0700 Subject: [PATCH 03/18] added-all --- pkg/init.go | 6 +++++- pkg/util/flags.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index 6215f6581..6704bd06c 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -50,8 +50,12 @@ func NewCmdInit(out io.Writer, errOut io.Writer) *cobra.Command { func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { upgrade := cmdutil.GetFlagBool(cmd, "upgrade") namespace := cmdutil.GetFlagString(cmd, "operator-namespace") - serviceAccount := cmdutil.GetFlagString(cmd, "operator-service-account") version := cmdutil.GetFlagString(cmd, "version") + configureRBAC := cmdutil.GetFlagBool(cmd, "rbac") + serviceAccount := "default" + if configureRBAC { + serviceAccount = "kubedb-operator" + } client, err := kube.NewKubeClient(cmd) if err != nil { diff --git a/pkg/util/flags.go b/pkg/util/flags.go index 5f17e3ee5..0da61127c 100644 --- a/pkg/util/flags.go +++ b/pkg/util/flags.go @@ -44,7 +44,7 @@ func AddEditFlags(cmd *cobra.Command) { func AddInitFlags(cmd *cobra.Command) { cmd.Flags().String("operator-namespace", "kube-system", "Name of namespace where operator will be deployed.") - cmd.Flags().String("operator-service-account", "default", "Service account name used to run operator") + cmd.Flags().Bool("rbac", false, "If true, configures RBAC roles for operator") cmd.Flags().String("version", "0.2.0", "Operator version") cmd.Flags().Bool("upgrade", false, "If present, Upgrade operator to use provided version") } From 4e4ca9b551f2c10eb97616adad83fe08184507a1 Mon Sep 17 00:00:00 2001 From: tamal Date: Tue, 27 Jun 2017 09:12:34 -0700 Subject: [PATCH 04/18] added-all --- glide.lock | 12 +- pkg/init.go | 47 ++++- vendor/github.com/yudai/gojsondiff/deltas.go | 2 +- .../yudai/gojsondiff/formatter/ascii.go | 8 +- vendor/gopkg.in/yaml.v2/LICENSE | 195 +----------------- vendor/gopkg.in/yaml.v2/decode.go | 3 +- vendor/gopkg.in/yaml.v2/emitterc.go | 1 - vendor/gopkg.in/yaml.v2/parserc.go | 1 - vendor/gopkg.in/yaml.v2/readerc.go | 7 +- vendor/gopkg.in/yaml.v2/resolve.go | 11 +- vendor/gopkg.in/yaml.v2/scannerc.go | 4 +- vendor/gopkg.in/yaml.v2/yaml.go | 2 +- 12 files changed, 83 insertions(+), 210 deletions(-) diff --git a/glide.lock b/glide.lock index bd198cc9a..28b309049 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: b737760e0f81a2850433fe5b9a0ddc1d6b15d93a1207fe0a607313978062c265 -updated: 2017-06-23T07:44:00.374256843-07:00 +updated: 2017-06-27T09:11:07.077647695-07:00 imports: - name: cloud.google.com/go version: fe3d41e1ecb2ce36ad3a979037c9b9a2b726226f @@ -216,11 +216,11 @@ imports: - pkg/eventer - pkg/validator - name: github.com/k8sdb/elasticsearch - version: 245f2a5be3a42e9e5c912fcf40801263ac061685 + version: 848a01d08ed3511f0259c5489d913a7bb80f4a6a subpackages: - pkg/validator - name: github.com/k8sdb/postgres - version: 83efb69b3cb6f1dc2118354e336375a314b6eab7 + version: 4f3b6881e32f658e4dc23dbe589f1d587354fab1 subpackages: - pkg/validator - name: github.com/mailru/easyjson @@ -254,7 +254,7 @@ imports: - name: github.com/Sirupsen/logrus version: 4b6ea7319e214d98c938f12692336f7ca9348d6b - name: github.com/spf13/cobra - version: e458bb7ab84aae1bb4b4d36eccf9332f0d659e38 + version: 4d647c8944eb42504a714e57e97f244ed6344722 subpackages: - doc - name: github.com/spf13/pflag @@ -264,7 +264,7 @@ imports: subpackages: - codec - name: github.com/yudai/gojsondiff - version: 9209d1532c51cabe0439993586a71c207b09a0ac + version: 081cda2ee95045a2c26da52c2ba80860838549de subpackages: - formatter - name: github.com/yudai/golcs @@ -338,7 +338,7 @@ imports: - name: gopkg.in/robfig/cron.v2 version: be2e0b0deed5a68ffee390b4583a13aff8321535 - name: gopkg.in/yaml.v2 - version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 + version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b - name: k8s.io/apimachinery version: 75b8dd260ef0469d96d578705a87cffd0e09dab8 subpackages: diff --git a/pkg/init.go b/pkg/init.go index 6704bd06c..778796141 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -16,6 +16,7 @@ import ( "k8s.io/client-go/kubernetes" apiv1 "k8s.io/client-go/pkg/api/v1" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + rbac "k8s.io/client-go/pkg/apis/rbac/v1beta1" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) @@ -52,9 +53,9 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { namespace := cmdutil.GetFlagString(cmd, "operator-namespace") version := cmdutil.GetFlagString(cmd, "version") configureRBAC := cmdutil.GetFlagBool(cmd, "rbac") - serviceAccount := "default" + serviceAccount := apiv1.NamespaceDefault if configureRBAC { - serviceAccount = "kubedb-operator" + serviceAccount = docker.OperatorName } client, err := kube.NewKubeClient(cmd) @@ -148,6 +149,48 @@ var operatorLabel = map[string]string{ "app": docker.OperatorName, } +func rbacstuff(client kubernetes.Interface, namespace, serviceAccount, version string) error { + roleBinding := rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: docker.OperatorName, + Namespace: namespace, + }, + RoleRef: rbac.RoleRef{ + APIGroup: rbac.GroupName, + Kind: "ClusterRole", + Name: docker.OperatorName, + }, + Subjects: []rbac.Subject{ + { + Kind: rbac.ServiceAccountKind, + Name: docker.OperatorName, + Namespace: namespace, + }, + }, + } + client.RbacV1beta1().ClusterRoleBindings().Create(&roleBinding) + + role := rbac.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: docker.OperatorName, + }, + Rules: []rbac.PolicyRule{ + {}, + }, + } + client.RbacV1beta1().ClusterRoles().Create(&role) + + sa := apiv1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: docker.OperatorName, + Namespace: namespace, + }, + } + client.CoreV1().ServiceAccounts(namespace).Create(&sa) + + return nil +} + func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAccount, version string) error { deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ diff --git a/vendor/github.com/yudai/gojsondiff/deltas.go b/vendor/github.com/yudai/gojsondiff/deltas.go index 403c5bf4c..a15a137e3 100644 --- a/vendor/github.com/yudai/gojsondiff/deltas.go +++ b/vendor/github.com/yudai/gojsondiff/deltas.go @@ -451,7 +451,7 @@ func (d *Moved) PostApply(object interface{}) interface{} { } func (d *Moved) similarity() (similarity float64) { - similarity = 0.6 // as type and contens are same + similarity = 0.6 // as type and contents are same ratio := float64(d.PrePosition().(Index)) / float64(d.PostPosition().(Index)) if ratio > 1 { ratio = 1 / ratio diff --git a/vendor/github.com/yudai/gojsondiff/formatter/ascii.go b/vendor/github.com/yudai/gojsondiff/formatter/ascii.go index b30781327..d86de1634 100644 --- a/vendor/github.com/yudai/gojsondiff/formatter/ascii.go +++ b/vendor/github.com/yudai/gojsondiff/formatter/ascii.go @@ -201,16 +201,16 @@ func (f *AsciiFormatter) processItem(value interface{}, deltas []diff.Delta, pos return nil } -func (f *AsciiFormatter) searchDeltas(deltas []diff.Delta, postion diff.Position) (results []diff.Delta) { +func (f *AsciiFormatter) searchDeltas(deltas []diff.Delta, position diff.Position) (results []diff.Delta) { results = make([]diff.Delta, 0) for _, delta := range deltas { switch delta.(type) { case diff.PostDelta: - if delta.(diff.PostDelta).PostPosition() == postion { + if delta.(diff.PostDelta).PostPosition() == position { results = append(results, delta) } case diff.PreDelta: - if delta.(diff.PreDelta).PrePosition() == postion { + if delta.(diff.PreDelta).PrePosition() == position { results = append(results, delta) } default: @@ -362,7 +362,7 @@ func (f *AsciiFormatter) printRecursive(name string, value interface{}, marker s func sortedKeys(m map[string]interface{}) (keys []string) { keys = make([]string, 0, len(m)) - for key, _ := range m { + for key := range m { keys = append(keys, key) } sort.Strings(keys) diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE index a68e67f01..866d74a7a 100644 --- a/vendor/gopkg.in/yaml.v2/LICENSE +++ b/vendor/gopkg.in/yaml.v2/LICENSE @@ -1,188 +1,13 @@ +Copyright 2011-2016 Canonical Ltd. -Copyright (c) 2011-2014 - Canonical Inc. +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 -This software is licensed under the LGPLv3, included below. + http://www.apache.org/licenses/LICENSE-2.0 -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. +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/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go index 085cddc44..052ecfcd1 100644 --- a/vendor/gopkg.in/yaml.v2/decode.go +++ b/vendor/gopkg.in/yaml.v2/decode.go @@ -120,7 +120,6 @@ func (p *parser) parse() *node { default: panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) } - panic("unreachable") } func (p *parser) node(kind int) *node { @@ -251,7 +250,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { // // If n holds a null value, prepare returns before doing anything. func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { - if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") { + if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) { return out, false, false } again := true diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go index 2befd553e..6ecdcb3c7 100644 --- a/vendor/gopkg.in/yaml.v2/emitterc.go +++ b/vendor/gopkg.in/yaml.v2/emitterc.go @@ -666,7 +666,6 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, return yaml_emitter_set_emitter_error(emitter, "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS") } - return false } // Expect ALIAS. diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go index 0a7037ad1..81d05dfe5 100644 --- a/vendor/gopkg.in/yaml.v2/parserc.go +++ b/vendor/gopkg.in/yaml.v2/parserc.go @@ -166,7 +166,6 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool default: panic("invalid parser state") } - return false } // Parse the production: diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go index d5fb09727..f45079171 100644 --- a/vendor/gopkg.in/yaml.v2/readerc.go +++ b/vendor/gopkg.in/yaml.v2/readerc.go @@ -247,7 +247,7 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { if parser.encoding == yaml_UTF16LE_ENCODING { low, high = 0, 1 } else { - high, low = 1, 0 + low, high = 1, 0 } // The UTF-16 encoding is not as simple as one might @@ -357,23 +357,26 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { if value <= 0x7F { // 0000 0000-0000 007F . 0xxxxxxx parser.buffer[buffer_len+0] = byte(value) + buffer_len += 1 } else if value <= 0x7FF { // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) + buffer_len += 2 } else if value <= 0xFFFF { // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) + buffer_len += 3 } else { // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) + buffer_len += 4 } - buffer_len += width parser.unread++ } diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go index 93a863274..232313cc0 100644 --- a/vendor/gopkg.in/yaml.v2/resolve.go +++ b/vendor/gopkg.in/yaml.v2/resolve.go @@ -3,6 +3,7 @@ package yaml import ( "encoding/base64" "math" + "regexp" "strconv" "strings" "unicode/utf8" @@ -80,6 +81,8 @@ func resolvableTag(tag string) bool { return false } +var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`) + func resolve(tag string, in string) (rtag string, out interface{}) { if !resolvableTag(tag) { return tag, in @@ -135,9 +138,11 @@ func resolve(tag string, in string) (rtag string, out interface{}) { if err == nil { return yaml_INT_TAG, uintv } - floatv, err := strconv.ParseFloat(plain, 64) - if err == nil { - return yaml_FLOAT_TAG, floatv + if yamlStyleFloat.MatchString(plain) { + floatv, err := strconv.ParseFloat(plain, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } } if strings.HasPrefix(plain, "0b") { intv, err := strconv.ParseInt(plain[2:], 2, 64) diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go index d97d76fa5..2c9d5111f 100644 --- a/vendor/gopkg.in/yaml.v2/scannerc.go +++ b/vendor/gopkg.in/yaml.v2/scannerc.go @@ -9,7 +9,7 @@ import ( // ************ // // The following notes assume that you are familiar with the YAML specification -// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in +// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in // some cases we are less restrictive that it requires. // // The process of transforming a YAML stream into a sequence of events is @@ -1546,7 +1546,7 @@ func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool // Unknown directive. } else { yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found uknown directive name") + start_mark, "found unknown directive name") return false } diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go index d133edf9d..36d6b883a 100644 --- a/vendor/gopkg.in/yaml.v2/yaml.go +++ b/vendor/gopkg.in/yaml.v2/yaml.go @@ -222,7 +222,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) { inlineMap := -1 for i := 0; i != n; i++ { field := st.Field(i) - if field.PkgPath != "" { + if field.PkgPath != "" && !field.Anonymous { continue // Private field } From b4c17a05ee1bbca0ba2b95b27d8460ec3cf308b0 Mon Sep 17 00:00:00 2001 From: tamal Date: Tue, 27 Jun 2017 09:35:23 -0700 Subject: [PATCH 05/18] added-all --- pkg/init.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index 778796141..2980ce0de 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -4,8 +4,11 @@ import ( "fmt" "io" "strings" - + tapi "github.com/k8sdb/apimachinery/api" "github.com/appscode/go/types" + batch "k8s.io/client-go/pkg/apis/batch/v1" + + apps "k8s.io/client-go/pkg/apis/apps/v1beta1" "github.com/k8sdb/apimachinery/pkg/docker" "github.com/k8sdb/cli/pkg/kube" "github.com/k8sdb/cli/pkg/util" @@ -175,7 +178,56 @@ func rbacstuff(client kubernetes.Interface, namespace, serviceAccount, version s Name: docker.OperatorName, }, Rules: []rbac.PolicyRule{ - {}, + { + APIGroups: []string{extensions.GroupName}, + Resources: []string{"thirdpartyresources"}, + Verbs: []string{"get", "create"}, + }, + { + APIGroups: []string{tapi.GroupName}, + Resources: []string{rbac.ResourceAll}, + Verbs: []string{rbac.VerbAll}, + }, + { + APIGroups: []string{extensions.GroupName}, + Resources: []string{"deployments"}, + Verbs: []string{"create", "get", "update"}, + }, + { + APIGroups: []string{apps.GroupName}, + Resources: []string{"deployments"}, + Verbs: []string{"create", "get", "update"}, + }, + { + APIGroups: []string{apps.GroupName}, + Resources: []string{"statefulsets"}, + Verbs: []string{rbac.VerbAll}, + }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"secrets", "services"}, + Verbs: []string{rbac.VerbAll}, + }, + { + APIGroups: []string{batch.GroupName}, + Resources: []string{"jobs"}, + Verbs: []string{"create", "delete"}, + }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"events"}, + Verbs: []string{"create"}, + }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"pods"}, + Verbs: []string{"get", "list", "delete"}, + }, + { + APIGroups: []string{"monitoring.coreos.com"}, + Resources: []string{"servicemonitors"}, + Verbs: []string{"get", "create", "update"}, + }, }, } client.RbacV1beta1().ClusterRoles().Create(&role) From 454f5c1d6dd475e4520d1158157581421d827084 Mon Sep 17 00:00:00 2001 From: shahriar Date: Mon, 3 Jul 2017 17:34:41 +0600 Subject: [PATCH 06/18] fix --- pkg/init.go | 104 ++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index 2980ce0de..42ab6c432 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -4,11 +4,9 @@ import ( "fmt" "io" "strings" - tapi "github.com/k8sdb/apimachinery/api" - "github.com/appscode/go/types" - batch "k8s.io/client-go/pkg/apis/batch/v1" - apps "k8s.io/client-go/pkg/apis/apps/v1beta1" + "github.com/appscode/go/types" + //tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" "github.com/k8sdb/cli/pkg/kube" "github.com/k8sdb/cli/pkg/util" @@ -18,6 +16,8 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" apiv1 "k8s.io/client-go/pkg/api/v1" + //apps "k8s.io/client-go/pkg/apis/apps/v1beta1" + batch "k8s.io/client-go/pkg/apis/batch/v1" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" rbac "k8s.io/client-go/pkg/apis/rbac/v1beta1" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -56,10 +56,6 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { namespace := cmdutil.GetFlagString(cmd, "operator-namespace") version := cmdutil.GetFlagString(cmd, "version") configureRBAC := cmdutil.GetFlagBool(cmd, "rbac") - serviceAccount := apiv1.NamespaceDefault - if configureRBAC { - serviceAccount = docker.OperatorName - } client, err := kube.NewKubeClient(cmd) if err != nil { @@ -120,6 +116,14 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { return nil } + serviceAccount := apiv1.NamespaceDefault + if configureRBAC { + serviceAccount = docker.OperatorName + if err := rbacStuff(client, namespace, serviceAccount); err != nil { + return err + } + } + if err := createOperatorDeployment(client, namespace, serviceAccount, version); err != nil { if kerr.IsAlreadyExists(err) { fmt.Fprintln(errOut, "Operator deployment already exists.") @@ -152,28 +156,8 @@ var operatorLabel = map[string]string{ "app": docker.OperatorName, } -func rbacstuff(client kubernetes.Interface, namespace, serviceAccount, version string) error { - roleBinding := rbac.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: docker.OperatorName, - Namespace: namespace, - }, - RoleRef: rbac.RoleRef{ - APIGroup: rbac.GroupName, - Kind: "ClusterRole", - Name: docker.OperatorName, - }, - Subjects: []rbac.Subject{ - { - Kind: rbac.ServiceAccountKind, - Name: docker.OperatorName, - Namespace: namespace, - }, - }, - } - client.RbacV1beta1().ClusterRoleBindings().Create(&roleBinding) - - role := rbac.ClusterRole{ +func rbacStuff(client kubernetes.Interface, namespace, serviceAccount string) error { + role := &rbac.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, }, @@ -183,35 +167,25 @@ func rbacstuff(client kubernetes.Interface, namespace, serviceAccount, version s Resources: []string{"thirdpartyresources"}, Verbs: []string{"get", "create"}, }, - { + /*{ APIGroups: []string{tapi.GroupName}, Resources: []string{rbac.ResourceAll}, - Verbs: []string{rbac.VerbAll}, - }, - { - APIGroups: []string{extensions.GroupName}, - Resources: []string{"deployments"}, - Verbs: []string{"create", "get", "update"}, - }, - { - APIGroups: []string{apps.GroupName}, - Resources: []string{"deployments"}, - Verbs: []string{"create", "get", "update"}, - }, - { + Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, + },*/ + /*{ APIGroups: []string{apps.GroupName}, Resources: []string{"statefulsets"}, - Verbs: []string{rbac.VerbAll}, + Verbs: []string{"get", "create", "update", "delete"}, }, { APIGroups: []string{apiv1.GroupName}, - Resources: []string{"secrets", "services"}, - Verbs: []string{rbac.VerbAll}, - }, + Resources: []string{"services", "secrets"}, + Verbs: []string{"get", "create", "delete"}, + },*/ { APIGroups: []string{batch.GroupName}, Resources: []string{"jobs"}, - Verbs: []string{"create", "delete"}, + Verbs: []string{"get", "create", "delete"}, }, { APIGroups: []string{apiv1.GroupName}, @@ -230,15 +204,41 @@ func rbacstuff(client kubernetes.Interface, namespace, serviceAccount, version s }, }, } - client.RbacV1beta1().ClusterRoles().Create(&role) + if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { + return err + } - sa := apiv1.ServiceAccount{ + sa := &apiv1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceAccount, + Namespace: namespace, + }, + } + if _, err := client.CoreV1().ServiceAccounts(namespace).Create(sa); err != nil { + return err + } + + roleBinding := &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, Namespace: namespace, }, + RoleRef: rbac.RoleRef{ + APIGroup: rbac.GroupName, + Kind: "ClusterRole", + Name: docker.OperatorName, + }, + Subjects: []rbac.Subject{ + { + Kind: rbac.ServiceAccountKind, + Name: serviceAccount, + Namespace: namespace, + }, + }, + } + if _, err := client.RbacV1beta1().ClusterRoleBindings().Create(roleBinding); err != nil { + return err } - client.CoreV1().ServiceAccounts(namespace).Create(&sa) return nil } From f5dbf2bc0244a6db49bd035ed12415cfda1c4fe6 Mon Sep 17 00:00:00 2001 From: shahriar Date: Mon, 3 Jul 2017 18:36:49 +0600 Subject: [PATCH 07/18] fix --- pkg/init.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/init.go b/pkg/init.go index 42ab6c432..f69d2a0e9 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/appscode/go/types" - //tapi "github.com/k8sdb/apimachinery/api" + tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" "github.com/k8sdb/cli/pkg/kube" "github.com/k8sdb/cli/pkg/util" @@ -16,7 +16,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" apiv1 "k8s.io/client-go/pkg/api/v1" - //apps "k8s.io/client-go/pkg/apis/apps/v1beta1" + apps "k8s.io/client-go/pkg/apis/apps/v1beta1" batch "k8s.io/client-go/pkg/apis/batch/v1" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" rbac "k8s.io/client-go/pkg/apis/rbac/v1beta1" @@ -167,12 +167,12 @@ func rbacStuff(client kubernetes.Interface, namespace, serviceAccount string) er Resources: []string{"thirdpartyresources"}, Verbs: []string{"get", "create"}, }, - /*{ + { APIGroups: []string{tapi.GroupName}, Resources: []string{rbac.ResourceAll}, Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, - },*/ - /*{ + }, + { APIGroups: []string{apps.GroupName}, Resources: []string{"statefulsets"}, Verbs: []string{"get", "create", "update", "delete"}, @@ -181,7 +181,7 @@ func rbacStuff(client kubernetes.Interface, namespace, serviceAccount string) er APIGroups: []string{apiv1.GroupName}, Resources: []string{"services", "secrets"}, Verbs: []string{"get", "create", "delete"}, - },*/ + }, { APIGroups: []string{batch.GroupName}, Resources: []string{"jobs"}, From f3c572cb2ef8a9263ce9dc07c3b474f5d83ad42d Mon Sep 17 00:00:00 2001 From: shahriar Date: Mon, 3 Jul 2017 18:45:26 +0600 Subject: [PATCH 08/18] fix --- pkg/init.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/init.go b/pkg/init.go index f69d2a0e9..41c6b6431 100644 --- a/pkg/init.go +++ b/pkg/init.go @@ -197,6 +197,11 @@ func rbacStuff(client kubernetes.Interface, namespace, serviceAccount string) er Resources: []string{"pods"}, Verbs: []string{"get", "list", "delete"}, }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"persistentvolumeclaims"}, + Verbs: []string{"list", "delete"}, + }, { APIGroups: []string{"monitoring.coreos.com"}, Resources: []string{"servicemonitors"}, @@ -204,6 +209,7 @@ func rbacStuff(client kubernetes.Interface, namespace, serviceAccount string) er }, }, } + if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { return err } From e5b1261c4e3629f1a79e65107c0eb771dd2b7104 Mon Sep 17 00:00:00 2001 From: shahriar Date: Tue, 4 Jul 2017 12:38:07 +0600 Subject: [PATCH 09/18] fixed --- pkg/cmds/init.go | 17 +++-- pkg/roles/role.go | 188 ++++++++++++++++++++++++++-------------------- 2 files changed, 119 insertions(+), 86 deletions(-) diff --git a/pkg/cmds/init.go b/pkg/cmds/init.go index dbba13c68..733c0ea16 100644 --- a/pkg/cmds/init.go +++ b/pkg/cmds/init.go @@ -6,9 +6,9 @@ import ( "strings" "github.com/appscode/go/types" - tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" "github.com/k8sdb/cli/pkg/kube" + "github.com/k8sdb/cli/pkg/roles" "github.com/k8sdb/cli/pkg/util" "github.com/spf13/cobra" kerr "k8s.io/apimachinery/pkg/api/errors" @@ -16,10 +16,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" apiv1 "k8s.io/client-go/pkg/api/v1" - apps "k8s.io/client-go/pkg/apis/apps/v1beta1" - batch "k8s.io/client-go/pkg/apis/batch/v1" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" - rbac "k8s.io/client-go/pkg/apis/rbac/v1beta1" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) @@ -105,6 +102,15 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { deployment.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%v:%v", docker.ImageOperator, version) + serviceAccount := apiv1.NamespaceDefault + if configureRBAC { + serviceAccount = docker.OperatorName + if err := roles.EnsureRBACStuff(client, namespace); err != nil { + return err + } + } + deployment.Spec.Template.Spec.ServiceAccountName = serviceAccount + if err := updateOperatorDeployment(client, deployment); err != nil { return err } @@ -119,7 +125,7 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { serviceAccount := apiv1.NamespaceDefault if configureRBAC { serviceAccount = docker.OperatorName - if err := rbacStuff(client, namespace, serviceAccount); err != nil { + if err := roles.EnsureRBACStuff(client, namespace); err != nil { return err } } @@ -156,7 +162,6 @@ var operatorLabel = map[string]string{ "app": "kubedb", } - func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAccount, version string) error { deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/roles/role.go b/pkg/roles/role.go index b23a1074f..2d996927d 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -1,8 +1,11 @@ package roles import ( + "fmt" + tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" + kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" apiv1 "k8s.io/client-go/pkg/api/v1" @@ -60,101 +63,126 @@ var policyRuleOperator = []rbac.PolicyRule{ }, } +var policyRuleChild = []rbac.PolicyRule{ + { + APIGroups: []string{tapi.GroupName}, + Resources: []string{tapi.ResourceTypePostgres, tapi.ResourceTypeElastic}, + Verbs: []string{"get"}, + }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"secrets"}, + Verbs: []string{"get"}, + }, +} + func EnsureRBACStuff(client kubernetes.Interface, namespace string) error { - operatorName := docker.OperatorName + name := docker.OperatorName - if _, err := client.RbacV1beta1().ClusterRoles().Create(operatorName, metav1.GetOptions{}); err != nil { - return err + // Ensure ClusterRoles for operator + clusterRoleOperator, err := client.RbacV1beta1().ClusterRoles().Get(name, metav1.GetOptions{}) + if err != nil { + if !kerr.IsNotFound(err) { + return err + } + // Create new one + role := &rbac.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Rules: policyRuleOperator, + } + if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { + return err + } + } else { + // Update existing one + clusterRoleOperator.Rules = policyRuleOperator + if _, err := client.RbacV1beta1().ClusterRoles().Update(clusterRoleOperator); err != nil { + return err + } } - - role := &rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: docker.OperatorName, - }, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{extensions.GroupName}, - Resources: []string{"thirdpartyresources"}, - Verbs: []string{"get", "create"}, - }, - { - APIGroups: []string{tapi.GroupName}, - Resources: []string{rbac.ResourceAll}, - Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, - }, - { - APIGroups: []string{apps.GroupName}, - Resources: []string{"statefulsets"}, - Verbs: []string{"get", "create", "update", "delete"}, - }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"services", "secrets"}, - Verbs: []string{"get", "create", "delete"}, - }, - { - APIGroups: []string{batch.GroupName}, - Resources: []string{"jobs"}, - Verbs: []string{"get", "create", "delete"}, - }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"events"}, - Verbs: []string{"create"}, + // Ensure ClusterRoles for database statefulsets + childRoleName := fmt.Sprintf("%v-child", name) + clusterRoleChild, err := client.RbacV1beta1().ClusterRoles().Get(childRoleName, metav1.GetOptions{}) + if err != nil { + if !kerr.IsNotFound(err) { + return err + } + // Create new one + role := &rbac.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: childRoleName, }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"pods"}, - Verbs: []string{"get", "list", "delete"}, - }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"persistentvolumeclaims"}, - Verbs: []string{"list", "delete"}, - }, - { - APIGroups: []string{"monitoring.coreos.com"}, - Resources: []string{"servicemonitors"}, - Verbs: []string{"get", "create", "update"}, - }, - }, + Rules: policyRuleChild, + } + if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { + return err + } + } else { + // Update existing one + clusterRoleChild.Rules = policyRuleChild + if _, err := client.RbacV1beta1().ClusterRoles().Update(clusterRoleChild); err != nil { + return err + } } - if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { - return err + // Ensure ServiceAccounts + if _, err := client.CoreV1().ServiceAccounts(namespace).Get(name, metav1.GetOptions{}); err != nil { + if !kerr.IsNotFound(err) { + return err + } + sa := &apiv1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + if _, err := client.CoreV1().ServiceAccounts(namespace).Create(sa); err != nil { + return err + } } - sa := &apiv1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: serviceAccount, + var roleBindingRef = rbac.RoleRef{ + APIGroup: rbac.GroupName, + Kind: "ClusterRole", + Name: name, + } + var roleBindingSubjects = []rbac.Subject{ + { + Kind: rbac.ServiceAccountKind, + Name: name, Namespace: namespace, }, } - if _, err := client.CoreV1().ServiceAccounts(namespace).Create(sa); err != nil { - return err - } - roleBinding := &rbac.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: docker.OperatorName, - Namespace: namespace, - }, - RoleRef: rbac.RoleRef{ - APIGroup: rbac.GroupName, - Kind: "ClusterRole", - Name: docker.OperatorName, - }, - Subjects: []rbac.Subject{ - { - Kind: rbac.ServiceAccountKind, - Name: serviceAccount, + // Ensure ClusterRoleBindings + roleBinding, err := client.RbacV1beta1().ClusterRoleBindings().Get(name, metav1.GetOptions{}) + if err != nil { + if !kerr.IsNotFound(err) { + return err + } + + roleBinding := &rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, Namespace: namespace, }, - }, - } - if _, err := client.RbacV1beta1().ClusterRoleBindings().Create(roleBinding); err != nil { - return err + RoleRef: roleBindingRef, + Subjects: roleBindingSubjects, + } + + if _, err := client.RbacV1beta1().ClusterRoleBindings().Create(roleBinding); err != nil { + return err + } + + } else { + roleBinding.RoleRef = roleBindingRef + roleBinding.Subjects = roleBindingSubjects + if _, err := client.RbacV1beta1().ClusterRoleBindings().Update(roleBinding); err != nil { + return err + } } return nil From c1368f019611b582723ad97fc1f9fe2fe8563674 Mon Sep 17 00:00:00 2001 From: shahriar Date: Tue, 4 Jul 2017 16:34:14 +0600 Subject: [PATCH 10/18] fix --- .../postgres-with-scheduled-backup.yaml | 6 ++-- docs/examples/postgres/snapshot.yaml | 6 ++-- pkg/cmds/init.go | 22 +++++++++++-- pkg/roles/role.go | 31 ++++++++++++------- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/docs/examples/postgres/postgres-with-scheduled-backup.yaml b/docs/examples/postgres/postgres-with-scheduled-backup.yaml index def2509f5..f5ea63e49 100644 --- a/docs/examples/postgres/postgres-with-scheduled-backup.yaml +++ b/docs/examples/postgres/postgres-with-scheduled-backup.yaml @@ -6,6 +6,6 @@ spec: version: 9.5 backupSchedule: cronExpression: "@every 6h" - bucketName: "bucket-for-snapshot" - storageSecret: - secretName: "secret-for-bucket" + storageSecretName: "secret-for-bucket" + gcs: + bucket: "bucket-for-snapshot" diff --git a/docs/examples/postgres/snapshot.yaml b/docs/examples/postgres/snapshot.yaml index 4f195d5d8..ce5db4c37 100644 --- a/docs/examples/postgres/snapshot.yaml +++ b/docs/examples/postgres/snapshot.yaml @@ -6,6 +6,6 @@ metadata: kubedb.com/kind: Postgres spec: databaseName: postgres-db - bucketName: "bucket-for-snapshot" - storageSecret: - secretName: "secret-for-bucket" + storageSecretName: "google-cred" + gcs: + bucket: "restik" diff --git a/pkg/cmds/init.go b/pkg/cmds/init.go index 733c0ea16..7a94bd13f 100644 --- a/pkg/cmds/init.go +++ b/pkg/cmds/init.go @@ -105,10 +105,22 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { serviceAccount := apiv1.NamespaceDefault if configureRBAC { serviceAccount = docker.OperatorName - if err := roles.EnsureRBACStuff(client, namespace); err != nil { + if err := roles.EnsureRBACStuff(client, namespace, serviceAccount); err != nil { return err } } + + clusterRole := serviceAccount + if clusterRole != "default" { + clusterRole = fmt.Sprintf("%v-child", serviceAccount) + } + deployment.Spec.Template.Spec.Containers[0].Args = []string{ + "run", + fmt.Sprintf("--address=:%v", docker.OperatorPortNumber), + fmt.Sprintf("--cluster-role=%v", clusterRole), + "--v=3", + } + deployment.Spec.Template.Spec.ServiceAccountName = serviceAccount if err := updateOperatorDeployment(client, deployment); err != nil { @@ -125,7 +137,7 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { serviceAccount := apiv1.NamespaceDefault if configureRBAC { serviceAccount = docker.OperatorName - if err := roles.EnsureRBACStuff(client, namespace); err != nil { + if err := roles.EnsureRBACStuff(client, namespace, serviceAccount); err != nil { return err } } @@ -163,6 +175,11 @@ var operatorLabel = map[string]string{ } func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAccount, version string) error { + clusterRole := serviceAccount + if clusterRole != "default" { + clusterRole = fmt.Sprintf("%v-child", serviceAccount) + } + deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, @@ -183,6 +200,7 @@ func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAcc Args: []string{ "run", fmt.Sprintf("--address=:%v", docker.OperatorPortNumber), + fmt.Sprintf("--cluster-role=%v", clusterRole), "--v=3", }, Env: []apiv1.EnvVar{ diff --git a/pkg/roles/role.go b/pkg/roles/role.go index 2d996927d..6e8a4394b 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -4,7 +4,6 @@ import ( "fmt" tapi "github.com/k8sdb/apimachinery/api" - "github.com/k8sdb/apimachinery/pkg/docker" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -22,9 +21,14 @@ var policyRuleOperator = []rbac.PolicyRule{ Verbs: []string{"get", "create"}, }, { - APIGroups: []string{tapi.GroupName}, - Resources: []string{rbac.ResourceAll}, - Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, + APIGroups: []string{rbac.GroupName}, + Resources: []string{"clusterroles", "clusterrolebindings"}, + Verbs: []string{"get", "create", "update"}, + }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"serviceaccounts"}, + Verbs: []string{"get", "create"}, }, { APIGroups: []string{apps.GroupName}, @@ -41,11 +45,6 @@ var policyRuleOperator = []rbac.PolicyRule{ Resources: []string{"jobs"}, Verbs: []string{"get", "create", "delete"}, }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"events"}, - Verbs: []string{"create"}, - }, { APIGroups: []string{apiv1.GroupName}, Resources: []string{"pods"}, @@ -56,6 +55,16 @@ var policyRuleOperator = []rbac.PolicyRule{ Resources: []string{"persistentvolumeclaims"}, Verbs: []string{"list", "delete"}, }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"events"}, + Verbs: []string{"create"}, + }, + { + APIGroups: []string{tapi.GroupName}, + Resources: []string{rbac.ResourceAll}, + Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, + }, { APIGroups: []string{"monitoring.coreos.com"}, Resources: []string{"servicemonitors"}, @@ -76,9 +85,7 @@ var policyRuleChild = []rbac.PolicyRule{ }, } -func EnsureRBACStuff(client kubernetes.Interface, namespace string) error { - name := docker.OperatorName - +func EnsureRBACStuff(client kubernetes.Interface, namespace, name string) error { // Ensure ClusterRoles for operator clusterRoleOperator, err := client.RbacV1beta1().ClusterRoles().Get(name, metav1.GetOptions{}) if err != nil { From 3104a761dcf90c9022d66f022b68eb519df8a25b Mon Sep 17 00:00:00 2001 From: shahriar Date: Tue, 4 Jul 2017 16:49:42 +0600 Subject: [PATCH 11/18] fixed --- docs/examples/postgres/snapshot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/postgres/snapshot.yaml b/docs/examples/postgres/snapshot.yaml index ce5db4c37..a3cdeebf8 100644 --- a/docs/examples/postgres/snapshot.yaml +++ b/docs/examples/postgres/snapshot.yaml @@ -8,4 +8,4 @@ spec: databaseName: postgres-db storageSecretName: "google-cred" gcs: - bucket: "restik" + bucket: "restic" From dc151dd7c017c40429e48c847ceabd3089a4db48 Mon Sep 17 00:00:00 2001 From: shahriar Date: Wed, 5 Jul 2017 17:37:38 +0600 Subject: [PATCH 12/18] fixed --- pkg/cmds/init.go | 44 +++++++++++------------------------ pkg/roles/role.go | 59 +++++++++++------------------------------------ 2 files changed, 27 insertions(+), 76 deletions(-) diff --git a/pkg/cmds/init.go b/pkg/cmds/init.go index 7a94bd13f..cffefcea6 100644 --- a/pkg/cmds/init.go +++ b/pkg/cmds/init.go @@ -102,27 +102,22 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { deployment.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%v:%v", docker.ImageOperator, version) - serviceAccount := apiv1.NamespaceDefault if configureRBAC { - serviceAccount = docker.OperatorName - if err := roles.EnsureRBACStuff(client, namespace, serviceAccount); err != nil { + if err := roles.EnsureRBACStuff(client, namespace); err != nil { return err } + deployment.Spec.Template.Spec.ServiceAccountName = roles.ServiceAccountName + } else { + deployment.Spec.Template.Spec.ServiceAccountName = "" } - clusterRole := serviceAccount - if clusterRole != "default" { - clusterRole = fmt.Sprintf("%v-child", serviceAccount) - } deployment.Spec.Template.Spec.Containers[0].Args = []string{ "run", fmt.Sprintf("--address=:%v", docker.OperatorPortNumber), - fmt.Sprintf("--cluster-role=%v", clusterRole), + fmt.Sprintf("--rbac=%v", configureRBAC), "--v=3", } - deployment.Spec.Template.Spec.ServiceAccountName = serviceAccount - if err := updateOperatorDeployment(client, deployment); err != nil { return err } @@ -134,15 +129,13 @@ func RunInit(cmd *cobra.Command, out, errOut io.Writer) error { return nil } - serviceAccount := apiv1.NamespaceDefault if configureRBAC { - serviceAccount = docker.OperatorName - if err := roles.EnsureRBACStuff(client, namespace, serviceAccount); err != nil { + if err := roles.EnsureRBACStuff(client, namespace); err != nil { return err } } - if err := createOperatorDeployment(client, namespace, serviceAccount, version); err != nil { + if err := createOperatorDeployment(client, namespace, version, configureRBAC); err != nil { if kerr.IsAlreadyExists(err) { fmt.Fprintln(errOut, "Operator deployment already exists.") } else { @@ -174,12 +167,7 @@ var operatorLabel = map[string]string{ "app": "kubedb", } -func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAccount, version string) error { - clusterRole := serviceAccount - if clusterRole != "default" { - clusterRole = fmt.Sprintf("%v-child", serviceAccount) - } - +func createOperatorDeployment(client kubernetes.Interface, namespace, version string, configureRBAC bool) error { deployment := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: docker.OperatorName, @@ -200,7 +188,7 @@ func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAcc Args: []string{ "run", fmt.Sprintf("--address=:%v", docker.OperatorPortNumber), - fmt.Sprintf("--cluster-role=%v", clusterRole), + fmt.Sprintf("--rbac=%v", configureRBAC), "--v=3", }, Env: []apiv1.EnvVar{ @@ -213,15 +201,6 @@ func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAcc }, }, }, - { - Name: "OPERATOR_SERVICE_ACCOUNT", - ValueFrom: &apiv1.EnvVarSource{ - FieldRef: &apiv1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "spec.serviceAccountName", - }, - }, - }, }, Ports: []apiv1.ContainerPort{ { @@ -232,12 +211,15 @@ func createOperatorDeployment(client kubernetes.Interface, namespace, serviceAcc }, }, }, - ServiceAccountName: serviceAccount, }, }, }, } + if configureRBAC { + deployment.Spec.Template.Spec.ServiceAccountName = roles.ServiceAccountName + } + _, err := client.ExtensionsV1beta1().Deployments(namespace).Create(deployment) return err } diff --git a/pkg/roles/role.go b/pkg/roles/role.go index 6e8a4394b..acf387024 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -1,9 +1,8 @@ package roles import ( - "fmt" - tapi "github.com/k8sdb/apimachinery/api" + "github.com/k8sdb/apimachinery/pkg/docker" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -14,6 +13,8 @@ import ( rbac "k8s.io/client-go/pkg/apis/rbac/v1beta1" ) +const ServiceAccountName = docker.OperatorName + var policyRuleOperator = []rbac.PolicyRule{ { APIGroups: []string{extensions.GroupName}, @@ -22,13 +23,18 @@ var policyRuleOperator = []rbac.PolicyRule{ }, { APIGroups: []string{rbac.GroupName}, - Resources: []string{"clusterroles", "clusterrolebindings"}, - Verbs: []string{"get", "create", "update"}, + Resources: []string{"roles"}, + Verbs: []string{"get", "create", "delete"}, + }, + { + APIGroups: []string{rbac.GroupName}, + Resources: []string{"rolebindings"}, + Verbs: []string{"create", "delete"}, }, { APIGroups: []string{apiv1.GroupName}, Resources: []string{"serviceaccounts"}, - Verbs: []string{"get", "create"}, + Verbs: []string{"create", "delete"}, }, { APIGroups: []string{apps.GroupName}, @@ -48,7 +54,7 @@ var policyRuleOperator = []rbac.PolicyRule{ { APIGroups: []string{apiv1.GroupName}, Resources: []string{"pods"}, - Verbs: []string{"get", "list", "delete"}, + Verbs: []string{"get", "list", "delete", "deletecollection"}, }, { APIGroups: []string{apiv1.GroupName}, @@ -72,20 +78,8 @@ var policyRuleOperator = []rbac.PolicyRule{ }, } -var policyRuleChild = []rbac.PolicyRule{ - { - APIGroups: []string{tapi.GroupName}, - Resources: []string{tapi.ResourceTypePostgres, tapi.ResourceTypeElastic}, - Verbs: []string{"get"}, - }, - { - APIGroups: []string{apiv1.GroupName}, - Resources: []string{"secrets"}, - Verbs: []string{"get"}, - }, -} - -func EnsureRBACStuff(client kubernetes.Interface, namespace, name string) error { +func EnsureRBACStuff(client kubernetes.Interface, namespace string) error { + name := ServiceAccountName // Ensure ClusterRoles for operator clusterRoleOperator, err := client.RbacV1beta1().ClusterRoles().Get(name, metav1.GetOptions{}) if err != nil { @@ -110,31 +104,6 @@ func EnsureRBACStuff(client kubernetes.Interface, namespace, name string) error } } - // Ensure ClusterRoles for database statefulsets - childRoleName := fmt.Sprintf("%v-child", name) - clusterRoleChild, err := client.RbacV1beta1().ClusterRoles().Get(childRoleName, metav1.GetOptions{}) - if err != nil { - if !kerr.IsNotFound(err) { - return err - } - // Create new one - role := &rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: childRoleName, - }, - Rules: policyRuleChild, - } - if _, err := client.RbacV1beta1().ClusterRoles().Create(role); err != nil { - return err - } - } else { - // Update existing one - clusterRoleChild.Rules = policyRuleChild - if _, err := client.RbacV1beta1().ClusterRoles().Update(clusterRoleChild); err != nil { - return err - } - } - // Ensure ServiceAccounts if _, err := client.CoreV1().ServiceAccounts(namespace).Get(name, metav1.GetOptions{}); err != nil { if !kerr.IsNotFound(err) { From 5fdd01f99307dbe04f4a5ba30b4d0d7abd89b72d Mon Sep 17 00:00:00 2001 From: shahriar Date: Fri, 7 Jul 2017 10:40:50 +0600 Subject: [PATCH 13/18] fixed --- .../elastic-with-scheduled-backup.yaml | 6 +- docs/examples/elastic/snapshot.yaml | 8 +- docs/examples/postgres/snapshot-local.yaml | 12 ++ docs/examples/postgres/snapshot.yaml | 4 +- glide.lock | 12 +- pkg/validator/validate.go | 2 +- .../k8sdb/apimachinery/api/elastic_types.go | 3 + .../k8sdb/apimachinery/api/helpers.go | 144 ++++++++++++++++++ .../k8sdb/apimachinery/api/postgres_types.go | 2 + .../k8sdb/apimachinery/api/register.go | 8 +- .../k8sdb/apimachinery/api/snapshot_types.go | 3 + .../k8sdb/apimachinery/api/types.go | 13 +- .../apimachinery/pkg/controller/controller.go | 5 +- .../k8sdb/apimachinery/pkg/controller/cron.go | 15 +- .../k8sdb/apimachinery/pkg/controller/lib.go | 6 +- .../apimachinery/pkg/controller/snapshot.go | 11 +- .../k8sdb/apimachinery/pkg/storage/osm.go | 59 +++---- .../apimachinery/pkg/validator/validate.go | 29 ++-- .../elasticsearch/pkg/validator/validate.go | 7 +- .../k8sdb/postgres/pkg/validator/validate.go | 7 +- vendor/k8s.io/kubernetes/pkg/api/helpers.go | 1 + vendor/k8s.io/kubernetes/pkg/version/base.go | 2 +- 22 files changed, 242 insertions(+), 117 deletions(-) create mode 100644 docs/examples/postgres/snapshot-local.yaml create mode 100644 vendor/github.com/k8sdb/apimachinery/api/helpers.go diff --git a/docs/examples/elastic/elastic-with-scheduled-backup.yaml b/docs/examples/elastic/elastic-with-scheduled-backup.yaml index 24fe7c34b..8af4ba6c2 100644 --- a/docs/examples/elastic/elastic-with-scheduled-backup.yaml +++ b/docs/examples/elastic/elastic-with-scheduled-backup.yaml @@ -7,6 +7,6 @@ spec: replicas: 1 backupSchedule: cronExpression: "@every 6h" - bucketName: "bucket-for-snapshot" - storageSecret: - secretName: "secret-for-bucket" + storageSecretName: "secret-for-bucket" + gcs: + bucket: "bucket-for-snapshot" diff --git a/docs/examples/elastic/snapshot.yaml b/docs/examples/elastic/snapshot.yaml index aeae378e2..af9e13e5a 100644 --- a/docs/examples/elastic/snapshot.yaml +++ b/docs/examples/elastic/snapshot.yaml @@ -1,11 +1,11 @@ apiVersion: kubedb.com/v1alpha1 kind: Snapshot metadata: - name: snapshot-xyz + name: snapshot-xyz-es labels: kubedb.com/kind: Elastic spec: databaseName: elasticsearch-db - bucketName: "bucket-for-snapshot" - storageSecret: - secretName: "secret-for-bucket" + storageSecretName: "google-cred" + gcs: + bucket: "restic" diff --git a/docs/examples/postgres/snapshot-local.yaml b/docs/examples/postgres/snapshot-local.yaml new file mode 100644 index 000000000..da8eafe17 --- /dev/null +++ b/docs/examples/postgres/snapshot-local.yaml @@ -0,0 +1,12 @@ +apiVersion: kubedb.com/v1alpha1 +kind: Snapshot +metadata: + name: snapshot-xyz-16 + labels: + kubedb.com/kind: Postgres +spec: + databaseName: postgres-db + local: + path: "/test" + volumeSource: + emptyDir: {} diff --git a/docs/examples/postgres/snapshot.yaml b/docs/examples/postgres/snapshot.yaml index a3cdeebf8..0c0f50489 100644 --- a/docs/examples/postgres/snapshot.yaml +++ b/docs/examples/postgres/snapshot.yaml @@ -6,6 +6,6 @@ metadata: kubedb.com/kind: Postgres spec: databaseName: postgres-db - storageSecretName: "google-cred" + storageSecretName: "secret-for-bucket" gcs: - bucket: "restic" + bucket: "bucket-for-snapshot" diff --git a/glide.lock b/glide.lock index 2177e4767..9ecb38c82 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: b737760e0f81a2850433fe5b9a0ddc1d6b15d93a1207fe0a607313978062c265 -updated: 2017-07-04T11:53:45.533670921+06:00 +updated: 2017-07-07T10:37:48.142224896+06:00 imports: - name: cloud.google.com/go version: fe3d41e1ecb2ce36ad3a979037c9b9a2b726226f @@ -212,7 +212,7 @@ imports: - name: github.com/juju/ratelimit version: 77ed1c8a01217656d2080ad51981f6e99adaa177 - name: github.com/k8sdb/apimachinery - version: cfbc99b5853355232cb2c6528aa9add2a28eeb4c + version: 5917fc8d1a327a444b7aeb0174a52b4dda9d33db subpackages: - api - api/install @@ -224,11 +224,11 @@ imports: - pkg/storage - pkg/validator - name: github.com/k8sdb/elasticsearch - version: 20f613b1ed7153e60352099b75434ea86152c706 + version: 5b70c117b44ceea3e8dc6bb8b7d929f0642f0e61 subpackages: - pkg/validator - name: github.com/k8sdb/postgres - version: e912a28c494089aff29b4bc4444fe9b1af4ff2e9 + version: e35afe4991856b68a00b33a91cb22f2769cf6fcc subpackages: - pkg/validator - name: github.com/mailru/easyjson @@ -402,7 +402,7 @@ imports: - third_party/forked/golang/netutil - third_party/forked/golang/reflect - name: k8s.io/apiserver - version: 3c5a3c8a9a4bac7e943cc4ffb8532e8ac0c08f7f + version: 087d1a2efeb6296f04bb0f54e7af9890052aa6d7 subpackages: - pkg/authentication/authenticator - pkg/authentication/serviceaccount @@ -505,7 +505,7 @@ imports: - util/integer - util/jsonpath - name: k8s.io/kubernetes - version: 7c3906a4eccd5a7cad245de0bd65337927a60bef + version: 313fd317f96265658831a576fafdd6ed85aaf428 subpackages: - federation/apis/federation - federation/apis/federation/install diff --git a/pkg/validator/validate.go b/pkg/validator/validate.go index f36c0f225..72574bffc 100644 --- a/pkg/validator/validate.go +++ b/pkg/validator/validate.go @@ -36,7 +36,7 @@ func Validate(client clientset.Interface, info *resource.Info) error { if err := yaml.Unmarshal(objByte, &snapshot); err != nil { return err } - return amv.ValidateSnapshot(client, snapshot) + return amv.ValidateSnapshotSpec(client, snapshot.Spec.SnapshotStorageSpec, info.Namespace) } return nil } diff --git a/vendor/github.com/k8sdb/apimachinery/api/elastic_types.go b/vendor/github.com/k8sdb/apimachinery/api/elastic_types.go index 987d96319..d20c88f3f 100644 --- a/vendor/github.com/k8sdb/apimachinery/api/elastic_types.go +++ b/vendor/github.com/k8sdb/apimachinery/api/elastic_types.go @@ -3,6 +3,7 @@ package api import ( "github.com/appscode/go/encoding/json/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "k8s.io/client-go/pkg/api/v1" ) const ( @@ -43,6 +44,8 @@ type ElasticSpec struct { // Monitor is used monitor database instance // +optional Monitor *MonitorSpec `json:"monitor,omitempty"` + // Compute Resources required by the sidecar container. + Resources apiv1.ResourceRequirements `json:"resources,omitempty"` } type ElasticStatus struct { diff --git a/vendor/github.com/k8sdb/apimachinery/api/helpers.go b/vendor/github.com/k8sdb/apimachinery/api/helpers.go new file mode 100644 index 000000000..672bdede4 --- /dev/null +++ b/vendor/github.com/k8sdb/apimachinery/api/helpers.go @@ -0,0 +1,144 @@ +package api + +import ( + "errors" + "path/filepath" + "strings" +) + +const ( + DatabaseNamePrefix = "kubedb" + + GenericKey = "kubedb.com" + + LabelDatabaseKind = GenericKey + "/kind" + LabelDatabaseName = GenericKey + "/name" + LabelJobType = GenericKey + "/job-type" + + PostgresKey = ResourceNamePostgres + "." + GenericKey + PostgresDatabaseVersion = PostgresKey + "/version" + + ElasticKey = ResourceNameElastic + ".kubedb.com" + ElasticDatabaseVersion = ElasticKey + "/version" + + SnapshotKey = ResourceNameSnapshot + "s.kubedb.com" + LabelSnapshotStatus = SnapshotKey + "/status" +) + +func (p Postgres) OffshootName() string { + return p.Name +} + +func (p Postgres) OffshootLabels() map[string]string { + return map[string]string{ + LabelDatabaseName: p.Name, + LabelDatabaseKind: ResourceKindPostgres, + } +} + +func (p Postgres) StatefulSetLabels() map[string]string { + labels := p.OffshootLabels() + for key, val := range p.Labels { + if !strings.HasPrefix(key, GenericKey+"/") && !strings.HasPrefix(key, PostgresKey+"/") { + labels[key] = val + } + } + return labels +} + +func (p Postgres) StatefulSetAnnotations() map[string]string { + annotations := make(map[string]string) + for key, val := range p.Annotations { + if !strings.HasPrefix(key, GenericKey+"/") && !strings.HasPrefix(key, PostgresKey+"/") { + annotations[key] = val + } + } + annotations[PostgresDatabaseVersion] = string(p.Spec.Version) + return annotations +} + +func (e Elastic) OffshootName() string { + return e.Name +} + +func (e Elastic) OffshootLabels() map[string]string { + return map[string]string{ + LabelDatabaseKind: ResourceKindElastic, + LabelDatabaseName: e.Name, + } +} + +func (e Elastic) StatefulSetLabels() map[string]string { + labels := e.OffshootLabels() + for key, val := range e.Labels { + if !strings.HasPrefix(key, GenericKey+"/") && !strings.HasPrefix(key, ElasticKey+"/") { + labels[key] = val + } + } + return labels +} + +func (e Elastic) StatefulSetAnnotations() map[string]string { + annotations := make(map[string]string) + for key, val := range e.Annotations { + if !strings.HasPrefix(key, GenericKey+"/") && !strings.HasPrefix(key, ElasticKey+"/") { + annotations[key] = val + } + } + annotations[ElasticDatabaseVersion] = string(e.Spec.Version) + return annotations +} + +func (s Snapshot) OffshootName() string { + return s.Name +} + +func (d DormantDatabase) OffshootName() string { + return d.Name +} + +func (s Snapshot) Location() (string, error) { + spec := s.Spec.SnapshotStorageSpec + if spec.S3 != nil { + return filepath.Join(spec.S3.Prefix, DatabaseNamePrefix, s.Namespace, s.Spec.DatabaseName), nil + } else if spec.GCS != nil { + return filepath.Join(spec.GCS.Prefix, DatabaseNamePrefix, s.Namespace, s.Spec.DatabaseName), nil + } else if spec.Azure != nil { + return filepath.Join(spec.Azure.Prefix, DatabaseNamePrefix, s.Namespace, s.Spec.DatabaseName), nil + } else if spec.Local != nil { + return filepath.Join(DatabaseNamePrefix, s.Namespace, s.Spec.DatabaseName), nil + } else if spec.Swift != nil { + return filepath.Join(spec.Swift.Prefix, DatabaseNamePrefix, s.Namespace, s.Spec.DatabaseName), nil + } + return "", errors.New("No storage provider is configured.") +} + +func (s SnapshotStorageSpec) Container() (string, error) { + if s.S3 != nil { + return s.S3.Bucket, nil + } else if s.GCS != nil { + return s.GCS.Bucket, nil + } else if s.Azure != nil { + return s.Azure.Container, nil + } else if s.Local != nil { + return s.Local.Path, nil + } else if s.Swift != nil { + return s.Swift.Container, nil + } + return "", errors.New("No storage provider is configured.") +} + +func (s SnapshotStorageSpec) Location() (string, error) { + if s.S3 != nil { + return "s3:" + s.S3.Bucket, nil + } else if s.GCS != nil { + return "gs:" + s.GCS.Bucket, nil + } else if s.Azure != nil { + return "azure:" + s.Azure.Container, nil + } else if s.Local != nil { + return "local:" + s.Local.Path, nil + } else if s.Swift != nil { + return "swift:" + s.Swift.Container, nil + } + return "", errors.New("No storage provider is configured.") +} diff --git a/vendor/github.com/k8sdb/apimachinery/api/postgres_types.go b/vendor/github.com/k8sdb/apimachinery/api/postgres_types.go index 7149509da..6a34f83c6 100644 --- a/vendor/github.com/k8sdb/apimachinery/api/postgres_types.go +++ b/vendor/github.com/k8sdb/apimachinery/api/postgres_types.go @@ -44,6 +44,8 @@ type PostgresSpec struct { // Monitor is used monitor database instance // +optional Monitor *MonitorSpec `json:"monitor,omitempty"` + // Compute Resources required by the sidecar container. + Resources apiv1.ResourceRequirements `json:"resources,omitempty"` } type PostgresStatus struct { diff --git a/vendor/github.com/k8sdb/apimachinery/api/register.go b/vendor/github.com/k8sdb/apimachinery/api/register.go index a2e123ae4..9cd89aa5e 100644 --- a/vendor/github.com/k8sdb/apimachinery/api/register.go +++ b/vendor/github.com/k8sdb/apimachinery/api/register.go @@ -45,14 +45,14 @@ func addKnownTypes(scheme *runtime.Scheme) error { return nil } -func (obj *Snapshot) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (s *Snapshot) GetObjectKind() schema.ObjectKind { return &s.TypeMeta } func (obj *SnapshotList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } -func (obj *DormantDatabase) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (d *DormantDatabase) GetObjectKind() schema.ObjectKind { return &d.TypeMeta } func (obj *DormantDatabaseList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } -func (obj *Elastic) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (e *Elastic) GetObjectKind() schema.ObjectKind { return &e.TypeMeta } func (obj *ElasticList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } -func (obj *Postgres) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (p *Postgres) GetObjectKind() schema.ObjectKind { return &p.TypeMeta } func (obj *PostgresList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/github.com/k8sdb/apimachinery/api/snapshot_types.go b/vendor/github.com/k8sdb/apimachinery/api/snapshot_types.go index 12b298b37..0ec940f74 100644 --- a/vendor/github.com/k8sdb/apimachinery/api/snapshot_types.go +++ b/vendor/github.com/k8sdb/apimachinery/api/snapshot_types.go @@ -2,6 +2,7 @@ package api import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "k8s.io/client-go/pkg/api/v1" ) const ( @@ -23,6 +24,8 @@ type SnapshotSpec struct { DatabaseName string `json:"databaseName,omitempty"` // Snapshot Spec SnapshotStorageSpec `json:",inline,omitempty"` + // Compute Resources required by the sidecar container. + Resources apiv1.ResourceRequirements `json:"resources,omitempty"` } type SnapshotPhase string diff --git a/vendor/github.com/k8sdb/apimachinery/api/types.go b/vendor/github.com/k8sdb/apimachinery/api/types.go index ff6f65fa5..c929f472a 100644 --- a/vendor/github.com/k8sdb/apimachinery/api/types.go +++ b/vendor/github.com/k8sdb/apimachinery/api/types.go @@ -30,6 +30,8 @@ type SnapshotSourceSpec struct { type BackupScheduleSpec struct { CronExpression string `json:"cronExpression,omitempty"` SnapshotStorageSpec `json:",inline,omitempty"` + // Compute Resources required by the sidecar container. + Resources apiv1.ResourceRequirements `json:"resources,omitempty"` } const ( @@ -70,7 +72,7 @@ const ( type SnapshotStorageSpec struct { StorageSecretName string `json:"storageSecretName,omitempty"` - Local *LocalSpec `json:"local"` + Local *LocalSpec `json:"local,omitempty"` S3 *S3Spec `json:"s3,omitempty"` GCS *GCSSpec `json:"gcs,omitempty"` Azure *AzureSpec `json:"azure,omitempty"` @@ -78,27 +80,30 @@ type SnapshotStorageSpec struct { } type LocalSpec struct { - Volume apiv1.Volume `json:"volume,omitempty"` - Path string `json:"path,omitempty"` + VolumeSource apiv1.VolumeSource `json:"volumeSource,omitempty"` + Path string `json:"path,omitempty"` } type S3Spec struct { Endpoint string `json:"endpoint,omitempty"` - Region string `json:"region,omitempty"` Bucket string `json:"bucket,omiempty"` + Prefix string `json:"prefix,omitempty"` } type GCSSpec struct { Location string `json:"location,omitempty"` Bucket string `json:"bucket,omiempty"` + Prefix string `json:"prefix,omitempty"` } type AzureSpec struct { Container string `json:"container,omitempty"` + Prefix string `json:"prefix,omitempty"` } type SwiftSpec struct { Container string `json:"container,omitempty"` + Prefix string `json:"prefix,omitempty"` } type MonitorSpec struct { diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/controller/controller.go b/vendor/github.com/k8sdb/apimachinery/pkg/controller/controller.go index a65082761..d949f1dc6 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/controller/controller.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/controller/controller.go @@ -15,8 +15,5 @@ type Controller struct { } const ( - DatabaseNamePrefix = "kubedb" - LabelDatabaseKind = "kubedb.com/kind" - LabelDatabaseName = "kubedb.com/name" - sleepDuration = time.Second * 10 + sleepDuration = time.Second * 10 ) diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/controller/cron.go b/vendor/github.com/k8sdb/apimachinery/pkg/controller/cron.go index 40559a5d5..b82394f91 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/controller/cron.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/controller/cron.go @@ -167,9 +167,9 @@ func (s *snapshotInvoker) createScheduledSnapshot() { name := s.om.Name labelMap := map[string]string{ - LabelDatabaseKind: kind, - LabelDatabaseName: name, - LabelSnapshotStatus: string(tapi.SnapshotPhaseRunning), + tapi.LabelDatabaseKind: kind, + tapi.LabelDatabaseName: name, + tapi.LabelSnapshotStatus: string(tapi.SnapshotPhaseRunning), } snapshotList, err := s.extClient.Snapshots(s.om.Namespace).List(metav1.ListOptions{ @@ -200,8 +200,8 @@ func (s *snapshotInvoker) createScheduledSnapshot() { // Set label. Elastic controller will detect this using label selector labelMap = map[string]string{ - LabelDatabaseKind: kind, - LabelDatabaseName: name, + tapi.LabelDatabaseKind: kind, + tapi.LabelDatabaseName: name, } now := time.Now().UTC() @@ -214,8 +214,8 @@ func (s *snapshotInvoker) createScheduledSnapshot() { func (s *snapshotInvoker) createSnapshot(snapshotName string) error { labelMap := map[string]string{ - LabelDatabaseKind: s.runtimeObject.GetObjectKind().GroupVersionKind().Kind, - LabelDatabaseName: s.om.Name, + tapi.LabelDatabaseKind: s.runtimeObject.GetObjectKind().GroupVersionKind().Kind, + tapi.LabelDatabaseName: s.om.Name, } snapshot := &tapi.Snapshot{ @@ -227,6 +227,7 @@ func (s *snapshotInvoker) createSnapshot(snapshotName string) error { Spec: tapi.SnapshotSpec{ DatabaseName: s.om.Name, SnapshotStorageSpec: s.spec.SnapshotStorageSpec, + Resources: s.spec.Resources, }, } diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/controller/lib.go b/vendor/github.com/k8sdb/apimachinery/pkg/controller/lib.go index 62dae1fc7..f120343c5 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/controller/lib.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/controller/lib.go @@ -90,7 +90,7 @@ func (c *Controller) DeleteSnapshotData(snapshot *tapi.Snapshot) error { if err != nil { return err } - bucket, err := storage.GetContainer(snapshot.Spec.SnapshotStorageSpec) + bucket, err := snapshot.Spec.SnapshotStorageSpec.Container() if err != nil { return err } @@ -99,7 +99,7 @@ func (c *Controller) DeleteSnapshotData(snapshot *tapi.Snapshot) error { return err } - prefix := fmt.Sprintf("%v/%v/%v/%v", DatabaseNamePrefix, snapshot.Namespace, snapshot.Spec.DatabaseName, snapshot.Name) + prefix, _ := snapshot.Location() // error checked by .Container() cursor := stow.CursorStart for { items, next, err := container.Items(prefix, cursor, 50) @@ -287,7 +287,7 @@ func (c *Controller) DeleteService(name, namespace string) error { } } - if service.Spec.Selector[LabelDatabaseName] != name { + if service.Spec.Selector[tapi.LabelDatabaseName] != name { return nil } diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/controller/snapshot.go b/vendor/github.com/k8sdb/apimachinery/pkg/controller/snapshot.go index fea22d69b..b90806372 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/controller/snapshot.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/controller/snapshot.go @@ -44,11 +44,6 @@ type SnapshotController struct { syncPeriod time.Duration } -const ( - LabelJobType = "job.kubedb.com/type" - LabelSnapshotStatus = "snapshot.kubedb.com/status" -) - // NewSnapshotController creates a new SnapshotController func NewSnapshotController( client clientset.Interface, @@ -182,8 +177,8 @@ func (c *SnapshotController) create(snapshot *tapi.Snapshot) error { return err } - snapshot.Labels[LabelDatabaseName] = snapshot.Spec.DatabaseName - snapshot.Labels[LabelSnapshotStatus] = string(tapi.SnapshotPhaseRunning) + snapshot.Labels[tapi.LabelDatabaseName] = snapshot.Spec.DatabaseName + snapshot.Labels[tapi.LabelSnapshotStatus] = string(tapi.SnapshotPhaseRunning) snapshot.Status.Phase = tapi.SnapshotPhaseRunning if _, err = c.extClient.Snapshots(snapshot.Namespace).Update(snapshot); err != nil { c.eventRecorder.Eventf( @@ -429,7 +424,7 @@ func (c *SnapshotController) checkSnapshotJob(snapshot *tapi.Snapshot, jobName s ) } - delete(snapshot.Labels, LabelSnapshotStatus) + delete(snapshot.Labels, tapi.LabelSnapshotStatus) if _, err := c.extClient.Snapshots(snapshot.Namespace).Update(snapshot); err != nil { c.eventRecorder.Eventf( snapshot, diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/storage/osm.go b/vendor/github.com/k8sdb/apimachinery/pkg/storage/osm.go index b1dd0825f..6cecf70a8 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/storage/osm.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/storage/osm.go @@ -57,7 +57,7 @@ func CheckBucketAccess(client clientset.Interface, spec tapi.SnapshotStorageSpec if err != nil { return err } - c, err := GetContainer(spec) + c, err := spec.Container() if err != nil { return err } @@ -77,9 +77,14 @@ func CheckBucketAccess(client clientset.Interface, spec tapi.SnapshotStorageSpec } func NewOSMContext(client clientset.Interface, spec tapi.SnapshotStorageSpec, namespace string) (*otx.Context, error) { - secret, err := client.CoreV1().Secrets(namespace).Get(spec.StorageSecretName, metav1.GetOptions{}) - if err != nil { - return nil, err + config := make(map[string][]byte) + + if spec.StorageSecretName != "" { + secret, err := client.CoreV1().Secrets(namespace).Get(spec.StorageSecretName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + config = secret.Data } nc := &otx.Context{ @@ -89,23 +94,23 @@ func NewOSMContext(client clientset.Interface, spec tapi.SnapshotStorageSpec, na if spec.S3 != nil { nc.Provider = s3.Kind - nc.Config[s3.ConfigAccessKeyID] = string(secret.Data[tapi.AWS_ACCESS_KEY_ID]) + nc.Config[s3.ConfigAccessKeyID] = string(config[tapi.AWS_ACCESS_KEY_ID]) nc.Config[s3.ConfigEndpoint] = spec.S3.Endpoint - nc.Config[s3.ConfigRegion] = spec.S3.Region - nc.Config[s3.ConfigSecretKey] = string(secret.Data[tapi.AWS_SECRET_ACCESS_KEY]) + nc.Config[s3.ConfigRegion] = "us-east-1" // only used for creating buckets + nc.Config[s3.ConfigSecretKey] = string(config[tapi.AWS_SECRET_ACCESS_KEY]) if u, err := url.Parse(spec.S3.Endpoint); err == nil { nc.Config[s3.ConfigDisableSSL] = strconv.FormatBool(u.Scheme == "http") } return nc, nil } else if spec.GCS != nil { nc.Provider = gcs.Kind - nc.Config[gcs.ConfigProjectId] = string(secret.Data[tapi.GOOGLE_PROJECT_ID]) - nc.Config[gcs.ConfigJSON] = string(secret.Data[tapi.GOOGLE_SERVICE_ACCOUNT_JSON_KEY]) + nc.Config[gcs.ConfigProjectId] = string(config[tapi.GOOGLE_PROJECT_ID]) + nc.Config[gcs.ConfigJSON] = string(config[tapi.GOOGLE_SERVICE_ACCOUNT_JSON_KEY]) return nc, nil } else if spec.Azure != nil { nc.Provider = azure.Kind - nc.Config[azure.ConfigAccount] = string(secret.Data[tapi.AZURE_ACCOUNT_NAME]) - nc.Config[azure.ConfigKey] = string(secret.Data[tapi.AZURE_ACCOUNT_KEY]) + nc.Config[azure.ConfigAccount] = string(config[tapi.AZURE_ACCOUNT_NAME]) + nc.Config[azure.ConfigKey] = string(config[tapi.AZURE_ACCOUNT_KEY]) return nc, nil } else if spec.Local != nil { nc.Provider = local.Kind @@ -143,40 +148,10 @@ func NewOSMContext(client clientset.Interface, spec tapi.SnapshotStorageSpec, na {swift.ConfigAuthToken, tapi.OS_AUTH_TOKEN}, } { if _, exists := nc.Config.Config(val.stowKey); !exists { - nc.Config[val.stowKey] = string(secret.Data[val.secretKey]) + nc.Config[val.stowKey] = string(config[val.secretKey]) } } return nc, nil } return nil, errors.New("No storage provider is configured.") } - -func GetContainer(spec tapi.SnapshotStorageSpec) (string, error) { - if spec.S3 != nil { - return spec.S3.Bucket, nil - } else if spec.GCS != nil { - return spec.GCS.Bucket, nil - } else if spec.Azure != nil { - return spec.Azure.Container, nil - } else if spec.Local != nil { - return "kubedb", nil - } else if spec.Swift != nil { - return spec.Swift.Container, nil - } - return "", errors.New("No storage provider is configured.") -} - -func GetLocation(spec tapi.SnapshotStorageSpec) string { - if spec.S3 != nil { - return "s3://" + spec.S3.Bucket - } else if spec.GCS != nil { - return "gs://" + spec.GCS.Bucket - } else if spec.Azure != nil { - return "azure://" + spec.Azure.Container - } else if spec.Local != nil { - return "local://kubedb" - } else if spec.Swift != nil { - return "swift://" + spec.Swift.Container - } - return "Unknown" -} diff --git a/vendor/github.com/k8sdb/apimachinery/pkg/validator/validate.go b/vendor/github.com/k8sdb/apimachinery/pkg/validator/validate.go index 36e0a89cb..2199a3e4f 100644 --- a/vendor/github.com/k8sdb/apimachinery/pkg/validator/validate.go +++ b/vendor/github.com/k8sdb/apimachinery/pkg/validator/validate.go @@ -48,7 +48,7 @@ func ValidateStorageSpec(client clientset.Interface, spec *tapi.StorageSpec) (*t return spec, nil } -func ValidateBackupSchedule(spec *tapi.BackupScheduleSpec) error { +func ValidateBackupSchedule(client clientset.Interface, spec *tapi.BackupScheduleSpec, namespace string) error { if spec == nil { return nil } @@ -57,19 +57,28 @@ func ValidateBackupSchedule(spec *tapi.BackupScheduleSpec) error { return errors.New("Invalid cron expression") } - return ValidateSnapshotSpec(spec.SnapshotStorageSpec) + return ValidateSnapshotSpec(client, spec.SnapshotStorageSpec, namespace) } -func ValidateSnapshotSpec(spec tapi.SnapshotStorageSpec) error { +func ValidateSnapshotSpec(client clientset.Interface, spec tapi.SnapshotStorageSpec, namespace string) error { // BucketName can't be empty if spec.S3 == nil && spec.GCS == nil && spec.Azure == nil && spec.Swift == nil && spec.Local == nil { return errors.New("No storage provider is configured.") } + if spec.Local != nil { + return nil + } + // Need to provide Storage credential secret if spec.StorageSecretName == "" { - return fmt.Errorf(`Object 'SecretName' is missing in '%v'`, spec.StorageSecretName) + return fmt.Errorf(`Object 'SecretName' is missing in '%v'`, spec) + } + + if err := storage.CheckBucketAccess(client, spec, namespace); err != nil { + return err } + return nil } @@ -90,15 +99,3 @@ func ValidateMonitorSpec(monitorSpec *tapi.MonitorSpec) error { return nil } - -func ValidateSnapshot(client clientset.Interface, snapshot *tapi.Snapshot) error { - snapshotSpec := snapshot.Spec.SnapshotStorageSpec - if err := ValidateSnapshotSpec(snapshotSpec); err != nil { - return err - } - - if err := storage.CheckBucketAccess(client, snapshot.Spec.SnapshotStorageSpec, snapshot.Namespace); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/k8sdb/elasticsearch/pkg/validator/validate.go b/vendor/github.com/k8sdb/elasticsearch/pkg/validator/validate.go index 77c22955b..dd7f90c53 100644 --- a/vendor/github.com/k8sdb/elasticsearch/pkg/validator/validate.go +++ b/vendor/github.com/k8sdb/elasticsearch/pkg/validator/validate.go @@ -5,7 +5,6 @@ import ( tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" - "github.com/k8sdb/apimachinery/pkg/storage" amv "github.com/k8sdb/apimachinery/pkg/validator" clientset "k8s.io/client-go/kubernetes" ) @@ -28,11 +27,7 @@ func ValidateElastic(client clientset.Interface, elastic *tapi.Elastic) error { backupScheduleSpec := elastic.Spec.BackupSchedule if backupScheduleSpec != nil { - if err := amv.ValidateBackupSchedule(backupScheduleSpec); err != nil { - return err - } - - if err := storage.CheckBucketAccess(client, backupScheduleSpec.SnapshotStorageSpec, elastic.Namespace); err != nil { + if err := amv.ValidateBackupSchedule(client, backupScheduleSpec, elastic.Namespace); err != nil { return err } } diff --git a/vendor/github.com/k8sdb/postgres/pkg/validator/validate.go b/vendor/github.com/k8sdb/postgres/pkg/validator/validate.go index e1957f05d..49972a884 100644 --- a/vendor/github.com/k8sdb/postgres/pkg/validator/validate.go +++ b/vendor/github.com/k8sdb/postgres/pkg/validator/validate.go @@ -5,7 +5,6 @@ import ( tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/pkg/docker" - "github.com/k8sdb/apimachinery/pkg/storage" amv "github.com/k8sdb/apimachinery/pkg/validator" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" @@ -37,11 +36,7 @@ func ValidatePostgres(client clientset.Interface, postgres *tapi.Postgres) error backupScheduleSpec := postgres.Spec.BackupSchedule if backupScheduleSpec != nil { - if err := amv.ValidateBackupSchedule(backupScheduleSpec); err != nil { - return err - } - - if err := storage.CheckBucketAccess(client, backupScheduleSpec.SnapshotStorageSpec, postgres.Namespace); err != nil { + if err := amv.ValidateBackupSchedule(client, backupScheduleSpec, postgres.Namespace); err != nil { return err } } diff --git a/vendor/k8s.io/kubernetes/pkg/api/helpers.go b/vendor/k8s.io/kubernetes/pkg/api/helpers.go index faa7df7c0..21b35a4fa 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/api/helpers.go @@ -246,6 +246,7 @@ func IsServiceIPRequested(service *Service) bool { var standardFinalizers = sets.NewString( string(FinalizerKubernetes), metav1.FinalizerOrphanDependents, + metav1.FinalizerDeleteDependents, ) // HasAnnotation returns a bool if passed in annotation exists diff --git a/vendor/k8s.io/kubernetes/pkg/version/base.go b/vendor/k8s.io/kubernetes/pkg/version/base.go index f289a64a5..a2652c247 100644 --- a/vendor/k8s.io/kubernetes/pkg/version/base.go +++ b/vendor/k8s.io/kubernetes/pkg/version/base.go @@ -51,7 +51,7 @@ var ( // semantic version is a git hash, but the version itself is no // longer the direct output of "git describe", but a slight // translation to be semver compliant. - gitVersion string = "v1.6.7-beta.0+$Format:%h$" + gitVersion string = "v1.6.8-beta.0+$Format:%h$" gitCommit string = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD) gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty" From ea96e056030e88433661ab317ab3943f62d67723 Mon Sep 17 00:00:00 2001 From: shahriar Date: Fri, 7 Jul 2017 12:08:49 +0600 Subject: [PATCH 14/18] fixed --- docs/examples/elastic/snapshot-local.yaml | 12 ++++++++++++ docs/examples/elastic/snapshot.yaml | 6 +++--- docs/examples/postgres/snapshot-local.yaml | 2 +- pkg/describer/k8sdb_describer.go | 22 +++++++++++++--------- pkg/printer/resource_printer.go | 10 ++++++---- pkg/roles/role.go | 5 +++++ 6 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 docs/examples/elastic/snapshot-local.yaml diff --git a/docs/examples/elastic/snapshot-local.yaml b/docs/examples/elastic/snapshot-local.yaml new file mode 100644 index 000000000..4edbd8294 --- /dev/null +++ b/docs/examples/elastic/snapshot-local.yaml @@ -0,0 +1,12 @@ +apiVersion: kubedb.com/v1alpha1 +kind: Snapshot +metadata: + name: snapshot-xyz + labels: + kubedb.com/kind: Elastic +spec: + databaseName: elasticsearch-db + local: + path: "/test" + volumeSource: + emptyDir: {} diff --git a/docs/examples/elastic/snapshot.yaml b/docs/examples/elastic/snapshot.yaml index af9e13e5a..01727ff68 100644 --- a/docs/examples/elastic/snapshot.yaml +++ b/docs/examples/elastic/snapshot.yaml @@ -1,11 +1,11 @@ apiVersion: kubedb.com/v1alpha1 kind: Snapshot metadata: - name: snapshot-xyz-es + name: snapshot-xyz labels: kubedb.com/kind: Elastic spec: databaseName: elasticsearch-db - storageSecretName: "google-cred" + storageSecretName: "secret-for-bucket" gcs: - bucket: "restic" + bucket: "bucket-for-snapshot" diff --git a/docs/examples/postgres/snapshot-local.yaml b/docs/examples/postgres/snapshot-local.yaml index da8eafe17..4dc13286e 100644 --- a/docs/examples/postgres/snapshot-local.yaml +++ b/docs/examples/postgres/snapshot-local.yaml @@ -1,7 +1,7 @@ apiVersion: kubedb.com/v1alpha1 kind: Snapshot metadata: - name: snapshot-xyz-16 + name: snapshot-xyz labels: kubedb.com/kind: Postgres spec: diff --git a/pkg/describer/k8sdb_describer.go b/pkg/describer/k8sdb_describer.go index f5a582180..c8f0d17d4 100644 --- a/pkg/describer/k8sdb_describer.go +++ b/pkg/describer/k8sdb_describer.go @@ -6,8 +6,6 @@ import ( "github.com/golang/glog" tapi "github.com/k8sdb/apimachinery/api" - amc "github.com/k8sdb/apimachinery/pkg/controller" - "github.com/k8sdb/apimachinery/pkg/storage" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/pkg/api" @@ -16,6 +14,8 @@ import ( "k8s.io/kubernetes/pkg/printers" ) +const statusUnknown = "Unknown" + func (d *humanReadableDescriber) describeElastic(item *tapi.Elastic, describerSettings *printers.DescriberSettings) (string, error) { clientSet, err := d.ClientSet() if err != nil { @@ -26,8 +26,8 @@ func (d *humanReadableDescriber) describeElastic(item *tapi.Elastic, describerSe metav1.ListOptions{ LabelSelector: labels.SelectorFromSet( map[string]string{ - amc.LabelDatabaseKind: tapi.ResourceKindElastic, - amc.LabelDatabaseName: item.Name, + tapi.LabelDatabaseKind: tapi.ResourceKindElastic, + tapi.LabelDatabaseName: item.Name, }, ).String(), }, @@ -96,8 +96,8 @@ func (d *humanReadableDescriber) describePostgres(item *tapi.Postgres, describer metav1.ListOptions{ LabelSelector: labels.SelectorFromSet( map[string]string{ - amc.LabelDatabaseKind: tapi.ResourceKindPostgres, - amc.LabelDatabaseName: item.Name, + tapi.LabelDatabaseKind: tapi.ResourceKindPostgres, + tapi.LabelDatabaseName: item.Name, }, ).String(), }, @@ -215,8 +215,8 @@ func (d *humanReadableDescriber) describeDormantDatabase(item *tapi.DormantDatab metav1.ListOptions{ LabelSelector: labels.SelectorFromSet( map[string]string{ - amc.LabelDatabaseKind: item.Labels[amc.LabelDatabaseKind], - amc.LabelDatabaseName: item.Name, + tapi.LabelDatabaseKind: item.Labels[tapi.LabelDatabaseKind], + tapi.LabelDatabaseName: item.Name, }, ).String(), }, @@ -321,9 +321,13 @@ func listSnapshots(snapshotList *tapi.SnapshotList, out io.Writer) { fmt.Fprint(w, " Name\tBucket\tStartTime\tCompletionTime\tPhase\n") fmt.Fprint(w, " ----\t------\t---------\t--------------\t-----\n") for _, e := range snapshotList.Items { + container, err := e.Spec.SnapshotStorageSpec.Location() + if err != nil { + container = statusUnknown + } fmt.Fprintf(w, " %s\t%s\t%s\t%s\t%s\n", e.Name, - storage.GetLocation(e.Spec.SnapshotStorageSpec), + container, timeToString(e.Status.StartTime), timeToString(e.Status.CompletionTime), e.Status.Phase, diff --git a/pkg/printer/resource_printer.go b/pkg/printer/resource_printer.go index 5f3155157..768214fd9 100644 --- a/pkg/printer/resource_printer.go +++ b/pkg/printer/resource_printer.go @@ -12,8 +12,6 @@ import ( "github.com/golang/glog" tapi "github.com/k8sdb/apimachinery/api" "github.com/k8sdb/apimachinery/client/clientset" - amc "github.com/k8sdb/apimachinery/pkg/controller" - "github.com/k8sdb/apimachinery/pkg/storage" "github.com/k8sdb/cli/pkg/decoder" "github.com/k8sdb/cli/pkg/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -261,7 +259,7 @@ func (h *HumanReadablePrinter) printSnapshot(item *tapi.Snapshot, w io.Writer, o status = statusUnknown } - short, found := util.ResourceShortFormFor(item.Labels[amc.LabelDatabaseKind]) + short, found := util.ResourceShortFormFor(item.Labels[tapi.LabelDatabaseKind]) database := fmt.Sprintf(`%v/%v`, short, item.Spec.DatabaseName) if !found { database = fmt.Sprintf(`%v`, item.Spec.DatabaseName) @@ -272,7 +270,11 @@ func (h *HumanReadablePrinter) printSnapshot(item *tapi.Snapshot, w io.Writer, o } if options.Wide { - if _, err := fmt.Fprintf(w, "%s\t", storage.GetLocation(item.Spec.SnapshotStorageSpec)); err != nil { + container, err := item.Spec.SnapshotStorageSpec.Location() + if err != nil { + container = statusUnknown + } + if _, err := fmt.Fprintf(w, "%s\t", container); err != nil { return err } } diff --git a/pkg/roles/role.go b/pkg/roles/role.go index acf387024..1dffb3111 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -46,6 +46,11 @@ var policyRuleOperator = []rbac.PolicyRule{ Resources: []string{"services", "secrets"}, Verbs: []string{"get", "create", "delete"}, }, + { + APIGroups: []string{apiv1.GroupName}, + Resources: []string{"endpoints"}, + Verbs: []string{"get",}, + }, { APIGroups: []string{batch.GroupName}, Resources: []string{"jobs"}, From 6f1443720b213c10d38deacd5728b32cb0350169 Mon Sep 17 00:00:00 2001 From: shahriar Date: Fri, 7 Jul 2017 16:30:59 +0600 Subject: [PATCH 15/18] reference --- docs/reference/kubedb_init.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/reference/kubedb_init.md b/docs/reference/kubedb_init.md index c303f572a..8db0e7993 100644 --- a/docs/reference/kubedb_init.md +++ b/docs/reference/kubedb_init.md @@ -24,11 +24,11 @@ kubedb init [flags] ### Options ``` - -h, --help help for init - --operator-namespace string Name of namespace where operator will be deployed. (default "kube-system") - --operator-service-account string Service account name used to run operator (default "default") - --upgrade If present, Upgrade operator to use provided version - --version string Operator version (default "0.2.0") + -h, --help help for init + --operator-namespace string Name of namespace where operator will be deployed. (default "kube-system") + --rbac If true, configures RBAC roles for operator + --upgrade If present, Upgrade operator to use provided version + --version string Operator version (default "0.2.0") ``` ### Options inherited from parent commands From 018e4aba17ab0f8b63db790cab682c548cc04f19 Mon Sep 17 00:00:00 2001 From: shahriar Date: Fri, 7 Jul 2017 17:26:28 +0600 Subject: [PATCH 16/18] docs --- docs/describe.md | 2 +- docs/edit.md | 8 ++-- docs/elastic.md | 10 +++-- docs/examples/elastic/snapshot-local.yaml | 2 +- docs/examples/postgres/snapshot-local.yaml | 2 +- docs/examples/snapshot/gcs/gcs-snapshot.yaml | 1 - .../snapshot/local/local-snapshot.yaml | 5 +-- docs/get.md | 8 ++-- docs/postgres.md | 4 +- docs/snapshot.md | 38 +++++++++---------- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/docs/describe.md b/docs/describe.md index 38e723e7c..41a2c6a71 100644 --- a/docs/describe.md +++ b/docs/describe.md @@ -14,7 +14,7 @@ Status: Running No volumes. StatefulSet: - Name: postgres-demo-pg + Name: postgres-demo Replicas: 1 current / 1 desired CreationTimestamp: Mon, 05 Jun 2017 10:10:14 +0600 Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed diff --git a/docs/edit.md b/docs/edit.md index f64b26645..b123d678a 100644 --- a/docs/edit.md +++ b/docs/edit.md @@ -12,9 +12,9 @@ $ kubedb edit pg postgres-demo # Add following under Spec to configure periodic backups # backupSchedule: # cronExpression: "@every 6h" -# bucketName: "bucket-name" -# storageSecret: -# secretName: "secret-name" +# storageSecretName: "secret-name" +# gcs: +# bucket: "bucket-name" postgres "postgres-demo" edited ``` @@ -43,6 +43,6 @@ Elastic: * _spec.nodeSelector_ * _spec.init_ -For DormantDatabase, _spec.origin_ can't be edited using `kbuedb edit` +For DormantDatabase, _spec.origin_ can't be edited using `kubedb edit` To learn about various options of `edit` command, please visit [here](/docs/reference/kubedb_edit.md). diff --git a/docs/elastic.md b/docs/elastic.md index e168f627a..26bb83f7a 100644 --- a/docs/elastic.md +++ b/docs/elastic.md @@ -70,13 +70,14 @@ As `spec.storage` fields are set, StatefulSet will be created with dynamically p ```bash $ kubectl get pvc --selector='kubedb.com/kind=Elastic,kubedb.com/name=elasticsearch-db' -NAME STATUS VOLUME CAPACITY ACCESSMODES AGE -data-elasticsearch-db-pg-0 Bound pvc-a1a95954-4a75-11e7-8b69-12f236046fba 10Gi RWO 2m +NAME STATUS VOLUME CAPACITY ACCESSMODES AGE +data-elasticsearch-db-0 Bound pvc-a1a95954-4a75-11e7-8b69-12f236046fba 10Gi RWO 2m ``` ### Database Initialization -Elasticsearch databases can be created from a previously takes Snapshot. To initialize from prior snapshot, set the `spec.init.snapshotSource` section when creating an Elastic object. +Elasticsearch databases can be created from a previously takes Snapshot. +To initialize from prior snapshot, set the `spec.init.snapshotSource` section when creating an Elastic object. In this case, SnapshotSource must have following information: 1. `namespace:` Namespace of Snapshot object @@ -95,4 +96,5 @@ spec: name: "snapshot-xyz" ``` -In the above example, Elasticsearch database will be initialized from Snapshot `snapshot-xyz` in `default` namespace. Here, KubeDB operator will launch a Job to initialize Elasticsearch once StatefulSet pods are running. +In the above example, Elasticsearch database will be initialized from Snapshot `snapshot-xyz` in `default` +namespace. Here, KubeDB operator will launch a Job to initialize Elasticsearch once StatefulSet pods are running. diff --git a/docs/examples/elastic/snapshot-local.yaml b/docs/examples/elastic/snapshot-local.yaml index 4edbd8294..3ebd9e43b 100644 --- a/docs/examples/elastic/snapshot-local.yaml +++ b/docs/examples/elastic/snapshot-local.yaml @@ -7,6 +7,6 @@ metadata: spec: databaseName: elasticsearch-db local: - path: "/test" + path: /repo volumeSource: emptyDir: {} diff --git a/docs/examples/postgres/snapshot-local.yaml b/docs/examples/postgres/snapshot-local.yaml index 4dc13286e..6a57fbc48 100644 --- a/docs/examples/postgres/snapshot-local.yaml +++ b/docs/examples/postgres/snapshot-local.yaml @@ -7,6 +7,6 @@ metadata: spec: databaseName: postgres-db local: - path: "/test" + path: /repo volumeSource: emptyDir: {} diff --git a/docs/examples/snapshot/gcs/gcs-snapshot.yaml b/docs/examples/snapshot/gcs/gcs-snapshot.yaml index 8dd670dab..5648a0e3b 100644 --- a/docs/examples/snapshot/gcs/gcs-snapshot.yaml +++ b/docs/examples/snapshot/gcs/gcs-snapshot.yaml @@ -8,5 +8,4 @@ spec: databaseName: postgres-db storageSecretName: gcs-secret gcs: - location: /repo bucket: bucket-for-snapshot diff --git a/docs/examples/snapshot/local/local-snapshot.yaml b/docs/examples/snapshot/local/local-snapshot.yaml index 4f46c2844..e200e1276 100644 --- a/docs/examples/snapshot/local/local-snapshot.yaml +++ b/docs/examples/snapshot/local/local-snapshot.yaml @@ -1,13 +1,12 @@ apiVersion: kubedb.com/v1alpha1 kind: Snapshot metadata: - name: snapshot-xyz + name: local-snapshot labels: kubedb.com/kind: Postgres spec: databaseName: postgres-db local: path: /repo - volume: + volumeSource: emptyDir: {} - name: repo diff --git a/docs/get.md b/docs/get.md index 14391e1d4..464b1ec58 100644 --- a/docs/get.md +++ b/docs/get.md @@ -53,10 +53,10 @@ pg/postgres-dev 9.5 Running 3h pg/postgres-prod 9.5 Running 3h pg/postgres-qa 9.5 Running 3h -NAME DATABASE BUCKET STATUS AGE -snap/postgres-demo-20170605-073557 pg/postgres-demo bucket-name Succeeded 9m -snap/snapshot-20170505-1147 pg/postgres-demo bucket-name Succeeded 1h -snap/snapshot-xyz es/elasticsearch-demo bucket-name Succeeded 5m +NAME DATABASE BUCKET STATUS AGE +snap/postgres-demo-20170605-073557 pg/postgres-demo gs:bucket-name Succeeded 9m +snap/snapshot-20170505-1147 pg/postgres-demo gs:bucket-name Succeeded 1h +snap/snapshot-xyz es/elasticsearch-demo local:/directory Succeeded 5m ``` Flag `--output=wide` is used to print additional information. diff --git a/docs/postgres.md b/docs/postgres.md index 92f757366..06e1d6875 100644 --- a/docs/postgres.md +++ b/docs/postgres.md @@ -93,8 +93,8 @@ As `spec.storage` fields are set, StatefulSet will be created with dynamically p ```sh $ kubectl get pvc --selector='kubedb.com/kind=Postgres,kubedb.com/name=postgres-db' -NAME STATUS VOLUME CAPACITY ACCESSMODES AGE -data-postgres-db-pg-0 Bound pvc-a1a95954-4a75-11e7-8b69-12f236046fba 10Gi RWO 2m +NAME STATUS VOLUME CAPACITY ACCESSMODES AGE +data-postgres-db-0 Bound pvc-a1a95954-4a75-11e7-8b69-12f236046fba 10Gi RWO 2m ``` diff --git a/docs/snapshot.md b/docs/snapshot.md index 435f26d3d..accafa5b9 100644 --- a/docs/snapshot.md +++ b/docs/snapshot.md @@ -3,10 +3,12 @@ # Snapshots ## What is Snapshot -A `Snapshot` is a Kubernetes `Third Party Object` (TPR). It provides declarative configuration for database snapshots in a Kubernetes native way. You only need to describe the desired backup operations in a Snapshot object, and the KubeDB operator will launch a Job to perform backup operation. +A `Snapshot` is a Kubernetes `Third Party Object` (TPR). It provides declarative configuration for database snapshots in a Kubernetes native way. +You only need to describe the desired backup operations in a Snapshot object, and the KubeDB operator will launch a Job to perform backup operation. ## Snapshot Spec -As with all other Kubernetes objects, a Snapshot needs `apiVersion`, `kind`, and `metadata` fields. The metadata field must contain a label with `kubedb.com/kind` key. +As with all other Kubernetes objects, a Snapshot needs `apiVersion`, `kind`, and `metadata` fields. +The metadata field must contain a label with `kubedb.com/kind` key. The valid values for this label are `Postgres` or `Elastic`. It also needs a `.spec` section. Below is an example Snapshot object. ```yaml @@ -17,7 +19,7 @@ metadata: labels: kubedb.com/kind: Postgres|Elastic spec: - databaseName: postgres-db + databaseName: database-name storageSecretName: s3-secret s3: endpoint: 's3.amazonaws.com' @@ -32,11 +34,11 @@ The `.spec` section supports the following different cloud providers to store sn `Local` backend refers to a local path inside snapshot job container. Any Kubernetes supported [persistent volume](https://kubernetes.io/docs/concepts/storage/volumes/) can be used here. Some examples are: `emptyDir` for testing, NFS, Ceph, GlusterFS, etc. To configure this backend, no secret is needed. Following parameters are available for `Local` backend. -| Parameter | Description | -|---------------------|-----------------------------------------------------------------------------------------| -| `spec.databaseName` | `Required`. Name of database | -| `spec.local.path` | `Required`. Path where this volume will be mounted in the job container. Example: /repo | -| `spec.local.volume` | `Required`. Any Kubernetes volume | +| Parameter | Description | +|---------------------------|-----------------------------------------------------------------------------------------| +| `spec.databaseName` | `Required`. Name of database | +| `spec.local.path` | `Required`. Path where this volume will be mounted in the job container. Example: /repo | +| `spec.local.volumeSource` | `Required`. Any Kubernetes volumeSource | ```sh $ kubectl create -f ./docs/examples/snapshot/local/local-snapshot.yaml @@ -60,12 +62,10 @@ spec: databaseName: postgres-db local: path: /repo - volume: + volumeSource: emptyDir: {} - name: repo ``` - ### AWS S3 KubeDB supports AWS S3 service or [Minio](https://minio.io/) servers as snapshot storage backend. To configure this backend, following secret keys are needed: @@ -108,8 +108,8 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.s3.endpoint` | `Required`. For S3, use `s3.amazonaws.com`. If your bucket is in a different location, S3 server (s3.amazonaws.com) will redirect snapshot to the correct endpoint. For an S3-compatible server that is not Amazon (like Minio), or is only available via HTTP, you can specify the endpoint like this: `http://server:port`. | -| `spec.s3.region` | `Required`. Name of AWS region | | `spec.s3.bucket` | `Required`. Name of Bucket | +| `spec.s3.prefix` | `Required`. Path prefix in Bucket | ```sh $ kubectl create -f ./docs/examples/snapshot/s3/s3-snapshot.yaml @@ -181,8 +181,8 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a |--------------------------|---------------------------------------------------------------------------------| | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | -| `spec.gcs.location` | `Required`. Name of Google Cloud region. | | `spec.gcs.bucket` | `Required`. Name of Bucket | +| `spec.gcs.prefix` | `Required`. Path prefix in Bucket | ```sh $ kubectl create -f ./docs/examples/snapshot/gcs/gcs-snapshot.yaml @@ -207,11 +207,9 @@ spec: databaseName: postgres-db storageSecretName: gcs-secret gcs: - location: /repo bucket: bucket-for-snapshot ``` - ### Microsoft Azure Storage KubeDB supports Microsoft Azure Storage as snapshot storage backend. To configure this backend, following secret keys are needed: @@ -254,6 +252,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.azure.container` | `Required`. Name of Storage container | +| `spec.azure.prefix` | `Required`. Path prefix in container | ```sh $ kubectl create -f ./docs/examples/snapshot/azure/azure-snapshot.yaml @@ -352,6 +351,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.swift.container` | `Required`. Name of Storage container | +| `spec.swift.prefix` | `Required`. Path prefix in container | ```sh $ kubectl create -f ./docs/examples/snapshot/swift/swift-snapshot.yaml @@ -405,13 +405,14 @@ Use `kubedb get` to check snap0shot status. ```sh $ kubedb get snap snapshot-xyz -o wide -NAME DATABASE BUCKET STATUS AGE -snapshot-xyz es/elasticsearch-db snapshot Succeeded 24m +NAME DATABASE BUCKET STATUS AGE +snapshot-xyz es/elasticsearch-db s3:snapshot Succeeded 24m ``` ## Schedule Backups -Scheduled backups are supported for all types of databases. To schedule backups, add the following `BackupScheduleSpec` in `spec` of a database tpr. All snapshot storage backends are supported for scheduled backup. +Scheduled backups are supported for all types of databases. To schedule backups, add the following `BackupScheduleSpec` in `spec` of a database tpr. +All snapshot storage backends are supported for scheduled backup. ```yaml spec: @@ -420,7 +421,6 @@ spec: storageSecretName: "secret-for-bucket" s3: endpoint: 's3.amazonaws.com' - region: us-east-1 bucket: kubedb-qa ``` From 17a4e177466649c81a8ebdad62938ebffed02b27 Mon Sep 17 00:00:00 2001 From: tamal Date: Fri, 7 Jul 2017 05:01:19 -0700 Subject: [PATCH 17/18] added-all --- docs/reference/kubedb_init.md | 2 +- docs/snapshot.md | 8 ++++---- pkg/util/flags.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/reference/kubedb_init.md b/docs/reference/kubedb_init.md index 8db0e7993..534cb805d 100644 --- a/docs/reference/kubedb_init.md +++ b/docs/reference/kubedb_init.md @@ -26,7 +26,7 @@ kubedb init [flags] ``` -h, --help help for init --operator-namespace string Name of namespace where operator will be deployed. (default "kube-system") - --rbac If true, configures RBAC roles for operator + --rbac If true, uses RBAC with operator and database objects --upgrade If present, Upgrade operator to use provided version --version string Operator version (default "0.2.0") ``` diff --git a/docs/snapshot.md b/docs/snapshot.md index accafa5b9..e393a39f7 100644 --- a/docs/snapshot.md +++ b/docs/snapshot.md @@ -109,7 +109,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.s3.endpoint` | `Required`. For S3, use `s3.amazonaws.com`. If your bucket is in a different location, S3 server (s3.amazonaws.com) will redirect snapshot to the correct endpoint. For an S3-compatible server that is not Amazon (like Minio), or is only available via HTTP, you can specify the endpoint like this: `http://server:port`. | | `spec.s3.bucket` | `Required`. Name of Bucket | -| `spec.s3.prefix` | `Required`. Path prefix in Bucket | +| `spec.s3.prefix` | `Optional`. Path prefix in Bucket | ```sh $ kubectl create -f ./docs/examples/snapshot/s3/s3-snapshot.yaml @@ -182,7 +182,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.gcs.bucket` | `Required`. Name of Bucket | -| `spec.gcs.prefix` | `Required`. Path prefix in Bucket | +| `spec.gcs.prefix` | `Optional`. Path prefix in Bucket | ```sh $ kubectl create -f ./docs/examples/snapshot/gcs/gcs-snapshot.yaml @@ -252,7 +252,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.azure.container` | `Required`. Name of Storage container | -| `spec.azure.prefix` | `Required`. Path prefix in container | +| `spec.azure.prefix` | `Optional`. Path prefix in container | ```sh $ kubectl create -f ./docs/examples/snapshot/azure/azure-snapshot.yaml @@ -351,7 +351,7 @@ Now, you can create a Snapshot tpr using this secret. Following parameters are a | `spec.databaseName` | `Required`. Name of database | | `spec.storageSecretName` | `Required`. Name of storage secret | | `spec.swift.container` | `Required`. Name of Storage container | -| `spec.swift.prefix` | `Required`. Path prefix in container | +| `spec.swift.prefix` | `Optional`. Path prefix in container | ```sh $ kubectl create -f ./docs/examples/snapshot/swift/swift-snapshot.yaml diff --git a/pkg/util/flags.go b/pkg/util/flags.go index 0da61127c..9b2e223dc 100644 --- a/pkg/util/flags.go +++ b/pkg/util/flags.go @@ -44,7 +44,7 @@ func AddEditFlags(cmd *cobra.Command) { func AddInitFlags(cmd *cobra.Command) { cmd.Flags().String("operator-namespace", "kube-system", "Name of namespace where operator will be deployed.") - cmd.Flags().Bool("rbac", false, "If true, configures RBAC roles for operator") + cmd.Flags().Bool("rbac", false, "If true, uses RBAC with operator and database objects") cmd.Flags().String("version", "0.2.0", "Operator version") cmd.Flags().Bool("upgrade", false, "If present, Upgrade operator to use provided version") } From d18d2b1b74fd8838f19fda58a4e2ac6a0fed0651 Mon Sep 17 00:00:00 2001 From: tamal Date: Fri, 7 Jul 2017 05:03:48 -0700 Subject: [PATCH 18/18] added-all --- docs/snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snapshot.md b/docs/snapshot.md index e393a39f7..3a49789d5 100644 --- a/docs/snapshot.md +++ b/docs/snapshot.md @@ -38,7 +38,7 @@ To configure this backend, no secret is needed. Following parameters are availab |---------------------------|-----------------------------------------------------------------------------------------| | `spec.databaseName` | `Required`. Name of database | | `spec.local.path` | `Required`. Path where this volume will be mounted in the job container. Example: /repo | -| `spec.local.volumeSource` | `Required`. Any Kubernetes volumeSource | +| `spec.local.volumeSource` | `Required`. Any Kubernetes [volume](https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes) | ```sh $ kubectl create -f ./docs/examples/snapshot/local/local-snapshot.yaml