+++ /dev/null
-# Build the manager binary
-FROM golang:1.13 as builder
-
-WORKDIR /workspace
-# Copy the Go Modules manifests
-COPY go.mod go.mod
-COPY go.sum go.sum
-# cache deps before building and copying source so that we don't need to re-download as much
-# and so that source changes don't invalidate our downloaded layer
-RUN go mod download
-
-# Copy the go source
-COPY main.go main.go
-COPY api/ api/
-COPY controllers/ controllers/
-COPY openwrt/ openwrt/
-COPY wrtprovider/ wrtprovider/
-
-# Build
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go
-
-# Use distroless as minimal base image to package the manager binary
-# Refer to https://github.com/GoogleContainerTools/distroless for more details
-FROM gcr.io/distroless/static:nonroot
-WORKDIR /
-COPY --from=builder /workspace/manager .
-USER nonroot:nonroot
-
-ENTRYPOINT ["/manager"]
+++ /dev/null
-
-# Image URL to use all building/pushing image targets
-IMG ?= integratedcloudnative/sdewan-controller:dev
-# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
-CRD_OPTIONS ?= "crd:trivialVersions=true"
-
-# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
-ifeq (,$(shell go env GOBIN))
-GOBIN=$(shell go env GOPATH)/bin
-else
-GOBIN=$(shell go env GOBIN)
-endif
-
-all: manager
-
-# Run tests
-test: generate fmt vet manifests
- go test ./... -coverprofile cover.out
-
-# Build manager binary
-manager: generate fmt vet
- go build -o bin/manager main.go
-
-# Run against the configured Kubernetes cluster in ~/.kube/config
-run: generate fmt vet manifests
- go run ./main.go
-
-# Install CRDs into a cluster
-install: manifests
- kustomize build config/crd | kubectl apply -f -
-
-# Uninstall CRDs from a cluster
-uninstall: manifests
- kustomize build config/crd | kubectl delete -f -
-
-# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
-yaml-gen: manifests
- cd config/manager && kustomize edit set image controller=${IMG}
- kustomize build config/default > my-sdewan-deploy.yaml
-
-# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
-deploy: yaml-gen
- kubectl apply -f my-sdewan-deploy.yaml
-
-# Generate manifests e.g. CRD, RBAC etc.
-manifests: controller-gen
- $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
-
-# Run go fmt against code
-fmt:
- go fmt ./...
-
-# Run go vet against code
-vet:
- go vet ./...
-
-# Generate code
-generate: controller-gen
- $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths="./..."
-
-# Build the docker image
-docker-build: test
- docker build . -t ${IMG}
-
-# Push the docker image
-docker-push:
- docker push ${IMG}
-
-# find or download controller-gen
-# download controller-gen if necessary
-controller-gen:
-ifeq (, $(shell which controller-gen))
- @{ \
- set -e ;\
- CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
- cd $$CONTROLLER_GEN_TMP_DIR ;\
- go mod init tmp ;\
- go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
- rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
- }
-CONTROLLER_GEN=$(GOBIN)/controller-gen
-else
-CONTROLLER_GEN=$(shell which controller-gen)
-endif
+++ /dev/null
-domain: sdewan.akraino.org
-repo: sdewan.akraino.org/sdewan
-resources:
-- group: batch
- kind: Sdewan
- version: v1alpha1
-- group: batch
- kind: Mwan3Conf
- version: v1alpha1
-version: "2"
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package v1alpha1 contains API Schema definitions for the batch v1alpha1 API group
-// +kubebuilder:object:generate=true
-// +groupName=batch.sdewan.akraino.org
-package v1alpha1
-
-import (
- "k8s.io/apimachinery/pkg/runtime/schema"
- "sigs.k8s.io/controller-runtime/pkg/scheme"
-)
-
-var (
- // GroupVersion is group version used to register these objects
- GroupVersion = schema.GroupVersion{Group: "batch.sdewan.akraino.org", Version: "v1alpha1"}
-
- // SchemeBuilder is used to add go types to the GroupVersionKind scheme
- SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
-
- // AddToScheme adds the types in this group-version to the given scheme.
- AddToScheme = SchemeBuilder.AddToScheme
-)
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
-// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
-
-type PolicyMember struct {
- Network string `json:"network"`
- Metric int `json:"metric"`
- Weight int `json:"weight"`
-}
-
-type PolicyMembers struct {
- Members []PolicyMember `json:"members"`
-}
-type Rule struct {
- UsePolicy string `json:"use_policy"`
-
- // +optional
- DestIP string `json:"dest_ip"`
-
- // +optional
- DestPort string `json:"dest_port"`
-
- // +optional
- SrcIP string `json:"src_IP"`
-
- // +optional
- SrcPort string `json:"src_port"`
-
- // +optional
- Proto string `json:"proto"`
-
- // +optional
- Family string `json:"family"`
-
- // +optional
- Sticky string `json:"sticky"`
-
- // +optional
- Timeout string `json:"timeout"`
-}
-
-// Mwan3ConfSpec defines the desired state of Mwan3Conf
-type Mwan3ConfSpec struct {
- // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-
- Policies map[string]PolicyMembers `json:"policy"`
- Rules map[string]Rule `json:"rule"`
-}
-
-// Mwan3ConfStatus defines the observed state of Mwan3Conf
-type Mwan3ConfStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-}
-
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-
-// Mwan3Conf is the Schema for the mwan3confs API
-type Mwan3Conf struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec Mwan3ConfSpec `json:"spec,omitempty"`
- Status Mwan3ConfStatus `json:"status,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-
-// Mwan3ConfList contains a list of Mwan3Conf
-type Mwan3ConfList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
- Items []Mwan3Conf `json:"items"`
-}
-
-func init() {
- SchemeBuilder.Register(&Mwan3Conf{}, &Mwan3ConfList{})
-}
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
- "k8s.io/apimachinery/pkg/runtime"
- ctrl "sigs.k8s.io/controller-runtime"
- logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
- "sigs.k8s.io/controller-runtime/pkg/webhook"
-)
-
-// log is for logging in this package.
-var mwan3conflog = logf.Log.WithName("mwan3conf-resource")
-
-func (r *Mwan3Conf) SetupWebhookWithManager(mgr ctrl.Manager) error {
- return ctrl.NewWebhookManagedBy(mgr).
- For(r).
- Complete()
-}
-
-// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
-
-// +kubebuilder:webhook:path=/mutate-batch-sdewan-akraino-org-v1alpha1-mwan3conf,mutating=true,failurePolicy=fail,groups=batch.sdewan.akraino.org,resources=mwan3confs,verbs=create;update,versions=v1alpha1,name=mmwan3conf.kb.io
-
-var _ webhook.Defaulter = &Mwan3Conf{}
-
-// Default implements webhook.Defaulter so a webhook will be registered for the type
-func (r *Mwan3Conf) Default() {
- mwan3conflog.Info("default", "name", r.Name)
-
- // TODO(user): fill in your defaulting logic.
-}
-
-// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
-// +kubebuilder:webhook:verbs=create;update,path=/validate-batch-sdewan-akraino-org-v1alpha1-mwan3conf,mutating=false,failurePolicy=fail,groups=batch.sdewan.akraino.org,resources=mwan3confs,versions=v1alpha1,name=vmwan3conf.kb.io
-
-var _ webhook.Validator = &Mwan3Conf{}
-
-// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
-func (r *Mwan3Conf) ValidateCreate() error {
- mwan3conflog.Info("validate create", "name", r.Name)
-
- // TODO(user): fill in your validation logic upon object creation.
- return r.ValidateMwan3()
-}
-
-// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
-func (r *Mwan3Conf) ValidateUpdate(old runtime.Object) error {
- mwan3conflog.Info("validate update", "name", r.Name)
-
- // TODO(user): fill in your validation logic upon object update.
- return r.ValidateMwan3()
-}
-
-// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
-func (r *Mwan3Conf) ValidateDelete() error {
- mwan3conflog.Info("validate delete", "name", r.Name)
-
- // TODO(user): fill in your validation logic upon object deletion.
- return nil
-}
-
-func (r *Mwan3Conf) ValidateMwan3() error {
- policies := r.Spec.Policies
- for _, rOptions := range r.Spec.Rules {
- if _, ok := policies[rOptions.UsePolicy]; !ok {
- return &UnmatchError{"policy", rOptions.UsePolicy}
- }
- }
- return nil
-}
-
-type UnmatchError struct {
- RType string
- Name string
-}
-
-func (err *UnmatchError) Error() string {
- return err.RType + " :" + err.Name + " doesnt' exist"
-}
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
-// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
-
-type Network struct {
- Name string `json:"name"`
-
- // +optional
- IsProvider bool `json:"isProvider"`
-
- // +optional
- Interface string `json:"interface"`
-
- // +optional
- DefaultGateway bool `json:"defaultGateway"`
-}
-
-// SdewanSpec defines the desired state of Sdewan
-type SdewanSpec struct {
- // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-
- // Foo is an example field of Sdewan. Edit Sdewan_types.go to remove/update
- Node string `json:"node"`
- Networks []Network `json:"networks"`
- // +optional
- Mwan3Conf string `json:"mwan3Conf"`
-}
-
-type Mwan3Status struct {
- Name string `json:"name"`
-
- IsApplied bool `json:"isApplied"`
-
- // +optional
- // +nullable
- AppliedTime *metav1.Time `json:"appliedTime"`
-}
-
-// SdewanStatus defines the observed state of Sdewan
-type SdewanStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
- // +optional
- Mwan3Status Mwan3Status `json:"mwan3Status"`
- Msg string `json:"msg"`
-}
-
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-
-// Sdewan is the Schema for the sdewans API
-type Sdewan struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec SdewanSpec `json:"spec,omitempty"`
- Status SdewanStatus `json:"status,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-
-// SdewanList contains a list of Sdewan
-type SdewanList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
- Items []Sdewan `json:"items"`
-}
-
-func init() {
- SchemeBuilder.Register(&Sdewan{}, &SdewanList{})
-}
+++ /dev/null
-// +build !ignore_autogenerated
-
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by controller-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
- "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Mwan3Conf) DeepCopyInto(out *Mwan3Conf) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- in.Spec.DeepCopyInto(&out.Spec)
- out.Status = in.Status
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mwan3Conf.
-func (in *Mwan3Conf) DeepCopy() *Mwan3Conf {
- if in == nil {
- return nil
- }
- out := new(Mwan3Conf)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Mwan3Conf) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Mwan3ConfList) DeepCopyInto(out *Mwan3ConfList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]Mwan3Conf, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mwan3ConfList.
-func (in *Mwan3ConfList) DeepCopy() *Mwan3ConfList {
- if in == nil {
- return nil
- }
- out := new(Mwan3ConfList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Mwan3ConfList) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Mwan3ConfSpec) DeepCopyInto(out *Mwan3ConfSpec) {
- *out = *in
- if in.Policies != nil {
- in, out := &in.Policies, &out.Policies
- *out = make(map[string]PolicyMembers, len(*in))
- for key, val := range *in {
- (*out)[key] = *val.DeepCopy()
- }
- }
- if in.Rules != nil {
- in, out := &in.Rules, &out.Rules
- *out = make(map[string]Rule, len(*in))
- for key, val := range *in {
- (*out)[key] = val
- }
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mwan3ConfSpec.
-func (in *Mwan3ConfSpec) DeepCopy() *Mwan3ConfSpec {
- if in == nil {
- return nil
- }
- out := new(Mwan3ConfSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Mwan3ConfStatus) DeepCopyInto(out *Mwan3ConfStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mwan3ConfStatus.
-func (in *Mwan3ConfStatus) DeepCopy() *Mwan3ConfStatus {
- if in == nil {
- return nil
- }
- out := new(Mwan3ConfStatus)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Mwan3Status) DeepCopyInto(out *Mwan3Status) {
- *out = *in
- if in.AppliedTime != nil {
- in, out := &in.AppliedTime, &out.AppliedTime
- *out = (*in).DeepCopy()
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mwan3Status.
-func (in *Mwan3Status) DeepCopy() *Mwan3Status {
- if in == nil {
- return nil
- }
- out := new(Mwan3Status)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Network) DeepCopyInto(out *Network) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Network.
-func (in *Network) DeepCopy() *Network {
- if in == nil {
- return nil
- }
- out := new(Network)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *PolicyMember) DeepCopyInto(out *PolicyMember) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyMember.
-func (in *PolicyMember) DeepCopy() *PolicyMember {
- if in == nil {
- return nil
- }
- out := new(PolicyMember)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *PolicyMembers) DeepCopyInto(out *PolicyMembers) {
- *out = *in
- if in.Members != nil {
- in, out := &in.Members, &out.Members
- *out = make([]PolicyMember, len(*in))
- copy(*out, *in)
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyMembers.
-func (in *PolicyMembers) DeepCopy() *PolicyMembers {
- if in == nil {
- return nil
- }
- out := new(PolicyMembers)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Rule) DeepCopyInto(out *Rule) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
-func (in *Rule) DeepCopy() *Rule {
- if in == nil {
- return nil
- }
- out := new(Rule)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Sdewan) DeepCopyInto(out *Sdewan) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- in.Spec.DeepCopyInto(&out.Spec)
- in.Status.DeepCopyInto(&out.Status)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sdewan.
-func (in *Sdewan) DeepCopy() *Sdewan {
- if in == nil {
- return nil
- }
- out := new(Sdewan)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Sdewan) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SdewanList) DeepCopyInto(out *SdewanList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]Sdewan, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SdewanList.
-func (in *SdewanList) DeepCopy() *SdewanList {
- if in == nil {
- return nil
- }
- out := new(SdewanList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *SdewanList) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SdewanSpec) DeepCopyInto(out *SdewanSpec) {
- *out = *in
- if in.Networks != nil {
- in, out := &in.Networks, &out.Networks
- *out = make([]Network, len(*in))
- copy(*out, *in)
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SdewanSpec.
-func (in *SdewanSpec) DeepCopy() *SdewanSpec {
- if in == nil {
- return nil
- }
- out := new(SdewanSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SdewanStatus) DeepCopyInto(out *SdewanStatus) {
- *out = *in
- in.Mwan3Status.DeepCopyInto(&out.Mwan3Status)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SdewanStatus.
-func (in *SdewanStatus) DeepCopy() *SdewanStatus {
- if in == nil {
- return nil
- }
- out := new(SdewanStatus)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *UnmatchError) DeepCopyInto(out *UnmatchError) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnmatchError.
-func (in *UnmatchError) DeepCopy() *UnmatchError {
- if in == nil {
- return nil
- }
- out := new(UnmatchError)
- in.DeepCopyInto(out)
- return out
-}
+++ /dev/null
-# The following manifests contain a self-signed issuer CR and a certificate CR.
-# More document can be found at https://docs.cert-manager.io
-# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
-apiVersion: cert-manager.io/v1alpha2
-kind: Issuer
-metadata:
- name: selfsigned-issuer
- namespace: system
-spec:
- selfSigned: {}
----
-apiVersion: cert-manager.io/v1alpha2
-kind: Certificate
-metadata:
- name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
- namespace: system
-spec:
- # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
- dnsNames:
- - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
- - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
- issuerRef:
- kind: Issuer
- name: selfsigned-issuer
- secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
+++ /dev/null
-resources:
-- certificate.yaml
-
-configurations:
-- kustomizeconfig.yaml
+++ /dev/null
-# This configuration is for teaching kustomize how to update name ref and var substitution
-nameReference:
-- kind: Issuer
- group: cert-manager.io
- fieldSpecs:
- - kind: Certificate
- group: cert-manager.io
- path: spec/issuerRef/name
-
-varReference:
-- kind: Certificate
- group: cert-manager.io
- path: spec/commonName
-- kind: Certificate
- group: cert-manager.io
- path: spec/dnsNames
+++ /dev/null
-
----
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.2.5
- creationTimestamp: null
- name: mwan3confs.batch.sdewan.akraino.org
-spec:
- group: batch.sdewan.akraino.org
- names:
- kind: Mwan3Conf
- listKind: Mwan3ConfList
- plural: mwan3confs
- singular: mwan3conf
- scope: Namespaced
- subresources:
- status: {}
- validation:
- openAPIV3Schema:
- description: Mwan3Conf is the Schema for the mwan3confs API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation
- of an object. Servers should convert recognized schemas to the latest
- internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: Mwan3ConfSpec defines the desired state of Mwan3Conf
- properties:
- policy:
- additionalProperties:
- properties:
- members:
- items:
- properties:
- metric:
- type: integer
- network:
- type: string
- weight:
- type: integer
- required:
- - metric
- - network
- - weight
- type: object
- type: array
- required:
- - members
- type: object
- type: object
- rule:
- additionalProperties:
- properties:
- dest_ip:
- type: string
- dest_port:
- type: string
- family:
- type: string
- proto:
- type: string
- src_IP:
- type: string
- src_port:
- type: string
- sticky:
- type: string
- timeout:
- type: string
- use_policy:
- type: string
- required:
- - use_policy
- type: object
- type: object
- required:
- - policy
- - rule
- type: object
- status:
- description: Mwan3ConfStatus defines the observed state of Mwan3Conf
- type: object
- type: object
- version: v1alpha1
- versions:
- - name: v1alpha1
- served: true
- storage: true
-status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []
+++ /dev/null
-
----
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.2.5
- creationTimestamp: null
- name: sdewans.batch.sdewan.akraino.org
-spec:
- group: batch.sdewan.akraino.org
- names:
- kind: Sdewan
- listKind: SdewanList
- plural: sdewans
- singular: sdewan
- scope: Namespaced
- subresources:
- status: {}
- validation:
- openAPIV3Schema:
- description: Sdewan is the Schema for the sdewans API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation
- of an object. Servers should convert recognized schemas to the latest
- internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: SdewanSpec defines the desired state of Sdewan
- properties:
- mwan3Conf:
- type: string
- networks:
- items:
- properties:
- defaultGateway:
- type: boolean
- interface:
- type: string
- isProvider:
- type: boolean
- name:
- type: string
- required:
- - name
- type: object
- type: array
- node:
- description: Foo is an example field of Sdewan. Edit Sdewan_types.go
- to remove/update
- type: string
- required:
- - networks
- - node
- type: object
- status:
- description: SdewanStatus defines the observed state of Sdewan
- properties:
- msg:
- type: string
- mwan3Status:
- description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
- of cluster Important: Run "make" to regenerate code after modifying
- this file'
- properties:
- appliedTime:
- format: date-time
- nullable: true
- type: string
- isApplied:
- type: boolean
- name:
- type: string
- required:
- - isApplied
- - name
- type: object
- required:
- - msg
- type: object
- type: object
- version: v1alpha1
- versions:
- - name: v1alpha1
- served: true
- storage: true
-status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []
+++ /dev/null
-# This kustomization.yaml is not intended to be run by itself,
-# since it depends on service name and namespace that are out of this kustomize package.
-# It should be run by config/default
-resources:
-- bases/batch.sdewan.akraino.org_sdewans.yaml
-- bases/batch.sdewan.akraino.org_mwan3confs.yaml
-# +kubebuilder:scaffold:crdkustomizeresource
-
-patchesStrategicMerge:
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
-# patches here are for enabling the conversion webhook for each CRD
-#- patches/webhook_in_sdewans.yaml
-#- patches/webhook_in_mwan3confs.yaml
-# +kubebuilder:scaffold:crdkustomizewebhookpatch
-
-# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
-# patches here are for enabling the CA injection for each CRD
-#- patches/cainjection_in_sdewans.yaml
-#- patches/cainjection_in_mwan3confs.yaml
-# +kubebuilder:scaffold:crdkustomizecainjectionpatch
-
-# the following config is for teaching kustomize how to do kustomization for CRDs.
-configurations:
-- kustomizeconfig.yaml
+++ /dev/null
-# This file is for teaching kustomize how to substitute name and namespace reference in CRD
-nameReference:
-- kind: Service
- version: v1
- fieldSpecs:
- - kind: CustomResourceDefinition
- group: apiextensions.k8s.io
- path: spec/conversion/webhookClientConfig/service/name
-
-namespace:
-- kind: CustomResourceDefinition
- group: apiextensions.k8s.io
- path: spec/conversion/webhookClientConfig/service/namespace
- create: false
-
-varReference:
-- path: metadata/annotations
+++ /dev/null
-# The following patch adds a directive for certmanager to inject CA into the CRD
-# CRD conversion requires k8s 1.13 or later.
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
- name: mwan3confs.batch.sdewan.akraino.org
+++ /dev/null
-# The following patch adds a directive for certmanager to inject CA into the CRD
-# CRD conversion requires k8s 1.13 or later.
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
- name: sdewans.batch.sdewan.akraino.org
+++ /dev/null
-# The following patch enables conversion webhook for CRD
-# CRD conversion requires k8s 1.13 or later.
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- name: mwan3confs.batch.sdewan.akraino.org
-spec:
- conversion:
- strategy: Webhook
- webhookClientConfig:
- # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
- # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
- caBundle: Cg==
- service:
- namespace: system
- name: webhook-service
- path: /convert
+++ /dev/null
-# The following patch enables conversion webhook for CRD
-# CRD conversion requires k8s 1.13 or later.
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- name: sdewans.batch.sdewan.akraino.org
-spec:
- conversion:
- strategy: Webhook
- webhookClientConfig:
- # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
- # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
- caBundle: Cg==
- service:
- namespace: system
- name: webhook-service
- path: /convert
+++ /dev/null
-# Adds namespace to all resources.
-namespace: sdwan-system
-
-# Value of this field is prepended to the
-# names of all resources, e.g. a deployment named
-# "wordpress" becomes "alices-wordpress".
-# Note that it should also match with the prefix (text before '-') of the namespace
-# field above.
-namePrefix: sdwan-
-
-# Labels to add to all resources and selectors.
-#commonLabels:
-# someName: someValue
-
-bases:
-- ../crd
-- ../rbac
-- ../manager
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml
-- ../webhook
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
-- ../certmanager
-# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
-#- ../prometheus
-
-patchesStrategicMerge:
-- manager_image_patch.yaml
- # Protect the /metrics endpoint by putting it behind auth.
- # Only one of manager_auth_proxy_patch.yaml and
- # manager_prometheus_metrics_patch.yaml should be enabled.
-- manager_auth_proxy_patch.yaml
- # If you want your controller-manager to expose the /metrics
- # endpoint w/o any authn/z, uncomment the following line and
- # comment manager_auth_proxy_patch.yaml.
- # Only one of manager_auth_proxy_patch.yaml and
- # manager_prometheus_metrics_patch.yaml should be enabled.
-#- manager_prometheus_metrics_patch.yaml
-
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml
-- manager_webhook_patch.yaml
-
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
-# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
-# 'CERTMANAGER' needs to be enabled to use ca injection
-- webhookcainjection_patch.yaml
-
-# the following config is for teaching kustomize how to do var substitution
-vars:
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
-- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
- objref:
- kind: Certificate
- group: cert-manager.io
- version: v1alpha2
- name: serving-cert # this name should match the one in certificate.yaml
- fieldref:
- fieldpath: metadata.namespace
-- name: CERTIFICATE_NAME
- objref:
- kind: Certificate
- group: cert-manager.io
- version: v1alpha2
- name: serving-cert # this name should match the one in certificate.yaml
-- name: SERVICE_NAMESPACE # namespace of the service
- objref:
- kind: Service
- version: v1
- name: webhook-service
- fieldref:
- fieldpath: metadata.namespace
-- name: SERVICE_NAME
- objref:
- kind: Service
- version: v1
- name: webhook-service
+++ /dev/null
-# This patch inject a sidecar container which is a HTTP proxy for the controller manager,
-# it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
-spec:
- template:
- spec:
- containers:
- - name: kube-rbac-proxy
- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1
- args:
- - "--secure-listen-address=0.0.0.0:8443"
- - "--upstream=http://127.0.0.1:8080/"
- - "--logtostderr=true"
- - "--v=10"
- ports:
- - containerPort: 8443
- name: https
- - name: manager
- args:
- - "--metrics-addr=127.0.0.1:8080"
- - "--enable-leader-election"
+++ /dev/null
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
-spec:
- template:
- spec:
- containers:
- - name: manager
- imagePullPolicy: IfNotPresent
- image: integratedcloudnative/sdewan-controller:dev
- env:
- - name: OPENWRT_IMAGE
- value: "integratedcloudnative/openwrt:dev"
+++ /dev/null
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
-spec:
- template:
- spec:
- containers:
- - name: manager
- ports:
- - containerPort: 9443
- name: webhook-server
- protocol: TCP
- volumeMounts:
- - mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
- volumes:
- - name: cert
- secret:
- defaultMode: 420
- secretName: webhook-server-cert
+++ /dev/null
-# This patch add annotation to admission webhook config and
-# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize.
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: MutatingWebhookConfiguration
-metadata:
- name: mutating-webhook-configuration
- annotations:
- cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
----
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: ValidatingWebhookConfiguration
-metadata:
- name: validating-webhook-configuration
- annotations:
- cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+++ /dev/null
-resources:
-- manager.yaml
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-images:
-- name: controller
- newName: integratedcloudnative/sdewan-controller
- newTag: dev
+++ /dev/null
-apiVersion: v1
-kind: Namespace
-metadata:
- labels:
- control-plane: controller-manager
- name: system
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
- labels:
- control-plane: controller-manager
-spec:
- selector:
- matchLabels:
- control-plane: controller-manager
- replicas: 1
- template:
- metadata:
- labels:
- control-plane: controller-manager
- spec:
- containers:
- - command:
- - /manager
- args:
- - --enable-leader-election
- image: controller:latest
- name: manager
- resources:
- limits:
- cpu: 100m
- memory: 30Mi
- requests:
- cpu: 100m
- memory: 20Mi
- terminationGracePeriodSeconds: 10
+++ /dev/null
-resources:
-- monitor.yaml
+++ /dev/null
-
-# Prometheus Monitor Service (Metrics)
-apiVersion: monitoring.coreos.com/v1
-kind: ServiceMonitor
-metadata:
- labels:
- control-plane: controller-manager
- name: controller-manager-metrics-monitor
- namespace: system
-spec:
- endpoints:
- - path: /metrics
- port: https
- selector:
- control-plane: controller-manager
+++ /dev/null
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: proxy-role
-rules:
-- apiGroups: ["authentication.k8s.io"]
- resources:
- - tokenreviews
- verbs: ["create"]
-- apiGroups: ["authorization.k8s.io"]
- resources:
- - subjectaccessreviews
- verbs: ["create"]
+++ /dev/null
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: proxy-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: proxy-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: system
+++ /dev/null
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- control-plane: controller-manager
- name: controller-manager-metrics-service
- namespace: system
-spec:
- ports:
- - name: https
- port: 8443
- targetPort: https
- selector:
- control-plane: controller-manager
+++ /dev/null
-resources:
-- role.yaml
-- role_binding.yaml
-- leader_election_role.yaml
-- leader_election_role_binding.yaml
-# Comment the following 3 lines if you want to disable
-# the auth proxy (https://github.com/brancz/kube-rbac-proxy)
-# which protects your /metrics endpoint.
-- auth_proxy_service.yaml
-- auth_proxy_role.yaml
-- auth_proxy_role_binding.yaml
+++ /dev/null
-# permissions to do leader election.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- name: leader-election-role
-rules:
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - ""
- resources:
- - configmaps/status
- verbs:
- - get
- - update
- - patch
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
+++ /dev/null
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- name: leader-election-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: leader-election-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: system
+++ /dev/null
-# permissions to do edit mwan3confs.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: mwan3conf-editor-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs/status
- verbs:
- - get
- - patch
- - update
+++ /dev/null
-# permissions to do viewer mwan3confs.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: mwan3conf-viewer-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs/status
- verbs:
- - get
+++ /dev/null
-
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- creationTimestamp: null
- name: manager-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans/status
- verbs:
- - get
- - patch
- - update
+++ /dev/null
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: manager-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: manager-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: system
+++ /dev/null
-# permissions to do edit sdewans.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: sdewan-editor-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans/status
- verbs:
- - get
- - patch
- - update
+++ /dev/null
-# permissions to do viewer sdewans.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: sdewan-viewer-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans/status
- verbs:
- - get
+++ /dev/null
-apiVersion: batch.sdewan.akraino.org/v1alpha1
-kind: Mwan3Conf
-metadata:
- name: example-mwan3conf
-spec:
- # Add fields here
- policy:
- testpolicy1:
- members:
- - network: ovn-priv-net
- metric: 1
- weight: 4
- rule:
- https:
- use_policy: testpolicy1
- dest_ip: 10.10.10.16
+++ /dev/null
-apiVersion: batch.sdewan.akraino.org/v1alpha1
-kind: Sdewan
-metadata:
- name: example-sdewan
-spec:
- # Add fields here
- node: "ubuntu18"
- networks:
- - name: ovn-priv-net
- mwan3Conf: example-mwan3conf
+++ /dev/null
-resources:
-- manifests.yaml
-- service.yaml
-
-configurations:
-- kustomizeconfig.yaml
+++ /dev/null
-# the following config is for teaching kustomize where to look at when substituting vars.
-# It requires kustomize v2.1.0 or newer to work properly.
-nameReference:
-- kind: Service
- version: v1
- fieldSpecs:
- - kind: MutatingWebhookConfiguration
- group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service/name
- - kind: ValidatingWebhookConfiguration
- group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service/name
-
-namespace:
-- kind: MutatingWebhookConfiguration
- group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service/namespace
- create: true
-- kind: ValidatingWebhookConfiguration
- group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service/namespace
- create: true
-
-varReference:
-- path: metadata/annotations
+++ /dev/null
-
----
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: MutatingWebhookConfiguration
-metadata:
- creationTimestamp: null
- name: mutating-webhook-configuration
-webhooks:
-- clientConfig:
- caBundle: Cg==
- service:
- name: webhook-service
- namespace: system
- path: /mutate-batch-sdewan-akraino-org-v1alpha1-mwan3conf
- failurePolicy: Fail
- name: mmwan3conf.kb.io
- rules:
- - apiGroups:
- - batch.sdewan.akraino.org
- apiVersions:
- - v1alpha1
- operations:
- - CREATE
- - UPDATE
- resources:
- - mwan3confs
-
----
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: ValidatingWebhookConfiguration
-metadata:
- creationTimestamp: null
- name: validating-webhook-configuration
-webhooks:
-- clientConfig:
- caBundle: Cg==
- service:
- name: webhook-service
- namespace: system
- path: /validate-batch-sdewan-akraino-org-v1alpha1-mwan3conf
- failurePolicy: Fail
- name: vmwan3conf.kb.io
- rules:
- - apiGroups:
- - batch.sdewan.akraino.org
- apiVersions:
- - v1alpha1
- operations:
- - CREATE
- - UPDATE
- resources:
- - mwan3confs
+++ /dev/null
-
-apiVersion: v1
-kind: Service
-metadata:
- name: webhook-service
- namespace: system
-spec:
- ports:
- - port: 443
- targetPort: 9443
- selector:
- control-plane: controller-manager
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package controllers
-
-import (
- "context"
- "time"
-
- "github.com/go-logr/logr"
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/runtime"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-
- batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
-)
-
-// Mwan3ConfReconciler reconciles a Mwan3Conf object
-type Mwan3ConfReconciler struct {
- client.Client
- Log logr.Logger
- Scheme *runtime.Scheme
-}
-
-// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=mwan3confs,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=mwan3confs/status,verbs=get;update;patch
-
-func (r *Mwan3ConfReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
- ctx := context.Background()
- log := r.Log.WithValues("mwan3conf", req.NamespacedName)
-
- instance := &batchv1alpha1.Mwan3Conf{}
- err := r.Get(ctx, req.NamespacedName, instance)
- if err != nil {
- if errors.IsNotFound(err) {
- // Request object not found, could have been deleted after reconcile request.
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
- // Return and don't requeue
- return ctrl.Result{}, nil
- }
- // Error reading the object - requeue the request.
- return ctrl.Result{}, err
- }
-
- foundSdewans := &batchv1alpha1.SdewanList{}
- err = r.List(ctx, foundSdewans, client.MatchingFields{".spec.mwan3Conf": instance.Name})
- if err != nil && errors.IsNotFound(err) {
- log.Info("No sdewan using this mwan3 conf", "mwan3conf", instance.Name)
- return ctrl.Result{}, nil
- } else if err != nil {
- log.Error(err, "Failed to get the sdewan list using this mwan3 conf", "mwan3conf", instance.Name)
- return ctrl.Result{}, nil
- } else {
- log.Info("Applying mwan3 conf for multiple sdewan instances as the conf changes", "mwan3conf", instance.Name)
- for _, sdewan := range foundSdewans.Items {
- // Updating sdewan to set status isapplied = false
- // this will trigger sdewan controller to apply the new conf
- sdewan.Status.Mwan3Status = batchv1alpha1.Mwan3Status{Name: instance.Name, IsApplied: false}
- sdewan.Status.Msg = "triggered by mwan3Conf update at " + time.Now().String()
- err := r.Status().Update(ctx, &sdewan)
- if err != nil {
- log.Error(err, "Failed to update the sdewan instance status", "sdewan", sdewan.Name)
- }
- }
- }
- return ctrl.Result{}, nil
-}
-
-func (r *Mwan3ConfReconciler) SetupWithManager(mgr ctrl.Manager) error {
- if err := mgr.GetFieldIndexer().IndexField(&batchv1alpha1.Sdewan{}, ".spec.mwan3Conf", func(rawObj runtime.Object) []string {
- // grab the job object, extract the owner...
- sdewan := rawObj.(*batchv1alpha1.Sdewan)
- return []string{sdewan.Spec.Mwan3Conf}
- }); err != nil {
- return err
- }
- return ctrl.NewControllerManagedBy(mgr).
- For(&batchv1alpha1.Mwan3Conf{}).
- Complete(r)
-}
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package controllers
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "os"
- "reflect"
- "time"
-
- "github.com/go-logr/logr"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/types"
- "k8s.io/apimachinery/pkg/util/intstr"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-
- batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
- "sdewan.akraino.org/sdewan/wrtprovider"
-)
-
-var OpenwrtTag = "hle2/openwrt-1806-mwan3:latest"
-
-func init() {
- if img := os.Getenv("OPENWRT_IMAGE"); img != "" {
- OpenwrtTag = img
- }
-}
-
-// SdewanReconciler reconciles a Sdewan object
-type SdewanReconciler struct {
- client.Client
- Log logr.Logger
- Scheme *runtime.Scheme
-}
-
-// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=sdewans,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=sdewans/status,verbs=get;update;patch
-
-func (r *SdewanReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
- ctx := context.Background()
- log := r.Log.WithValues("sdewan", req.NamespacedName)
-
- // your logic here
- // Fetch the Sdewan instance
- instance := &batchv1alpha1.Sdewan{}
- err := r.Get(ctx, req.NamespacedName, instance)
- if err != nil {
- if errors.IsNotFound(err) {
- // Request object not found, could have been deleted after reconcile request.
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
- // Return and don't requeue
- return ctrl.Result{}, nil
- }
- // Error reading the object - requeue the request.
- return ctrl.Result{}, err
- }
- for i, network := range instance.Spec.Networks {
- if network.Interface == "" {
- instance.Spec.Networks[i].Interface = fmt.Sprintf("net%d", i)
- }
- }
-
- cm := newConfigmapForCR(instance)
- if err := ctrl.SetControllerReference(instance, cm, r.Scheme); err != nil {
- log.Error(err, "Failed to set configmap controller reference", "Configmap.Name", cm.Name)
- return ctrl.Result{}, nil
- }
- foundcm := &corev1.ConfigMap{}
- err = r.Get(ctx, types.NamespacedName{Name: cm.Name, Namespace: cm.Namespace}, foundcm)
- if err != nil && errors.IsNotFound(err) {
- log.Info("Creating a new Configmap", "Configmap.Namespace", cm.Namespace, "Configmap.Name", cm.Name)
- err = r.Create(ctx, cm)
- if err != nil {
- log.Error(err, "Failed to create configmap", "Configmap.Name", cm.Name)
- return ctrl.Result{}, nil
- }
- } else if err != nil {
- log.Error(err, "Error happends when fetch the configmap", "Configmap.Name", cm.Name)
- return ctrl.Result{}, nil
- } else if reflect.DeepEqual(foundcm.Data, cm.Data) {
- log.Info("Updating Configmap", "Configmap.Namespace", cm.Namespace, "Configmap.Name", cm.Name)
- err = r.Update(ctx, cm)
- if err != nil {
- log.Error(err, "Failed to update configmap", "Configmap.Name", cm.Name)
- return ctrl.Result{}, nil
- }
- } else {
- log.Info("Configmap not changed", "Configmap.Namespace", foundcm.Namespace, "Configmap.Name", foundcm.Name)
- }
- // Define a new Pod object
- pod := newPodForCR(instance)
-
- // Set Sdewan instance as the owner and controller
- if err := ctrl.SetControllerReference(instance, pod, r.Scheme); err != nil {
- return ctrl.Result{}, nil
- }
-
- // Check if this Pod already exists
- foundpod := &corev1.Pod{}
- err = r.Get(ctx, types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}, foundpod)
- if err != nil && errors.IsNotFound(err) {
- log.Info("Creating a new Pod", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)
- err = r.Create(ctx, pod)
- if err != nil {
- log.Error(err, "Failed to create the new pod", "Name", pod.Name)
- return ctrl.Result{}, nil
- }
-
- // Pod created successfully - don't requeue
- log.Info("A new Pod created", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)
- } else if err != nil {
- return ctrl.Result{}, nil
- } else {
- // Pod already exists - don't requeue
- log.Info("Pod already exists", "Pod.Namespace", foundpod.Namespace, "Pod.Name", foundpod.Name)
- }
-
- svc := newSvcForCR(instance)
- // Set Sdewan instance as the owner and controller
- if err := ctrl.SetControllerReference(instance, svc, r.Scheme); err != nil {
- return ctrl.Result{}, nil
- }
- // Check if this svc already exists
- foundsvc := &corev1.Service{}
- err = r.Get(ctx, types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}, foundsvc)
- if err != nil && errors.IsNotFound(err) {
- log.Info("Creating a new Service", "Service.Namespace", svc.Namespace, "Service.Name", svc.Name)
- err = r.Create(ctx, svc)
- if err != nil {
- return ctrl.Result{}, nil
- }
- log.Info("A new Service created", "Service.Namespace", svc.Namespace, "Service.Name", svc.Name)
- } else if err != nil {
- return ctrl.Result{}, nil
- } else {
- log.Info("Service already exists", "Service.Namespace", foundsvc.Namespace, "Service.Name", foundsvc.Name)
- }
-
- // Apply rules if the pod is ready
- if len(foundpod.Status.ContainerStatuses) > 0 && foundpod.Status.ContainerStatuses[0].Ready {
- mwan3conf := &batchv1alpha1.Mwan3Conf{}
- err = r.Get(ctx, types.NamespacedName{Name: instance.Spec.Mwan3Conf, Namespace: instance.Namespace}, mwan3conf)
- if err != nil {
- log.Error(err, "unable to find the mwan3conf", "namespace", instance.Namespace, "mwan3 name", instance.Spec.Mwan3Conf)
- instance.Status.Mwan3Status = batchv1alpha1.Mwan3Status{Name: instance.Spec.Mwan3Conf, IsApplied: false}
- err = r.Status().Update(ctx, instance)
- if err != nil {
- log.Error(err, "Failed to update Sdewan status")
- return ctrl.Result{}, nil
- }
- return ctrl.Result{}, nil
- }
- if (instance.Status.Mwan3Status.Name != instance.Spec.Mwan3Conf) || !instance.Status.Mwan3Status.IsApplied {
- err = wrtprovider.Mwan3Apply(mwan3conf, instance)
- if err != nil {
- log.Error(err, "Failed to apply the mwan3conf", "namespace", instance.Namespace, "mwan3 name", instance.Spec.Mwan3Conf)
- instance.Status.Mwan3Status = batchv1alpha1.Mwan3Status{Name: instance.Spec.Mwan3Conf, IsApplied: false}
- r.Status().Update(ctx, instance)
- return ctrl.Result{}, nil
- }
- instance.Status.Mwan3Status = batchv1alpha1.Mwan3Status{Name: instance.Spec.Mwan3Conf, IsApplied: true, AppliedTime: &metav1.Time{Time: time.Now()}}
- err = r.Status().Update(ctx, instance)
- if err != nil {
- log.Error(err, "Failed to update Sdewan status")
- return ctrl.Result{}, nil
- }
- log.Info("sdewan config applied")
- } else {
- log.Info("mwan3 conf not chnaged, so not re-apply", "sdewan", instance.Name)
- }
- } else {
- log.Info("Don't apply conf as the pod is not ready", "sdewan", instance.Name)
- }
-
- return ctrl.Result{}, nil
-}
-
-func (r *SdewanReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return ctrl.NewControllerManagedBy(mgr).
- For(&batchv1alpha1.Sdewan{}).
- Owns(&corev1.Pod{}).
- Complete(r)
-}
-
-// newSvcForCR returns a svc with the same name/namespace as the cr
-func newSvcForCR(cr *batchv1alpha1.Sdewan) *corev1.Service {
- return &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: cr.Name,
- Namespace: cr.Namespace,
- },
- Spec: corev1.ServiceSpec{
- Ports: []corev1.ServicePort{
- {
- Name: "api",
- Port: 80,
- },
- },
- Selector: map[string]string{
- "app": cr.Name,
- },
- },
- }
-}
-
-// newConfigmapForCR returns a configmap with the same name/namespace as the cr
-func newConfigmapForCR(cr *batchv1alpha1.Sdewan) *corev1.ConfigMap {
- netjson, _ := json.MarshalIndent(cr.Spec.Networks, "", " ")
- return &corev1.ConfigMap{
- ObjectMeta: metav1.ObjectMeta{
- Name: cr.Name,
- Namespace: cr.Namespace,
- },
- Data: map[string]string{
- "networks.json": string(netjson),
- "entrypoint.sh": `#!/bin/bash
-# Always exit on errors.
-set -e
-echo "" > /etc/config/network
-cat > /etc/config/mwan3 <<EOF
-config globals 'globals'
- option mmx_mask '0x3F00'
- option local_source 'lan'
-EOF
-for net in $(jq -c ".[]" /tmp/sdewan/networks.json)
-do
- interface=$(echo $net | jq -r .interface)
- ipaddr=$(ifconfig $interface | awk '/inet/{print $2}' | cut -f2 -d ":" | awk 'NR==1 {print $1}')
- if [ "$isProvider" == "true" ] || [ "$isProvider" == "1" ]]
- then
- vif="wan_$interface"
- else
- vif="lan_$interface"
- fi
- netmask=$(ifconfig $interface | awk '/inet/{print $4}' | cut -f2 -d ":" | awk 'NR==1 {print $1}')
- cat >> /etc/config/network <<EOF
-config interface '$vif'
- option ifname '$interface'
- option proto 'static'
- option ipaddr '$ipaddr'
- option netmask '$netmask'
-EOF
- cat >> /etc/config/mwan3 <<EOF
-config interface '$vif'
- option enabled '1'
- option family 'ipv4'
- option reliability '2'
- option count '1'
- option timeout '2'
- option failure_latency '1000'
- option recovery_latency '500'
- option failure_loss '20'
- option recovery_loss '5'
- option interval '5'
- option down '3'
- option up '8'
-EOF
-done
-/sbin/procd &
-/sbin/ubusd &
-iptables -S
-sleep 1
-/etc/init.d/rpcd start
-/etc/init.d/dnsmasq start
-/etc/init.d/network start
-/etc/init.d/odhcpd start
-/etc/init.d/uhttpd start
-/etc/init.d/log start
-/etc/init.d/dropbear start
-/etc/init.d/mwan3 restart
-echo "Entering sleep... (success)"
-# Sleep forever.
-while true; do sleep 100; done`,
- },
- }
-}
-
-// newPodForCR returns a busybox pod with the same name/namespace as the cr
-func newPodForCR(cr *batchv1alpha1.Sdewan) *corev1.Pod {
- labels := map[string]string{
- "app": cr.Name,
- }
- priv := true
- var netmaps []map[string]interface{}
- for _, net := range cr.Spec.Networks {
- netmaps = append(netmaps, map[string]interface{}{
- "name": net.Name,
- "interface": net.Interface,
- "defaultGateway": fmt.Sprintf("%t", net.DefaultGateway),
- })
- }
- netjson, _ := json.MarshalIndent(netmaps, "", " ")
- volumes := []corev1.Volume{
- {
- Name: cr.Name,
- VolumeSource: corev1.VolumeSource{
- ConfigMap: &corev1.ConfigMapVolumeSource{
- LocalObjectReference: corev1.LocalObjectReference{Name: cr.Name},
- },
- },
- },
- }
- return &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: cr.Name,
- Namespace: cr.Namespace,
- Labels: labels,
- Annotations: map[string]string{
- "k8s.v1.cni.cncf.io/networks": `[{ "name": "ovn-networkobj"}]`,
- "k8s.plugin.opnfv.org/nfn-network": `{ "type": "ovn4nfv", "interface": ` + string(netjson) + "}",
- },
- },
- Spec: corev1.PodSpec{
- Containers: []corev1.Container{
- {
- Name: "sdewan",
- Image: OpenwrtTag,
- Command: []string{"/bin/sh", "/tmp/sdewan/entrypoint.sh"},
- ImagePullPolicy: corev1.PullIfNotPresent,
- ReadinessProbe: &corev1.Probe{
- Handler: corev1.Handler{HTTPGet: &corev1.HTTPGetAction{
- Path: "/",
- Port: intstr.IntOrString{IntVal: 80},
- Scheme: corev1.URISchemeHTTP},
- },
- InitialDelaySeconds: 5,
- PeriodSeconds: 5,
- FailureThreshold: 5,
- },
- SecurityContext: &corev1.SecurityContext{
- Privileged: &priv,
- },
- VolumeMounts: []corev1.VolumeMount{
- {
- Name: cr.Name,
- ReadOnly: true,
- MountPath: "/tmp/sdewan",
- },
- },
- },
- },
- NodeSelector: map[string]string{"kubernetes.io/hostname": cr.Spec.Node},
- Volumes: volumes,
- },
- }
-}
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package controllers
-
-import (
- "path/filepath"
- "testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- "k8s.io/client-go/kubernetes/scheme"
- "k8s.io/client-go/rest"
- batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/envtest"
- logf "sigs.k8s.io/controller-runtime/pkg/log"
- "sigs.k8s.io/controller-runtime/pkg/log/zap"
- // +kubebuilder:scaffold:imports
-)
-
-// These tests use Ginkgo (BDD-style Go testing framework). Refer to
-// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
-
-var cfg *rest.Config
-var k8sClient client.Client
-var testEnv *envtest.Environment
-
-func TestAPIs(t *testing.T) {
- RegisterFailHandler(Fail)
-
- RunSpecsWithDefaultAndCustomReporters(t,
- "Controller Suite",
- []Reporter{envtest.NewlineReporter{}})
-}
-
-var _ = BeforeSuite(func(done Done) {
- logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
-
- By("bootstrapping test environment")
- testEnv = &envtest.Environment{
- CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
- }
-
- var err error
- cfg, err = testEnv.Start()
- Expect(err).ToNot(HaveOccurred())
- Expect(cfg).ToNot(BeNil())
-
- err = batchv1alpha1.AddToScheme(scheme.Scheme)
- Expect(err).NotTo(HaveOccurred())
-
- err = batchv1alpha1.AddToScheme(scheme.Scheme)
- Expect(err).NotTo(HaveOccurred())
-
- // +kubebuilder:scaffold:scheme
-
- k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
- Expect(err).ToNot(HaveOccurred())
- Expect(k8sClient).ToNot(BeNil())
-
- close(done)
-}, 60)
-
-var _ = AfterSuite(func() {
- By("tearing down the test environment")
- err := testEnv.Stop()
- Expect(err).ToNot(HaveOccurred())
-})
+++ /dev/null
-module sdewan.akraino.org/sdewan
-
-go 1.13
-
-require (
- github.com/emicklei/go-restful v2.9.6+incompatible // indirect
- github.com/go-logr/logr v0.1.0
- github.com/go-openapi/spec v0.19.4 // indirect
- github.com/onsi/ginkgo v1.10.1
- github.com/onsi/gomega v1.7.0
- golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 // indirect
- k8s.io/api v0.0.0-20191114100352-16d7abae0d2a
- k8s.io/apimachinery v0.17.0
- k8s.io/client-go v0.0.0-20191114101535-6c5935290e33
- sigs.k8s.io/controller-runtime v0.4.0
-)
+++ /dev/null
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
-github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
-github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
-github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
-github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
-github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
-github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
-github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
-github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
-github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
-github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
-github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
-github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
-github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
-github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
-github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
-github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
-github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
-github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
-github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
-github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
-github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
-github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
-github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
-github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
-github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
-github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
-github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
-github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
-github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
-github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
-github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
-github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
-github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
-github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
-github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
-github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
-github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
-github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
-github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
-github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
-github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
-github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
-github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
-github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
-github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
-github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
-github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
-github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
-github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
-github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
-github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
-github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
-github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
-github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
-github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
-github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
-github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
-github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
-github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
-github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
-github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
-github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
-github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
-github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
-github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
-github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
-github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg=
-github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
-github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
-github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk=
-github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
-github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks=
-github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
-github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
-github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
-github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
-github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
-github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 h1:u4bArs140e9+AfE52mFHOXVFnOSBJBRlzTHrOPLOIhE=
-github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
-github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
-github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
-github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
-github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o=
-github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU=
-github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
-github.com/golangci/golangci-lint v1.19.1/go.mod h1:2CEc4Fxx3vxDv7g8DyXkHCBF73AOzAymcJAprs2vCps=
-github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
-github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
-github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
-github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
-github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
-github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
-github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
-github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
-github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
-github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
-github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
-github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
-github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
-github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
-github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
-github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
-github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
-github.com/matoous/godox v0.0.0-20190910121045-032ad8106c86/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
-github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
-github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
-github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
-github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
-github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
-github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
-github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
-github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
-github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
-github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
-github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
-github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
-github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
-github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
-go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
-go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
-golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
-golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
-golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
-golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
-gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
-gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
-gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
-gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
-gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
-gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
-gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
-k8s.io/api v0.0.0-20190918155943-95b840bb6a1f h1:8FRUST8oUkEI45WYKyD8ed7Ad0Kg5v11zHyPkEVb2xo=
-k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
-k8s.io/api v0.0.0-20191016225839-816a9b7df678 h1:z/0BV/tMBIvdwZvqBH/f7TWjQX9y3dj1nMNhrSK0h/8=
-k8s.io/api v0.0.0-20191016225839-816a9b7df678/go.mod h1:LZQaT8MvVpl7Bg2lYFcQm7+Mpdxq8p1NFl3yh+5DCwY=
-k8s.io/api v0.0.0-20191114100352-16d7abae0d2a h1:86XISgFlG7lPOWj6wYLxd+xqhhVt/WQjS4Tf39rP09s=
-k8s.io/api v0.0.0-20191114100352-16d7abae0d2a/go.mod h1:qetVJgs5i8jwdFIdoOZ70ks0ecgU+dYwqZ2uD1srwOU=
-k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM=
-k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
-k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783 h1:V6ndwCPoao1yZ52agqOKaUAl7DYWVGiXjV7ePA2i610=
-k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=
-k8s.io/apiextensions-apiserver v0.17.0 h1:+XgcGxqaMztkbbvsORgCmHIb4uImHKvTjNyu7b8gRnA=
-k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG55nHd1DCoHj8=
-k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
-k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655 h1:CS1tBQz3HOXiseWZu6ZicKX361CZLT97UFnnPx0aqBw=
-k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4=
-k8s.io/apimachinery v0.0.0-20191016225534-b1267f8c42b4/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw=
-k8s.io/apimachinery v0.0.0-20191020214737-6c8691705fc5/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw=
-k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ=
-k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo=
-k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
-k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
-k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg=
-k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90 h1:mLmhKUm1X+pXu0zXMEzNsOF5E2kKFGe5o6BZBIIqA6A=
-k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
-k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 h1:07mhG/2oEoo3N+sHVOo0L9PJ/qvbk3N5n2dj8IWefnQ=
-k8s.io/client-go v0.0.0-20191114101535-6c5935290e33/go.mod h1:4L/zQOBkEf4pArQJ+CMk1/5xjA30B5oyWv+Bzb44DOw=
-k8s.io/client-go v0.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg=
-k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
-k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=
-k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
-k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE=
-k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
-k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA=
-k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc=
-k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ=
-k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
-k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
-k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
-k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ=
-k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
-k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=
-k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
-k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
-modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
-modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
-modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
-modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
-sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
-sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
-sigs.k8s.io/controller-tools v0.2.5 h1:kH7HKWed9XO42OTxyhUtqyImiefdZV2Q9Jbrytvhf18=
-sigs.k8s.io/controller-tools v0.2.5/go.mod h1:+t0Hz6tOhJQCdd7IYO0mNzimmiM9sqMU0021u6UCF2o=
-sigs.k8s.io/kustomize/api v0.1.1 h1:W2dWXex2MhF4/EZNokZllvet2RejCHqdAFklufN7VTg=
-sigs.k8s.io/kustomize/api v0.1.1/go.mod h1:FyfJD1q1QMjC/TvK78b6cCtZB+mbpnGIo9YOvbucJes=
-sigs.k8s.io/kustomize/kustomize/v3 v3.2.1/go.mod h1:jXW5RpjfoZtLLrpCKVCZ6AHs8iV3+nkRl084TFFsWLE=
-sigs.k8s.io/kustomize/kustomize/v3 v3.2.2/go.mod h1:fptJqEJbGtNOHHQgc9dhN/Vme7q3aCHu2x9vi7fAFoQ=
-sigs.k8s.io/kustomize/kustomize/v3 v3.2.3/go.mod h1:zdSwGK28DHEPaQoYmSIi/sgg4uCRPtWljj1mxz3Mafw=
-sigs.k8s.io/kustomize/kustomize/v3 v3.3.0 h1:1uBNN0OUo7jKHIyvvTYtjNIZNFcyG3d4i2xbWr3dKVc=
-sigs.k8s.io/kustomize/kustomize/v3 v3.3.0/go.mod h1:eMtSZo5hDlU1358uVNF+sj2fhc2Jod0MxESFemKpFe8=
-sigs.k8s.io/kustomize/v3 v3.2.0/go.mod h1:ztX4zYc/QIww3gSripwF7TBOarBTm5BvyAMem0kCzOE=
-sigs.k8s.io/kustomize/v3 v3.3.0/go.mod h1:STVEDXXV/PoFIQPMI8uVcrYME/YnMIp1+lyBnK4xgik=
-sigs.k8s.io/kustomize/v3 v3.3.1/go.mod h1:2ojB+51Z+YIBpEOknAFX3U8f0XXa94PFcfXPccDxAfg=
-sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
-sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
-sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
-sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
-sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
-sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
-sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
\ No newline at end of file
+++ /dev/null
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package main
-
-import (
- "flag"
- "os"
-
- "k8s.io/apimachinery/pkg/runtime"
- clientgoscheme "k8s.io/client-go/kubernetes/scheme"
- _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
- batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
- "sdewan.akraino.org/sdewan/controllers"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/log/zap"
- // +kubebuilder:scaffold:imports
-)
-
-var (
- scheme = runtime.NewScheme()
- setupLog = ctrl.Log.WithName("setup")
-)
-
-func init() {
- _ = clientgoscheme.AddToScheme(scheme)
-
- _ = batchv1alpha1.AddToScheme(scheme)
- // +kubebuilder:scaffold:scheme
-}
-
-func main() {
- var metricsAddr string
- var enableLeaderElection bool
- flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
- flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
- "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
- flag.Parse()
-
- ctrl.SetLogger(zap.New(func(o *zap.Options) {
- o.Development = true
- }))
-
- mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
- Scheme: scheme,
- MetricsBindAddress: metricsAddr,
- LeaderElection: enableLeaderElection,
- Port: 9443,
- })
- if err != nil {
- setupLog.Error(err, "unable to start manager")
- os.Exit(1)
- }
-
- if err = (&controllers.SdewanReconciler{
- Client: mgr.GetClient(),
- Log: ctrl.Log.WithName("controllers").WithName("Sdewan"),
- Scheme: mgr.GetScheme(),
- }).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "Sdewan")
- os.Exit(1)
- }
- if err = (&controllers.Mwan3ConfReconciler{
- Client: mgr.GetClient(),
- Log: ctrl.Log.WithName("controllers").WithName("Mwan3Conf"),
- Scheme: mgr.GetScheme(),
- }).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "Mwan3Conf")
- os.Exit(1)
- }
- if os.Getenv("ENABLE_WEBHOOKS") != "false" {
- if err = (&batchv1alpha1.Mwan3Conf{}).SetupWebhookWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create webhook", "webhook", "Mwan3Conf")
- os.Exit(1)
- }
- }
- // +kubebuilder:scaffold:builder
-
- setupLog.Info("starting manager")
- if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
- setupLog.Error(err, "problem running manager")
- os.Exit(1)
- }
-}
+++ /dev/null
-package openwrt
-
-import (
- "encoding/json"
-)
-
-const (
- firewallBaseURL = "sdewan/firewall/v1/"
-)
-
-type FirewallClient struct {
- OpenwrtClient *openwrtClient
-}
-
-// Firewall Zones
-type SdewanFirewallZone struct {
- Name string `json:"name"`
- Network []string `json:"network"`
- Masq string `json:"masq"`
- MasqSrc []string `json:"masq_src"`
- MasqDest []string `json:"masq_dest"`
- MasqAllowInvalid string `json:"masq_allow_invalid"`
- MtuFix string `json:"mtu_fix"`
- Input string `json:"input"`
- Forward string `json:"forward"`
- Output string `json:"output"`
- Family string `json:"family"`
- Subnet []string `json:"subnet"`
- ExtraSrc string `json:"extra_src"`
- ExtraDest string `json:"etra_dest"`
-}
-
-type SdewanFirewallZones struct {
- Zones []SdewanFirewallZone `json:"zones"`
-}
-
-// Firewall Forwarding
-type SdewanFirewallForwarding struct {
- Name string `json:"name"`
- Src string `json:"src"`
- Dest string `json:"dest"`
- Family string `json:"family"`
-}
-
-type SdewanFirewallForwardings struct {
- Forwardings []SdewanFirewallForwarding `json:"forwardings"`
-}
-
-// Firewall Rule
-type SdewanFirewallRule struct {
- Name string `json:"name"`
- Src string `json:"src"`
- SrcIp string `json:"src_ip"`
- SrcMac string `json:"src_mac"`
- SrcPort string `json:"src_port"`
- Proto string `json:"proto"`
- IcmpType []string `json:"icmp_type"`
- Dest string `json:"dest"`
- DestIp string `json:"dest_ip"`
- DestPort string `json:"dest_port"`
- Mark string `json:"mark"`
- Target string `json:"target"`
- SetMark string `json:"set_mark"`
- SetXmark string `json:"set_xmark"`
- Family string `json:"family"`
- Extra string `json:"extra"`
-}
-
-type SdewanFirewallRules struct {
- Rules []SdewanFirewallRule `json:"rules"`
-}
-
-// Firewall Redirect
-type SdewanFirewallRedirect struct {
- Name string `json:"name"`
- Src string `json:"src"`
- SrcIp string `json:"src_ip"`
- SrcDIp string `json:"src_dip"`
- SrcMac string `json:"src_mac"`
- SrcPort string `json:"src_port"`
- SrcDPort string `json:"src_dport"`
- Proto string `json:"proto"`
- Dest string `json:"dest"`
- DestIp string `json:"dest_ip"`
- DestPort string `json:"dest_port"`
- Mark string `json:"mark"`
- Target string `json:"target"`
- Family string `json:"family"`
-}
-
-type SdewanFirewallRedirects struct {
- Redirects []SdewanFirewallRedirect `json:"redirects"`
-}
-
-// Zone APIs
-// get zones
-func (f *FirewallClient) GetZones() (*SdewanFirewallZones, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(firewallBaseURL + "zones")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallZones SdewanFirewallZones
- err = json.Unmarshal([]byte(response), &sdewanFirewallZones)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallZones, nil
-}
-
-// get zone
-func (m *FirewallClient) GetZone(zone string) (*SdewanFirewallZone, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(firewallBaseURL + "zone/" + zone)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallZone SdewanFirewallZone
- err = json.Unmarshal([]byte(response), &sdewanFirewallZone)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallZone, nil
-}
-
-// create zone
-func (m *FirewallClient) CreateZone(zone SdewanFirewallZone) (*SdewanFirewallZone, error) {
- var response string
- var err error
- zone_obj, _ := json.Marshal(zone)
- response, err = m.OpenwrtClient.Post(firewallBaseURL + "zone", string(zone_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallZone SdewanFirewallZone
- err = json.Unmarshal([]byte(response), &sdewanFirewallZone)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallZone, nil
-}
-
-// delete zone
-func (m *FirewallClient) DeleteZone(zone_name string) (error) {
- _, err := m.OpenwrtClient.Delete(firewallBaseURL + "zone/" + zone_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update zone
-func (m *FirewallClient) UpdateZone(zone SdewanFirewallZone) (*SdewanFirewallZone, error) {
- var response string
- var err error
- zone_obj, _ := json.Marshal(zone)
- zone_name := zone.Name
- response, err = m.OpenwrtClient.Put(firewallBaseURL + "zone/" + zone_name, string(zone_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallZone SdewanFirewallZone
- err = json.Unmarshal([]byte(response), &sdewanFirewallZone)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallZone, nil
-}
-
-// Rule APIs
-// get rules
-func (f *FirewallClient) GetRules() (*SdewanFirewallRules, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(firewallBaseURL + "rules")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRules SdewanFirewallRules
- err = json.Unmarshal([]byte(response), &sdewanFirewallRules)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRules, nil
-}
-
-// get rule
-func (m *FirewallClient) GetRule(rule string) (*SdewanFirewallRule, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(firewallBaseURL + "rule/" + rule)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRule SdewanFirewallRule
- err = json.Unmarshal([]byte(response), &sdewanFirewallRule)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRule, nil
-}
-
-// create rule
-func (m *FirewallClient) CreateRule(rule SdewanFirewallRule) (*SdewanFirewallRule, error) {
- var response string
- var err error
- rule_obj, _ := json.Marshal(rule)
- response, err = m.OpenwrtClient.Post(firewallBaseURL + "rule", string(rule_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRule SdewanFirewallRule
- err = json.Unmarshal([]byte(response), &sdewanFirewallRule)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRule, nil
-}
-
-// delete rule
-func (m *FirewallClient) DeleteRule(rule_name string) (error) {
- _, err := m.OpenwrtClient.Delete(firewallBaseURL + "rule/" + rule_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update rule
-func (m *FirewallClient) UpdateRule(rule SdewanFirewallRule) (*SdewanFirewallRule, error) {
- var response string
- var err error
- rule_obj, _ := json.Marshal(rule)
- rule_name := rule.Name
- response, err = m.OpenwrtClient.Put(firewallBaseURL + "rule/" + rule_name, string(rule_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRule SdewanFirewallRule
- err = json.Unmarshal([]byte(response), &sdewanFirewallRule)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRule, nil
-}
-
-// Forwarding APIs
-// get forwardings
-func (f *FirewallClient) GetForwardings() (*SdewanFirewallForwardings, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(firewallBaseURL + "forwardings")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallForwardings SdewanFirewallForwardings
- err = json.Unmarshal([]byte(response), &sdewanFirewallForwardings)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallForwardings, nil
-}
-
-// get forwarding
-func (m *FirewallClient) GetForwarding(forwarding string) (*SdewanFirewallForwarding, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(firewallBaseURL + "forwarding/" + forwarding)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallForwarding SdewanFirewallForwarding
- err = json.Unmarshal([]byte(response), &sdewanFirewallForwarding)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallForwarding, nil
-}
-
-// create forwarding
-func (m *FirewallClient) CreateForwarding(forwarding SdewanFirewallForwarding) (*SdewanFirewallForwarding, error) {
- var response string
- var err error
- forwarding_obj, _ := json.Marshal(forwarding)
- response, err = m.OpenwrtClient.Post(firewallBaseURL + "forwarding", string(forwarding_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallForwarding SdewanFirewallForwarding
- err = json.Unmarshal([]byte(response), &sdewanFirewallForwarding)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallForwarding, nil
-}
-
-// delete forwarding
-func (m *FirewallClient) DeleteForwarding(forwarding_name string) (error) {
- _, err := m.OpenwrtClient.Delete(firewallBaseURL + "forwarding/" + forwarding_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update forwarding
-func (m *FirewallClient) UpdateForwarding(forwarding SdewanFirewallForwarding) (*SdewanFirewallForwarding, error) {
- var response string
- var err error
- forwarding_obj, _ := json.Marshal(forwarding)
- forwarding_name := forwarding.Name
- response, err = m.OpenwrtClient.Put(firewallBaseURL + "forwarding/" + forwarding_name, string(forwarding_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallForwarding SdewanFirewallForwarding
- err = json.Unmarshal([]byte(response), &sdewanFirewallForwarding)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallForwarding, nil
-}
-
-// Redirect APIs
-// get redirects
-func (f *FirewallClient) GetRedirects() (*SdewanFirewallRedirects, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(firewallBaseURL + "redirects")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRedirects SdewanFirewallRedirects
- err = json.Unmarshal([]byte(response), &sdewanFirewallRedirects)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRedirects, nil
-}
-
-// get redirect
-func (m *FirewallClient) GetRedirect(redirect string) (*SdewanFirewallRedirect, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(firewallBaseURL + "redirect/" + redirect)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRedirect SdewanFirewallRedirect
- err = json.Unmarshal([]byte(response), &sdewanFirewallRedirect)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRedirect, nil
-}
-
-// create redirect
-func (m *FirewallClient) CreateRedirect(redirect SdewanFirewallRedirect) (*SdewanFirewallRedirect, error) {
- var response string
- var err error
- redirect_obj, _ := json.Marshal(redirect)
- response, err = m.OpenwrtClient.Post(firewallBaseURL + "redirect", string(redirect_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRedirect SdewanFirewallRedirect
- err = json.Unmarshal([]byte(response), &sdewanFirewallRedirect)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRedirect, nil
-}
-
-// delete redirect
-func (m *FirewallClient) DeleteRedirect(redirect_name string) (error) {
- _, err := m.OpenwrtClient.Delete(firewallBaseURL + "redirect/" + redirect_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update redirect
-func (m *FirewallClient) UpdateRedirect(redirect SdewanFirewallRedirect) (*SdewanFirewallRedirect, error) {
- var response string
- var err error
- redirect_obj, _ := json.Marshal(redirect)
- redirect_name := redirect.Name
- response, err = m.OpenwrtClient.Put(firewallBaseURL + "redirect/" + redirect_name, string(redirect_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanFirewallRedirect SdewanFirewallRedirect
- err = json.Unmarshal([]byte(response), &sdewanFirewallRedirect)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanFirewallRedirect, nil
-}
+++ /dev/null
-package openwrt
-
-import (
- "encoding/json"
-)
-
-const (
- ipsecBaseURL = "sdewan/ipsec/v1/"
-)
-
-type IpsecClient struct {
- OpenwrtClient *openwrtClient
-}
-
-// Proposals
-type SdewanIpsecProposal struct {
- Name string `json:"name"`
- EncryptionAlgorithm string `json:"encryption_algorithm"`
- HashAlgorithm string `json:"hash_algorithm"`
- DhGroup string `json:"dh_group"`
-}
-
-type SdewanIpsecProposals struct {
- Proposals []SdewanIpsecProposal `json:"proposals"`
-}
-
-// Sites
-type SdewanIpsecConnection struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Mode string `json:"mode"`
- LocalSubnet string `json:"local_subnet"`
- LocalNat string `json:"local_nat"`
- LocalSourceip string `json:"local_sourceip"`
- LocalUpdown string `json:"local_updown"`
- LocalFirewall string `json:"local_firewall"`
- RemoteSubnet string `json:"remote_subnet"`
- RemoteSourceip string `json:"remote_sourceip"`
- RemoteUpdown string `json:"remote_updown"`
- RemoteFirewall string `json:"remote_firewall"`
- CryptoProposal []string `json:"crypto_proposal"`
-}
-
-type SdewanIpsecSite struct {
- Name string `json:"name"`
- Gateway string `json:"gateway"`
- PreSharedKey string `json:"pre_shared_key"`
- AuthenticationMethod string `json:"authentication_method"`
- LocalIdentifier string `json:"local_identifier"`
- RemoteIdentifier string `json:"remote_identifier"`
- CryptoProposal []string `json:"crypto_proposal"`
- ForceCryptoProposal string `json:"force_crypto_proposal"`
- LocalPublicCert string `json:"local_public_cert"`
- LocalPrivateCert string `json:"local_private_cert"`
- SharedCa string `json:"shared_ca"`
- Connections []SdewanIpsecConnection `json:"connections"`
-}
-
-type SdewanIpsecSites struct {
- Sites []SdewanIpsecSite `json:"sites"`
-}
-
-// Proposal APIs
-// get proposals
-func (f *IpsecClient) GetProposals() (*SdewanIpsecProposals, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(ipsecBaseURL + "proposals")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecProposals SdewanIpsecProposals
- err = json.Unmarshal([]byte(response), &sdewanIpsecProposals)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecProposals, nil
-}
-
-// get proposal
-func (m *IpsecClient) GetProposal(proposal string) (*SdewanIpsecProposal, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(ipsecBaseURL + "proposal/" + proposal)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecProposal SdewanIpsecProposal
- err = json.Unmarshal([]byte(response), &sdewanIpsecProposal)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecProposal, nil
-}
-
-// create proposal
-func (m *IpsecClient) CreateProposal(proposal SdewanIpsecProposal) (*SdewanIpsecProposal, error) {
- var response string
- var err error
- proposal_obj, _ := json.Marshal(proposal)
- response, err = m.OpenwrtClient.Post(ipsecBaseURL + "proposal", string(proposal_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecProposal SdewanIpsecProposal
- err = json.Unmarshal([]byte(response), &sdewanIpsecProposal)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecProposal, nil
-}
-
-// delete proposal
-func (m *IpsecClient) DeleteProposal(proposal_name string) (error) {
- _, err := m.OpenwrtClient.Delete(ipsecBaseURL + "proposal/" + proposal_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update proposal
-func (m *IpsecClient) UpdateProposal(proposal SdewanIpsecProposal) (*SdewanIpsecProposal, error) {
- var response string
- var err error
- proposal_obj, _ := json.Marshal(proposal)
- proposal_name := proposal.Name
- response, err = m.OpenwrtClient.Put(ipsecBaseURL + "proposal/" + proposal_name, string(proposal_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecProposal SdewanIpsecProposal
- err = json.Unmarshal([]byte(response), &sdewanIpsecProposal)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecProposal, nil
-}
-
-// Site APIs
-// get sites
-func (f *IpsecClient) GetSites() (*SdewanIpsecSites, error) {
- var response string
- var err error
- response, err = f.OpenwrtClient.Get(ipsecBaseURL + "sites")
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecSites SdewanIpsecSites
- err = json.Unmarshal([]byte(response), &sdewanIpsecSites)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecSites, nil
-}
-
-// get site
-func (m *IpsecClient) GetSite(site string) (*SdewanIpsecSite, error) {
- var response string
- var err error
- response, err = m.OpenwrtClient.Get(ipsecBaseURL + "site/" + site)
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecSite, nil
-}
-
-// create site
-func (m *IpsecClient) CreateSite(site SdewanIpsecSite) (*SdewanIpsecSite, error) {
- var response string
- var err error
- site_obj, _ := json.Marshal(site)
- response, err = m.OpenwrtClient.Post(ipsecBaseURL + "site", string(site_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecSite, nil
-}
-
-// delete site
-func (m *IpsecClient) DeleteSite(site_name string) (error) {
- _, err := m.OpenwrtClient.Delete(ipsecBaseURL + "site/" + site_name)
- if (err != nil) {
- return err
- }
-
- return nil
-}
-
-// update site
-func (m *IpsecClient) UpdateSite(site SdewanIpsecSite) (*SdewanIpsecSite, error) {
- var response string
- var err error
- site_obj, _ := json.Marshal(site)
- site_name := site.Name
- response, err = m.OpenwrtClient.Put(ipsecBaseURL + "site/" + site_name, string(site_obj))
- if (err != nil) {
- return nil, err
- }
-
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
- if (err != nil) {
- return nil, err
- }
-
- return &sdewanIpsecSite, nil
-}
+++ /dev/null
-package openwrt
-
-import (
- "encoding/json"
-)
-
-const (
- mwan3BaseURL = "sdewan/mwan3/v1/"
-)
-
-type Mwan3Client struct {
- OpenwrtClient *openwrtClient
-}
-
-// MWAN3 interface status
-type IpStatus struct {
- Status string `json:"status"`
- Latency int `json:"latency"`
- Packetloss int `json:"packetloss"`
- Ip string `json:"ip"`
-}
-
-type WanInterfaceStatus struct {
- Running bool `json:"running"`
- Score int `json:"score"`
- Lost int `json:"lost"`
- Status string `json:"status"`
- Age int `json:"age"`
- Turn int `json:"turn"`
- Ips []IpStatus `json:"track_ip"`
-}
-
-type InterfaceStatus struct {
- Interfaces map[string]WanInterfaceStatus `json:"interfaces"`
- Connected map[string][]string `json:"connected"`
-}
-
-// MWAN3 Policy
-type SdewanMember struct {
- Interface string `json:"interface"`
- Metric string `json:"metric"`
- Weight string `json:"weight"`
-}
-
-type SdewanPolicy struct {
- Name string `json:"name"`
- Members []SdewanMember `json:"members"`
-}
-
-type SdewanPolicies struct {
- Policies []SdewanPolicy `json:"policies"`
-}
-
-// MWAN3 Rule
-type SdewanRule struct {
- Name string `json:"name"`
- Policy string `json:"policy"`
- SrcIp string `json:"src_ip"`
- SrcPort string `json:"src_port"`
- DestIp string `json:"dest_ip"`
- DestPort string `json:"dest_port"`
- Proto string `json:"proto"`
- Family string `json:"family"`
- Sticky string `json:"sticky"`
- Timeout string `json:"timeout"`
-}
-
-type SdewanRules struct {
- Rules []SdewanRule `json:"rules"`
-}
-
-// get interface status
-func (m *Mwan3Client) GetInterfaceStatus() (*InterfaceStatus, error) {
- response, err := m.OpenwrtClient.Get("admin/status/mwan/interface_status")
- if err != nil {
- return nil, err
- }
-
- var interfaceStatus InterfaceStatus
- err2 := json.Unmarshal([]byte(response), &interfaceStatus)
- if err2 != nil {
- return nil, err2
- }
-
- return &interfaceStatus, nil
-}
-
-// Policy APIs
-// get policies
-func (m *Mwan3Client) GetPolicies() (*SdewanPolicies, error) {
- response, err := m.OpenwrtClient.Get(mwan3BaseURL + "policies")
- if err != nil {
- return nil, err
- }
-
- var sdewanPolicies SdewanPolicies
- err2 := json.Unmarshal([]byte(response), &sdewanPolicies)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanPolicies, nil
-}
-
-// get policy
-func (m *Mwan3Client) GetPolicy(policy_name string) (*SdewanPolicy, error) {
- response, err := m.OpenwrtClient.Get(mwan3BaseURL + "policies/" + policy_name)
- if err != nil {
- return nil, err
- }
-
- var sdewanPolicy SdewanPolicy
- err2 := json.Unmarshal([]byte(response), &sdewanPolicy)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanPolicy, nil
-}
-
-// create policy
-func (m *Mwan3Client) CreatePolicy(policy SdewanPolicy) (*SdewanPolicy, error) {
- policy_obj, _ := json.Marshal(policy)
- response, err := m.OpenwrtClient.Post(mwan3BaseURL+"policies", string(policy_obj))
- if err != nil {
- return nil, err
- }
-
- var sdewanPolicy SdewanPolicy
- err2 := json.Unmarshal([]byte(response), &sdewanPolicy)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanPolicy, nil
-}
-
-// delete policy
-func (m *Mwan3Client) DeletePolicy(policy_name string) error {
- _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "policies/" + policy_name)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// update policy
-func (m *Mwan3Client) UpdatePolicy(policy SdewanPolicy) (*SdewanPolicy, error) {
- policy_obj, _ := json.Marshal(policy)
- policy_name := policy.Name
- response, err := m.OpenwrtClient.Put(mwan3BaseURL+"policies/"+policy_name, string(policy_obj))
- if err != nil {
- return nil, err
- }
-
- var sdewanPolicy SdewanPolicy
- err2 := json.Unmarshal([]byte(response), &sdewanPolicy)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanPolicy, nil
-}
-
-// Rule APIs
-// get rules
-func (m *Mwan3Client) GetRules() (*SdewanRules, error) {
- response, err := m.OpenwrtClient.Get(mwan3BaseURL + "rules")
- if err != nil {
- return nil, err
- }
-
- var sdewanRules SdewanRules
- err2 := json.Unmarshal([]byte(response), &sdewanRules)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanRules, nil
-}
-
-// get rule
-func (m *Mwan3Client) GetRule(rule string) (*SdewanRule, error) {
- response, err := m.OpenwrtClient.Get(mwan3BaseURL + "rules/" + rule)
- if err != nil {
- return nil, err
- }
-
- var sdewanRule SdewanRule
- err2 := json.Unmarshal([]byte(response), &sdewanRule)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanRule, nil
-}
-
-// create rule
-func (m *Mwan3Client) CreateRule(rule SdewanRule) (*SdewanRule, error) {
- rule_obj, _ := json.Marshal(rule)
- response, err := m.OpenwrtClient.Post(mwan3BaseURL+"rules", string(rule_obj))
- if err != nil {
- return nil, err
- }
-
- var sdewanRule SdewanRule
- err2 := json.Unmarshal([]byte(response), &sdewanRule)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanRule, nil
-}
-
-// delete rule
-func (m *Mwan3Client) DeleteRule(rule_name string) error {
- _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "rules/" + rule_name)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// update rule
-func (m *Mwan3Client) UpdateRule(rule SdewanRule) (*SdewanRule, error) {
- rule_obj, _ := json.Marshal(rule)
- rule_name := rule.Name
- response, err := m.OpenwrtClient.Put(mwan3BaseURL+"rules/"+rule_name, string(rule_obj))
- if err != nil {
- return nil, err
- }
-
- var sdewanRule SdewanRule
- err2 := json.Unmarshal([]byte(response), &sdewanRule)
- if err2 != nil {
- return nil, err2
- }
-
- return &sdewanRule, nil
-}
+++ /dev/null
-package openwrt
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "net/http"
- "runtime"
- "strings"
-)
-
-type OpenwrtError struct {
- Code int
- Message string
-}
-
-func (e *OpenwrtError) Error() string {
- return fmt.Sprintf("Error Code: %d, Error Message: %s", e.Code, e.Message)
-}
-
-type openwrtClient struct {
- ip string
- user string
- password string
- token string
-}
-
-func CloseClient(o *openwrtClient) {
- o.logout()
- runtime.SetFinalizer(o, nil)
-}
-
-func NewOpenwrtClient(ip string, user string, password string) *openwrtClient {
- client := &openwrtClient{
- ip: ip,
- user: user,
- password: password,
- token: "",
- }
-
- runtime.SetFinalizer(client, CloseClient)
- return client
-}
-
-// openwrt base URL
-func (o *openwrtClient) getBaseURL() string {
- return "http://" + o.ip + "/cgi-bin/luci/"
-}
-
-// login to openwrt http server
-func (o *openwrtClient) login() error {
- client := &http.Client{
- // block redirect
- CheckRedirect: func(req *http.Request, via []*http.Request) error {
- return http.ErrUseLastResponse
- },
- }
-
- // login
- login_info := "luci_username=" + o.user + "&luci_password=" + o.password
- var req_body = []byte(login_info)
- req, _ := http.NewRequest("POST", o.getBaseURL(), bytes.NewBuffer(req_body))
- req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
-
- resp, err := client.Do(req)
- if resp != nil {
- defer resp.Body.Close()
- }
-
- if err != nil {
- return err
- } else if resp.StatusCode != 302 {
- // fail to auth
- return &OpenwrtError{Code: resp.StatusCode, Message: "Unauthorized"}
- } else {
- // get token
- res_cookie := resp.Header["Set-Cookie"][0]
- res_cookies := strings.Split(res_cookie, ";")
- for _, cookie := range res_cookies {
- cookie := strings.TrimSpace(cookie)
- index := strings.Index(cookie, "=")
- var key = cookie
- var value = ""
- if index != -1 {
- key = cookie[:index]
- value = cookie[index+1:]
- }
-
- if key == "sysauth" {
- o.token = value
- break
- }
- }
- }
-
- return nil
-}
-
-// logout to openwrt http server
-func (o *openwrtClient) logout() error {
- if o.token != "" {
- _, err:= o.Get("admin/logout")
- o.token = ""
- return err
- }
-
- return nil
-}
-
-// call openwrt restful API
-func (o *openwrtClient) call(method string, url string, request string) (string, error) {
- for i := 0; i < 2; i++ {
- if o.token == "" {
- err := o.login()
- if err != nil {
- return "", err
- }
- }
-
- client := &http.Client{}
- req_body := bytes.NewBuffer([]byte(request))
- req, _ := http.NewRequest(method, o.getBaseURL()+url, req_body)
- req.Header.Add("Cookie", "sysauth="+o.token)
- resp, err := client.Do(req)
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
-
- body, _ := ioutil.ReadAll(resp.Body)
- if resp.StatusCode >= 400 {
- if resp.StatusCode == 403 {
- // token expired, retry
- o.token = ""
- continue
- } else {
- // error request
- return "", &OpenwrtError{Code: resp.StatusCode, Message: string(body)}
- }
- }
-
- return string(body), nil
- }
-
- return "", nil
-}
-
-// call openwrt Get restful API
-func (o *openwrtClient) Get(url string) (string, error) {
- return o.call("GET", url, "")
-}
-
-// call openwrt restful API
-func (o *openwrtClient) Post(url string, request string) (string, error) {
- return o.call("POST", url, request)
-}
-
-// call openwrt restful API
-func (o *openwrtClient) Put(url string, request string) (string, error) {
- return o.call("PUT", url, request)
-}
-
-// call openwrt restful API
-func (o *openwrtClient) Delete(url string) (string, error) {
- return o.call("DELETE", url, "")
-}
+++ /dev/null
-package openwrt
-
-import (
- "encoding/json"
-)
-
-const (
- serviceBaseURL = "sdewan/v1/"
-)
-
-var available_Services = []string{"mwan3", "firewall", "ipsec"}
-
-type ServiceClient struct {
- OpenwrtClient *openwrtClient
-}
-
-// Service API struct
-type AvailableServices struct {
- Services []string `json:"services"`
-}
-
-// get available services
-func (s *ServiceClient) GetAvailableServices() (*AvailableServices, error) {
- response, err := s.OpenwrtClient.Get(serviceBaseURL + "services")
- if err != nil {
- return nil, err
- }
-
- var servs AvailableServices
- err2 := json.Unmarshal([]byte(response), &servs)
- if err2 != nil {
- return nil, err2
- }
-
- return &servs, nil
-}
-
-func (s *ServiceClient) formatExecuteServiceBody(operation string) string {
- return "{\"action\":\"" + operation + "\"}"
-}
-
-// execute operation on service
-func (s *ServiceClient) ExecuteService(service string, operation string) (bool, error) {
- if !IsContained(available_Services, service) {
- return false, &OpenwrtError{Code: 400, Message: "Bad Request: not supported service(" + service + ")"}
- }
-
- _, err := s.OpenwrtClient.Put(serviceBaseURL+"service/"+service, s.formatExecuteServiceBody(operation))
- if err != nil {
- return false, err
- }
-
- return true, nil
-}
+++ /dev/null
-package openwrt
-
-import (
- "reflect"
-)
-
-// util function to check whether items contains item
-func IsContained(items interface{}, item interface{}) bool {
- switch reflect.TypeOf(items).Kind() {
- case reflect.Slice:
- v := reflect.ValueOf(items)
- for i := 0; i < v.Len(); i++ {
- if reflect.DeepEqual(item, v.Index(i).Interface()) {
- return true
- }
- }
- default:
- return false
- }
-
- return false
-}
+++ /dev/null
-apiVersion: v1
-kind: Namespace
-metadata:
- labels:
- control-plane: controller-manager
- name: sdwan-system
----
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.2.5
- creationTimestamp: null
- name: mwan3confs.batch.sdewan.akraino.org
-spec:
- group: batch.sdewan.akraino.org
- names:
- kind: Mwan3Conf
- listKind: Mwan3ConfList
- plural: mwan3confs
- singular: mwan3conf
- scope: Namespaced
- subresources:
- status: {}
- validation:
- openAPIV3Schema:
- description: Mwan3Conf is the Schema for the mwan3confs API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation
- of an object. Servers should convert recognized schemas to the latest
- internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: Mwan3ConfSpec defines the desired state of Mwan3Conf
- properties:
- policy:
- additionalProperties:
- properties:
- members:
- items:
- properties:
- metric:
- type: integer
- network:
- type: string
- weight:
- type: integer
- required:
- - metric
- - network
- - weight
- type: object
- type: array
- required:
- - members
- type: object
- type: object
- rule:
- additionalProperties:
- properties:
- dest_ip:
- type: string
- dest_port:
- type: string
- family:
- type: string
- proto:
- type: string
- src_IP:
- type: string
- src_port:
- type: string
- sticky:
- type: string
- timeout:
- type: string
- use_policy:
- type: string
- required:
- - use_policy
- type: object
- type: object
- required:
- - policy
- - rule
- type: object
- status:
- description: Mwan3ConfStatus defines the observed state of Mwan3Conf
- type: object
- type: object
- version: v1alpha1
- versions:
- - name: v1alpha1
- served: true
- storage: true
-status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []
----
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.2.5
- creationTimestamp: null
- name: sdewans.batch.sdewan.akraino.org
-spec:
- group: batch.sdewan.akraino.org
- names:
- kind: Sdewan
- listKind: SdewanList
- plural: sdewans
- singular: sdewan
- scope: Namespaced
- subresources:
- status: {}
- validation:
- openAPIV3Schema:
- description: Sdewan is the Schema for the sdewans API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation
- of an object. Servers should convert recognized schemas to the latest
- internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: SdewanSpec defines the desired state of Sdewan
- properties:
- mwan3Conf:
- type: string
- networks:
- items:
- properties:
- defaultGateway:
- type: boolean
- interface:
- type: string
- isProvider:
- type: boolean
- name:
- type: string
- required:
- - name
- type: object
- type: array
- node:
- description: Foo is an example field of Sdewan. Edit Sdewan_types.go
- to remove/update
- type: string
- required:
- - networks
- - node
- type: object
- status:
- description: SdewanStatus defines the observed state of Sdewan
- properties:
- mwan3Status:
- description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
- of cluster Important: Run "make" to regenerate code after modifying
- this file'
- properties:
- appliedTime:
- format: date-time
- nullable: true
- type: string
- isApplied:
- type: boolean
- name:
- type: string
- required:
- - isApplied
- - name
- type: object
- type: object
- type: object
- version: v1alpha1
- versions:
- - name: v1alpha1
- served: true
- storage: true
-status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []
----
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: MutatingWebhookConfiguration
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: sdwan-system/sdwan-serving-cert
- creationTimestamp: null
- name: sdwan-mutating-webhook-configuration
-webhooks:
-- clientConfig:
- caBundle: Cg==
- service:
- name: sdwan-webhook-service
- namespace: sdwan-system
- path: /mutate-batch-sdewan-akraino-org-v1alpha1-mwan3conf
- failurePolicy: Fail
- name: mmwan3conf.kb.io
- rules:
- - apiGroups:
- - batch.sdewan.akraino.org
- apiVersions:
- - v1alpha1
- operations:
- - CREATE
- - UPDATE
- resources:
- - mwan3confs
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- name: sdwan-leader-election-role
- namespace: sdwan-system
-rules:
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - ""
- resources:
- - configmaps/status
- verbs:
- - get
- - update
- - patch
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- creationTimestamp: null
- name: sdwan-manager-role
-rules:
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - mwan3confs/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch.sdewan.akraino.org
- resources:
- - sdewans/status
- verbs:
- - get
- - patch
- - update
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: sdwan-proxy-role
-rules:
-- apiGroups:
- - authentication.k8s.io
- resources:
- - tokenreviews
- verbs:
- - create
-- apiGroups:
- - authorization.k8s.io
- resources:
- - subjectaccessreviews
- verbs:
- - create
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- name: sdwan-leader-election-rolebinding
- namespace: sdwan-system
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: sdwan-leader-election-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: sdwan-system
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: sdwan-manager-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: sdwan-manager-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: sdwan-system
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: sdwan-proxy-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: sdwan-proxy-role
-subjects:
-- kind: ServiceAccount
- name: default
- namespace: sdwan-system
----
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- control-plane: controller-manager
- name: sdwan-controller-manager-metrics-service
- namespace: sdwan-system
-spec:
- ports:
- - name: https
- port: 8443
- targetPort: https
- selector:
- control-plane: controller-manager
----
-apiVersion: v1
-kind: Service
-metadata:
- name: sdwan-webhook-service
- namespace: sdwan-system
-spec:
- ports:
- - port: 443
- targetPort: 9443
- selector:
- control-plane: controller-manager
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- labels:
- control-plane: controller-manager
- name: sdwan-controller-manager
- namespace: sdwan-system
-spec:
- replicas: 1
- selector:
- matchLabels:
- control-plane: controller-manager
- template:
- metadata:
- labels:
- control-plane: controller-manager
- spec:
- containers:
- - args:
- - --secure-listen-address=0.0.0.0:8443
- - --upstream=http://127.0.0.1:8080/
- - --logtostderr=true
- - --v=10
- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1
- name: kube-rbac-proxy
- ports:
- - containerPort: 8443
- name: https
- - args:
- - --metrics-addr=127.0.0.1:8080
- - --enable-leader-election
- command:
- - /manager
- env:
- - name: OPENWRT_IMAGE
- value: integratedcloudnative/openwrt:dev
- image: integratedcloudnative/sdewan-controller:dev
- imagePullPolicy: IfNotPresent
- name: manager
- ports:
- - containerPort: 9443
- name: webhook-server
- protocol: TCP
- resources:
- limits:
- cpu: 100m
- memory: 30Mi
- requests:
- cpu: 100m
- memory: 20Mi
- volumeMounts:
- - mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
- terminationGracePeriodSeconds: 10
- volumes:
- - name: cert
- secret:
- defaultMode: 420
- secretName: webhook-server-cert
----
-apiVersion: cert-manager.io/v1alpha2
-kind: Certificate
-metadata:
- name: sdwan-serving-cert
- namespace: sdwan-system
-spec:
- dnsNames:
- - sdwan-webhook-service.sdwan-system.svc
- - sdwan-webhook-service.sdwan-system.svc.cluster.local
- issuerRef:
- kind: Issuer
- name: sdwan-selfsigned-issuer
- secretName: webhook-server-cert
----
-apiVersion: cert-manager.io/v1alpha2
-kind: Issuer
-metadata:
- name: sdwan-selfsigned-issuer
- namespace: sdwan-system
-spec:
- selfSigned: {}
----
-apiVersion: admissionregistration.k8s.io/v1beta1
-kind: ValidatingWebhookConfiguration
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: sdwan-system/sdwan-serving-cert
- creationTimestamp: null
- name: sdwan-validating-webhook-configuration
-webhooks:
-- clientConfig:
- caBundle: Cg==
- service:
- name: sdwan-webhook-service
- namespace: sdwan-system
- path: /validate-batch-sdewan-akraino-org-v1alpha1-mwan3conf
- failurePolicy: Fail
- name: vmwan3conf.kb.io
- rules:
- - apiGroups:
- - batch.sdewan.akraino.org
- apiVersions:
- - v1alpha1
- operations:
- - CREATE
- - UPDATE
- resources:
- - mwan3confs
+++ /dev/null
-package wrtprovider
-
-import (
- "fmt"
- "reflect"
- sdewanv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
- "sdewan.akraino.org/sdewan/openwrt"
- logf "sigs.k8s.io/controller-runtime/pkg/log"
-)
-
-var log = logf.Log.WithName("controller_sdewan")
-
-func NetworkInterfaceMap(instance *sdewanv1alpha1.Sdewan) map[string]string {
- ifMap := make(map[string]string)
- for i, network := range instance.Spec.Networks {
- prefix := "lan_"
- if network.IsProvider {
- prefix = "wan_"
- }
- if network.Interface == "" {
- network.Interface = fmt.Sprintf("net%d", i)
- }
- ifMap[network.Name] = prefix + fmt.Sprintf("net%d", i)
- }
- return ifMap
-}
-
-func Mwan3ReplacePolicies(policies []openwrt.SdewanPolicy, existOnes []openwrt.SdewanPolicy, client *openwrt.Mwan3Client) error {
- // create/update new policies
- for _, policy := range policies {
- found := false
- for _, p := range existOnes {
- if p.Name == policy.Name {
- if !reflect.DeepEqual(policy, p) {
- _, err := client.UpdatePolicy(policy)
- if err != nil {
- return err
- }
- }
- found = true
- break
- }
- }
- if found == false {
- _, err := client.CreatePolicy(policy)
- if err != nil {
- return err
- }
- }
- }
-
- // remove old policies
- for _, p := range existOnes {
- found := false
- for _, policy := range policies {
- if p.Name == policy.Name {
- found = true
- break
- }
- }
- if found == false {
- err := client.DeletePolicy(p.Name)
- if err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-func Mwan3ReplaceRules(rules []openwrt.SdewanRule, existOnes []openwrt.SdewanRule, client *openwrt.Mwan3Client) error {
- // create/update new rules
- for _, rule := range rules {
- found := false
- for _, r := range existOnes {
- if r.Name == rule.Name {
- if !reflect.DeepEqual(rule, r) {
- _, err := client.UpdateRule(rule)
- if err != nil {
- return err
- }
- }
- found = true
- break
- }
- }
- if found == false {
- _, err := client.CreateRule(rule)
- if err != nil {
- return err
- }
- }
- }
-
- // remove old rules
- for _, r := range existOnes {
- found := false
- for _, rule := range rules {
- if r.Name == rule.Name {
- found = true
- break
- }
- }
- if found == false {
- err := client.DeleteRule(r.Name)
- if err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-// apply policy and rules
-func Mwan3Apply(mwan3Conf *sdewanv1alpha1.Mwan3Conf, sdewan *sdewanv1alpha1.Sdewan) error {
- reqLogger := log.WithValues("Mwan3Provider", mwan3Conf.Name, "Sdewan", sdewan.Name)
- openwrtClient := openwrt.NewOpenwrtClient(sdewan.Name + "." + sdewan.Namespace, "root", "")
- mwan3 := openwrt.Mwan3Client{OpenwrtClient: openwrtClient}
- service := openwrt.ServiceClient{OpenwrtClient: openwrtClient}
- netMap := NetworkInterfaceMap(sdewan)
- var policies []openwrt.SdewanPolicy
- for policyName, members := range mwan3Conf.Spec.Policies {
- openwrtMembers := make([]openwrt.SdewanMember, len(members.Members))
- for i, member := range members.Members {
- openwrtMembers[i] = openwrt.SdewanMember{
- Interface: netMap[member.Network],
- Metric: fmt.Sprintf("%d", member.Metric),
- Weight: fmt.Sprintf("%d", member.Weight),
- }
- }
- policies = append(policies, openwrt.SdewanPolicy{
- Name: policyName,
- Members: openwrtMembers})
- }
- existPolicies, err := mwan3.GetPolicies()
- if err != nil {
- reqLogger.Error(err, "Failed to fetch existing policies")
- return err
- }
- err = Mwan3ReplacePolicies(policies, existPolicies.Policies, &mwan3)
- if err != nil {
- reqLogger.Error(err, "Failed to apply Policies")
- return err
- }
- var rules []openwrt.SdewanRule
- for ruleName, rule := range mwan3Conf.Spec.Rules {
- openwrtRule := openwrt.SdewanRule{
- Name: ruleName,
- Policy: rule.UsePolicy,
- SrcIp: rule.SrcIP,
- SrcPort: rule.SrcPort,
- DestIp: rule.DestIP,
- DestPort: rule.DestPort,
- Proto: rule.Proto,
- Family: rule.Family,
- Sticky: rule.Sticky,
- Timeout: rule.Timeout,
- }
- rules = append(rules, openwrtRule)
- }
- existRules, err := mwan3.GetRules()
- if err != nil {
- reqLogger.Error(err, "Failed to fetch existing rules")
- return err
- }
- err = Mwan3ReplaceRules(rules, existRules.Rules, &mwan3)
- if err != nil {
- reqLogger.Error(err, "Failed to apply rules")
- return err
- }
- _, err = service.ExecuteService("mwan3", "restart")
- if err != nil {
- reqLogger.Error(err, "Failed to restart mwan3 service")
- return err
- }
- return nil
-}