--- /dev/null
+kubectl delete -f monitor/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml\r
+kubectl delete -f monitor/role.yaml\r
+kubectl delete -f monitor/cluster_role.yaml\r
+kubectl delete -f monitor/role_binding.yaml\r
+kubectl delete -f monitor/clusterrole_binding.yaml\r
+kubectl delete -f monitor/service_account.yaml\r
+kubectl delete -f monitor/operator.yaml\r
-package main\r
-\r
-import (\r
- "context"\r
- "flag"\r
- "fmt"\r
- "os"\r
- "runtime"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis"\r
- "github.com/open-ness/EMCO/src/monitor/pkg/controller"\r
- "github.com/operator-framework/operator-sdk/pkg/k8sutil"\r
- "github.com/operator-framework/operator-sdk/pkg/leader"\r
- sdkVersion "github.com/operator-framework/operator-sdk/version"\r
- "github.com/spf13/pflag"\r
- "sigs.k8s.io/controller-runtime/pkg/client/config"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"\r
- "sigs.k8s.io/controller-runtime/pkg/runtime/signals"\r
-)\r
-\r
-// Change below variables to serve metrics on different host or port.\r
-var (\r
- metricsHost = "0.0.0.0"\r
- metricsPort int32 = 8383\r
- operatorMetricsPort int32 = 8686\r
-)\r
-var log = logf.Log.WithName("cmd")\r
-\r
-func printVersion() {\r
- log.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))\r
- log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH))\r
- log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version))\r
-}\r
-\r
-func main() {\r
- // Add the zap logger flag set to the CLI. The flag set must\r
- // be added before calling pflag.Parse().\r
- //pflag.CommandLine.AddFlagSet(zap.FlagSet())\r
-\r
- // Add flags registered by imported packages (e.g. glog and\r
- // controller-runtime)\r
- pflag.CommandLine.AddGoFlagSet(flag.CommandLine)\r
-\r
- pflag.Parse()\r
-\r
- // Use a zap logr.Logger implementation. If none of the zap\r
- // flags are configured (or if the zap flag set is not being\r
- // used), this defaults to a production zap logger.\r
- //\r
- // The logger instantiated here can be changed to any logger\r
- // implementing the logr.Logger interface. This logger will\r
- // be propagated through the whole operator, generating\r
- // uniform and structured logs.\r
- //logf.SetLogger(zap.Logger())\r
-\r
- printVersion()\r
-\r
- namespace, err := k8sutil.GetWatchNamespace()\r
- if err != nil {\r
- log.Error(err, "Failed to get watch namespace")\r
- os.Exit(1)\r
- }\r
-\r
- // Get a config to talk to the apiserver\r
- cfg, err := config.GetConfig()\r
- if err != nil {\r
- log.Error(err, "")\r
- os.Exit(1)\r
- }\r
-\r
- ctx := context.TODO()\r
- // Become the leader before proceeding\r
- err = leader.Become(ctx, "monitor-lock")\r
- if err != nil {\r
- log.Error(err, "")\r
- os.Exit(1)\r
- }\r
-\r
- // Create a new Cmd to provide shared dependencies and start components\r
- mgr, err := manager.New(cfg, manager.Options{\r
- Namespace: namespace,\r
- MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),\r
- })\r
- if err != nil {\r
- log.Error(err, "")\r
- os.Exit(1)\r
- }\r
-\r
- log.Info("Registering Components.")\r
-\r
- // Setup Scheme for all resources\r
- if err := apis.AddToScheme(mgr.GetScheme()); err != nil {\r
- log.Error(err, "")\r
- os.Exit(1)\r
- }\r
-\r
- // Setup all Controllers\r
- if err := controller.AddToManager(mgr); err != nil {\r
- log.Error(err, "")\r
- os.Exit(1)\r
- }\r
- log.Info("Starting the Cmd.")\r
-\r
- // Start the Cmd\r
- if err := mgr.Start(signals.SetupSignalHandler()); err != nil {\r
- log.Error(err, "Manager exited non-zero")\r
- os.Exit(1)\r
- }\r
-}\r
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "os"
+ "runtime"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis"
+ "github.com/open-ness/EMCO/src/monitor/pkg/controller"
+ "github.com/operator-framework/operator-sdk/pkg/k8sutil"
+ "github.com/operator-framework/operator-sdk/pkg/leader"
+ sdkVersion "github.com/operator-framework/operator-sdk/version"
+ "github.com/spf13/pflag"
+ "sigs.k8s.io/controller-runtime/pkg/client/config"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+ "sigs.k8s.io/controller-runtime/pkg/runtime/signals"
+)
+
+// Change below variables to serve metrics on different host or port.
+var (
+ metricsHost = "0.0.0.0"
+ metricsPort int32 = 8383
+ operatorMetricsPort int32 = 8686
+)
+var log = logf.Log.WithName("cmd")
+
+func printVersion() {
+ log.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))
+ log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH))
+ log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version))
+}
+
+func main() {
+ // Add the zap logger flag set to the CLI. The flag set must
+ // be added before calling pflag.Parse().
+ //pflag.CommandLine.AddFlagSet(zap.FlagSet())
+
+ // Add flags registered by imported packages (e.g. glog and
+ // controller-runtime)
+ pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
+
+ pflag.Parse()
+
+ // Use a zap logr.Logger implementation. If none of the zap
+ // flags are configured (or if the zap flag set is not being
+ // used), this defaults to a production zap logger.
+ //
+ // The logger instantiated here can be changed to any logger
+ // implementing the logr.Logger interface. This logger will
+ // be propagated through the whole operator, generating
+ // uniform and structured logs.
+ //logf.SetLogger(zap.Logger())
+
+ printVersion()
+
+ namespace, err := k8sutil.GetWatchNamespace()
+ if err != nil {
+ log.Error(err, "Failed to get watch namespace")
+ os.Exit(1)
+ }
+
+ // Get a config to talk to the apiserver
+ cfg, err := config.GetConfig()
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ ctx := context.TODO()
+ // Become the leader before proceeding
+ err = leader.Become(ctx, "monitor-lock")
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ // Create a new Cmd to provide shared dependencies and start components
+ mgr, err := manager.New(cfg, manager.Options{
+ Namespace: namespace,
+ MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
+ })
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ log.Info("Registering Components.")
+
+ // Setup Scheme for all resources
+ if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ // Setup all Controllers
+ if err := controller.AddToManager(mgr); err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+ log.Info("Starting the Cmd.")
+
+ // Start the Cmd
+ if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
+ log.Error(err, "Manager exited non-zero")
+ os.Exit(1)
+ }
+}
-package apis\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-)\r
-\r
-func init() {\r
- // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back\r
- AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme)\r
-}\r
+package apis
+
+import (
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+)
+
+func init() {
+ // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
+ AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme)
+}
-package apis\r
-\r
-import (\r
- "k8s.io/apimachinery/pkg/runtime"\r
-)\r
-\r
-// AddToSchemes may be used to add all resources defined in the project to a Scheme\r
-var AddToSchemes runtime.SchemeBuilder\r
-\r
-// AddToScheme adds all Resources to the Scheme\r
-func AddToScheme(s *runtime.Scheme) error {\r
- return AddToSchemes.AddToScheme(s)\r
-}\r
+package apis
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+// AddToSchemes may be used to add all resources defined in the project to a Scheme
+var AddToSchemes runtime.SchemeBuilder
+
+// AddToScheme adds all Resources to the Scheme
+func AddToScheme(s *runtime.Scheme) error {
+ return AddToSchemes.AddToScheme(s)
+}
-// Package k8splugin contains k8splugin API versions.\r
-//\r
-// This file ensures Go source parsers acknowledge the k8splugin package\r
-// and any child packages. It can be removed if any other Go source files are\r
-// added to this package.\r
-package k8splugin\r
+// Package k8splugin contains k8splugin API versions.
+//
+// This file ensures Go source parsers acknowledge the k8splugin package
+// and any child packages. It can be removed if any other Go source files are
+// added to this package.
+package k8splugin
-// Package v1alpha1 contains API Schema definitions for the k8splugin v1alpha1 API group\r
-// +k8s:deepcopy-gen=package,register\r
-// +groupName=k8splugin.io\r
-package v1alpha1\r
+// Package v1alpha1 contains API Schema definitions for the k8splugin v1alpha1 API group
+// +k8s:deepcopy-gen=package,register
+// +groupName=k8splugin.io
+package v1alpha1
-// NOTE: Boilerplate only. Ignore this file.\r
-\r
-// Package v1alpha1 contains API Schema definitions for the k8splugin v1alpha1 API group\r
-// +k8s:deepcopy-gen=package,register\r
-// +groupName=k8splugin.io\r
-package v1alpha1\r
-\r
-import (\r
- "k8s.io/apimachinery/pkg/runtime/schema"\r
- "sigs.k8s.io/controller-runtime/pkg/runtime/scheme"\r
-)\r
-\r
-var (\r
- // SchemeGroupVersion is group version used to register these objects\r
- SchemeGroupVersion = schema.GroupVersion{Group: "k8splugin.io", Version: "v1alpha1"}\r
-\r
- // SchemeBuilder is used to add go types to the GroupVersionKind scheme\r
- SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}\r
-\r
- // AddToScheme is a global function variable that registers this API\r
- AddToScheme = SchemeBuilder.AddToScheme\r
-)\r
-\r
-// Kind takes an unqualified kind and returns back a Group qualified GroupKind\r
-func Kind(kind string) schema.GroupKind {\r
- return SchemeGroupVersion.WithKind(kind).GroupKind()\r
-}\r
-\r
-// Resource takes an unqualified resource and returns a Group qualified GroupResource\r
-func Resource(resource string) schema.GroupResource {\r
- return SchemeGroupVersion.WithResource(resource).GroupResource()\r
-}\r
+// NOTE: Boilerplate only. Ignore this file.
+
+// Package v1alpha1 contains API Schema definitions for the k8splugin v1alpha1 API group
+// +k8s:deepcopy-gen=package,register
+// +groupName=k8splugin.io
+package v1alpha1
+
+import (
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
+)
+
+var (
+ // SchemeGroupVersion is group version used to register these objects
+ SchemeGroupVersion = schema.GroupVersion{Group: "k8splugin.io", Version: "v1alpha1"}
+
+ // SchemeBuilder is used to add go types to the GroupVersionKind scheme
+ SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
+
+ // AddToScheme is a global function variable that registers this API
+ AddToScheme = SchemeBuilder.AddToScheme
+)
+
+// Kind takes an unqualified kind and returns back a Group qualified GroupKind
+func Kind(kind string) schema.GroupKind {
+ return SchemeGroupVersion.WithKind(kind).GroupKind()
+}
+
+// Resource takes an unqualified resource and returns a Group qualified GroupResource
+func Resource(resource string) schema.GroupResource {
+ return SchemeGroupVersion.WithResource(resource).GroupResource()
+}
-package v1alpha1\r
-\r
-import (\r
- appsv1 "k8s.io/api/apps/v1"\r
- v1 "k8s.io/api/batch/v1"\r
- certsapi "k8s.io/api/certificates/v1beta1"\r
- corev1 "k8s.io/api/core/v1"\r
- v1beta1 "k8s.io/api/extensions/v1beta1"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
-)\r
-\r
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\r
-\r
-// ResourceBundleState is the Schema for the ResourceBundleStatees API\r
-// +k8s:openapi-gen=true\r
-// +kubebuilder:subresource:status\r
-// +genclient\r
-type ResourceBundleState struct {\r
- metav1.TypeMeta `json:",inline" yaml:",inline"`\r
- metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata" yaml:"metadata"`\r
-\r
- Spec ResourceBundleStateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`\r
- Status ResourceBundleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`\r
-}\r
-\r
-// ResourceBundleStateSpec defines the desired state of ResourceBundleState\r
-// +k8s:openapi-gen=true\r
-type ResourceBundleStateSpec struct {\r
- Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,1,opt,name=selector"`\r
-}\r
-\r
-// ResourceBundleStatus defines the observed state of ResourceBundleState\r
-// +k8s:openapi-gen=true\r
-type ResourceBundleStatus struct {\r
- Ready bool `json:"ready" protobuf:"varint,1,opt,name=ready"`\r
- ResourceCount int32 `json:"resourceCount" protobuf:"varint,2,opt,name=resourceCount"`\r
- PodStatuses []corev1.Pod `json:"podStatuses" protobuf:"varint,3,opt,name=podStatuses"`\r
- ServiceStatuses []corev1.Service `json:"serviceStatuses" protobuf:"varint,4,opt,name=serviceStatuses"`\r
- ConfigMapStatuses []corev1.ConfigMap `json:"configMapStatuses" protobuf:"varint,5,opt,name=configMapStatuses"`\r
- DeploymentStatuses []appsv1.Deployment `json:"deploymentStatuses" protobuf:"varint,6,opt,name=deploymentStatuses"`\r
- SecretStatuses []corev1.Secret `json:"secretStatuses" protobuf:"varint,7,opt,name=secretStatuses"`\r
- DaemonSetStatuses []appsv1.DaemonSet `json:"daemonSetStatuses" protobuf:"varint,8,opt,name=daemonSetStatuses"`\r
- IngressStatuses []v1beta1.Ingress `json:"ingressStatuses" protobuf:"varint,11,opt,name=ingressStatuses"`\r
- JobStatuses []v1.Job `json:"jobStatuses" protobuf:"varint,12,opt,name=jobStatuses"`\r
- StatefulSetStatuses []appsv1.StatefulSet `json:"statefulSetStatuses" protobuf:"varint,13,opt,name=statefulSetStatuses"`\r
- CsrStatuses []certsapi.CertificateSigningRequest `json:"csrStatuses" protobuf:"varint,3,opt,name=csrStatuses"`\r
-}\r
-\r
-// PodStatus defines the observed state of ResourceBundleState\r
-// +k8s:openapi-gen=true\r
-type PodStatus struct {\r
- metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`\r
- Ready bool `json:"ready" protobuf:"varint,2,opt,name=ready"`\r
- Status corev1.PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`\r
-}\r
-\r
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\r
-\r
-// ResourceBundleStateList contains a list of ResourceBundleState\r
-type ResourceBundleStateList struct {\r
- metav1.TypeMeta `json:",inline"`\r
- metav1.ListMeta `json:"metadata,omitempty"`\r
- Items []ResourceBundleState `json:"items"`\r
-}\r
-\r
-func init() {\r
- SchemeBuilder.Register(&ResourceBundleState{}, &ResourceBundleStateList{})\r
-}\r
+package v1alpha1
+
+import (
+ appsv1 "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/batch/v1"
+ certsapi "k8s.io/api/certificates/v1beta1"
+ corev1 "k8s.io/api/core/v1"
+ v1beta1 "k8s.io/api/extensions/v1beta1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ResourceBundleState is the Schema for the ResourceBundleStatees API
+// +k8s:openapi-gen=true
+// +kubebuilder:subresource:status
+// +genclient
+type ResourceBundleState struct {
+ metav1.TypeMeta `json:",inline" yaml:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata" yaml:"metadata"`
+
+ Spec ResourceBundleStateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
+ Status ResourceBundleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
+}
+
+// ResourceBundleStateSpec defines the desired state of ResourceBundleState
+// +k8s:openapi-gen=true
+type ResourceBundleStateSpec struct {
+ Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,1,opt,name=selector"`
+}
+
+// ResourceBundleStatus defines the observed state of ResourceBundleState
+// +k8s:openapi-gen=true
+type ResourceBundleStatus struct {
+ Ready bool `json:"ready" protobuf:"varint,1,opt,name=ready"`
+ ResourceCount int32 `json:"resourceCount" protobuf:"varint,2,opt,name=resourceCount"`
+ PodStatuses []corev1.Pod `json:"podStatuses" protobuf:"varint,3,opt,name=podStatuses"`
+ ServiceStatuses []corev1.Service `json:"serviceStatuses" protobuf:"varint,4,opt,name=serviceStatuses"`
+ ConfigMapStatuses []corev1.ConfigMap `json:"configMapStatuses" protobuf:"varint,5,opt,name=configMapStatuses"`
+ DeploymentStatuses []appsv1.Deployment `json:"deploymentStatuses" protobuf:"varint,6,opt,name=deploymentStatuses"`
+ SecretStatuses []corev1.Secret `json:"secretStatuses" protobuf:"varint,7,opt,name=secretStatuses"`
+ DaemonSetStatuses []appsv1.DaemonSet `json:"daemonSetStatuses" protobuf:"varint,8,opt,name=daemonSetStatuses"`
+ IngressStatuses []v1beta1.Ingress `json:"ingressStatuses" protobuf:"varint,11,opt,name=ingressStatuses"`
+ JobStatuses []v1.Job `json:"jobStatuses" protobuf:"varint,12,opt,name=jobStatuses"`
+ StatefulSetStatuses []appsv1.StatefulSet `json:"statefulSetStatuses" protobuf:"varint,13,opt,name=statefulSetStatuses"`
+ CsrStatuses []certsapi.CertificateSigningRequest `json:"csrStatuses" protobuf:"varint,3,opt,name=csrStatuses"`
+}
+
+// PodStatus defines the observed state of ResourceBundleState
+// +k8s:openapi-gen=true
+type PodStatus struct {
+ metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+ Ready bool `json:"ready" protobuf:"varint,2,opt,name=ready"`
+ Status corev1.PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ResourceBundleStateList contains a list of ResourceBundleState
+type ResourceBundleStateList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []ResourceBundleState `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&ResourceBundleState{}, &ResourceBundleStateList{})
+}
-// +build !ignore_autogenerated\r
-\r
-// Code generated by operator-sdk. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- appsv1 "k8s.io/api/apps/v1"\r
- batchv1 "k8s.io/api/batch/v1"\r
- corev1 "k8s.io/api/core/v1"\r
- v1beta1 "k8s.io/api/extensions/v1beta1"\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
-)\r
-\r
-/*\r
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\r
-func (in *PodStatus) DeepCopyInto(out *PodStatus) {\r
- *out = *in\r
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)\r
- in.Status.DeepCopyInto(&out.Status)\r
- return\r
-}\r
-\r
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodStatus.\r
-func (in *PodStatus) DeepCopy() *PodStatus {\r
- if in == nil {\r
- return nil\r
- }\r
- out := new(PodStatus)\r
- in.DeepCopyInto(out)\r
- return out\r
-}\r
-*/\r
-\r
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\r
-func (in *ResourceBundleState) DeepCopyInto(out *ResourceBundleState) {\r
- *out = *in\r
- out.TypeMeta = in.TypeMeta\r
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)\r
- in.Spec.DeepCopyInto(&out.Spec)\r
- in.Status.DeepCopyInto(&out.Status)\r
- return\r
-}\r
-\r
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleState.\r
-func (in *ResourceBundleState) DeepCopy() *ResourceBundleState {\r
- if in == nil {\r
- return nil\r
- }\r
- out := new(ResourceBundleState)\r
- in.DeepCopyInto(out)\r
- return out\r
-}\r
-\r
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\r
-func (in *ResourceBundleState) DeepCopyObject() runtime.Object {\r
- if c := in.DeepCopy(); c != nil {\r
- return c\r
- }\r
- return nil\r
-}\r
-\r
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\r
-func (in *ResourceBundleStateList) DeepCopyInto(out *ResourceBundleStateList) {\r
- *out = *in\r
- out.TypeMeta = in.TypeMeta\r
- out.ListMeta = in.ListMeta\r
- if in.Items != nil {\r
- in, out := &in.Items, &out.Items\r
- *out = make([]ResourceBundleState, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- return\r
-}\r
-\r
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStateList.\r
-func (in *ResourceBundleStateList) DeepCopy() *ResourceBundleStateList {\r
- if in == nil {\r
- return nil\r
- }\r
- out := new(ResourceBundleStateList)\r
- in.DeepCopyInto(out)\r
- return out\r
-}\r
-\r
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\r
-func (in *ResourceBundleStateList) DeepCopyObject() runtime.Object {\r
- if c := in.DeepCopy(); c != nil {\r
- return c\r
- }\r
- return nil\r
-}\r
-\r
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\r
-func (in *ResourceBundleStateSpec) DeepCopyInto(out *ResourceBundleStateSpec) {\r
- *out = *in\r
- if in.Selector != nil {\r
- in, out := &in.Selector, &out.Selector\r
- *out = new(v1.LabelSelector)\r
- (*in).DeepCopyInto(*out)\r
- }\r
- return\r
-}\r
-\r
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStateSpec.\r
-func (in *ResourceBundleStateSpec) DeepCopy() *ResourceBundleStateSpec {\r
- if in == nil {\r
- return nil\r
- }\r
- out := new(ResourceBundleStateSpec)\r
- in.DeepCopyInto(out)\r
- return out\r
-}\r
-\r
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\r
-func (in *ResourceBundleStatus) DeepCopyInto(out *ResourceBundleStatus) {\r
- *out = *in\r
- if in.PodStatuses != nil {\r
- in, out := &in.PodStatuses, &out.PodStatuses\r
- *out = make([]corev1.Pod, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.ServiceStatuses != nil {\r
- in, out := &in.ServiceStatuses, &out.ServiceStatuses\r
- *out = make([]corev1.Service, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.ConfigMapStatuses != nil {\r
- in, out := &in.ConfigMapStatuses, &out.ConfigMapStatuses\r
- *out = make([]corev1.ConfigMap, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.DeploymentStatuses != nil {\r
- in, out := &in.DeploymentStatuses, &out.DeploymentStatuses\r
- *out = make([]appsv1.Deployment, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.SecretStatuses != nil {\r
- in, out := &in.SecretStatuses, &out.SecretStatuses\r
- *out = make([]corev1.Secret, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.DaemonSetStatuses != nil {\r
- in, out := &in.DaemonSetStatuses, &out.DaemonSetStatuses\r
- *out = make([]appsv1.DaemonSet, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.IngressStatuses != nil {\r
- in, out := &in.IngressStatuses, &out.IngressStatuses\r
- *out = make([]v1beta1.Ingress, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.JobStatuses != nil {\r
- in, out := &in.JobStatuses, &out.JobStatuses\r
- *out = make([]batchv1.Job, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- if in.StatefulSetStatuses != nil {\r
- in, out := &in.StatefulSetStatuses, &out.StatefulSetStatuses\r
- *out = make([]appsv1.StatefulSet, len(*in))\r
- for i := range *in {\r
- (*in)[i].DeepCopyInto(&(*out)[i])\r
- }\r
- }\r
- return\r
-}\r
-\r
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStatus.\r
-func (in *ResourceBundleStatus) DeepCopy() *ResourceBundleStatus {\r
- if in == nil {\r
- return nil\r
- }\r
- out := new(ResourceBundleStatus)\r
- in.DeepCopyInto(out)\r
- return out\r
-}\r
+// +build !ignore_autogenerated
+
+// Code generated by operator-sdk. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ appsv1 "k8s.io/api/apps/v1"
+ batchv1 "k8s.io/api/batch/v1"
+ corev1 "k8s.io/api/core/v1"
+ v1beta1 "k8s.io/api/extensions/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+/*
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PodStatus) DeepCopyInto(out *PodStatus) {
+ *out = *in
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Status.DeepCopyInto(&out.Status)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodStatus.
+func (in *PodStatus) DeepCopy() *PodStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(PodStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+*/
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ResourceBundleState) DeepCopyInto(out *ResourceBundleState) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleState.
+func (in *ResourceBundleState) DeepCopy() *ResourceBundleState {
+ if in == nil {
+ return nil
+ }
+ out := new(ResourceBundleState)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ResourceBundleState) 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 *ResourceBundleStateList) DeepCopyInto(out *ResourceBundleStateList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ out.ListMeta = in.ListMeta
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]ResourceBundleState, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStateList.
+func (in *ResourceBundleStateList) DeepCopy() *ResourceBundleStateList {
+ if in == nil {
+ return nil
+ }
+ out := new(ResourceBundleStateList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ResourceBundleStateList) 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 *ResourceBundleStateSpec) DeepCopyInto(out *ResourceBundleStateSpec) {
+ *out = *in
+ if in.Selector != nil {
+ in, out := &in.Selector, &out.Selector
+ *out = new(v1.LabelSelector)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStateSpec.
+func (in *ResourceBundleStateSpec) DeepCopy() *ResourceBundleStateSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(ResourceBundleStateSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ResourceBundleStatus) DeepCopyInto(out *ResourceBundleStatus) {
+ *out = *in
+ if in.PodStatuses != nil {
+ in, out := &in.PodStatuses, &out.PodStatuses
+ *out = make([]corev1.Pod, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.ServiceStatuses != nil {
+ in, out := &in.ServiceStatuses, &out.ServiceStatuses
+ *out = make([]corev1.Service, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.ConfigMapStatuses != nil {
+ in, out := &in.ConfigMapStatuses, &out.ConfigMapStatuses
+ *out = make([]corev1.ConfigMap, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.DeploymentStatuses != nil {
+ in, out := &in.DeploymentStatuses, &out.DeploymentStatuses
+ *out = make([]appsv1.Deployment, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.SecretStatuses != nil {
+ in, out := &in.SecretStatuses, &out.SecretStatuses
+ *out = make([]corev1.Secret, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.DaemonSetStatuses != nil {
+ in, out := &in.DaemonSetStatuses, &out.DaemonSetStatuses
+ *out = make([]appsv1.DaemonSet, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.IngressStatuses != nil {
+ in, out := &in.IngressStatuses, &out.IngressStatuses
+ *out = make([]v1beta1.Ingress, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.JobStatuses != nil {
+ in, out := &in.JobStatuses, &out.JobStatuses
+ *out = make([]batchv1.Job, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.StatefulSetStatuses != nil {
+ in, out := &in.StatefulSetStatuses, &out.StatefulSetStatuses
+ *out = make([]appsv1.StatefulSet, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBundleStatus.
+func (in *ResourceBundleStatus) DeepCopy() *ResourceBundleStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(ResourceBundleStatus)
+ in.DeepCopyInto(out)
+ return out
+}
-// +build !ignore_autogenerated\r
-\r
-// This file was autogenerated by openapi-gen. Do not edit it manually!\r
-\r
-package v1alpha1\r
-\r
-import (\r
- spec "github.com/go-openapi/spec"\r
- common "k8s.io/kube-openapi/pkg/common"\r
-)\r
-\r
-func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {\r
- return map[string]common.OpenAPIDefinition{\r
- "./pkg/apis/k8splugin/v1alpha1.PodStatus": schema_pkg_apis_k8splugin_v1alpha1_PodStatus(ref),\r
- "./pkg/apis/k8splugin/v1alpha1.ResourceBundleState": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleState(ref),\r
- "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStateSpec(ref),\r
- "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStatus(ref),\r
- }\r
-}\r
-\r
-func schema_pkg_apis_k8splugin_v1alpha1_PodStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {\r
- return common.OpenAPIDefinition{\r
- Schema: spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Description: "PodStatus defines the observed state of ResourceBundleState",\r
- Type: []string{"object"},\r
- Properties: map[string]spec.Schema{\r
- "metadata": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),\r
- },\r
- },\r
- "ready": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"boolean"},\r
- Format: "",\r
- },\r
- },\r
- "status": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/api/core/v1.PodStatus"),\r
- },\r
- },\r
- },\r
- Required: []string{"ready"},\r
- },\r
- },\r
- Dependencies: []string{\r
- "k8s.io/api/core/v1.PodStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},\r
- }\r
-}\r
-\r
-func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleState(ref common.ReferenceCallback) common.OpenAPIDefinition {\r
- return common.OpenAPIDefinition{\r
- Schema: spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Description: "ResourceBundleState is the Schema for the ResourceBundleStatees API",\r
- Type: []string{"object"},\r
- Properties: map[string]spec.Schema{\r
- "kind": {\r
- SchemaProps: spec.SchemaProps{\r
- 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/api-conventions.md#types-kinds",\r
- Type: []string{"string"},\r
- Format: "",\r
- },\r
- },\r
- "apiVersion": {\r
- SchemaProps: spec.SchemaProps{\r
- 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/api-conventions.md#resources",\r
- Type: []string{"string"},\r
- Format: "",\r
- },\r
- },\r
- "metadata": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),\r
- },\r
- },\r
- "spec": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec"),\r
- },\r
- },\r
- "status": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus"),\r
- },\r
- },\r
- },\r
- },\r
- },\r
- Dependencies: []string{\r
- "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec", "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},\r
- }\r
-}\r
-\r
-func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStateSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {\r
- return common.OpenAPIDefinition{\r
- Schema: spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Description: "ResourceBundleStateSpec defines the desired state of ResourceBundleState",\r
- Type: []string{"object"},\r
- Properties: map[string]spec.Schema{\r
- "selector": {\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"),\r
- },\r
- },\r
- },\r
- Required: []string{"selector"},\r
- },\r
- },\r
- Dependencies: []string{\r
- "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"},\r
- }\r
-}\r
-\r
-func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {\r
- return common.OpenAPIDefinition{\r
- Schema: spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Description: "ResourceBundleStatus defines the observed state of ResourceBundleState",\r
- Type: []string{"object"},\r
- Properties: map[string]spec.Schema{\r
- "ready": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"boolean"},\r
- Format: "",\r
- },\r
- },\r
- "resourceCount": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"integer"},\r
- Format: "int32",\r
- },\r
- },\r
- "podStatuses": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"array"},\r
- Items: &spec.SchemaOrArray{\r
- Schema: &spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("./pkg/apis/k8splugin/v1alpha1.PodStatus"),\r
- },\r
- },\r
- },\r
- },\r
- },\r
- "serviceStatuses": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"array"},\r
- Items: &spec.SchemaOrArray{\r
- Schema: &spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/api/core/v1.Service"),\r
- },\r
- },\r
- },\r
- },\r
- },\r
- "configMapStatuses": {\r
- SchemaProps: spec.SchemaProps{\r
- Type: []string{"array"},\r
- Items: &spec.SchemaOrArray{\r
- Schema: &spec.Schema{\r
- SchemaProps: spec.SchemaProps{\r
- Ref: ref("k8s.io/api/core/v1.ConfigMap"),\r
- },\r
- },\r
- },\r
- },\r
- },\r
- },\r
- Required: []string{"ready", "resourceCount", "podStatuses", "serviceStatuses"},\r
- },\r
- },\r
- Dependencies: []string{\r
- "./pkg/apis/k8splugin/v1alpha1.PodStatus", "k8s.io/api/core/v1.ConfigMap", "k8s.io/api/core/v1.Service"},\r
- }\r
-}\r
+// +build !ignore_autogenerated
+
+// This file was autogenerated by openapi-gen. Do not edit it manually!
+
+package v1alpha1
+
+import (
+ spec "github.com/go-openapi/spec"
+ common "k8s.io/kube-openapi/pkg/common"
+)
+
+func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
+ return map[string]common.OpenAPIDefinition{
+ "./pkg/apis/k8splugin/v1alpha1.PodStatus": schema_pkg_apis_k8splugin_v1alpha1_PodStatus(ref),
+ "./pkg/apis/k8splugin/v1alpha1.ResourceBundleState": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleState(ref),
+ "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStateSpec(ref),
+ "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus": schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStatus(ref),
+ }
+}
+
+func schema_pkg_apis_k8splugin_v1alpha1_PodStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "PodStatus defines the observed state of ResourceBundleState",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "metadata": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
+ },
+ },
+ "ready": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"boolean"},
+ Format: "",
+ },
+ },
+ "status": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/api/core/v1.PodStatus"),
+ },
+ },
+ },
+ Required: []string{"ready"},
+ },
+ },
+ Dependencies: []string{
+ "k8s.io/api/core/v1.PodStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
+ }
+}
+
+func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleState(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "ResourceBundleState is the Schema for the ResourceBundleStatees API",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "kind": {
+ SchemaProps: spec.SchemaProps{
+ 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/api-conventions.md#types-kinds",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "apiVersion": {
+ SchemaProps: spec.SchemaProps{
+ 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/api-conventions.md#resources",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "metadata": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
+ },
+ },
+ "spec": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec"),
+ },
+ },
+ "status": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus"),
+ },
+ },
+ },
+ },
+ },
+ Dependencies: []string{
+ "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStateSpec", "./pkg/apis/k8splugin/v1alpha1.ResourceBundleStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
+ }
+}
+
+func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStateSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "ResourceBundleStateSpec defines the desired state of ResourceBundleState",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "selector": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"),
+ },
+ },
+ },
+ Required: []string{"selector"},
+ },
+ },
+ Dependencies: []string{
+ "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"},
+ }
+}
+
+func schema_pkg_apis_k8splugin_v1alpha1_ResourceBundleStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "ResourceBundleStatus defines the observed state of ResourceBundleState",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "ready": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"boolean"},
+ Format: "",
+ },
+ },
+ "resourceCount": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"integer"},
+ Format: "int32",
+ },
+ },
+ "podStatuses": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("./pkg/apis/k8splugin/v1alpha1.PodStatus"),
+ },
+ },
+ },
+ },
+ },
+ "serviceStatuses": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/api/core/v1.Service"),
+ },
+ },
+ },
+ },
+ },
+ "configMapStatuses": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("k8s.io/api/core/v1.ConfigMap"),
+ },
+ },
+ },
+ },
+ },
+ },
+ Required: []string{"ready", "resourceCount", "podStatuses", "serviceStatuses"},
+ },
+ },
+ Dependencies: []string{
+ "./pkg/apis/k8splugin/v1alpha1.PodStatus", "k8s.io/api/core/v1.ConfigMap", "k8s.io/api/core/v1.Service"},
+ }
+}
-package controller\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/monitor/pkg/controller/resourcebundlestate"\r
-)\r
-\r
-func init() {\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.Add)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddPodController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddServiceController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddConfigMapController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddDeploymentController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddSecretController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddDaemonSetController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddIngressController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddJobController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddStatefulSetController)\r
- AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddCsrController)\r
-}\r
+package controller
+
+import (
+ "github.com/open-ness/EMCO/src/monitor/pkg/controller/resourcebundlestate"
+)
+
+func init() {
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.Add)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddPodController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddServiceController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddConfigMapController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddDeploymentController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddSecretController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddDaemonSetController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddIngressController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddJobController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddStatefulSetController)
+ AddToManagerFuncs = append(AddToManagerFuncs, resourcebundlestate.AddCsrController)
+}
-package controller\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
-)\r
-\r
-// AddToManagerFuncs is a list of functions to add all Controllers to the Manager\r
-var AddToManagerFuncs []func(manager.Manager) error\r
-\r
-// AddToManager adds all Controllers to the Manager\r
-func AddToManager(m manager.Manager) error {\r
- for _, f := range AddToManagerFuncs {\r
- if err := f(m); err != nil {\r
- return err\r
- }\r
- }\r
- return nil\r
-}\r
+package controller
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+)
+
+// AddToManagerFuncs is a list of functions to add all Controllers to the Manager
+var AddToManagerFuncs []func(manager.Manager) error
+
+// AddToManager adds all Controllers to the Manager
+func AddToManager(m manager.Manager) error {
+ for _, f := range AddToManagerFuncs {
+ if err := f(m); err != nil {
+ return err
+ }
+ }
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddConfigMapController the new controller to the controller manager\r
-func AddConfigMapController(mgr manager.Manager) error {\r
- return addConfigMapController(mgr, newConfigMapReconciler(mgr))\r
-}\r
-\r
-func addConfigMapController(mgr manager.Manager, r *configMapReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("ConfigMap-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource ConfigMaps\r
- // Predicate filters Service which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, &handler.EnqueueRequestForObject{}, &configMapPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newConfigMapReconciler(m manager.Manager) *configMapReconciler {\r
- return &configMapReconciler{client: m.GetClient()}\r
-}\r
-\r
-type configMapReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the ConfigMaps we watch.\r
-func (r *configMapReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for ConfigMap: %+v\n", req)\r
-\r
- cm := &corev1.ConfigMap{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, cm)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("ConfigMap not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the ConfigMap's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the ConfigMap has been deleted.\r
- r.deleteConfigMapFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get ConfigMap: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this ConfigMap via the labelselector\r
- crSelector := returnLabel(cm.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this ConfigMap")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, cm)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteConfigMapFromAllCRs deletes ConfigMap status from all the CRs when the ConfigMap itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the ConfigMap's labels, we need to look at all the CRs in this namespace\r
-func (r *configMapReconciler) deleteConfigMapFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *configMapReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, cm *corev1.ConfigMap) error {\r
-\r
- for _, cr := range crl.Items {\r
- // ConfigMap is not scheduled for deletion\r
- if cm.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, cm)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // ConfigMap is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, cm.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *configMapReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.ConfigMapStatuses)\r
- for i, rstatus := range cr.Status.ConfigMapStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.ConfigMapStatuses[i] = cr.Status.ConfigMapStatuses[length-1]\r
- cr.Status.ConfigMapStatuses = cr.Status.ConfigMapStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for ConfigMapStatuses in CR")\r
- return nil\r
-}\r
-\r
-func (r *configMapReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, cm *corev1.ConfigMap) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for _, rstatus := range cr.Status.ConfigMapStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == cm.Name {\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.ConfigMapStatuses = append(cr.Status.ConfigMapStatuses, corev1.ConfigMap{\r
- TypeMeta: cm.TypeMeta,\r
- ObjectMeta: cm.ObjectMeta,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ corev1 "k8s.io/api/core/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddConfigMapController the new controller to the controller manager
+func AddConfigMapController(mgr manager.Manager) error {
+ return addConfigMapController(mgr, newConfigMapReconciler(mgr))
+}
+
+func addConfigMapController(mgr manager.Manager, r *configMapReconciler) error {
+ // Create a new controller
+ c, err := controller.New("ConfigMap-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource ConfigMaps
+ // Predicate filters Service which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, &handler.EnqueueRequestForObject{}, &configMapPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newConfigMapReconciler(m manager.Manager) *configMapReconciler {
+ return &configMapReconciler{client: m.GetClient()}
+}
+
+type configMapReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the ConfigMaps we watch.
+func (r *configMapReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for ConfigMap: %+v\n", req)
+
+ cm := &corev1.ConfigMap{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, cm)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("ConfigMap not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the ConfigMap's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the ConfigMap has been deleted.
+ r.deleteConfigMapFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get ConfigMap: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this ConfigMap via the labelselector
+ crSelector := returnLabel(cm.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this ConfigMap")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, cm)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteConfigMapFromAllCRs deletes ConfigMap status from all the CRs when the ConfigMap itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the ConfigMap's labels, we need to look at all the CRs in this namespace
+func (r *configMapReconciler) deleteConfigMapFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *configMapReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, cm *corev1.ConfigMap) error {
+
+ for _, cr := range crl.Items {
+ // ConfigMap is not scheduled for deletion
+ if cm.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, cm)
+ if err != nil {
+ return err
+ }
+ } else {
+ // ConfigMap is scheduled for deletion
+ r.deleteFromSingleCR(&cr, cm.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *configMapReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.ConfigMapStatuses)
+ for i, rstatus := range cr.Status.ConfigMapStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.ConfigMapStatuses[i] = cr.Status.ConfigMapStatuses[length-1]
+ cr.Status.ConfigMapStatuses = cr.Status.ConfigMapStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for ConfigMapStatuses in CR")
+ return nil
+}
+
+func (r *configMapReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, cm *corev1.ConfigMap) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for _, rstatus := range cr.Status.ConfigMapStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == cm.Name {
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.ConfigMapStatuses = append(cr.Status.ConfigMapStatuses, corev1.ConfigMap{
+ TypeMeta: cm.TypeMeta,
+ ObjectMeta: cm.ObjectMeta,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type configMapPredicate struct {\r
-}\r
-\r
-func (c *configMapPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (c *configMapPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (c *configMapPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (c *configMapPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type configMapPredicate struct {
+}
+
+func (c *configMapPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (c *configMapPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (c *configMapPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (c *configMapPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- appsv1 "k8s.io/api/apps/v1"\r
- v1 "k8s.io/api/batch/v1"\r
- certsapi "k8s.io/api/certificates/v1beta1"\r
- corev1 "k8s.io/api/core/v1"\r
- v1beta1 "k8s.io/api/extensions/v1beta1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// Add the new controller to the controller manager\r
-func Add(mgr manager.Manager) error {\r
- return add(mgr, newReconciler(mgr))\r
-}\r
-\r
-func add(mgr manager.Manager, r *reconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("ResourceBundleState-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to primary resource ResourceBundleState\r
- err = c.Watch(&source.Kind{Type: &v1alpha1.ResourceBundleState{}}, &EventHandler{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newReconciler(m manager.Manager) *reconciler {\r
- return &reconciler{client: m.GetClient()}\r
-}\r
-\r
-type reconciler struct {\r
- // Stores an array of all the ResourceBundleState\r
- crList []v1alpha1.ResourceBundleState\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will manage the ResourceBundleState CR\r
-// We only accept CREATE events here and any subsequent changes are ignored.\r
-func (r *reconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Reconciling ResourceBundleState %+v\n", req)\r
-\r
- rbstate := &v1alpha1.ResourceBundleState{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, rbstate)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Object not found: %+v. Ignore as it must have been deleted.\n", req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get object: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updatePods(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding podstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateServices(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding servicestatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateConfigMaps(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding configmapstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateDeployments(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding deploymentstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateSecrets(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding secretstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateDaemonSets(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding daemonSetstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateIngresses(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding ingressStatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateJobs(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding jobstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateStatefulSets(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding statefulSetstatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- err = r.updateCsrs(rbstate, rbstate.Spec.Selector.MatchLabels)\r
- if err != nil {\r
- log.Printf("Error adding csrStatuses: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // TODO: Update this based on the statuses of the lower resources\r
- rbstate.Status.Ready = false\r
- err = r.client.Status().Update(context.TODO(), rbstate)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-func (r *reconciler) updateServices(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the Services created as well\r
- serviceList := &corev1.ServiceList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, serviceList)\r
- if err != nil {\r
- log.Printf("Failed to list services: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.ServiceStatuses = []corev1.Service{}\r
-\r
- for _, svc := range serviceList.Items {\r
- resStatus := corev1.Service{\r
- TypeMeta: svc.TypeMeta,\r
- ObjectMeta: svc.ObjectMeta,\r
- Status: svc.Status,\r
- }\r
- rbstate.Status.ServiceStatuses = append(rbstate.Status.ServiceStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updatePods(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the pods tracked\r
- podList := &corev1.PodList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, podList)\r
- if err != nil {\r
- log.Printf("Failed to list pods: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.PodStatuses = []corev1.Pod{}\r
-\r
- for _, pod := range podList.Items {\r
- resStatus := corev1.Pod{\r
- TypeMeta: pod.TypeMeta,\r
- ObjectMeta: pod.ObjectMeta,\r
- Status: pod.Status,\r
- }\r
- rbstate.Status.PodStatuses = append(rbstate.Status.PodStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateConfigMaps(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the ConfigMaps created as well\r
- configMapList := &corev1.ConfigMapList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, configMapList)\r
- if err != nil {\r
- log.Printf("Failed to list configMaps: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.ConfigMapStatuses = []corev1.ConfigMap{}\r
-\r
- for _, cm := range configMapList.Items {\r
- resStatus := corev1.ConfigMap{\r
- TypeMeta: cm.TypeMeta,\r
- ObjectMeta: cm.ObjectMeta,\r
- }\r
- rbstate.Status.ConfigMapStatuses = append(rbstate.Status.ConfigMapStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateDeployments(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the Deployments created as well\r
- deploymentList := &appsv1.DeploymentList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, deploymentList)\r
- if err != nil {\r
- log.Printf("Failed to list deployments: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.DeploymentStatuses = []appsv1.Deployment{}\r
-\r
- for _, dep := range deploymentList.Items {\r
- resStatus := appsv1.Deployment{\r
- TypeMeta: dep.TypeMeta,\r
- ObjectMeta: dep.ObjectMeta,\r
- Status: dep.Status,\r
- }\r
- rbstate.Status.DeploymentStatuses = append(rbstate.Status.DeploymentStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateSecrets(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the Secrets created as well\r
- secretList := &corev1.SecretList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, secretList)\r
- if err != nil {\r
- log.Printf("Failed to list secrets: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.SecretStatuses = []corev1.Secret{}\r
-\r
- for _, sec := range secretList.Items {\r
- resStatus := corev1.Secret{\r
- TypeMeta: sec.TypeMeta,\r
- ObjectMeta: sec.ObjectMeta,\r
- }\r
- rbstate.Status.SecretStatuses = append(rbstate.Status.SecretStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateDaemonSets(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the DaemonSets created as well\r
- daemonSetList := &appsv1.DaemonSetList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, daemonSetList)\r
- if err != nil {\r
- log.Printf("Failed to list DaemonSets: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.DaemonSetStatuses = []appsv1.DaemonSet{}\r
-\r
- for _, ds := range daemonSetList.Items {\r
- resStatus := appsv1.DaemonSet{\r
- TypeMeta: ds.TypeMeta,\r
- ObjectMeta: ds.ObjectMeta,\r
- Status: ds.Status,\r
- }\r
- rbstate.Status.DaemonSetStatuses = append(rbstate.Status.DaemonSetStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateIngresses(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the Ingresses created as well\r
- ingressList := &v1beta1.IngressList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, ingressList)\r
- if err != nil {\r
- log.Printf("Failed to list ingresses: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.IngressStatuses = []v1beta1.Ingress{}\r
-\r
- for _, ing := range ingressList.Items {\r
- resStatus := v1beta1.Ingress{\r
- TypeMeta: ing.TypeMeta,\r
- ObjectMeta: ing.ObjectMeta,\r
- Status: ing.Status,\r
- }\r
- rbstate.Status.IngressStatuses = append(rbstate.Status.IngressStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateJobs(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the Services created as well\r
- jobList := &v1.JobList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, jobList)\r
- if err != nil {\r
- log.Printf("Failed to list jobs: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.JobStatuses = []v1.Job{}\r
-\r
- for _, job := range jobList.Items {\r
- resStatus := v1.Job{\r
- TypeMeta: job.TypeMeta,\r
- ObjectMeta: job.ObjectMeta,\r
- Status: job.Status,\r
- }\r
- rbstate.Status.JobStatuses = append(rbstate.Status.JobStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateStatefulSets(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the StatefulSets created as well\r
- statefulSetList := &appsv1.StatefulSetList{}\r
- err := listResources(r.client, rbstate.Namespace, selectors, statefulSetList)\r
- if err != nil {\r
- log.Printf("Failed to list statefulSets: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.StatefulSetStatuses = []appsv1.StatefulSet{}\r
-\r
- for _, sfs := range statefulSetList.Items {\r
- resStatus := appsv1.StatefulSet{\r
- TypeMeta: sfs.TypeMeta,\r
- ObjectMeta: sfs.ObjectMeta,\r
- Status: sfs.Status,\r
- }\r
- rbstate.Status.StatefulSetStatuses = append(rbstate.Status.StatefulSetStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *reconciler) updateCsrs(rbstate *v1alpha1.ResourceBundleState,\r
- selectors map[string]string) error {\r
-\r
- // Update the CR with the csrs tracked\r
- csrList := &certsapi.CertificateSigningRequestList{}\r
- err := listResources(r.client, "", selectors, csrList)\r
- if err != nil {\r
- log.Printf("Failed to list csrs: %v", err)\r
- return err\r
- }\r
-\r
- rbstate.Status.CsrStatuses = []certsapi.CertificateSigningRequest{}\r
-\r
- for _, csr := range csrList.Items {\r
- resStatus := certsapi.CertificateSigningRequest{\r
- TypeMeta: csr.TypeMeta,\r
- ObjectMeta: csr.ObjectMeta,\r
- Status: csr.Status,\r
- }\r
- rbstate.Status.CsrStatuses = append(rbstate.Status.CsrStatuses, resStatus)\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ appsv1 "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/batch/v1"
+ certsapi "k8s.io/api/certificates/v1beta1"
+ corev1 "k8s.io/api/core/v1"
+ v1beta1 "k8s.io/api/extensions/v1beta1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// Add the new controller to the controller manager
+func Add(mgr manager.Manager) error {
+ return add(mgr, newReconciler(mgr))
+}
+
+func add(mgr manager.Manager, r *reconciler) error {
+ // Create a new controller
+ c, err := controller.New("ResourceBundleState-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to primary resource ResourceBundleState
+ err = c.Watch(&source.Kind{Type: &v1alpha1.ResourceBundleState{}}, &EventHandler{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newReconciler(m manager.Manager) *reconciler {
+ return &reconciler{client: m.GetClient()}
+}
+
+type reconciler struct {
+ // Stores an array of all the ResourceBundleState
+ crList []v1alpha1.ResourceBundleState
+ client client.Client
+}
+
+// Reconcile implements the loop that will manage the ResourceBundleState CR
+// We only accept CREATE events here and any subsequent changes are ignored.
+func (r *reconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Reconciling ResourceBundleState %+v\n", req)
+
+ rbstate := &v1alpha1.ResourceBundleState{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, rbstate)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Object not found: %+v. Ignore as it must have been deleted.\n", req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get object: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updatePods(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding podstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateServices(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding servicestatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateConfigMaps(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding configmapstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateDeployments(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding deploymentstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateSecrets(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding secretstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateDaemonSets(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding daemonSetstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateIngresses(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding ingressStatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateJobs(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding jobstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateStatefulSets(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding statefulSetstatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ err = r.updateCsrs(rbstate, rbstate.Spec.Selector.MatchLabels)
+ if err != nil {
+ log.Printf("Error adding csrStatuses: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ // TODO: Update this based on the statuses of the lower resources
+ rbstate.Status.Ready = false
+ err = r.client.Status().Update(context.TODO(), rbstate)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+func (r *reconciler) updateServices(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the Services created as well
+ serviceList := &corev1.ServiceList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, serviceList)
+ if err != nil {
+ log.Printf("Failed to list services: %v", err)
+ return err
+ }
+
+ rbstate.Status.ServiceStatuses = []corev1.Service{}
+
+ for _, svc := range serviceList.Items {
+ resStatus := corev1.Service{
+ TypeMeta: svc.TypeMeta,
+ ObjectMeta: svc.ObjectMeta,
+ Status: svc.Status,
+ }
+ rbstate.Status.ServiceStatuses = append(rbstate.Status.ServiceStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updatePods(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the pods tracked
+ podList := &corev1.PodList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, podList)
+ if err != nil {
+ log.Printf("Failed to list pods: %v", err)
+ return err
+ }
+
+ rbstate.Status.PodStatuses = []corev1.Pod{}
+
+ for _, pod := range podList.Items {
+ resStatus := corev1.Pod{
+ TypeMeta: pod.TypeMeta,
+ ObjectMeta: pod.ObjectMeta,
+ Status: pod.Status,
+ }
+ rbstate.Status.PodStatuses = append(rbstate.Status.PodStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateConfigMaps(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the ConfigMaps created as well
+ configMapList := &corev1.ConfigMapList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, configMapList)
+ if err != nil {
+ log.Printf("Failed to list configMaps: %v", err)
+ return err
+ }
+
+ rbstate.Status.ConfigMapStatuses = []corev1.ConfigMap{}
+
+ for _, cm := range configMapList.Items {
+ resStatus := corev1.ConfigMap{
+ TypeMeta: cm.TypeMeta,
+ ObjectMeta: cm.ObjectMeta,
+ }
+ rbstate.Status.ConfigMapStatuses = append(rbstate.Status.ConfigMapStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateDeployments(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the Deployments created as well
+ deploymentList := &appsv1.DeploymentList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, deploymentList)
+ if err != nil {
+ log.Printf("Failed to list deployments: %v", err)
+ return err
+ }
+
+ rbstate.Status.DeploymentStatuses = []appsv1.Deployment{}
+
+ for _, dep := range deploymentList.Items {
+ resStatus := appsv1.Deployment{
+ TypeMeta: dep.TypeMeta,
+ ObjectMeta: dep.ObjectMeta,
+ Status: dep.Status,
+ }
+ rbstate.Status.DeploymentStatuses = append(rbstate.Status.DeploymentStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateSecrets(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the Secrets created as well
+ secretList := &corev1.SecretList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, secretList)
+ if err != nil {
+ log.Printf("Failed to list secrets: %v", err)
+ return err
+ }
+
+ rbstate.Status.SecretStatuses = []corev1.Secret{}
+
+ for _, sec := range secretList.Items {
+ resStatus := corev1.Secret{
+ TypeMeta: sec.TypeMeta,
+ ObjectMeta: sec.ObjectMeta,
+ }
+ rbstate.Status.SecretStatuses = append(rbstate.Status.SecretStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateDaemonSets(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the DaemonSets created as well
+ daemonSetList := &appsv1.DaemonSetList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, daemonSetList)
+ if err != nil {
+ log.Printf("Failed to list DaemonSets: %v", err)
+ return err
+ }
+
+ rbstate.Status.DaemonSetStatuses = []appsv1.DaemonSet{}
+
+ for _, ds := range daemonSetList.Items {
+ resStatus := appsv1.DaemonSet{
+ TypeMeta: ds.TypeMeta,
+ ObjectMeta: ds.ObjectMeta,
+ Status: ds.Status,
+ }
+ rbstate.Status.DaemonSetStatuses = append(rbstate.Status.DaemonSetStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateIngresses(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the Ingresses created as well
+ ingressList := &v1beta1.IngressList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, ingressList)
+ if err != nil {
+ log.Printf("Failed to list ingresses: %v", err)
+ return err
+ }
+
+ rbstate.Status.IngressStatuses = []v1beta1.Ingress{}
+
+ for _, ing := range ingressList.Items {
+ resStatus := v1beta1.Ingress{
+ TypeMeta: ing.TypeMeta,
+ ObjectMeta: ing.ObjectMeta,
+ Status: ing.Status,
+ }
+ rbstate.Status.IngressStatuses = append(rbstate.Status.IngressStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateJobs(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the Services created as well
+ jobList := &v1.JobList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, jobList)
+ if err != nil {
+ log.Printf("Failed to list jobs: %v", err)
+ return err
+ }
+
+ rbstate.Status.JobStatuses = []v1.Job{}
+
+ for _, job := range jobList.Items {
+ resStatus := v1.Job{
+ TypeMeta: job.TypeMeta,
+ ObjectMeta: job.ObjectMeta,
+ Status: job.Status,
+ }
+ rbstate.Status.JobStatuses = append(rbstate.Status.JobStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateStatefulSets(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the StatefulSets created as well
+ statefulSetList := &appsv1.StatefulSetList{}
+ err := listResources(r.client, rbstate.Namespace, selectors, statefulSetList)
+ if err != nil {
+ log.Printf("Failed to list statefulSets: %v", err)
+ return err
+ }
+
+ rbstate.Status.StatefulSetStatuses = []appsv1.StatefulSet{}
+
+ for _, sfs := range statefulSetList.Items {
+ resStatus := appsv1.StatefulSet{
+ TypeMeta: sfs.TypeMeta,
+ ObjectMeta: sfs.ObjectMeta,
+ Status: sfs.Status,
+ }
+ rbstate.Status.StatefulSetStatuses = append(rbstate.Status.StatefulSetStatuses, resStatus)
+ }
+
+ return nil
+}
+
+func (r *reconciler) updateCsrs(rbstate *v1alpha1.ResourceBundleState,
+ selectors map[string]string) error {
+
+ // Update the CR with the csrs tracked
+ csrList := &certsapi.CertificateSigningRequestList{}
+ err := listResources(r.client, "", selectors, csrList)
+ if err != nil {
+ log.Printf("Failed to list csrs: %v", err)
+ return err
+ }
+
+ rbstate.Status.CsrStatuses = []certsapi.CertificateSigningRequest{}
+
+ for _, csr := range csrList.Items {
+ resStatus := certsapi.CertificateSigningRequest{
+ TypeMeta: csr.TypeMeta,
+ ObjectMeta: csr.ObjectMeta,
+ Status: csr.Status,
+ }
+ rbstate.Status.CsrStatuses = append(rbstate.Status.CsrStatuses, resStatus)
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- certsapi "k8s.io/api/certificates/v1beta1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddCsrController the new controller to the controller manager\r
-func AddCsrController(mgr manager.Manager) error {\r
- return addCsrController(mgr, newCsrReconciler(mgr))\r
-}\r
-\r
-func addCsrController(mgr manager.Manager, r *csrReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Csr-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondary resource Csrs\r
- // Predicate filters csrs which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &certsapi.CertificateSigningRequest{}}, &handler.EnqueueRequestForObject{}, &csrPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newCsrReconciler(m manager.Manager) *csrReconciler {\r
- return &csrReconciler{client: m.GetClient()}\r
-}\r
-\r
-type csrReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the csrs we watch.\r
-func (r *csrReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Csr: %+v\n", req)\r
-\r
- csr := &certsapi.CertificateSigningRequest{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, csr)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Csr not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Csr's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the POD has been deleted.\r
- r.deleteCsrFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get csr: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this csr via the labelselector\r
- crSelector := returnLabel(csr.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Csr")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listClusterResources(r.client, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, csr)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteCsrFromAllCRs deletes csr status from all the CRs when the POD itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the csr's labels, we need to look at all the CRs in this namespace\r
-func (r *csrReconciler) deleteCsrFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listClusterResources(r.client, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *csrReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, csr *certsapi.CertificateSigningRequest) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Csr is not scheduled for deletion\r
- if csr.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, csr)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Csr is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, csr.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *csrReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.CsrStatuses)\r
- for i, rstatus := range cr.Status.CsrStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.CsrStatuses[i] = cr.Status.CsrStatuses[length-1]\r
- cr.Status.CsrStatuses[length-1] = certsapi.CertificateSigningRequest{}\r
- cr.Status.CsrStatuses = cr.Status.CsrStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for POD in CR")\r
- return nil\r
-}\r
-\r
-func (r *csrReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, csr *certsapi.CertificateSigningRequest) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.CsrStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == csr.Name {\r
- csr.Status.DeepCopyInto(&cr.Status.CsrStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.CsrStatuses = append(cr.Status.CsrStatuses, certsapi.CertificateSigningRequest{\r
- TypeMeta: csr.TypeMeta,\r
- ObjectMeta: csr.ObjectMeta,\r
- Status: csr.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ certsapi "k8s.io/api/certificates/v1beta1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddCsrController the new controller to the controller manager
+func AddCsrController(mgr manager.Manager) error {
+ return addCsrController(mgr, newCsrReconciler(mgr))
+}
+
+func addCsrController(mgr manager.Manager, r *csrReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Csr-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondary resource Csrs
+ // Predicate filters csrs which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &certsapi.CertificateSigningRequest{}}, &handler.EnqueueRequestForObject{}, &csrPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newCsrReconciler(m manager.Manager) *csrReconciler {
+ return &csrReconciler{client: m.GetClient()}
+}
+
+type csrReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the csrs we watch.
+func (r *csrReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Csr: %+v\n", req)
+
+ csr := &certsapi.CertificateSigningRequest{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, csr)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Csr not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Csr's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the POD has been deleted.
+ r.deleteCsrFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get csr: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this csr via the labelselector
+ crSelector := returnLabel(csr.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Csr")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listClusterResources(r.client, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, csr)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteCsrFromAllCRs deletes csr status from all the CRs when the POD itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the csr's labels, we need to look at all the CRs in this namespace
+func (r *csrReconciler) deleteCsrFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listClusterResources(r.client, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *csrReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, csr *certsapi.CertificateSigningRequest) error {
+
+ for _, cr := range crl.Items {
+ // Csr is not scheduled for deletion
+ if csr.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, csr)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Csr is scheduled for deletion
+ r.deleteFromSingleCR(&cr, csr.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *csrReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.CsrStatuses)
+ for i, rstatus := range cr.Status.CsrStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.CsrStatuses[i] = cr.Status.CsrStatuses[length-1]
+ cr.Status.CsrStatuses[length-1] = certsapi.CertificateSigningRequest{}
+ cr.Status.CsrStatuses = cr.Status.CsrStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for POD in CR")
+ return nil
+}
+
+func (r *csrReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, csr *certsapi.CertificateSigningRequest) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.CsrStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == csr.Name {
+ csr.Status.DeepCopyInto(&cr.Status.CsrStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.CsrStatuses = append(cr.Status.CsrStatuses, certsapi.CertificateSigningRequest{
+ TypeMeta: csr.TypeMeta,
+ ObjectMeta: csr.ObjectMeta,
+ Status: csr.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type csrPredicate struct {\r
-}\r
-\r
-func (p *csrPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *csrPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *csrPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *csrPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type csrPredicate struct {
+}
+
+func (p *csrPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *csrPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *csrPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *csrPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- appsv1 "k8s.io/api/apps/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddDaemonSetController the new controller to the controller manager\r
-func AddDaemonSetController(mgr manager.Manager) error {\r
- return addDaemonSetController(mgr, newDaemonSetReconciler(mgr))\r
-}\r
-\r
-func addDaemonSetController(mgr manager.Manager, r *daemonSetReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Daemonset-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource DaemonSets\r
- // Predicate filters DaemonSets which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &appsv1.DaemonSet{}}, &handler.EnqueueRequestForObject{}, &daemonSetPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newDaemonSetReconciler(m manager.Manager) *daemonSetReconciler {\r
- return &daemonSetReconciler{client: m.GetClient()}\r
-}\r
-\r
-type daemonSetReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the daemonSets we watch.\r
-func (r *daemonSetReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for DaemonSet: %+v\n", req)\r
-\r
- ds := &appsv1.DaemonSet{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, ds)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("DaemonSet not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the DaemonSet's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the DaemonSet has been deleted.\r
- r.deleteDaemonSetFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get daemonSet: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this daemonSet via the labelselector\r
- crSelector := returnLabel(ds.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this DaemonSet")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, ds)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteDaemonSetFromAllCRs deletes daemonSet status from all the CRs when the DaemonSet itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the daemonSet's labels, we need to look at all the CRs in this namespace\r
-func (r *daemonSetReconciler) deleteDaemonSetFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *daemonSetReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, ds *appsv1.DaemonSet) error {\r
-\r
- for _, cr := range crl.Items {\r
- // DaemonSet is not scheduled for deletion\r
- if ds.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, ds)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // DaemonSet is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, ds.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *daemonSetReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.DaemonSetStatuses)\r
- for i, rstatus := range cr.Status.DaemonSetStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.DaemonSetStatuses[i] = cr.Status.DaemonSetStatuses[length-1]\r
- cr.Status.DaemonSetStatuses[length-1].Status = appsv1.DaemonSetStatus{}\r
- cr.Status.DaemonSetStatuses = cr.Status.DaemonSetStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for DaemonSet in CR")\r
- return nil\r
-}\r
-\r
-func (r *daemonSetReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, ds *appsv1.DaemonSet) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.DaemonSetStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == ds.Name {\r
- ds.Status.DeepCopyInto(&cr.Status.DaemonSetStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.DaemonSetStatuses = append(cr.Status.DaemonSetStatuses, appsv1.DaemonSet{\r
- TypeMeta: ds.TypeMeta,\r
- ObjectMeta: ds.ObjectMeta,\r
- Status: ds.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ appsv1 "k8s.io/api/apps/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddDaemonSetController the new controller to the controller manager
+func AddDaemonSetController(mgr manager.Manager) error {
+ return addDaemonSetController(mgr, newDaemonSetReconciler(mgr))
+}
+
+func addDaemonSetController(mgr manager.Manager, r *daemonSetReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Daemonset-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource DaemonSets
+ // Predicate filters DaemonSets which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &appsv1.DaemonSet{}}, &handler.EnqueueRequestForObject{}, &daemonSetPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newDaemonSetReconciler(m manager.Manager) *daemonSetReconciler {
+ return &daemonSetReconciler{client: m.GetClient()}
+}
+
+type daemonSetReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the daemonSets we watch.
+func (r *daemonSetReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for DaemonSet: %+v\n", req)
+
+ ds := &appsv1.DaemonSet{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, ds)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("DaemonSet not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the DaemonSet's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the DaemonSet has been deleted.
+ r.deleteDaemonSetFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get daemonSet: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this daemonSet via the labelselector
+ crSelector := returnLabel(ds.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this DaemonSet")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, ds)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteDaemonSetFromAllCRs deletes daemonSet status from all the CRs when the DaemonSet itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the daemonSet's labels, we need to look at all the CRs in this namespace
+func (r *daemonSetReconciler) deleteDaemonSetFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *daemonSetReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, ds *appsv1.DaemonSet) error {
+
+ for _, cr := range crl.Items {
+ // DaemonSet is not scheduled for deletion
+ if ds.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, ds)
+ if err != nil {
+ return err
+ }
+ } else {
+ // DaemonSet is scheduled for deletion
+ r.deleteFromSingleCR(&cr, ds.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *daemonSetReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.DaemonSetStatuses)
+ for i, rstatus := range cr.Status.DaemonSetStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.DaemonSetStatuses[i] = cr.Status.DaemonSetStatuses[length-1]
+ cr.Status.DaemonSetStatuses[length-1].Status = appsv1.DaemonSetStatus{}
+ cr.Status.DaemonSetStatuses = cr.Status.DaemonSetStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for DaemonSet in CR")
+ return nil
+}
+
+func (r *daemonSetReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, ds *appsv1.DaemonSet) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.DaemonSetStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == ds.Name {
+ ds.Status.DeepCopyInto(&cr.Status.DaemonSetStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.DaemonSetStatuses = append(cr.Status.DaemonSetStatuses, appsv1.DaemonSet{
+ TypeMeta: ds.TypeMeta,
+ ObjectMeta: ds.ObjectMeta,
+ Status: ds.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type daemonSetPredicate struct {\r
-}\r
-\r
-func (d *daemonSetPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *daemonSetPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *daemonSetPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *daemonSetPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type daemonSetPredicate struct {
+}
+
+func (d *daemonSetPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *daemonSetPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *daemonSetPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *daemonSetPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- appsv1 "k8s.io/api/apps/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddDeploymentController the new controller to the controller manager\r
-func AddDeploymentController(mgr manager.Manager) error {\r
- return addDeploymentController(mgr, newDeploymentReconciler(mgr))\r
-}\r
-\r
-func addDeploymentController(mgr manager.Manager, r *deploymentReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Deployment-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Deployments\r
- // Predicate filters Deployment which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForObject{}, &deploymentPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newDeploymentReconciler(m manager.Manager) *deploymentReconciler {\r
- return &deploymentReconciler{client: m.GetClient()}\r
-}\r
-\r
-type deploymentReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the deployments we watch.\r
-func (r *deploymentReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Deployment: %+v\n", req)\r
-\r
- dep := &appsv1.Deployment{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, dep)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Deployment not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Deployment's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the Deployment has been deleted.\r
- r.deleteDeploymentFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get deployment: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this deployment via the labelselector\r
- crSelector := returnLabel(dep.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Deployment")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, dep)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteDeploymentFromAllCRs deletes deployment status from all the CRs when the Deployment itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the deployment's labels, we need to look at all the CRs in this namespace\r
-func (r *deploymentReconciler) deleteDeploymentFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *deploymentReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, dep *appsv1.Deployment) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Deployment is not scheduled for deletion\r
- if dep.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, dep)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Deployment is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, dep.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *deploymentReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.DeploymentStatuses)\r
- for i, rstatus := range cr.Status.DeploymentStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.DeploymentStatuses[i] = cr.Status.DeploymentStatuses[length-1]\r
- cr.Status.DeploymentStatuses[length-1].Status = appsv1.DeploymentStatus{}\r
- cr.Status.DeploymentStatuses = cr.Status.DeploymentStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for Deployment in CR")\r
- return nil\r
-}\r
-\r
-func (r *deploymentReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, dep *appsv1.Deployment) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.DeploymentStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == dep.Name {\r
- dep.Status.DeepCopyInto(&cr.Status.DeploymentStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.DeploymentStatuses = append(cr.Status.DeploymentStatuses, appsv1.Deployment{\r
- TypeMeta: dep.TypeMeta,\r
- ObjectMeta: dep.ObjectMeta,\r
- Status: dep.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ appsv1 "k8s.io/api/apps/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddDeploymentController the new controller to the controller manager
+func AddDeploymentController(mgr manager.Manager) error {
+ return addDeploymentController(mgr, newDeploymentReconciler(mgr))
+}
+
+func addDeploymentController(mgr manager.Manager, r *deploymentReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Deployment-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Deployments
+ // Predicate filters Deployment which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForObject{}, &deploymentPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newDeploymentReconciler(m manager.Manager) *deploymentReconciler {
+ return &deploymentReconciler{client: m.GetClient()}
+}
+
+type deploymentReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the deployments we watch.
+func (r *deploymentReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Deployment: %+v\n", req)
+
+ dep := &appsv1.Deployment{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, dep)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Deployment not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Deployment's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the Deployment has been deleted.
+ r.deleteDeploymentFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get deployment: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this deployment via the labelselector
+ crSelector := returnLabel(dep.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Deployment")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, dep)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteDeploymentFromAllCRs deletes deployment status from all the CRs when the Deployment itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the deployment's labels, we need to look at all the CRs in this namespace
+func (r *deploymentReconciler) deleteDeploymentFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *deploymentReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, dep *appsv1.Deployment) error {
+
+ for _, cr := range crl.Items {
+ // Deployment is not scheduled for deletion
+ if dep.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, dep)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Deployment is scheduled for deletion
+ r.deleteFromSingleCR(&cr, dep.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *deploymentReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.DeploymentStatuses)
+ for i, rstatus := range cr.Status.DeploymentStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.DeploymentStatuses[i] = cr.Status.DeploymentStatuses[length-1]
+ cr.Status.DeploymentStatuses[length-1].Status = appsv1.DeploymentStatus{}
+ cr.Status.DeploymentStatuses = cr.Status.DeploymentStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for Deployment in CR")
+ return nil
+}
+
+func (r *deploymentReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, dep *appsv1.Deployment) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.DeploymentStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == dep.Name {
+ dep.Status.DeepCopyInto(&cr.Status.DeploymentStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.DeploymentStatuses = append(cr.Status.DeploymentStatuses, appsv1.Deployment{
+ TypeMeta: dep.TypeMeta,
+ ObjectMeta: dep.ObjectMeta,
+ Status: dep.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type deploymentPredicate struct {\r
-}\r
-\r
-func (d *deploymentPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *deploymentPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *deploymentPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (d *deploymentPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type deploymentPredicate struct {
+}
+
+func (d *deploymentPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *deploymentPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *deploymentPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (d *deploymentPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "k8s.io/client-go/util/workqueue"\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
-)\r
-\r
-// EventHandler adds some specific handling for certain types of events\r
-// related to the ResourceBundleState CR.\r
-type EventHandler struct {\r
- handler.EnqueueRequestForObject\r
-}\r
-\r
-// Delete ignores any delete operations on a ResourceBundleState CR\r
-func (p *EventHandler) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) {\r
- return\r
-}\r
-\r
-// Update ignores any update operations on a ResourceBundleState CR\r
-func (p *EventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) {\r
- return\r
-}\r
-\r
-// Generic ignores any generic operations on a ResourceBundleState CR\r
-func (p *EventHandler) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) {\r
- return\r
-}\r
+package resourcebundlestate
+
+import (
+ "k8s.io/client-go/util/workqueue"
+ "sigs.k8s.io/controller-runtime/pkg/event"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+)
+
+// EventHandler adds some specific handling for certain types of events
+// related to the ResourceBundleState CR.
+type EventHandler struct {
+ handler.EnqueueRequestForObject
+}
+
+// Delete ignores any delete operations on a ResourceBundleState CR
+func (p *EventHandler) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) {
+ return
+}
+
+// Update ignores any update operations on a ResourceBundleState CR
+func (p *EventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) {
+ return
+}
+
+// Generic ignores any generic operations on a ResourceBundleState CR
+func (p *EventHandler) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) {
+ return
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "k8s.io/apimachinery/pkg/labels"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
-)\r
-\r
-// checkLabel verifies if the expected label exists and returns bool\r
-func checkLabel(labels map[string]string) bool {\r
-\r
- _, ok := labels["emco/deployment-id"]\r
- if !ok {\r
- log.Printf("Pod does not have label. Filter it.")\r
- return false\r
- }\r
- return true\r
-}\r
-\r
-// returnLabel verifies if the expected label exists and returns a map\r
-func returnLabel(labels map[string]string) map[string]string {\r
-\r
- l, ok := labels["emco/deployment-id"]\r
- if !ok {\r
- log.Printf("Pod does not have label. Filter it.")\r
- return nil\r
- }\r
- return map[string]string{\r
- "emco/deployment-id": l,\r
- }\r
-}\r
-\r
-// listResources lists resources based on the selectors provided\r
-// The data is returned in the pointer to the runtime.Object\r
-// provided as argument.\r
-func listResources(cli client.Client, namespace string,\r
- labelSelector map[string]string, returnData runtime.Object) error {\r
-\r
- listOptions := &client.ListOptions{\r
- Namespace: namespace,\r
- LabelSelector: labels.SelectorFromSet(labelSelector),\r
- }\r
-\r
- err := cli.List(context.TODO(), returnData, listOptions)\r
- if err != nil {\r
- log.Printf("Failed to list CRs: %v", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// listClusterResources lists non-namespace resources based\r
-// on the selectors provided.\r
-// The data is returned in the pointer to the runtime.Object\r
-// provided as argument.\r
-func listClusterResources(cli client.Client,\r
- labelSelector map[string]string, returnData runtime.Object) error {\r
- return listResources(cli, "", labelSelector, returnData)\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// checkLabel verifies if the expected label exists and returns bool
+func checkLabel(labels map[string]string) bool {
+
+ _, ok := labels["emco/deployment-id"]
+ if !ok {
+ log.Printf("Pod does not have label. Filter it.")
+ return false
+ }
+ return true
+}
+
+// returnLabel verifies if the expected label exists and returns a map
+func returnLabel(labels map[string]string) map[string]string {
+
+ l, ok := labels["emco/deployment-id"]
+ if !ok {
+ log.Printf("Pod does not have label. Filter it.")
+ return nil
+ }
+ return map[string]string{
+ "emco/deployment-id": l,
+ }
+}
+
+// listResources lists resources based on the selectors provided
+// The data is returned in the pointer to the runtime.Object
+// provided as argument.
+func listResources(cli client.Client, namespace string,
+ labelSelector map[string]string, returnData runtime.Object) error {
+
+ listOptions := &client.ListOptions{
+ Namespace: namespace,
+ LabelSelector: labels.SelectorFromSet(labelSelector),
+ }
+
+ err := cli.List(context.TODO(), returnData, listOptions)
+ if err != nil {
+ log.Printf("Failed to list CRs: %v", err)
+ return err
+ }
+
+ return nil
+}
+
+// listClusterResources lists non-namespace resources based
+// on the selectors provided.
+// The data is returned in the pointer to the runtime.Object
+// provided as argument.
+func listClusterResources(cli client.Client,
+ labelSelector map[string]string, returnData runtime.Object) error {
+ return listResources(cli, "", labelSelector, returnData)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- v1beta1 "k8s.io/api/extensions/v1beta1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddIngressController the new controller to the controller manager\r
-func AddIngressController(mgr manager.Manager) error {\r
- return addIngressController(mgr, newIngressReconciler(mgr))\r
-}\r
-\r
-func addIngressController(mgr manager.Manager, r *ingressReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Ingress-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Ingress\r
- // Predicate filters Ingress which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &v1beta1.Ingress{}}, &handler.EnqueueRequestForObject{}, &ingressPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newIngressReconciler(m manager.Manager) *ingressReconciler {\r
- return &ingressReconciler{client: m.GetClient()}\r
-}\r
-\r
-type ingressReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the ingress we watch.\r
-func (r *ingressReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Ingress: %+v\n", req)\r
-\r
- ing := &v1beta1.Ingress{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, ing)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Ingress not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Ingress's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the Ingress has been deleted.\r
- r.deleteIngressFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get ingress: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this Ingress via the labelselector\r
- crSelector := returnLabel(ing.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Ingress")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, ing)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteIngressFromAllCRs deletes ingress status from all the CRs when the Ingress itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the Ingress's labels, we need to look at all the CRs in this namespace\r
-func (r *ingressReconciler) deleteIngressFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *ingressReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, ing *v1beta1.Ingress) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Ingress is not scheduled for deletion\r
- if ing.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, ing)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Ingress is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, ing.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *ingressReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.IngressStatuses)\r
- for i, rstatus := range cr.Status.IngressStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.IngressStatuses[i] = cr.Status.IngressStatuses[length-1]\r
- cr.Status.IngressStatuses[length-1].Status = v1beta1.IngressStatus{}\r
- cr.Status.IngressStatuses = cr.Status.IngressStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for Ingress in CR")\r
- return nil\r
-}\r
-\r
-func (r *ingressReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, ing *v1beta1.Ingress) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.IngressStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == ing.Name {\r
- ing.Status.DeepCopyInto(&cr.Status.IngressStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.IngressStatuses = append(cr.Status.IngressStatuses, v1beta1.Ingress{\r
- TypeMeta: ing.TypeMeta,\r
- ObjectMeta: ing.ObjectMeta,\r
- Status: ing.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ v1beta1 "k8s.io/api/extensions/v1beta1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddIngressController the new controller to the controller manager
+func AddIngressController(mgr manager.Manager) error {
+ return addIngressController(mgr, newIngressReconciler(mgr))
+}
+
+func addIngressController(mgr manager.Manager, r *ingressReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Ingress-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Ingress
+ // Predicate filters Ingress which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &v1beta1.Ingress{}}, &handler.EnqueueRequestForObject{}, &ingressPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newIngressReconciler(m manager.Manager) *ingressReconciler {
+ return &ingressReconciler{client: m.GetClient()}
+}
+
+type ingressReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the ingress we watch.
+func (r *ingressReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Ingress: %+v\n", req)
+
+ ing := &v1beta1.Ingress{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, ing)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Ingress not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Ingress's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the Ingress has been deleted.
+ r.deleteIngressFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get ingress: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this Ingress via the labelselector
+ crSelector := returnLabel(ing.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Ingress")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, ing)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteIngressFromAllCRs deletes ingress status from all the CRs when the Ingress itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the Ingress's labels, we need to look at all the CRs in this namespace
+func (r *ingressReconciler) deleteIngressFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *ingressReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, ing *v1beta1.Ingress) error {
+
+ for _, cr := range crl.Items {
+ // Ingress is not scheduled for deletion
+ if ing.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, ing)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Ingress is scheduled for deletion
+ r.deleteFromSingleCR(&cr, ing.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *ingressReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.IngressStatuses)
+ for i, rstatus := range cr.Status.IngressStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.IngressStatuses[i] = cr.Status.IngressStatuses[length-1]
+ cr.Status.IngressStatuses[length-1].Status = v1beta1.IngressStatus{}
+ cr.Status.IngressStatuses = cr.Status.IngressStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for Ingress in CR")
+ return nil
+}
+
+func (r *ingressReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, ing *v1beta1.Ingress) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.IngressStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == ing.Name {
+ ing.Status.DeepCopyInto(&cr.Status.IngressStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.IngressStatuses = append(cr.Status.IngressStatuses, v1beta1.Ingress{
+ TypeMeta: ing.TypeMeta,
+ ObjectMeta: ing.ObjectMeta,
+ Status: ing.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type ingressPredicate struct {\r
-}\r
-\r
-func (i *ingressPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (i *ingressPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (i *ingressPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (i *ingressPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type ingressPredicate struct {
+}
+
+func (i *ingressPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (i *ingressPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (i *ingressPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (i *ingressPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- v1 "k8s.io/api/batch/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddJobController the new controller to the controller manager\r
-func AddJobController(mgr manager.Manager) error {\r
- return addJobController(mgr, newJobReconciler(mgr))\r
-}\r
-\r
-func addJobController(mgr manager.Manager, r *jobReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Job-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Jobs\r
- // Predicate filters Job which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &v1.Job{}}, &handler.EnqueueRequestForObject{}, &jobPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newJobReconciler(m manager.Manager) *jobReconciler {\r
- return &jobReconciler{client: m.GetClient()}\r
-}\r
-\r
-type jobReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the jobs we watch.\r
-func (r *jobReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Job: %+v\n", req)\r
-\r
- job := &v1.Job{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, job)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Job not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Job's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the Job has been deleted.\r
- r.deleteJobFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get Job: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this Job via the labelselector\r
- crSelector := returnLabel(job.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Job")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, job)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteJobFromAllCRs deletes job status from all the CRs when the Job itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the job's labels, we need to look at all the CRs in this namespace\r
-func (r *jobReconciler) deleteJobFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *jobReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, job *v1.Job) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Job is not scheduled for deletion\r
- if job.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, job)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Job is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, job.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *jobReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.JobStatuses)\r
- for i, rstatus := range cr.Status.JobStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.JobStatuses[i] = cr.Status.JobStatuses[length-1]\r
- cr.Status.JobStatuses[length-1].Status = v1.JobStatus{}\r
- cr.Status.JobStatuses = cr.Status.JobStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for Job in CR")\r
- return nil\r
-}\r
-\r
-func (r *jobReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, job *v1.Job) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.JobStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == job.Name {\r
- job.Status.DeepCopyInto(&cr.Status.JobStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.JobStatuses = append(cr.Status.JobStatuses, v1.Job{\r
- TypeMeta: job.TypeMeta,\r
- ObjectMeta: job.ObjectMeta,\r
- Status: job.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ v1 "k8s.io/api/batch/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddJobController the new controller to the controller manager
+func AddJobController(mgr manager.Manager) error {
+ return addJobController(mgr, newJobReconciler(mgr))
+}
+
+func addJobController(mgr manager.Manager, r *jobReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Job-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Jobs
+ // Predicate filters Job which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &v1.Job{}}, &handler.EnqueueRequestForObject{}, &jobPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newJobReconciler(m manager.Manager) *jobReconciler {
+ return &jobReconciler{client: m.GetClient()}
+}
+
+type jobReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the jobs we watch.
+func (r *jobReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Job: %+v\n", req)
+
+ job := &v1.Job{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, job)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Job not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Job's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the Job has been deleted.
+ r.deleteJobFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get Job: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this Job via the labelselector
+ crSelector := returnLabel(job.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Job")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, job)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteJobFromAllCRs deletes job status from all the CRs when the Job itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the job's labels, we need to look at all the CRs in this namespace
+func (r *jobReconciler) deleteJobFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *jobReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, job *v1.Job) error {
+
+ for _, cr := range crl.Items {
+ // Job is not scheduled for deletion
+ if job.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, job)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Job is scheduled for deletion
+ r.deleteFromSingleCR(&cr, job.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *jobReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.JobStatuses)
+ for i, rstatus := range cr.Status.JobStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.JobStatuses[i] = cr.Status.JobStatuses[length-1]
+ cr.Status.JobStatuses[length-1].Status = v1.JobStatus{}
+ cr.Status.JobStatuses = cr.Status.JobStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for Job in CR")
+ return nil
+}
+
+func (r *jobReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, job *v1.Job) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.JobStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == job.Name {
+ job.Status.DeepCopyInto(&cr.Status.JobStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.JobStatuses = append(cr.Status.JobStatuses, v1.Job{
+ TypeMeta: job.TypeMeta,
+ ObjectMeta: job.ObjectMeta,
+ Status: job.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type jobPredicate struct {\r
-}\r
-\r
-func (j *jobPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (j *jobPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (j *jobPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (j *jobPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type jobPredicate struct {
+}
+
+func (j *jobPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (j *jobPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (j *jobPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (j *jobPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddPodController the new controller to the controller manager\r
-func AddPodController(mgr manager.Manager) error {\r
- return addPodController(mgr, newPodReconciler(mgr))\r
-}\r
-\r
-func addPodController(mgr manager.Manager, r *podReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Pod-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Pods\r
- // Predicate filters pods which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForObject{}, &podPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newPodReconciler(m manager.Manager) *podReconciler {\r
- return &podReconciler{client: m.GetClient()}\r
-}\r
-\r
-type podReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the pods we watch.\r
-func (r *podReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Pod: %+v\n", req)\r
-\r
- pod := &corev1.Pod{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, pod)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Pod not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Pod's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the POD has been deleted.\r
- r.deletePodFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get pod: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this pod via the labelselector\r
- crSelector := returnLabel(pod.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Pod")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, pod)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deletePodFromAllCRs deletes pod status from all the CRs when the POD itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the pod's labels, we need to look at all the CRs in this namespace\r
-func (r *podReconciler) deletePodFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *podReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, pod *corev1.Pod) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Pod is not scheduled for deletion\r
- if pod.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, pod)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Pod is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, pod.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *podReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.PodStatuses)\r
- for i, rstatus := range cr.Status.PodStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.PodStatuses[i] = cr.Status.PodStatuses[length-1]\r
- cr.Status.PodStatuses[length-1] = corev1.Pod{}\r
- cr.Status.PodStatuses = cr.Status.PodStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for POD in CR")\r
- return nil\r
-}\r
-\r
-func (r *podReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, pod *corev1.Pod) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.PodStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == pod.Name {\r
- pod.Status.DeepCopyInto(&cr.Status.PodStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.PodStatuses = append(cr.Status.PodStatuses, corev1.Pod{\r
- TypeMeta: pod.TypeMeta,\r
- ObjectMeta: pod.ObjectMeta,\r
- Status: pod.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ corev1 "k8s.io/api/core/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddPodController the new controller to the controller manager
+func AddPodController(mgr manager.Manager) error {
+ return addPodController(mgr, newPodReconciler(mgr))
+}
+
+func addPodController(mgr manager.Manager, r *podReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Pod-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Pods
+ // Predicate filters pods which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForObject{}, &podPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newPodReconciler(m manager.Manager) *podReconciler {
+ return &podReconciler{client: m.GetClient()}
+}
+
+type podReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the pods we watch.
+func (r *podReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Pod: %+v\n", req)
+
+ pod := &corev1.Pod{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, pod)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Pod not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Pod's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the POD has been deleted.
+ r.deletePodFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get pod: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this pod via the labelselector
+ crSelector := returnLabel(pod.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Pod")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, pod)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deletePodFromAllCRs deletes pod status from all the CRs when the POD itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the pod's labels, we need to look at all the CRs in this namespace
+func (r *podReconciler) deletePodFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *podReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, pod *corev1.Pod) error {
+
+ for _, cr := range crl.Items {
+ // Pod is not scheduled for deletion
+ if pod.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, pod)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Pod is scheduled for deletion
+ r.deleteFromSingleCR(&cr, pod.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *podReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.PodStatuses)
+ for i, rstatus := range cr.Status.PodStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.PodStatuses[i] = cr.Status.PodStatuses[length-1]
+ cr.Status.PodStatuses[length-1] = corev1.Pod{}
+ cr.Status.PodStatuses = cr.Status.PodStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for POD in CR")
+ return nil
+}
+
+func (r *podReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, pod *corev1.Pod) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.PodStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == pod.Name {
+ pod.Status.DeepCopyInto(&cr.Status.PodStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.PodStatuses = append(cr.Status.PodStatuses, corev1.Pod{
+ TypeMeta: pod.TypeMeta,
+ ObjectMeta: pod.ObjectMeta,
+ Status: pod.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type podPredicate struct {\r
-}\r
-\r
-func (p *podPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *podPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *podPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (p *podPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type podPredicate struct {
+}
+
+func (p *podPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *podPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *podPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (p *podPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddSecretController the new controller to the controller manager\r
-func AddSecretController(mgr manager.Manager) error {\r
- return addSecretController(mgr, newSecretReconciler(mgr))\r
-}\r
-\r
-func addSecretController(mgr manager.Manager, r *secretReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Secret-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Secret\r
- // Predicate filters Secret which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestForObject{}, &secretPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newSecretReconciler(m manager.Manager) *secretReconciler {\r
- return &secretReconciler{client: m.GetClient()}\r
-}\r
-\r
-type secretReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the Secrets we watch.\r
-func (r *secretReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Secret: %+v\n", req)\r
-\r
- sec := &corev1.Secret{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, sec)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Secret not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Secret's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the Secret has been deleted.\r
- r.deleteSecretFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get Secret: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this Secret via the labelselector\r
- crSelector := returnLabel(sec.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Secret")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, sec)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteSecretFromAllCRs deletes Secret status from all the CRs when the Secret itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the Secret's labels, we need to look at all the CRs in this namespace\r
-func (r *secretReconciler) deleteSecretFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *secretReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, sec *corev1.Secret) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Secret is not scheduled for deletion\r
- if sec.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, sec)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Secret is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, sec.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *secretReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.SecretStatuses)\r
- for i, rstatus := range cr.Status.SecretStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.SecretStatuses[i] = cr.Status.SecretStatuses[length-1]\r
- cr.Status.SecretStatuses = cr.Status.SecretStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for SecretStatuses in CR")\r
- return nil\r
-}\r
-\r
-func (r *secretReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, sec *corev1.Secret) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for _, rstatus := range cr.Status.SecretStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == sec.Name {\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.SecretStatuses = append(cr.Status.SecretStatuses, corev1.Secret{\r
- TypeMeta: sec.TypeMeta,\r
- ObjectMeta: sec.ObjectMeta,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ corev1 "k8s.io/api/core/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddSecretController the new controller to the controller manager
+func AddSecretController(mgr manager.Manager) error {
+ return addSecretController(mgr, newSecretReconciler(mgr))
+}
+
+func addSecretController(mgr manager.Manager, r *secretReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Secret-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Secret
+ // Predicate filters Secret which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestForObject{}, &secretPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newSecretReconciler(m manager.Manager) *secretReconciler {
+ return &secretReconciler{client: m.GetClient()}
+}
+
+type secretReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the Secrets we watch.
+func (r *secretReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Secret: %+v\n", req)
+
+ sec := &corev1.Secret{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, sec)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Secret not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Secret's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the Secret has been deleted.
+ r.deleteSecretFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get Secret: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this Secret via the labelselector
+ crSelector := returnLabel(sec.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Secret")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, sec)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteSecretFromAllCRs deletes Secret status from all the CRs when the Secret itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the Secret's labels, we need to look at all the CRs in this namespace
+func (r *secretReconciler) deleteSecretFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *secretReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, sec *corev1.Secret) error {
+
+ for _, cr := range crl.Items {
+ // Secret is not scheduled for deletion
+ if sec.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, sec)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Secret is scheduled for deletion
+ r.deleteFromSingleCR(&cr, sec.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *secretReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.SecretStatuses)
+ for i, rstatus := range cr.Status.SecretStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.SecretStatuses[i] = cr.Status.SecretStatuses[length-1]
+ cr.Status.SecretStatuses = cr.Status.SecretStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for SecretStatuses in CR")
+ return nil
+}
+
+func (r *secretReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, sec *corev1.Secret) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for _, rstatus := range cr.Status.SecretStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == sec.Name {
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.SecretStatuses = append(cr.Status.SecretStatuses, corev1.Secret{
+ TypeMeta: sec.TypeMeta,
+ ObjectMeta: sec.ObjectMeta,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type secretPredicate struct {\r
-}\r
-\r
-func (s *secretPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *secretPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *secretPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *secretPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type secretPredicate struct {
+}
+
+func (s *secretPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *secretPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *secretPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *secretPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddServiceController the new controller to the controller manager\r
-func AddServiceController(mgr manager.Manager) error {\r
- return addServiceController(mgr, newServiceReconciler(mgr))\r
-}\r
-\r
-func addServiceController(mgr manager.Manager, r *serviceReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Service-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource Services\r
- // Predicate filters Service which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &corev1.Service{}}, &handler.EnqueueRequestForObject{}, &servicePredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newServiceReconciler(m manager.Manager) *serviceReconciler {\r
- return &serviceReconciler{client: m.GetClient()}\r
-}\r
-\r
-type serviceReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the services we watch.\r
-func (r *serviceReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for Service: %+v\n", req)\r
-\r
- svc := &corev1.Service{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, svc)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("Service not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the Service's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the Service has been deleted.\r
- r.deleteServiceFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get service: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this service via the labelselector\r
- crSelector := returnLabel(svc.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this Service")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, svc)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteServiceFromAllCRs deletes service status from all the CRs when the Service itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the service's labels, we need to look at all the CRs in this namespace\r
-func (r *serviceReconciler) deleteServiceFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *serviceReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, svc *corev1.Service) error {\r
-\r
- for _, cr := range crl.Items {\r
- // Service is not scheduled for deletion\r
- if svc.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, svc)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // Service is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, svc.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *serviceReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.ServiceStatuses)\r
- for i, rstatus := range cr.Status.ServiceStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.ServiceStatuses[i] = cr.Status.ServiceStatuses[length-1]\r
- cr.Status.ServiceStatuses[length-1].Status = corev1.ServiceStatus{}\r
- cr.Status.ServiceStatuses = cr.Status.ServiceStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for Service in CR")\r
- return nil\r
-}\r
-\r
-func (r *serviceReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, svc *corev1.Service) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.ServiceStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == svc.Name {\r
- svc.Status.DeepCopyInto(&cr.Status.ServiceStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.ServiceStatuses = append(cr.Status.ServiceStatuses, corev1.Service{\r
- TypeMeta: svc.TypeMeta,\r
- ObjectMeta: svc.ObjectMeta,\r
- Status: svc.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ corev1 "k8s.io/api/core/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddServiceController the new controller to the controller manager
+func AddServiceController(mgr manager.Manager) error {
+ return addServiceController(mgr, newServiceReconciler(mgr))
+}
+
+func addServiceController(mgr manager.Manager, r *serviceReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Service-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource Services
+ // Predicate filters Service which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &corev1.Service{}}, &handler.EnqueueRequestForObject{}, &servicePredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newServiceReconciler(m manager.Manager) *serviceReconciler {
+ return &serviceReconciler{client: m.GetClient()}
+}
+
+type serviceReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the services we watch.
+func (r *serviceReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for Service: %+v\n", req)
+
+ svc := &corev1.Service{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, svc)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("Service not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the Service's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the Service has been deleted.
+ r.deleteServiceFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get service: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this service via the labelselector
+ crSelector := returnLabel(svc.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this Service")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, svc)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteServiceFromAllCRs deletes service status from all the CRs when the Service itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the service's labels, we need to look at all the CRs in this namespace
+func (r *serviceReconciler) deleteServiceFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *serviceReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, svc *corev1.Service) error {
+
+ for _, cr := range crl.Items {
+ // Service is not scheduled for deletion
+ if svc.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, svc)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Service is scheduled for deletion
+ r.deleteFromSingleCR(&cr, svc.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *serviceReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.ServiceStatuses)
+ for i, rstatus := range cr.Status.ServiceStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.ServiceStatuses[i] = cr.Status.ServiceStatuses[length-1]
+ cr.Status.ServiceStatuses[length-1].Status = corev1.ServiceStatus{}
+ cr.Status.ServiceStatuses = cr.Status.ServiceStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for Service in CR")
+ return nil
+}
+
+func (r *serviceReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, svc *corev1.Service) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.ServiceStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == svc.Name {
+ svc.Status.DeepCopyInto(&cr.Status.ServiceStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.ServiceStatuses = append(cr.Status.ServiceStatuses, corev1.Service{
+ TypeMeta: svc.TypeMeta,
+ ObjectMeta: svc.ObjectMeta,
+ Status: svc.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type servicePredicate struct {\r
-}\r
-\r
-func (s *servicePredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *servicePredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *servicePredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *servicePredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type servicePredicate struct {
+}
+
+func (s *servicePredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *servicePredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *servicePredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *servicePredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-package resourcebundlestate\r
-\r
-import (\r
- "context"\r
- "log"\r
-\r
- "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- appsv1 "k8s.io/api/apps/v1"\r
- k8serrors "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/types"\r
- "sigs.k8s.io/controller-runtime/pkg/client"\r
- "sigs.k8s.io/controller-runtime/pkg/controller"\r
- "sigs.k8s.io/controller-runtime/pkg/handler"\r
- "sigs.k8s.io/controller-runtime/pkg/manager"\r
- "sigs.k8s.io/controller-runtime/pkg/reconcile"\r
- "sigs.k8s.io/controller-runtime/pkg/source"\r
-)\r
-\r
-// AddStatefulSetController the new controller to the controller manager\r
-func AddStatefulSetController(mgr manager.Manager) error {\r
- return addStatefulSetController(mgr, newStatefulSetReconciler(mgr))\r
-}\r
-\r
-func addStatefulSetController(mgr manager.Manager, r *statefulSetReconciler) error {\r
- // Create a new controller\r
- c, err := controller.New("Statefulset-controller", mgr, controller.Options{Reconciler: r})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // Watch for changes to secondar resource StatefulSets\r
- // Predicate filters StatefulSet which don't have the k8splugin label\r
- err = c.Watch(&source.Kind{Type: &appsv1.StatefulSet{}}, &handler.EnqueueRequestForObject{}, &statefulSetPredicate{})\r
- if err != nil {\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func newStatefulSetReconciler(m manager.Manager) *statefulSetReconciler {\r
- return &statefulSetReconciler{client: m.GetClient()}\r
-}\r
-\r
-type statefulSetReconciler struct {\r
- client client.Client\r
-}\r
-\r
-// Reconcile implements the loop that will update the ResourceBundleState CR\r
-// whenever we get any updates from all the StatefulSets we watch.\r
-func (r *statefulSetReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {\r
- log.Printf("Updating ResourceBundleState for StatefulSet: %+v\n", req)\r
-\r
- sfs := &appsv1.StatefulSet{}\r
- err := r.client.Get(context.TODO(), req.NamespacedName, sfs)\r
- if err != nil {\r
- if k8serrors.IsNotFound(err) {\r
- log.Printf("StatefulSet not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)\r
- // Remove the StatefulSet's status from StatusList\r
- // This can happen if we get the DeletionTimeStamp event\r
- // after the StatefulSet has been deleted.\r
- r.deleteStatefulSetFromAllCRs(req.NamespacedName)\r
- return reconcile.Result{}, nil\r
- }\r
- log.Printf("Failed to get statefulSet: %+v\n", req.NamespacedName)\r
- return reconcile.Result{}, err\r
- }\r
-\r
- // Find the CRs which track this statefulSet via the labelselector\r
- crSelector := returnLabel(sfs.GetLabels())\r
- if crSelector == nil {\r
- log.Println("We should not be here. The predicate should have filtered this StatefulSet")\r
- }\r
-\r
- // Get the CRs which have this label and update them all\r
- // Ideally, we will have only one CR, but there is nothing\r
- // preventing the creation of multiple.\r
- // TODO: Consider using an admission validating webook to prevent multiple\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err = listResources(r.client, req.Namespace, crSelector, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return reconcile.Result{}, nil\r
- }\r
-\r
- err = r.updateCRs(rbStatusList, sfs)\r
- if err != nil {\r
- // Requeue the update\r
- return reconcile.Result{}, err\r
- }\r
-\r
- return reconcile.Result{}, nil\r
-}\r
-\r
-// deleteStatefulSetFromAllCRs deletes statefulSet status from all the CRs when the StatefulSet itself has been deleted\r
-// and we have not handled the updateCRs yet.\r
-// Since, we don't have the statefulSet's labels, we need to look at all the CRs in this namespace\r
-func (r *statefulSetReconciler) deleteStatefulSetFromAllCRs(namespacedName types.NamespacedName) error {\r
-\r
- rbStatusList := &v1alpha1.ResourceBundleStateList{}\r
- err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)\r
- if err != nil || len(rbStatusList.Items) == 0 {\r
- log.Printf("Did not find any CRs tracking this resource\n")\r
- return nil\r
- }\r
- for _, cr := range rbStatusList.Items {\r
- r.deleteFromSingleCR(&cr, namespacedName.Name)\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *statefulSetReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, sfs *appsv1.StatefulSet) error {\r
-\r
- for _, cr := range crl.Items {\r
- // StatefulSet is not scheduled for deletion\r
- if sfs.DeletionTimestamp == nil {\r
- err := r.updateSingleCR(&cr, sfs)\r
- if err != nil {\r
- return err\r
- }\r
- } else {\r
- // StatefulSet is scheduled for deletion\r
- r.deleteFromSingleCR(&cr, sfs.Name)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (r *statefulSetReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {\r
- cr.Status.ResourceCount--\r
- length := len(cr.Status.StatefulSetStatuses)\r
- for i, rstatus := range cr.Status.StatefulSetStatuses {\r
- if rstatus.Name == name {\r
- //Delete that status from the array\r
- cr.Status.StatefulSetStatuses[i] = cr.Status.StatefulSetStatuses[length-1]\r
- cr.Status.StatefulSetStatuses[length-1].Status = appsv1.StatefulSetStatus{}\r
- cr.Status.StatefulSetStatuses = cr.Status.StatefulSetStatuses[:length-1]\r
- return nil\r
- }\r
- }\r
-\r
- log.Println("Did not find a status for StatefulSet in CR")\r
- return nil\r
-}\r
-\r
-func (r *statefulSetReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, sfs *appsv1.StatefulSet) error {\r
-\r
- // Update status after searching for it in the list of resourceStatuses\r
- for i, rstatus := range cr.Status.StatefulSetStatuses {\r
- // Look for the status if we already have it in the CR\r
- if rstatus.Name == sfs.Name {\r
- sfs.Status.DeepCopyInto(&cr.Status.StatefulSetStatuses[i].Status)\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
- return nil\r
- }\r
- }\r
-\r
- // Exited for loop with no status found\r
- // Increment the number of tracked resources\r
- cr.Status.ResourceCount++\r
-\r
- // Add it to CR\r
- cr.Status.StatefulSetStatuses = append(cr.Status.StatefulSetStatuses, appsv1.StatefulSet{\r
- TypeMeta: sfs.TypeMeta,\r
- ObjectMeta: sfs.ObjectMeta,\r
- Status: sfs.Status,\r
- })\r
-\r
- err := r.client.Status().Update(context.TODO(), cr)\r
- if err != nil {\r
- log.Printf("failed to update rbstate: %v\n", err)\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
+package resourcebundlestate
+
+import (
+ "context"
+ "log"
+
+ "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ appsv1 "k8s.io/api/apps/v1"
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+)
+
+// AddStatefulSetController the new controller to the controller manager
+func AddStatefulSetController(mgr manager.Manager) error {
+ return addStatefulSetController(mgr, newStatefulSetReconciler(mgr))
+}
+
+func addStatefulSetController(mgr manager.Manager, r *statefulSetReconciler) error {
+ // Create a new controller
+ c, err := controller.New("Statefulset-controller", mgr, controller.Options{Reconciler: r})
+ if err != nil {
+ return err
+ }
+
+ // Watch for changes to secondar resource StatefulSets
+ // Predicate filters StatefulSet which don't have the k8splugin label
+ err = c.Watch(&source.Kind{Type: &appsv1.StatefulSet{}}, &handler.EnqueueRequestForObject{}, &statefulSetPredicate{})
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func newStatefulSetReconciler(m manager.Manager) *statefulSetReconciler {
+ return &statefulSetReconciler{client: m.GetClient()}
+}
+
+type statefulSetReconciler struct {
+ client client.Client
+}
+
+// Reconcile implements the loop that will update the ResourceBundleState CR
+// whenever we get any updates from all the StatefulSets we watch.
+func (r *statefulSetReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {
+ log.Printf("Updating ResourceBundleState for StatefulSet: %+v\n", req)
+
+ sfs := &appsv1.StatefulSet{}
+ err := r.client.Get(context.TODO(), req.NamespacedName, sfs)
+ if err != nil {
+ if k8serrors.IsNotFound(err) {
+ log.Printf("StatefulSet not found: %+v. Remove from CR if it is stored there.\n", req.NamespacedName)
+ // Remove the StatefulSet's status from StatusList
+ // This can happen if we get the DeletionTimeStamp event
+ // after the StatefulSet has been deleted.
+ r.deleteStatefulSetFromAllCRs(req.NamespacedName)
+ return reconcile.Result{}, nil
+ }
+ log.Printf("Failed to get statefulSet: %+v\n", req.NamespacedName)
+ return reconcile.Result{}, err
+ }
+
+ // Find the CRs which track this statefulSet via the labelselector
+ crSelector := returnLabel(sfs.GetLabels())
+ if crSelector == nil {
+ log.Println("We should not be here. The predicate should have filtered this StatefulSet")
+ }
+
+ // Get the CRs which have this label and update them all
+ // Ideally, we will have only one CR, but there is nothing
+ // preventing the creation of multiple.
+ // TODO: Consider using an admission validating webook to prevent multiple
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err = listResources(r.client, req.Namespace, crSelector, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return reconcile.Result{}, nil
+ }
+
+ err = r.updateCRs(rbStatusList, sfs)
+ if err != nil {
+ // Requeue the update
+ return reconcile.Result{}, err
+ }
+
+ return reconcile.Result{}, nil
+}
+
+// deleteStatefulSetFromAllCRs deletes statefulSet status from all the CRs when the StatefulSet itself has been deleted
+// and we have not handled the updateCRs yet.
+// Since, we don't have the statefulSet's labels, we need to look at all the CRs in this namespace
+func (r *statefulSetReconciler) deleteStatefulSetFromAllCRs(namespacedName types.NamespacedName) error {
+
+ rbStatusList := &v1alpha1.ResourceBundleStateList{}
+ err := listResources(r.client, namespacedName.Namespace, nil, rbStatusList)
+ if err != nil || len(rbStatusList.Items) == 0 {
+ log.Printf("Did not find any CRs tracking this resource\n")
+ return nil
+ }
+ for _, cr := range rbStatusList.Items {
+ r.deleteFromSingleCR(&cr, namespacedName.Name)
+ }
+
+ return nil
+}
+
+func (r *statefulSetReconciler) updateCRs(crl *v1alpha1.ResourceBundleStateList, sfs *appsv1.StatefulSet) error {
+
+ for _, cr := range crl.Items {
+ // StatefulSet is not scheduled for deletion
+ if sfs.DeletionTimestamp == nil {
+ err := r.updateSingleCR(&cr, sfs)
+ if err != nil {
+ return err
+ }
+ } else {
+ // StatefulSet is scheduled for deletion
+ r.deleteFromSingleCR(&cr, sfs.Name)
+ }
+ }
+
+ return nil
+}
+
+func (r *statefulSetReconciler) deleteFromSingleCR(cr *v1alpha1.ResourceBundleState, name string) error {
+ cr.Status.ResourceCount--
+ length := len(cr.Status.StatefulSetStatuses)
+ for i, rstatus := range cr.Status.StatefulSetStatuses {
+ if rstatus.Name == name {
+ //Delete that status from the array
+ cr.Status.StatefulSetStatuses[i] = cr.Status.StatefulSetStatuses[length-1]
+ cr.Status.StatefulSetStatuses[length-1].Status = appsv1.StatefulSetStatus{}
+ cr.Status.StatefulSetStatuses = cr.Status.StatefulSetStatuses[:length-1]
+ return nil
+ }
+ }
+
+ log.Println("Did not find a status for StatefulSet in CR")
+ return nil
+}
+
+func (r *statefulSetReconciler) updateSingleCR(cr *v1alpha1.ResourceBundleState, sfs *appsv1.StatefulSet) error {
+
+ // Update status after searching for it in the list of resourceStatuses
+ for i, rstatus := range cr.Status.StatefulSetStatuses {
+ // Look for the status if we already have it in the CR
+ if rstatus.Name == sfs.Name {
+ sfs.Status.DeepCopyInto(&cr.Status.StatefulSetStatuses[i].Status)
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Exited for loop with no status found
+ // Increment the number of tracked resources
+ cr.Status.ResourceCount++
+
+ // Add it to CR
+ cr.Status.StatefulSetStatuses = append(cr.Status.StatefulSetStatuses, appsv1.StatefulSet{
+ TypeMeta: sfs.TypeMeta,
+ ObjectMeta: sfs.ObjectMeta,
+ Status: sfs.Status,
+ })
+
+ err := r.client.Status().Update(context.TODO(), cr)
+ if err != nil {
+ log.Printf("failed to update rbstate: %v\n", err)
+ return err
+ }
+
+ return nil
+}
-package resourcebundlestate\r
-\r
-import (\r
- "sigs.k8s.io/controller-runtime/pkg/event"\r
-)\r
-\r
-type statefulSetPredicate struct {\r
-}\r
-\r
-func (s *statefulSetPredicate) Create(evt event.CreateEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *statefulSetPredicate) Delete(evt event.DeleteEvent) bool {\r
-\r
- if evt.Meta == nil {\r
- return false\r
- }\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *statefulSetPredicate) Update(evt event.UpdateEvent) bool {\r
-\r
- if evt.MetaNew == nil {\r
- return false\r
- }\r
-\r
- labels := evt.MetaNew.GetLabels()\r
- return checkLabel(labels)\r
-}\r
-\r
-func (s *statefulSetPredicate) Generic(evt event.GenericEvent) bool {\r
-\r
- labels := evt.Meta.GetLabels()\r
- return checkLabel(labels)\r
-}\r
+package resourcebundlestate
+
+import (
+ "sigs.k8s.io/controller-runtime/pkg/event"
+)
+
+type statefulSetPredicate struct {
+}
+
+func (s *statefulSetPredicate) Create(evt event.CreateEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *statefulSetPredicate) Delete(evt event.DeleteEvent) bool {
+
+ if evt.Meta == nil {
+ return false
+ }
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *statefulSetPredicate) Update(evt event.UpdateEvent) bool {
+
+ if evt.MetaNew == nil {
+ return false
+ }
+
+ labels := evt.MetaNew.GetLabels()
+ return checkLabel(labels)
+}
+
+func (s *statefulSetPredicate) Generic(evt event.GenericEvent) bool {
+
+ labels := evt.Meta.GetLabels()
+ return checkLabel(labels)
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package versioned\r
-\r
-import (\r
- "fmt"\r
- k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"\r
-\r
- discovery "k8s.io/client-go/discovery"\r
- rest "k8s.io/client-go/rest"\r
- flowcontrol "k8s.io/client-go/util/flowcontrol"\r
-)\r
-\r
-type Interface interface {\r
- Discovery() discovery.DiscoveryInterface\r
- K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface\r
-}\r
-\r
-// Clientset contains the clients for groups. Each group has exactly one\r
-// version included in a Clientset.\r
-type Clientset struct {\r
- *discovery.DiscoveryClient\r
- k8spluginV1alpha1 *k8spluginv1alpha1.K8spluginV1alpha1Client\r
-}\r
-\r
-// K8spluginV1alpha1 retrieves the K8spluginV1alpha1Client\r
-func (c *Clientset) K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface {\r
- return c.k8spluginV1alpha1\r
-}\r
-\r
-// Discovery retrieves the DiscoveryClient\r
-func (c *Clientset) Discovery() discovery.DiscoveryInterface {\r
- if c == nil {\r
- return nil\r
- }\r
- return c.DiscoveryClient\r
-}\r
-\r
-// NewForConfig creates a new Clientset for the given config.\r
-// If config's RateLimiter is not set and QPS and Burst are acceptable,\r
-// NewForConfig will generate a rate-limiter in configShallowCopy.\r
-func NewForConfig(c *rest.Config) (*Clientset, error) {\r
- configShallowCopy := *c\r
- if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {\r
- if configShallowCopy.Burst <= 0 {\r
- return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")\r
- }\r
- configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)\r
- }\r
- var cs Clientset\r
- var err error\r
- cs.k8spluginV1alpha1, err = k8spluginv1alpha1.NewForConfig(&configShallowCopy)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return &cs, nil\r
-}\r
-\r
-// NewForConfigOrDie creates a new Clientset for the given config and\r
-// panics if there is an error in the config.\r
-func NewForConfigOrDie(c *rest.Config) *Clientset {\r
- var cs Clientset\r
- cs.k8spluginV1alpha1 = k8spluginv1alpha1.NewForConfigOrDie(c)\r
-\r
- cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)\r
- return &cs\r
-}\r
-\r
-// New creates a new Clientset for the given RESTClient.\r
-func New(c rest.Interface) *Clientset {\r
- var cs Clientset\r
- cs.k8spluginV1alpha1 = k8spluginv1alpha1.New(c)\r
-\r
- cs.DiscoveryClient = discovery.NewDiscoveryClient(c)\r
- return &cs\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package versioned
+
+import (
+ "fmt"
+ k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"
+
+ discovery "k8s.io/client-go/discovery"
+ rest "k8s.io/client-go/rest"
+ flowcontrol "k8s.io/client-go/util/flowcontrol"
+)
+
+type Interface interface {
+ Discovery() discovery.DiscoveryInterface
+ K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface
+}
+
+// Clientset contains the clients for groups. Each group has exactly one
+// version included in a Clientset.
+type Clientset struct {
+ *discovery.DiscoveryClient
+ k8spluginV1alpha1 *k8spluginv1alpha1.K8spluginV1alpha1Client
+}
+
+// K8spluginV1alpha1 retrieves the K8spluginV1alpha1Client
+func (c *Clientset) K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface {
+ return c.k8spluginV1alpha1
+}
+
+// Discovery retrieves the DiscoveryClient
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+ if c == nil {
+ return nil
+ }
+ return c.DiscoveryClient
+}
+
+// NewForConfig creates a new Clientset for the given config.
+// If config's RateLimiter is not set and QPS and Burst are acceptable,
+// NewForConfig will generate a rate-limiter in configShallowCopy.
+func NewForConfig(c *rest.Config) (*Clientset, error) {
+ configShallowCopy := *c
+ if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
+ if configShallowCopy.Burst <= 0 {
+ return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
+ }
+ configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
+ }
+ var cs Clientset
+ var err error
+ cs.k8spluginV1alpha1, err = k8spluginv1alpha1.NewForConfig(&configShallowCopy)
+ if err != nil {
+ return nil, err
+ }
+
+ cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
+ if err != nil {
+ return nil, err
+ }
+ return &cs, nil
+}
+
+// NewForConfigOrDie creates a new Clientset for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *Clientset {
+ var cs Clientset
+ cs.k8spluginV1alpha1 = k8spluginv1alpha1.NewForConfigOrDie(c)
+
+ cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
+ return &cs
+}
+
+// New creates a new Clientset for the given RESTClient.
+func New(c rest.Interface) *Clientset {
+ var cs Clientset
+ cs.k8spluginV1alpha1 = k8spluginv1alpha1.New(c)
+
+ cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
+ return &cs
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-// This package has the automatically generated clientset.\r
-package versioned\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated clientset.
+package versioned
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package fake\r
-\r
-import (\r
- clientset "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"\r
- k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"\r
- fakek8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1/fake"\r
-\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/apimachinery/pkg/watch"\r
- "k8s.io/client-go/discovery"\r
- fakediscovery "k8s.io/client-go/discovery/fake"\r
- "k8s.io/client-go/testing"\r
-)\r
-\r
-// NewSimpleClientset returns a clientset that will respond with the provided objects.\r
-// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,\r
-// without applying any validations and/or defaults. It shouldn't be considered a replacement\r
-// for a real clientset and is mostly useful in simple unit tests.\r
-func NewSimpleClientset(objects ...runtime.Object) *Clientset {\r
- o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())\r
- for _, obj := range objects {\r
- if err := o.Add(obj); err != nil {\r
- panic(err)\r
- }\r
- }\r
-\r
- cs := &Clientset{tracker: o}\r
- cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}\r
- cs.AddReactor("*", "*", testing.ObjectReaction(o))\r
- cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {\r
- gvr := action.GetResource()\r
- ns := action.GetNamespace()\r
- watch, err := o.Watch(gvr, ns)\r
- if err != nil {\r
- return false, nil, err\r
- }\r
- return true, watch, nil\r
- })\r
-\r
- return cs\r
-}\r
-\r
-// Clientset implements clientset.Interface. Meant to be embedded into a\r
-// struct to get a default implementation. This makes faking out just the method\r
-// you want to test easier.\r
-type Clientset struct {\r
- testing.Fake\r
- discovery *fakediscovery.FakeDiscovery\r
- tracker testing.ObjectTracker\r
-}\r
-\r
-func (c *Clientset) Discovery() discovery.DiscoveryInterface {\r
- return c.discovery\r
-}\r
-\r
-func (c *Clientset) Tracker() testing.ObjectTracker {\r
- return c.tracker\r
-}\r
-\r
-var _ clientset.Interface = &Clientset{}\r
-\r
-// K8spluginV1alpha1 retrieves the K8spluginV1alpha1Client\r
-func (c *Clientset) K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface {\r
- return &fakek8spluginv1alpha1.FakeK8spluginV1alpha1{Fake: &c.Fake}\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ clientset "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"
+ k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"
+ fakek8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1/fake"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/watch"
+ "k8s.io/client-go/discovery"
+ fakediscovery "k8s.io/client-go/discovery/fake"
+ "k8s.io/client-go/testing"
+)
+
+// NewSimpleClientset returns a clientset that will respond with the provided objects.
+// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
+// without applying any validations and/or defaults. It shouldn't be considered a replacement
+// for a real clientset and is mostly useful in simple unit tests.
+func NewSimpleClientset(objects ...runtime.Object) *Clientset {
+ o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
+ for _, obj := range objects {
+ if err := o.Add(obj); err != nil {
+ panic(err)
+ }
+ }
+
+ cs := &Clientset{tracker: o}
+ cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
+ cs.AddReactor("*", "*", testing.ObjectReaction(o))
+ cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
+ gvr := action.GetResource()
+ ns := action.GetNamespace()
+ watch, err := o.Watch(gvr, ns)
+ if err != nil {
+ return false, nil, err
+ }
+ return true, watch, nil
+ })
+
+ return cs
+}
+
+// Clientset implements clientset.Interface. Meant to be embedded into a
+// struct to get a default implementation. This makes faking out just the method
+// you want to test easier.
+type Clientset struct {
+ testing.Fake
+ discovery *fakediscovery.FakeDiscovery
+ tracker testing.ObjectTracker
+}
+
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+ return c.discovery
+}
+
+func (c *Clientset) Tracker() testing.ObjectTracker {
+ return c.tracker
+}
+
+var _ clientset.Interface = &Clientset{}
+
+// K8spluginV1alpha1 retrieves the K8spluginV1alpha1Client
+func (c *Clientset) K8spluginV1alpha1() k8spluginv1alpha1.K8spluginV1alpha1Interface {
+ return &fakek8spluginv1alpha1.FakeK8spluginV1alpha1{Fake: &c.Fake}
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-// This package has the automatically generated fake clientset.\r
-package fake\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated fake clientset.
+package fake
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package fake\r
-\r
-import (\r
- k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
- schema "k8s.io/apimachinery/pkg/runtime/schema"\r
- serializer "k8s.io/apimachinery/pkg/runtime/serializer"\r
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"\r
-)\r
-\r
-var scheme = runtime.NewScheme()\r
-var codecs = serializer.NewCodecFactory(scheme)\r
-var parameterCodec = runtime.NewParameterCodec(scheme)\r
-var localSchemeBuilder = runtime.SchemeBuilder{\r
- k8spluginv1alpha1.AddToScheme,\r
-}\r
-\r
-// AddToScheme adds all types of this clientset into the given scheme. This allows composition\r
-// of clientsets, like in:\r
-//\r
-// import (\r
-// "k8s.io/client-go/kubernetes"\r
-// clientsetscheme "k8s.io/client-go/kubernetes/scheme"\r
-// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"\r
-// )\r
-//\r
-// kclientset, _ := kubernetes.NewForConfig(c)\r
-// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)\r
-//\r
-// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types\r
-// correctly.\r
-var AddToScheme = localSchemeBuilder.AddToScheme\r
-\r
-func init() {\r
- v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})\r
- utilruntime.Must(AddToScheme(scheme))\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+var scheme = runtime.NewScheme()
+var codecs = serializer.NewCodecFactory(scheme)
+var parameterCodec = runtime.NewParameterCodec(scheme)
+var localSchemeBuilder = runtime.SchemeBuilder{
+ k8spluginv1alpha1.AddToScheme,
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+// import (
+// "k8s.io/client-go/kubernetes"
+// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
+// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+// )
+//
+// kclientset, _ := kubernetes.NewForConfig(c)
+// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+var AddToScheme = localSchemeBuilder.AddToScheme
+
+func init() {
+ v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
+ utilruntime.Must(AddToScheme(scheme))
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-// This package contains the scheme of the automatically generated clientset.\r
-package scheme\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package contains the scheme of the automatically generated clientset.
+package scheme
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package scheme\r
-\r
-import (\r
- k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
- schema "k8s.io/apimachinery/pkg/runtime/schema"\r
- serializer "k8s.io/apimachinery/pkg/runtime/serializer"\r
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"\r
-)\r
-\r
-var Scheme = runtime.NewScheme()\r
-var Codecs = serializer.NewCodecFactory(Scheme)\r
-var ParameterCodec = runtime.NewParameterCodec(Scheme)\r
-var localSchemeBuilder = runtime.SchemeBuilder{\r
- k8spluginv1alpha1.AddToScheme,\r
-}\r
-\r
-// AddToScheme adds all types of this clientset into the given scheme. This allows composition\r
-// of clientsets, like in:\r
-//\r
-// import (\r
-// "k8s.io/client-go/kubernetes"\r
-// clientsetscheme "k8s.io/client-go/kubernetes/scheme"\r
-// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"\r
-// )\r
-//\r
-// kclientset, _ := kubernetes.NewForConfig(c)\r
-// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)\r
-//\r
-// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types\r
-// correctly.\r
-var AddToScheme = localSchemeBuilder.AddToScheme\r
-\r
-func init() {\r
- v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})\r
- utilruntime.Must(AddToScheme(Scheme))\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package scheme
+
+import (
+ k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+var Scheme = runtime.NewScheme()
+var Codecs = serializer.NewCodecFactory(Scheme)
+var ParameterCodec = runtime.NewParameterCodec(Scheme)
+var localSchemeBuilder = runtime.SchemeBuilder{
+ k8spluginv1alpha1.AddToScheme,
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+// import (
+// "k8s.io/client-go/kubernetes"
+// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
+// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+// )
+//
+// kclientset, _ := kubernetes.NewForConfig(c)
+// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+var AddToScheme = localSchemeBuilder.AddToScheme
+
+func init() {
+ v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
+ utilruntime.Must(AddToScheme(Scheme))
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-// This package has the automatically generated typed clients.\r
-package v1alpha1\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated typed clients.
+package v1alpha1
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-// Package fake has the automatically generated clients.\r
-package fake\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+// Package fake has the automatically generated clients.
+package fake
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package fake\r
-\r
-import (\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"\r
-\r
- rest "k8s.io/client-go/rest"\r
- testing "k8s.io/client-go/testing"\r
-)\r
-\r
-type FakeK8spluginV1alpha1 struct {\r
- *testing.Fake\r
-}\r
-\r
-func (c *FakeK8spluginV1alpha1) ResourceBundleStates(namespace string) v1alpha1.ResourceBundleStateInterface {\r
- return &FakeResourceBundleStates{c, namespace}\r
-}\r
-\r
-// RESTClient returns a RESTClient that is used to communicate\r
-// with API server by this client implementation.\r
-func (c *FakeK8spluginV1alpha1) RESTClient() rest.Interface {\r
- var ret *rest.RESTClient\r
- return ret\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/typed/k8splugin/v1alpha1"
+
+ rest "k8s.io/client-go/rest"
+ testing "k8s.io/client-go/testing"
+)
+
+type FakeK8spluginV1alpha1 struct {
+ *testing.Fake
+}
+
+func (c *FakeK8spluginV1alpha1) ResourceBundleStates(namespace string) v1alpha1.ResourceBundleStateInterface {
+ return &FakeResourceBundleStates{c, namespace}
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *FakeK8spluginV1alpha1) RESTClient() rest.Interface {
+ var ret *rest.RESTClient
+ return ret
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package fake\r
-\r
-import (\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- labels "k8s.io/apimachinery/pkg/labels"\r
- schema "k8s.io/apimachinery/pkg/runtime/schema"\r
- types "k8s.io/apimachinery/pkg/types"\r
- watch "k8s.io/apimachinery/pkg/watch"\r
- testing "k8s.io/client-go/testing"\r
-)\r
-\r
-// FakeResourceBundleStates implements ResourceBundleStateInterface\r
-type FakeResourceBundleStates struct {\r
- Fake *FakeK8spluginV1alpha1\r
- ns string\r
-}\r
-\r
-var resourcebundlestatesResource = schema.GroupVersionResource{Group: "k8splugin.io", Version: "v1alpha1", Resource: "resourcebundlestates"}\r
-\r
-var resourcebundlestatesKind = schema.GroupVersionKind{Group: "k8splugin.io", Version: "v1alpha1", Kind: "ResourceBundleState"}\r
-\r
-// Get takes name of the resourceBundleState, and returns the corresponding resourceBundleState object, and an error if there is any.\r
-func (c *FakeResourceBundleStates) Get(name string, options v1.GetOptions) (result *v1alpha1.ResourceBundleState, err error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewGetAction(resourcebundlestatesResource, c.ns, name), &v1alpha1.ResourceBundleState{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), err\r
-}\r
-\r
-// List takes label and field selectors, and returns the list of ResourceBundleStates that match those selectors.\r
-func (c *FakeResourceBundleStates) List(opts v1.ListOptions) (result *v1alpha1.ResourceBundleStateList, err error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewListAction(resourcebundlestatesResource, resourcebundlestatesKind, c.ns, opts), &v1alpha1.ResourceBundleStateList{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
-\r
- label, _, _ := testing.ExtractFromListOptions(opts)\r
- if label == nil {\r
- label = labels.Everything()\r
- }\r
- list := &v1alpha1.ResourceBundleStateList{ListMeta: obj.(*v1alpha1.ResourceBundleStateList).ListMeta}\r
- for _, item := range obj.(*v1alpha1.ResourceBundleStateList).Items {\r
- if label.Matches(labels.Set(item.Labels)) {\r
- list.Items = append(list.Items, item)\r
- }\r
- }\r
- return list, err\r
-}\r
-\r
-// Watch returns a watch.Interface that watches the requested resourceBundleStates.\r
-func (c *FakeResourceBundleStates) Watch(opts v1.ListOptions) (watch.Interface, error) {\r
- return c.Fake.\r
- InvokesWatch(testing.NewWatchAction(resourcebundlestatesResource, c.ns, opts))\r
-\r
-}\r
-\r
-// Create takes the representation of a resourceBundleState and creates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.\r
-func (c *FakeResourceBundleStates) Create(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewCreateAction(resourcebundlestatesResource, c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), err\r
-}\r
-\r
-// Update takes the representation of a resourceBundleState and updates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.\r
-func (c *FakeResourceBundleStates) Update(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewUpdateAction(resourcebundlestatesResource, c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), err\r
-}\r
-\r
-// UpdateStatus was generated because the type contains a Status member.\r
-// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().\r
-func (c *FakeResourceBundleStates) UpdateStatus(resourceBundleState *v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewUpdateSubresourceAction(resourcebundlestatesResource, "status", c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), err\r
-}\r
-\r
-// Delete takes name of the resourceBundleState and deletes it. Returns an error if one occurs.\r
-func (c *FakeResourceBundleStates) Delete(name string, options *v1.DeleteOptions) error {\r
- _, err := c.Fake.\r
- Invokes(testing.NewDeleteAction(resourcebundlestatesResource, c.ns, name), &v1alpha1.ResourceBundleState{})\r
-\r
- return err\r
-}\r
-\r
-// DeleteCollection deletes a collection of objects.\r
-func (c *FakeResourceBundleStates) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {\r
- action := testing.NewDeleteCollectionAction(resourcebundlestatesResource, c.ns, listOptions)\r
-\r
- _, err := c.Fake.Invokes(action, &v1alpha1.ResourceBundleStateList{})\r
- return err\r
-}\r
-\r
-// Patch applies the patch and returns the patched resourceBundleState.\r
-func (c *FakeResourceBundleStates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error) {\r
- obj, err := c.Fake.\r
- Invokes(testing.NewPatchSubresourceAction(resourcebundlestatesResource, c.ns, name, pt, data, subresources...), &v1alpha1.ResourceBundleState{})\r
-\r
- if obj == nil {\r
- return nil, err\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ testing "k8s.io/client-go/testing"
+)
+
+// FakeResourceBundleStates implements ResourceBundleStateInterface
+type FakeResourceBundleStates struct {
+ Fake *FakeK8spluginV1alpha1
+ ns string
+}
+
+var resourcebundlestatesResource = schema.GroupVersionResource{Group: "k8splugin.io", Version: "v1alpha1", Resource: "resourcebundlestates"}
+
+var resourcebundlestatesKind = schema.GroupVersionKind{Group: "k8splugin.io", Version: "v1alpha1", Kind: "ResourceBundleState"}
+
+// Get takes name of the resourceBundleState, and returns the corresponding resourceBundleState object, and an error if there is any.
+func (c *FakeResourceBundleStates) Get(name string, options v1.GetOptions) (result *v1alpha1.ResourceBundleState, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewGetAction(resourcebundlestatesResource, c.ns, name), &v1alpha1.ResourceBundleState{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.ResourceBundleState), err
+}
+
+// List takes label and field selectors, and returns the list of ResourceBundleStates that match those selectors.
+func (c *FakeResourceBundleStates) List(opts v1.ListOptions) (result *v1alpha1.ResourceBundleStateList, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewListAction(resourcebundlestatesResource, resourcebundlestatesKind, c.ns, opts), &v1alpha1.ResourceBundleStateList{})
+
+ if obj == nil {
+ return nil, err
+ }
+
+ label, _, _ := testing.ExtractFromListOptions(opts)
+ if label == nil {
+ label = labels.Everything()
+ }
+ list := &v1alpha1.ResourceBundleStateList{ListMeta: obj.(*v1alpha1.ResourceBundleStateList).ListMeta}
+ for _, item := range obj.(*v1alpha1.ResourceBundleStateList).Items {
+ if label.Matches(labels.Set(item.Labels)) {
+ list.Items = append(list.Items, item)
+ }
+ }
+ return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested resourceBundleStates.
+func (c *FakeResourceBundleStates) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ return c.Fake.
+ InvokesWatch(testing.NewWatchAction(resourcebundlestatesResource, c.ns, opts))
+
+}
+
+// Create takes the representation of a resourceBundleState and creates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.
+func (c *FakeResourceBundleStates) Create(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewCreateAction(resourcebundlestatesResource, c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.ResourceBundleState), err
+}
+
+// Update takes the representation of a resourceBundleState and updates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.
+func (c *FakeResourceBundleStates) Update(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateAction(resourcebundlestatesResource, c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.ResourceBundleState), err
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *FakeResourceBundleStates) UpdateStatus(resourceBundleState *v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateSubresourceAction(resourcebundlestatesResource, "status", c.ns, resourceBundleState), &v1alpha1.ResourceBundleState{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.ResourceBundleState), err
+}
+
+// Delete takes name of the resourceBundleState and deletes it. Returns an error if one occurs.
+func (c *FakeResourceBundleStates) Delete(name string, options *v1.DeleteOptions) error {
+ _, err := c.Fake.
+ Invokes(testing.NewDeleteAction(resourcebundlestatesResource, c.ns, name), &v1alpha1.ResourceBundleState{})
+
+ return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeResourceBundleStates) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ action := testing.NewDeleteCollectionAction(resourcebundlestatesResource, c.ns, listOptions)
+
+ _, err := c.Fake.Invokes(action, &v1alpha1.ResourceBundleStateList{})
+ return err
+}
+
+// Patch applies the patch and returns the patched resourceBundleState.
+func (c *FakeResourceBundleStates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewPatchSubresourceAction(resourcebundlestatesResource, c.ns, name, pt, data, subresources...), &v1alpha1.ResourceBundleState{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.ResourceBundleState), err
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-type ResourceBundleStateExpansion interface{}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+type ResourceBundleStateExpansion interface{}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
- "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/scheme"\r
-\r
- //"k8s.io/apimachinery/pkg/runtime/serializer"\r
- rest "k8s.io/client-go/rest"\r
-)\r
-\r
-type K8spluginV1alpha1Interface interface {\r
- RESTClient() rest.Interface\r
- ResourceBundleStatesGetter\r
-}\r
-\r
-// K8spluginV1alpha1Client is used to interact with features provided by the k8splugin.io group.\r
-type K8spluginV1alpha1Client struct {\r
- restClient rest.Interface\r
-}\r
-\r
-func (c *K8spluginV1alpha1Client) ResourceBundleStates(namespace string) ResourceBundleStateInterface {\r
- return newResourceBundleStates(c, namespace)\r
-}\r
-\r
-// NewForConfig creates a new K8spluginV1alpha1Client for the given config.\r
-func NewForConfig(c *rest.Config) (*K8spluginV1alpha1Client, error) {\r
- config := *c\r
- if err := setConfigDefaults(&config); err != nil {\r
- return nil, err\r
- }\r
- client, err := rest.RESTClientFor(&config)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return &K8spluginV1alpha1Client{client}, nil\r
-}\r
-\r
-// NewForConfigOrDie creates a new K8spluginV1alpha1Client for the given config and\r
-// panics if there is an error in the config.\r
-func NewForConfigOrDie(c *rest.Config) *K8spluginV1alpha1Client {\r
- client, err := NewForConfig(c)\r
- if err != nil {\r
- panic(err)\r
- }\r
- return client\r
-}\r
-\r
-// New creates a new K8spluginV1alpha1Client for the given RESTClient.\r
-func New(c rest.Interface) *K8spluginV1alpha1Client {\r
- return &K8spluginV1alpha1Client{c}\r
-}\r
-\r
-func setConfigDefaults(config *rest.Config) error {\r
- gv := v1alpha1.SchemeGroupVersion\r
- config.GroupVersion = &gv\r
- config.APIPath = "/apis"\r
- //config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}\r
- config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()\r
-\r
- if config.UserAgent == "" {\r
- config.UserAgent = rest.DefaultKubernetesUserAgent()\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// RESTClient returns a RESTClient that is used to communicate\r
-// with API server by this client implementation.\r
-func (c *K8spluginV1alpha1Client) RESTClient() rest.Interface {\r
- if c == nil {\r
- return nil\r
- }\r
- return c.restClient\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+ "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/scheme"
+
+ //"k8s.io/apimachinery/pkg/runtime/serializer"
+ rest "k8s.io/client-go/rest"
+)
+
+type K8spluginV1alpha1Interface interface {
+ RESTClient() rest.Interface
+ ResourceBundleStatesGetter
+}
+
+// K8spluginV1alpha1Client is used to interact with features provided by the k8splugin.io group.
+type K8spluginV1alpha1Client struct {
+ restClient rest.Interface
+}
+
+func (c *K8spluginV1alpha1Client) ResourceBundleStates(namespace string) ResourceBundleStateInterface {
+ return newResourceBundleStates(c, namespace)
+}
+
+// NewForConfig creates a new K8spluginV1alpha1Client for the given config.
+func NewForConfig(c *rest.Config) (*K8spluginV1alpha1Client, error) {
+ config := *c
+ if err := setConfigDefaults(&config); err != nil {
+ return nil, err
+ }
+ client, err := rest.RESTClientFor(&config)
+ if err != nil {
+ return nil, err
+ }
+ return &K8spluginV1alpha1Client{client}, nil
+}
+
+// NewForConfigOrDie creates a new K8spluginV1alpha1Client for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *K8spluginV1alpha1Client {
+ client, err := NewForConfig(c)
+ if err != nil {
+ panic(err)
+ }
+ return client
+}
+
+// New creates a new K8spluginV1alpha1Client for the given RESTClient.
+func New(c rest.Interface) *K8spluginV1alpha1Client {
+ return &K8spluginV1alpha1Client{c}
+}
+
+func setConfigDefaults(config *rest.Config) error {
+ gv := v1alpha1.SchemeGroupVersion
+ config.GroupVersion = &gv
+ config.APIPath = "/apis"
+ //config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
+ config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
+
+ if config.UserAgent == "" {
+ config.UserAgent = rest.DefaultKubernetesUserAgent()
+ }
+
+ return nil
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *K8spluginV1alpha1Client) RESTClient() rest.Interface {
+ if c == nil {
+ return nil
+ }
+ return c.restClient
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by client-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- "context"\r
- "time"\r
-\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
- scheme "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/scheme"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- types "k8s.io/apimachinery/pkg/types"\r
- watch "k8s.io/apimachinery/pkg/watch"\r
- rest "k8s.io/client-go/rest"\r
-)\r
-\r
-// ResourceBundleStatesGetter has a method to return a ResourceBundleStateInterface.\r
-// A group's client should implement this interface.\r
-type ResourceBundleStatesGetter interface {\r
- ResourceBundleStates(namespace string) ResourceBundleStateInterface\r
-}\r
-\r
-// ResourceBundleStateInterface has methods to work with ResourceBundleState resources.\r
-type ResourceBundleStateInterface interface {\r
- Create(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)\r
- Update(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)\r
- UpdateStatus(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)\r
- Delete(name string, options *v1.DeleteOptions) error\r
- DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error\r
- Get(name string, options v1.GetOptions) (*v1alpha1.ResourceBundleState, error)\r
- List(opts v1.ListOptions) (*v1alpha1.ResourceBundleStateList, error)\r
- Watch(opts v1.ListOptions) (watch.Interface, error)\r
- Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error)\r
- ResourceBundleStateExpansion\r
-}\r
-\r
-// resourceBundleStates implements ResourceBundleStateInterface\r
-type resourceBundleStates struct {\r
- client rest.Interface\r
- ns string\r
-}\r
-\r
-// newResourceBundleStates returns a ResourceBundleStates\r
-func newResourceBundleStates(c *K8spluginV1alpha1Client, namespace string) *resourceBundleStates {\r
- return &resourceBundleStates{\r
- client: c.RESTClient(),\r
- ns: namespace,\r
- }\r
-}\r
-\r
-// Get takes name of the resourceBundleState, and returns the corresponding resourceBundleState object, and an error if there is any.\r
-func (c *resourceBundleStates) Get(name string, options v1.GetOptions) (result *v1alpha1.ResourceBundleState, err error) {\r
- result = &v1alpha1.ResourceBundleState{}\r
- err = c.client.Get().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- Name(name).\r
- VersionedParams(&options, scheme.ParameterCodec).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
-\r
-// List takes label and field selectors, and returns the list of ResourceBundleStates that match those selectors.\r
-func (c *resourceBundleStates) List(opts v1.ListOptions) (result *v1alpha1.ResourceBundleStateList, err error) {\r
- var timeout time.Duration\r
- if opts.TimeoutSeconds != nil {\r
- timeout = time.Duration(*opts.TimeoutSeconds) * time.Second\r
- }\r
- result = &v1alpha1.ResourceBundleStateList{}\r
- err = c.client.Get().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- VersionedParams(&opts, scheme.ParameterCodec).\r
- Timeout(timeout).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
-\r
-// Watch returns a watch.Interface that watches the requested resourceBundleStates.\r
-func (c *resourceBundleStates) Watch(opts v1.ListOptions) (watch.Interface, error) {\r
- var timeout time.Duration\r
- if opts.TimeoutSeconds != nil {\r
- timeout = time.Duration(*opts.TimeoutSeconds) * time.Second\r
- }\r
- opts.Watch = true\r
- return c.client.Get().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- VersionedParams(&opts, scheme.ParameterCodec).\r
- Timeout(timeout).\r
- Watch(context.TODO())\r
-}\r
-\r
-// Create takes the representation of a resourceBundleState and creates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.\r
-func (c *resourceBundleStates) Create(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {\r
- result = &v1alpha1.ResourceBundleState{}\r
- err = c.client.Post().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- Body(resourceBundleState).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
-\r
-// Update takes the representation of a resourceBundleState and updates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.\r
-func (c *resourceBundleStates) Update(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {\r
- result = &v1alpha1.ResourceBundleState{}\r
- err = c.client.Put().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- Name(resourceBundleState.Name).\r
- Body(resourceBundleState).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
-\r
-// UpdateStatus was generated because the type contains a Status member.\r
-// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().\r
-\r
-func (c *resourceBundleStates) UpdateStatus(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {\r
- result = &v1alpha1.ResourceBundleState{}\r
- err = c.client.Put().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- Name(resourceBundleState.Name).\r
- SubResource("status").\r
- Body(resourceBundleState).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
-\r
-// Delete takes name of the resourceBundleState and deletes it. Returns an error if one occurs.\r
-func (c *resourceBundleStates) Delete(name string, options *v1.DeleteOptions) error {\r
- return c.client.Delete().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- Name(name).\r
- Body(options).\r
- Do(context.TODO()).\r
- Error()\r
-}\r
-\r
-// DeleteCollection deletes a collection of objects.\r
-func (c *resourceBundleStates) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {\r
- var timeout time.Duration\r
- if listOptions.TimeoutSeconds != nil {\r
- timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second\r
- }\r
- return c.client.Delete().\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- VersionedParams(&listOptions, scheme.ParameterCodec).\r
- Timeout(timeout).\r
- Body(options).\r
- Do(context.TODO()).\r
- Error()\r
-}\r
-\r
-// Patch applies the patch and returns the patched resourceBundleState.\r
-func (c *resourceBundleStates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error) {\r
- result = &v1alpha1.ResourceBundleState{}\r
- err = c.client.Patch(pt).\r
- Namespace(c.ns).\r
- Resource("resourcebundlestates").\r
- SubResource(subresources...).\r
- Name(name).\r
- Body(data).\r
- Do(context.TODO()).\r
- Into(result)\r
- return\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "context"
+ "time"
+
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+ scheme "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned/scheme"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ rest "k8s.io/client-go/rest"
+)
+
+// ResourceBundleStatesGetter has a method to return a ResourceBundleStateInterface.
+// A group's client should implement this interface.
+type ResourceBundleStatesGetter interface {
+ ResourceBundleStates(namespace string) ResourceBundleStateInterface
+}
+
+// ResourceBundleStateInterface has methods to work with ResourceBundleState resources.
+type ResourceBundleStateInterface interface {
+ Create(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)
+ Update(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)
+ UpdateStatus(*v1alpha1.ResourceBundleState) (*v1alpha1.ResourceBundleState, error)
+ Delete(name string, options *v1.DeleteOptions) error
+ DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
+ Get(name string, options v1.GetOptions) (*v1alpha1.ResourceBundleState, error)
+ List(opts v1.ListOptions) (*v1alpha1.ResourceBundleStateList, error)
+ Watch(opts v1.ListOptions) (watch.Interface, error)
+ Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error)
+ ResourceBundleStateExpansion
+}
+
+// resourceBundleStates implements ResourceBundleStateInterface
+type resourceBundleStates struct {
+ client rest.Interface
+ ns string
+}
+
+// newResourceBundleStates returns a ResourceBundleStates
+func newResourceBundleStates(c *K8spluginV1alpha1Client, namespace string) *resourceBundleStates {
+ return &resourceBundleStates{
+ client: c.RESTClient(),
+ ns: namespace,
+ }
+}
+
+// Get takes name of the resourceBundleState, and returns the corresponding resourceBundleState object, and an error if there is any.
+func (c *resourceBundleStates) Get(name string, options v1.GetOptions) (result *v1alpha1.ResourceBundleState, err error) {
+ result = &v1alpha1.ResourceBundleState{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ Name(name).
+ VersionedParams(&options, scheme.ParameterCodec).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
+
+// List takes label and field selectors, and returns the list of ResourceBundleStates that match those selectors.
+func (c *resourceBundleStates) List(opts v1.ListOptions) (result *v1alpha1.ResourceBundleStateList, err error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ result = &v1alpha1.ResourceBundleStateList{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
+
+// Watch returns a watch.Interface that watches the requested resourceBundleStates.
+func (c *resourceBundleStates) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ opts.Watch = true
+ return c.client.Get().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Watch(context.TODO())
+}
+
+// Create takes the representation of a resourceBundleState and creates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.
+func (c *resourceBundleStates) Create(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {
+ result = &v1alpha1.ResourceBundleState{}
+ err = c.client.Post().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ Body(resourceBundleState).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
+
+// Update takes the representation of a resourceBundleState and updates it. Returns the server's representation of the resourceBundleState, and an error, if there is any.
+func (c *resourceBundleStates) Update(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {
+ result = &v1alpha1.ResourceBundleState{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ Name(resourceBundleState.Name).
+ Body(resourceBundleState).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+
+func (c *resourceBundleStates) UpdateStatus(resourceBundleState *v1alpha1.ResourceBundleState) (result *v1alpha1.ResourceBundleState, err error) {
+ result = &v1alpha1.ResourceBundleState{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ Name(resourceBundleState.Name).
+ SubResource("status").
+ Body(resourceBundleState).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
+
+// Delete takes name of the resourceBundleState and deletes it. Returns an error if one occurs.
+func (c *resourceBundleStates) Delete(name string, options *v1.DeleteOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ Name(name).
+ Body(options).
+ Do(context.TODO()).
+ Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *resourceBundleStates) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ var timeout time.Duration
+ if listOptions.TimeoutSeconds != nil {
+ timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
+ }
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ VersionedParams(&listOptions, scheme.ParameterCodec).
+ Timeout(timeout).
+ Body(options).
+ Do(context.TODO()).
+ Error()
+}
+
+// Patch applies the patch and returns the patched resourceBundleState.
+func (c *resourceBundleStates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ResourceBundleState, err error) {
+ result = &v1alpha1.ResourceBundleState{}
+ err = c.client.Patch(pt).
+ Namespace(c.ns).
+ Resource("resourcebundlestates").
+ SubResource(subresources...).
+ Name(name).
+ Body(data).
+ Do(context.TODO()).
+ Into(result)
+ return
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package externalversions\r
-\r
-import (\r
- versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"\r
- internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"\r
- k8splugin "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/k8splugin"\r
- reflect "reflect"\r
- sync "sync"\r
- time "time"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
- schema "k8s.io/apimachinery/pkg/runtime/schema"\r
- cache "k8s.io/client-go/tools/cache"\r
-)\r
-\r
-// SharedInformerOption defines the functional option type for SharedInformerFactory.\r
-type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory\r
-\r
-type sharedInformerFactory struct {\r
- client versioned.Interface\r
- namespace string\r
- tweakListOptions internalinterfaces.TweakListOptionsFunc\r
- lock sync.Mutex\r
- defaultResync time.Duration\r
- customResync map[reflect.Type]time.Duration\r
-\r
- informers map[reflect.Type]cache.SharedIndexInformer\r
- // startedInformers is used for tracking which informers have been started.\r
- // This allows Start() to be called multiple times safely.\r
- startedInformers map[reflect.Type]bool\r
-}\r
-\r
-// WithCustomResyncConfig sets a custom resync period for the specified informer types.\r
-func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {\r
- return func(factory *sharedInformerFactory) *sharedInformerFactory {\r
- for k, v := range resyncConfig {\r
- factory.customResync[reflect.TypeOf(k)] = v\r
- }\r
- return factory\r
- }\r
-}\r
-\r
-// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.\r
-func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {\r
- return func(factory *sharedInformerFactory) *sharedInformerFactory {\r
- factory.tweakListOptions = tweakListOptions\r
- return factory\r
- }\r
-}\r
-\r
-// WithNamespace limits the SharedInformerFactory to the specified namespace.\r
-func WithNamespace(namespace string) SharedInformerOption {\r
- return func(factory *sharedInformerFactory) *sharedInformerFactory {\r
- factory.namespace = namespace\r
- return factory\r
- }\r
-}\r
-\r
-// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.\r
-func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {\r
- return NewSharedInformerFactoryWithOptions(client, defaultResync)\r
-}\r
-\r
-// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.\r
-// Listers obtained via this SharedInformerFactory will be subject to the same filters\r
-// as specified here.\r
-// Deprecated: Please use NewSharedInformerFactoryWithOptions instead\r
-func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {\r
- return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))\r
-}\r
-\r
-// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.\r
-func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {\r
- factory := &sharedInformerFactory{\r
- client: client,\r
- namespace: v1.NamespaceAll,\r
- defaultResync: defaultResync,\r
- informers: make(map[reflect.Type]cache.SharedIndexInformer),\r
- startedInformers: make(map[reflect.Type]bool),\r
- customResync: make(map[reflect.Type]time.Duration),\r
- }\r
-\r
- // Apply all options\r
- for _, opt := range options {\r
- factory = opt(factory)\r
- }\r
-\r
- return factory\r
-}\r
-\r
-// Start initializes all requested informers.\r
-func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {\r
- f.lock.Lock()\r
- defer f.lock.Unlock()\r
-\r
- for informerType, informer := range f.informers {\r
- if !f.startedInformers[informerType] {\r
- go informer.Run(stopCh)\r
- f.startedInformers[informerType] = true\r
- }\r
- }\r
-}\r
-\r
-// WaitForCacheSync waits for all started informers' cache were synced.\r
-func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {\r
- informers := func() map[reflect.Type]cache.SharedIndexInformer {\r
- f.lock.Lock()\r
- defer f.lock.Unlock()\r
-\r
- informers := map[reflect.Type]cache.SharedIndexInformer{}\r
- for informerType, informer := range f.informers {\r
- if f.startedInformers[informerType] {\r
- informers[informerType] = informer\r
- }\r
- }\r
- return informers\r
- }()\r
-\r
- res := map[reflect.Type]bool{}\r
- for informType, informer := range informers {\r
- res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)\r
- }\r
- return res\r
-}\r
-\r
-// InternalInformerFor returns the SharedIndexInformer for obj using an internal\r
-// client.\r
-func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {\r
- f.lock.Lock()\r
- defer f.lock.Unlock()\r
-\r
- informerType := reflect.TypeOf(obj)\r
- informer, exists := f.informers[informerType]\r
- if exists {\r
- return informer\r
- }\r
-\r
- resyncPeriod, exists := f.customResync[informerType]\r
- if !exists {\r
- resyncPeriod = f.defaultResync\r
- }\r
-\r
- informer = newFunc(f.client, resyncPeriod)\r
- f.informers[informerType] = informer\r
-\r
- return informer\r
-}\r
-\r
-// SharedInformerFactory provides shared informers for resources in all known\r
-// API group versions.\r
-type SharedInformerFactory interface {\r
- internalinterfaces.SharedInformerFactory\r
- ForResource(resource schema.GroupVersionResource) (GenericInformer, error)\r
- WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool\r
-\r
- K8splugin() k8splugin.Interface\r
-}\r
-\r
-func (f *sharedInformerFactory) K8splugin() k8splugin.Interface {\r
- return k8splugin.New(f, f.namespace, f.tweakListOptions)\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package externalversions
+
+import (
+ versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"
+ internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"
+ k8splugin "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/k8splugin"
+ reflect "reflect"
+ sync "sync"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// SharedInformerOption defines the functional option type for SharedInformerFactory.
+type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
+
+type sharedInformerFactory struct {
+ client versioned.Interface
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+ lock sync.Mutex
+ defaultResync time.Duration
+ customResync map[reflect.Type]time.Duration
+
+ informers map[reflect.Type]cache.SharedIndexInformer
+ // startedInformers is used for tracking which informers have been started.
+ // This allows Start() to be called multiple times safely.
+ startedInformers map[reflect.Type]bool
+}
+
+// WithCustomResyncConfig sets a custom resync period for the specified informer types.
+func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ for k, v := range resyncConfig {
+ factory.customResync[reflect.TypeOf(k)] = v
+ }
+ return factory
+ }
+}
+
+// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
+func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ factory.tweakListOptions = tweakListOptions
+ return factory
+ }
+}
+
+// WithNamespace limits the SharedInformerFactory to the specified namespace.
+func WithNamespace(namespace string) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ factory.namespace = namespace
+ return factory
+ }
+}
+
+// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
+func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
+ return NewSharedInformerFactoryWithOptions(client, defaultResync)
+}
+
+// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
+// Listers obtained via this SharedInformerFactory will be subject to the same filters
+// as specified here.
+// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
+func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
+ return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
+}
+
+// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
+func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
+ factory := &sharedInformerFactory{
+ client: client,
+ namespace: v1.NamespaceAll,
+ defaultResync: defaultResync,
+ informers: make(map[reflect.Type]cache.SharedIndexInformer),
+ startedInformers: make(map[reflect.Type]bool),
+ customResync: make(map[reflect.Type]time.Duration),
+ }
+
+ // Apply all options
+ for _, opt := range options {
+ factory = opt(factory)
+ }
+
+ return factory
+}
+
+// Start initializes all requested informers.
+func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ for informerType, informer := range f.informers {
+ if !f.startedInformers[informerType] {
+ go informer.Run(stopCh)
+ f.startedInformers[informerType] = true
+ }
+ }
+}
+
+// WaitForCacheSync waits for all started informers' cache were synced.
+func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
+ informers := func() map[reflect.Type]cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informers := map[reflect.Type]cache.SharedIndexInformer{}
+ for informerType, informer := range f.informers {
+ if f.startedInformers[informerType] {
+ informers[informerType] = informer
+ }
+ }
+ return informers
+ }()
+
+ res := map[reflect.Type]bool{}
+ for informType, informer := range informers {
+ res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
+ }
+ return res
+}
+
+// InternalInformerFor returns the SharedIndexInformer for obj using an internal
+// client.
+func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informerType := reflect.TypeOf(obj)
+ informer, exists := f.informers[informerType]
+ if exists {
+ return informer
+ }
+
+ resyncPeriod, exists := f.customResync[informerType]
+ if !exists {
+ resyncPeriod = f.defaultResync
+ }
+
+ informer = newFunc(f.client, resyncPeriod)
+ f.informers[informerType] = informer
+
+ return informer
+}
+
+// SharedInformerFactory provides shared informers for resources in all known
+// API group versions.
+type SharedInformerFactory interface {
+ internalinterfaces.SharedInformerFactory
+ ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
+ WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
+
+ K8splugin() k8splugin.Interface
+}
+
+func (f *sharedInformerFactory) K8splugin() k8splugin.Interface {
+ return k8splugin.New(f, f.namespace, f.tweakListOptions)
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package externalversions\r
-\r
-import (\r
- "fmt"\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- schema "k8s.io/apimachinery/pkg/runtime/schema"\r
- cache "k8s.io/client-go/tools/cache"\r
-)\r
-\r
-// GenericInformer is type of SharedIndexInformer which will locate and delegate to other\r
-// sharedInformers based on type\r
-type GenericInformer interface {\r
- Informer() cache.SharedIndexInformer\r
- Lister() cache.GenericLister\r
-}\r
-\r
-type genericInformer struct {\r
- informer cache.SharedIndexInformer\r
- resource schema.GroupResource\r
-}\r
-\r
-// Informer returns the SharedIndexInformer.\r
-func (f *genericInformer) Informer() cache.SharedIndexInformer {\r
- return f.informer\r
-}\r
-\r
-// Lister returns the GenericLister.\r
-func (f *genericInformer) Lister() cache.GenericLister {\r
- return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)\r
-}\r
-\r
-// ForResource gives generic access to a shared informer of the matching type\r
-// TODO extend this to unknown resources with a client pool\r
-func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {\r
- switch resource {\r
- // Group=k8splugin.io, Version=v1alpha1\r
- case v1alpha1.SchemeGroupVersion.WithResource("resourcebundlestates"):\r
- return &genericInformer{resource: resource.GroupResource(), informer: f.K8splugin().V1alpha1().ResourceBundleStates().Informer()}, nil\r
-\r
- }\r
-\r
- return nil, fmt.Errorf("no informer found for %v", resource)\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package externalversions
+
+import (
+ "fmt"
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
+// sharedInformers based on type
+type GenericInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() cache.GenericLister
+}
+
+type genericInformer struct {
+ informer cache.SharedIndexInformer
+ resource schema.GroupResource
+}
+
+// Informer returns the SharedIndexInformer.
+func (f *genericInformer) Informer() cache.SharedIndexInformer {
+ return f.informer
+}
+
+// Lister returns the GenericLister.
+func (f *genericInformer) Lister() cache.GenericLister {
+ return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
+}
+
+// ForResource gives generic access to a shared informer of the matching type
+// TODO extend this to unknown resources with a client pool
+func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
+ switch resource {
+ // Group=k8splugin.io, Version=v1alpha1
+ case v1alpha1.SchemeGroupVersion.WithResource("resourcebundlestates"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.K8splugin().V1alpha1().ResourceBundleStates().Informer()}, nil
+
+ }
+
+ return nil, fmt.Errorf("no informer found for %v", resource)
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package internalinterfaces\r
-\r
-import (\r
- versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"\r
- time "time"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
- cache "k8s.io/client-go/tools/cache"\r
-)\r
-\r
-// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.\r
-type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer\r
-\r
-// SharedInformerFactory a small interface to allow for adding an informer without an import cycle\r
-type SharedInformerFactory interface {\r
- Start(stopCh <-chan struct{})\r
- InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer\r
-}\r
-\r
-// TweakListOptionsFunc is a function that transforms a v1.ListOptions.\r
-type TweakListOptionsFunc func(*v1.ListOptions)\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package internalinterfaces
+
+import (
+ versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
+type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
+
+// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
+type SharedInformerFactory interface {
+ Start(stopCh <-chan struct{})
+ InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
+}
+
+// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
+type TweakListOptionsFunc func(*v1.ListOptions)
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package k8splugin\r
-\r
-import (\r
- internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/k8splugin/v1alpha1"\r
-)\r
-\r
-// Interface provides access to each of this group's versions.\r
-type Interface interface {\r
- // V1alpha1 provides access to shared informers for resources in V1alpha1.\r
- V1alpha1() v1alpha1.Interface\r
-}\r
-\r
-type group struct {\r
- factory internalinterfaces.SharedInformerFactory\r
- namespace string\r
- tweakListOptions internalinterfaces.TweakListOptionsFunc\r
-}\r
-\r
-// New returns a new Interface.\r
-func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {\r
- return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}\r
-}\r
-\r
-// V1alpha1 returns a new v1alpha1.Interface.\r
-func (g *group) V1alpha1() v1alpha1.Interface {\r
- return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package k8splugin
+
+import (
+ internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/k8splugin/v1alpha1"
+)
+
+// Interface provides access to each of this group's versions.
+type Interface interface {
+ // V1alpha1 provides access to shared informers for resources in V1alpha1.
+ V1alpha1() v1alpha1.Interface
+}
+
+type group struct {
+ factory internalinterfaces.SharedInformerFactory
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
+ return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
+}
+
+// V1alpha1 returns a new v1alpha1.Interface.
+func (g *group) V1alpha1() v1alpha1.Interface {
+ return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"\r
-)\r
-\r
-// Interface provides access to all the informers in this group version.\r
-type Interface interface {\r
- // ResourceBundleStates returns a ResourceBundleStateInformer.\r
- ResourceBundleStates() ResourceBundleStateInformer\r
-}\r
-\r
-type version struct {\r
- factory internalinterfaces.SharedInformerFactory\r
- namespace string\r
- tweakListOptions internalinterfaces.TweakListOptionsFunc\r
-}\r
-\r
-// New returns a new Interface.\r
-func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {\r
- return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}\r
-}\r
-\r
-// ResourceBundleStates returns a ResourceBundleStateInformer.\r
-func (v *version) ResourceBundleStates() ResourceBundleStateInformer {\r
- return &resourceBundleStateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"
+)
+
+// Interface provides access to all the informers in this group version.
+type Interface interface {
+ // ResourceBundleStates returns a ResourceBundleStateInformer.
+ ResourceBundleStates() ResourceBundleStateInformer
+}
+
+type version struct {
+ factory internalinterfaces.SharedInformerFactory
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
+ return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
+}
+
+// ResourceBundleStates returns a ResourceBundleStateInformer.
+func (v *version) ResourceBundleStates() ResourceBundleStateInformer {
+ return &resourceBundleStateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by informer-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
- versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"\r
- internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/listers/k8splugin/v1alpha1"\r
- time "time"\r
-\r
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- runtime "k8s.io/apimachinery/pkg/runtime"\r
- watch "k8s.io/apimachinery/pkg/watch"\r
- cache "k8s.io/client-go/tools/cache"\r
-)\r
-\r
-// ResourceBundleStateInformer provides access to a shared informer and lister for\r
-// ResourceBundleStates.\r
-type ResourceBundleStateInformer interface {\r
- Informer() cache.SharedIndexInformer\r
- Lister() v1alpha1.ResourceBundleStateLister\r
-}\r
-\r
-type resourceBundleStateInformer struct {\r
- factory internalinterfaces.SharedInformerFactory\r
- tweakListOptions internalinterfaces.TweakListOptionsFunc\r
- namespace string\r
-}\r
-\r
-// NewResourceBundleStateInformer constructs a new informer for ResourceBundleState type.\r
-// Always prefer using an informer factory to get a shared informer instead of getting an independent\r
-// one. This reduces memory footprint and number of connections to the server.\r
-func NewResourceBundleStateInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {\r
- return NewFilteredResourceBundleStateInformer(client, namespace, resyncPeriod, indexers, nil)\r
-}\r
-\r
-// NewFilteredResourceBundleStateInformer constructs a new informer for ResourceBundleState type.\r
-// Always prefer using an informer factory to get a shared informer instead of getting an independent\r
-// one. This reduces memory footprint and number of connections to the server.\r
-func NewFilteredResourceBundleStateInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {\r
- return cache.NewSharedIndexInformer(\r
- &cache.ListWatch{\r
- ListFunc: func(options v1.ListOptions) (runtime.Object, error) {\r
- if tweakListOptions != nil {\r
- tweakListOptions(&options)\r
- }\r
- return client.K8spluginV1alpha1().ResourceBundleStates(namespace).List(options)\r
- },\r
- WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {\r
- if tweakListOptions != nil {\r
- tweakListOptions(&options)\r
- }\r
- return client.K8spluginV1alpha1().ResourceBundleStates(namespace).Watch(options)\r
- },\r
- },\r
- &k8spluginv1alpha1.ResourceBundleState{},\r
- resyncPeriod,\r
- indexers,\r
- )\r
-}\r
-\r
-func (f *resourceBundleStateInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {\r
- return NewFilteredResourceBundleStateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)\r
-}\r
-\r
-func (f *resourceBundleStateInformer) Informer() cache.SharedIndexInformer {\r
- return f.factory.InformerFor(&k8spluginv1alpha1.ResourceBundleState{}, f.defaultInformer)\r
-}\r
-\r
-func (f *resourceBundleStateInformer) Lister() v1alpha1.ResourceBundleStateLister {\r
- return v1alpha1.NewResourceBundleStateLister(f.Informer().GetIndexer())\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ k8spluginv1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+ versioned "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"
+ internalinterfaces "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions/internalinterfaces"
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/generated/listers/k8splugin/v1alpha1"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// ResourceBundleStateInformer provides access to a shared informer and lister for
+// ResourceBundleStates.
+type ResourceBundleStateInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1alpha1.ResourceBundleStateLister
+}
+
+type resourceBundleStateInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+ namespace string
+}
+
+// NewResourceBundleStateInformer constructs a new informer for ResourceBundleState type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewResourceBundleStateInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredResourceBundleStateInformer(client, namespace, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredResourceBundleStateInformer constructs a new informer for ResourceBundleState type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredResourceBundleStateInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.K8spluginV1alpha1().ResourceBundleStates(namespace).List(options)
+ },
+ WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.K8spluginV1alpha1().ResourceBundleStates(namespace).Watch(options)
+ },
+ },
+ &k8spluginv1alpha1.ResourceBundleState{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func (f *resourceBundleStateInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredResourceBundleStateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *resourceBundleStateInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&k8spluginv1alpha1.ResourceBundleState{}, f.defaultInformer)
+}
+
+func (f *resourceBundleStateInformer) Lister() v1alpha1.ResourceBundleStateLister {
+ return v1alpha1.NewResourceBundleStateLister(f.Informer().GetIndexer())
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by lister-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-// ResourceBundleStateListerExpansion allows custom methods to be added to\r
-// ResourceBundleStateLister.\r
-type ResourceBundleStateListerExpansion interface{}\r
-\r
-// ResourceBundleStateNamespaceListerExpansion allows custom methods to be added to\r
-// ResourceBundleStateNamespaceLister.\r
-type ResourceBundleStateNamespaceListerExpansion interface{}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+// ResourceBundleStateListerExpansion allows custom methods to be added to
+// ResourceBundleStateLister.
+type ResourceBundleStateListerExpansion interface{}
+
+// ResourceBundleStateNamespaceListerExpansion allows custom methods to be added to
+// ResourceBundleStateNamespaceLister.
+type ResourceBundleStateNamespaceListerExpansion interface{}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-// Code generated by lister-gen. DO NOT EDIT.\r
-\r
-package v1alpha1\r
-\r
-import (\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
-\r
- "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/labels"\r
- "k8s.io/client-go/tools/cache"\r
-)\r
-\r
-// ResourceBundleStateLister helps list ResourceBundleStates.\r
-type ResourceBundleStateLister interface {\r
- // List lists all ResourceBundleStates in the indexer.\r
- List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error)\r
- // ResourceBundleStates returns an object that can list and get ResourceBundleStates.\r
- ResourceBundleStates(namespace string) ResourceBundleStateNamespaceLister\r
- ResourceBundleStateListerExpansion\r
-}\r
-\r
-// resourceBundleStateLister implements the ResourceBundleStateLister interface.\r
-type resourceBundleStateLister struct {\r
- indexer cache.Indexer\r
-}\r
-\r
-// NewResourceBundleStateLister returns a new ResourceBundleStateLister.\r
-func NewResourceBundleStateLister(indexer cache.Indexer) ResourceBundleStateLister {\r
- return &resourceBundleStateLister{indexer: indexer}\r
-}\r
-\r
-// List lists all ResourceBundleStates in the indexer.\r
-func (s *resourceBundleStateLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error) {\r
- err = cache.ListAll(s.indexer, selector, func(m interface{}) {\r
- ret = append(ret, m.(*v1alpha1.ResourceBundleState))\r
- })\r
- return ret, err\r
-}\r
-\r
-// ResourceBundleStates returns an object that can list and get ResourceBundleStates.\r
-func (s *resourceBundleStateLister) ResourceBundleStates(namespace string) ResourceBundleStateNamespaceLister {\r
- return resourceBundleStateNamespaceLister{indexer: s.indexer, namespace: namespace}\r
-}\r
-\r
-// ResourceBundleStateNamespaceLister helps list and get ResourceBundleStates.\r
-type ResourceBundleStateNamespaceLister interface {\r
- // List lists all ResourceBundleStates in the indexer for a given namespace.\r
- List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error)\r
- // Get retrieves the ResourceBundleState from the indexer for a given namespace and name.\r
- Get(name string) (*v1alpha1.ResourceBundleState, error)\r
- ResourceBundleStateNamespaceListerExpansion\r
-}\r
-\r
-// resourceBundleStateNamespaceLister implements the ResourceBundleStateNamespaceLister\r
-// interface.\r
-type resourceBundleStateNamespaceLister struct {\r
- indexer cache.Indexer\r
- namespace string\r
-}\r
-\r
-// List lists all ResourceBundleStates in the indexer for a given namespace.\r
-func (s resourceBundleStateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error) {\r
- err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {\r
- ret = append(ret, m.(*v1alpha1.ResourceBundleState))\r
- })\r
- return ret, err\r
-}\r
-\r
-// Get retrieves the ResourceBundleState from the indexer for a given namespace and name.\r
-func (s resourceBundleStateNamespaceLister) Get(name string) (*v1alpha1.ResourceBundleState, error) {\r
- obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)\r
- if err != nil {\r
- return nil, err\r
- }\r
- if !exists {\r
- return nil, errors.NewNotFound(v1alpha1.Resource("resourcebundlestate"), name)\r
- }\r
- return obj.(*v1alpha1.ResourceBundleState), nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+)
+
+// ResourceBundleStateLister helps list ResourceBundleStates.
+type ResourceBundleStateLister interface {
+ // List lists all ResourceBundleStates in the indexer.
+ List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error)
+ // ResourceBundleStates returns an object that can list and get ResourceBundleStates.
+ ResourceBundleStates(namespace string) ResourceBundleStateNamespaceLister
+ ResourceBundleStateListerExpansion
+}
+
+// resourceBundleStateLister implements the ResourceBundleStateLister interface.
+type resourceBundleStateLister struct {
+ indexer cache.Indexer
+}
+
+// NewResourceBundleStateLister returns a new ResourceBundleStateLister.
+func NewResourceBundleStateLister(indexer cache.Indexer) ResourceBundleStateLister {
+ return &resourceBundleStateLister{indexer: indexer}
+}
+
+// List lists all ResourceBundleStates in the indexer.
+func (s *resourceBundleStateLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.ResourceBundleState))
+ })
+ return ret, err
+}
+
+// ResourceBundleStates returns an object that can list and get ResourceBundleStates.
+func (s *resourceBundleStateLister) ResourceBundleStates(namespace string) ResourceBundleStateNamespaceLister {
+ return resourceBundleStateNamespaceLister{indexer: s.indexer, namespace: namespace}
+}
+
+// ResourceBundleStateNamespaceLister helps list and get ResourceBundleStates.
+type ResourceBundleStateNamespaceLister interface {
+ // List lists all ResourceBundleStates in the indexer for a given namespace.
+ List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error)
+ // Get retrieves the ResourceBundleState from the indexer for a given namespace and name.
+ Get(name string) (*v1alpha1.ResourceBundleState, error)
+ ResourceBundleStateNamespaceListerExpansion
+}
+
+// resourceBundleStateNamespaceLister implements the ResourceBundleStateNamespaceLister
+// interface.
+type resourceBundleStateNamespaceLister struct {
+ indexer cache.Indexer
+ namespace string
+}
+
+// List lists all ResourceBundleStates in the indexer for a given namespace.
+func (s resourceBundleStateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceBundleState, err error) {
+ err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.ResourceBundleState))
+ })
+ return ret, err
+}
+
+// Get retrieves the ResourceBundleState from the indexer for a given namespace and name.
+func (s resourceBundleStateNamespaceLister) Get(name string) (*v1alpha1.ResourceBundleState, error) {
+ obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1alpha1.Resource("resourcebundlestate"), name)
+ }
+ return obj.(*v1alpha1.ResourceBundleState), nil
+}
-package version\r
-\r
-var (\r
- Version = "0.0.1"\r
-)\r
+package version
+
+var (
+ Version = "0.0.1"
+)
-package main\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- rsync "github.com/open-ness/EMCO/src/rsync/pkg/db"\r
- "log"\r
- "math/rand"\r
- "time"\r
- "io/ioutil"\r
- "encoding/base64"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-func registerCluster(provider_name string, cluster_name string, kubeconfig_file string) error {\r
- content, err := ioutil.ReadFile(kubeconfig_file)\r
-\r
- ccc := rsync.NewCloudConfigClient()\r
-\r
- _, err = ccc.CreateCloudConfig(provider_name, cluster_name, "0", "sdewan-system", base64.StdEncoding.EncodeToString(content))\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Error creating cloud config")\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func main() {\r
- rand.Seed(time.Now().UnixNano())\r
-\r
- // Initialize the mongodb\r
- err := db.InitializeDatabaseConnection("scc")\r
- if err != nil {\r
- log.Println("Unable to initialize database connection...")\r
- log.Println(err)\r
- log.Fatalln("Exiting...")\r
- }\r
-\r
- provider_name := "akraino_scc"\r
- cluster_name := "local"\r
- // Register cluster kubeconfig\r
- registerCluster(provider_name, cluster_name, "admin.conf") \r
-}\r
+package main
+
+import (
+ "encoding/base64"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ rsync "github.com/open-ness/EMCO/src/rsync/pkg/db"
+ pkgerrors "github.com/pkg/errors"
+ "io/ioutil"
+ "log"
+ "math/rand"
+ "time"
+)
+
+func registerCluster(provider_name string, cluster_name string, kubeconfig_file string) error {
+ content, err := ioutil.ReadFile(kubeconfig_file)
+
+ ccc := rsync.NewCloudConfigClient()
+
+ _, err = ccc.CreateCloudConfig(provider_name, cluster_name, "0", "default", base64.StdEncoding.EncodeToString(content))
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error creating cloud config")
+ }
+
+ return nil
+}
+
+func main() {
+ rand.Seed(time.Now().UnixNano())
+
+ // Initialize the mongodb
+ err := db.InitializeDatabaseConnection("scc")
+ if err != nil {
+ log.Println("Unable to initialize database connection...")
+ log.Println(err)
+ log.Fatalln("Exiting...")
+ }
+
+ provider_name := "akraino_scc"
+ cluster_name := "local"
+ // Register cluster kubeconfig
+ registerCluster(provider_name, cluster_name, "admin.conf")
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package main\r
-\r
-import (\r
- "fmt"\r
- "log"\r
- "math/rand"\r
- "net"\r
- "strings"\r
- "time"\r
-\r
- register "github.com/open-ness/EMCO/src/rsync/pkg/grpc"\r
- installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"\r
- "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installappserver"\r
- readynotifypb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"\r
- "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotifyserver"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "google.golang.org/grpc"\r
- "google.golang.org/grpc/credentials"\r
- "google.golang.org/grpc/testdata"\r
-)\r
-\r
-func startGrpcServer() error {\r
- var tls bool\r
-\r
- if strings.Contains(config.GetConfiguration().GrpcEnableTLS, "enable") {\r
- tls = true\r
- } else {\r
- tls = false\r
- }\r
- certFile := config.GetConfiguration().GrpcServerCert\r
- keyFile := config.GetConfiguration().GrpcServerKey\r
-\r
- _, port := register.GetServerHostPort()\r
-\r
- lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))\r
- if err != nil {\r
- log.Fatalf("Could not listen to port: %v", err)\r
- }\r
- var opts []grpc.ServerOption\r
- if tls {\r
- if certFile == "" {\r
- certFile = testdata.Path("server.pem")\r
- }\r
- if keyFile == "" {\r
- keyFile = testdata.Path("server.key")\r
- }\r
- creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)\r
- if err != nil {\r
- log.Fatalf("Could not generate credentials %v", err)\r
- }\r
- opts = []grpc.ServerOption{grpc.Creds(creds)}\r
- }\r
- grpcServer := grpc.NewServer(opts...)\r
- installpb.RegisterInstallappServer(grpcServer, installappserver.NewInstallAppServer())\r
- readyNotifyServer := readynotifyserver.NewReadyNotifyServer()\r
- readynotifypb.RegisterReadyNotifyServer(grpcServer, readyNotifyServer)\r
-\r
- log.Println("Starting rsync gRPC Server")\r
- err = grpcServer.Serve(lis)\r
- if err != nil {\r
- log.Fatalf("rsync grpc server is not serving %v", err)\r
- }\r
- return err\r
-}\r
-\r
-func main() {\r
-\r
- rand.Seed(time.Now().UnixNano())\r
-\r
- // Initialize the mongodb\r
- err := db.InitializeDatabaseConnection("scc")\r
- if err != nil {\r
- log.Println("Unable to initialize database connection...")\r
- log.Println(err)\r
- log.Fatalln("Exiting...")\r
- }\r
-\r
- // Initialize contextdb\r
- err = contextDb.InitializeContextDatabase()\r
- if err != nil {\r
- log.Println("Unable to initialize database connection...")\r
- log.Println(err)\r
- log.Fatalln("Exiting...")\r
- }\r
-\r
- err = startGrpcServer()\r
- if err != nil {\r
- log.Fatalf("GRPC server failed to start")\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "math/rand"
+ "net"
+ "strings"
+ "time"
+
+ register "github.com/open-ness/EMCO/src/rsync/pkg/grpc"
+ installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"
+ "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installappserver"
+ readynotifypb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"
+ "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotifyserver"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/testdata"
+)
+
+func startGrpcServer() error {
+ var tls bool
+
+ if strings.Contains(config.GetConfiguration().GrpcEnableTLS, "enable") {
+ tls = true
+ } else {
+ tls = false
+ }
+ certFile := config.GetConfiguration().GrpcServerCert
+ keyFile := config.GetConfiguration().GrpcServerKey
+
+ _, port := register.GetServerHostPort()
+
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
+ if err != nil {
+ log.Fatalf("Could not listen to port: %v", err)
+ }
+ var opts []grpc.ServerOption
+ if tls {
+ if certFile == "" {
+ certFile = testdata.Path("server.pem")
+ }
+ if keyFile == "" {
+ keyFile = testdata.Path("server.key")
+ }
+ creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
+ if err != nil {
+ log.Fatalf("Could not generate credentials %v", err)
+ }
+ opts = []grpc.ServerOption{grpc.Creds(creds)}
+ }
+
+ grpcServer := grpc.NewServer(opts...)
+ installpb.RegisterInstallappServer(grpcServer, installappserver.NewInstallAppServer())
+ readynotifypb.RegisterReadyNotifyServer(grpcServer, readynotifyserver.NewReadyNotifyServer())
+
+ log.Println("Starting rsync gRPC Server")
+ err = grpcServer.Serve(lis)
+ if err != nil {
+ log.Fatalf("rsync grpc server is not serving %v", err)
+ }
+ return err
+}
+
+func main() {
+
+ rand.Seed(time.Now().UnixNano())
+
+ // Initialize the mongodb
+ err := db.InitializeDatabaseConnection("scc")
+ if err != nil {
+ log.Println("Unable to initialize mongo database connection...")
+ log.Println(err)
+ log.Fatalln("Exiting...")
+ }
+
+ // Initialize contextdb
+ err = contextDb.InitializeContextDatabase()
+ if err != nil {
+ log.Println("Unable to initialize etcd database connection...")
+ log.Println(err)
+ log.Fatalln("Exiting...")
+ }
+
+ err = startGrpcServer()
+ if err != nil {
+ log.Fatalf("GRPC server failed to start")
+ }
+}
-{\r
-"etcd-ip": "192.168.65.173",\r
-"database-ip": "192.168.65.174"\r
-}
\ No newline at end of file
+{
+ "database-type": "mongo",
+ "database-ip": "mongo",
+ "etcd-ip": "etcd"
+}
--- /dev/null
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>readynotifyserver: Go Coverage Report</title>
+ <style>
+ body {
+ background: black;
+ color: rgb(80, 80, 80);
+ }
+ body, pre, #legend span {
+ font-family: Menlo, monospace;
+ font-weight: bold;
+ }
+ #topbar {
+ background: black;
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ height: 42px;
+ border-bottom: 1px solid rgb(80, 80, 80);
+ }
+ #content {
+ margin-top: 50px;
+ }
+ #nav, #legend {
+ float: left;
+ margin-left: 10px;
+ }
+ #legend {
+ margin-top: 12px;
+ }
+ #nav {
+ margin-top: 10px;
+ }
+ #legend span {
+ margin: 0 5px;
+ }
+ .cov0 { color: rgb(192, 0, 0) }
+.cov1 { color: rgb(128, 128, 128) }
+.cov2 { color: rgb(116, 140, 131) }
+.cov3 { color: rgb(104, 152, 134) }
+.cov4 { color: rgb(92, 164, 137) }
+.cov5 { color: rgb(80, 176, 140) }
+.cov6 { color: rgb(68, 188, 143) }
+.cov7 { color: rgb(56, 200, 146) }
+.cov8 { color: rgb(44, 212, 149) }
+.cov9 { color: rgb(32, 224, 152) }
+.cov10 { color: rgb(20, 236, 155) }
+
+ </style>
+ </head>
+ <body>
+ <div id="topbar">
+ <div id="nav">
+ <select id="files">
+
+ <option value="file0">github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotifyserver/readynotifyserver.go (69.4%)</option>
+
+ </select>
+ </div>
+ <div id="legend">
+ <span>not tracked</span>
+
+ <span class="cov0">no coverage</span>
+ <span class="cov1">low coverage</span>
+ <span class="cov2">*</span>
+ <span class="cov3">*</span>
+ <span class="cov4">*</span>
+ <span class="cov5">*</span>
+ <span class="cov6">*</span>
+ <span class="cov7">*</span>
+ <span class="cov8">*</span>
+ <span class="cov9">*</span>
+ <span class="cov10">high coverage</span>
+
+ </div>
+ </div>
+ <div id="content">
+
+ <pre class="file" id="file0" style="display: none">// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020-2021 Intel Corporation
+
+package readynotifyserver
+
+import (
+ "context"
+ "log"
+ "sync"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"
+)
+
+// readyNotifyServer will be initialized by NewReadyNotifyServer() and
+// its lifecycle is valid until all the clients unsubscribed the stream notification channel
+type readyNotifyServer struct {
+ name string
+ // alertNotify contains the map of "appContextID" and "map of client name and stream server"
+ // For Ex: map[12345687:map[[dtc:st1] [dcm:st2]] 456785369:map[[ncm:st3] [dtc:st4]]]
+ alertNotify map[string]map[string]pb.ReadyNotify_AlertServer
+ streamChannel map[pb.ReadyNotify_AlertServer]chan int
+ mutex sync.Mutex
+}
+
+var notifServer *readyNotifyServer
+
+// Alert gets notified when the subscriber subscribes for an appcontext event notification
+func (s *readyNotifyServer) Alert(topic *pb.Topic, stream pb.ReadyNotify_AlertServer) error <span class="cov4" title="2">{
+ client := topic.GetClientName()
+ appContextID := topic.GetAppContext()
+ log.Printf("[ReadyNotify gRPC] Received an Alert subscription request (%s, %s)", client, appContextID)
+
+ // Adding the appContextID entry to the map
+ s.mutex.Lock()
+ if len(s.alertNotify[appContextID]) == 0 </span><span class="cov1" title="1">{
+ s.alertNotify[appContextID] = make(map[string]pb.ReadyNotify_AlertServer)
+ }</span>
+ <span class="cov4" title="2">s.alertNotify[appContextID][client] = stream
+ s.streamChannel[stream] = make(chan int)
+ c := s.streamChannel[stream]
+ s.mutex.Unlock()
+
+ // Keep stream open
+ for </span><span class="cov4" title="2">{
+ select </span>{
+ case <-c:<span class="cov4" title="2">
+ log.Printf("[ReadyNotify gRPC] stop channel got triggered for the client = %s\n", client)
+ return nil</span>
+ }
+ }
+}
+
+//SendAppContextNotification sends appcontext back to the subscriber if pending
+func SendAppContextNotification(appContextID string) error <span class="cov0" title="0">{
+ streams := notifServer.alertNotify[appContextID]
+ var err error = nil
+ for _, stream := range streams </span><span class="cov0" title="0">{
+ err := stream.Send(&pb.Notification{AppContext: appContextID})
+ if err != nil </span><span class="cov0" title="0">{
+ logutils.Error("[ReadyNotify gRPC] Notification back to client failed to be sent", logutils.Fields{"err": err})
+ // return pkgerrors.New("Notification failed")
+ }</span> else<span class="cov0" title="0"> {
+ logutils.Info("[ReadyNotify gRPC] Notified the subscriber about appContext status changes", logutils.Fields{"appContextID": appContextID})
+ }</span>
+ }
+ <span class="cov0" title="0">return err</span>
+}
+
+// Unsubscribe will be called when the subscriber wants to terminate the stream
+func (s *readyNotifyServer) Unsubscribe(ctx context.Context, topic *pb.Topic) (*pb.UnsubscribeResponse, error) <span class="cov7" title="3">{
+
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ for appContextID, clientStreamMap := range s.alertNotify </span><span class="cov10" title="5">{
+ if appContextID == topic.GetAppContext() </span><span class="cov7" title="3">{
+ stream := clientStreamMap[topic.ClientName]
+ s.streamChannel[stream] <- 1
+
+ delete(clientStreamMap, topic.ClientName)
+ delete(s.streamChannel, stream)
+ // Delete the outer map's appcontextIDs if there is no inner map contents
+ if len(clientStreamMap) == 0 </span><span class="cov4" title="2">{
+ delete(s.alertNotify, appContextID)
+ }</span>
+ }
+ }
+
+ <span class="cov7" title="3">return &pb.UnsubscribeResponse{}, nil</span>
+}
+
+// NewReadyNotifyServer will create a new readyNotifyServer and destroys the previous one
+func NewReadyNotifyServer() *readyNotifyServer <span class="cov0" title="0">{
+ s := &readyNotifyServer{
+ name: "readyNotifyServer",
+ alertNotify: make(map[string](map[string]pb.ReadyNotify_AlertServer)),
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ }
+ notifServer = s
+ return s
+}</span>
+</pre>
+
+ </div>
+ </body>
+ <script>
+ (function() {
+ var files = document.getElementById('files');
+ var visible;
+ files.addEventListener('change', onChange, false);
+ function select(part) {
+ if (visible)
+ visible.style.display = 'none';
+ visible = document.getElementById(part);
+ if (!visible)
+ return;
+ files.value = part;
+ visible.style.display = 'block';
+ location.hash = part;
+ }
+ function onChange() {
+ select(files.value);
+ window.scrollTo(0, 0);
+ }
+ if (location.hash != "") {
+ select(location.hash.substr(1));
+ }
+ if (!visible) {
+ select("file0");
+ }
+ })();
+ </script>
+</html>
-module github.com/open-ness/EMCO/src/rsync\r
-\r
-go 1.13\r
-\r
-require (\r
- github.com/ghodss/yaml v1.0.0\r
- github.com/golang/protobuf v1.4.2\r
- github.com/jonboulle/clockwork v0.1.0\r
- github.com/open-ness/EMCO/src/monitor v0.0.0-00010101000000-000000000000\r
- github.com/open-ness/EMCO/src/orchestrator v0.0.0-00010101000000-000000000000\r
- github.com/pkg/errors v0.9.1\r
- github.com/sirupsen/logrus v1.6.0\r
- golang.org/x/net v0.0.0-20200707034311-ab3426394381\r
- golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e\r
- google.golang.org/grpc v1.28.0\r
- k8s.io/api v0.19.4\r
- k8s.io/apiextensions-apiserver v0.18.2\r
- k8s.io/apimachinery v0.19.4\r
- k8s.io/cli-runtime v0.19.4\r
- k8s.io/client-go v12.0.0+incompatible\r
- k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6\r
- k8s.io/kubectl v0.18.2\r
-)\r
-\r
-replace (\r
- github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.7.0\r
- github.com/open-ness/EMCO/src/monitor => ../monitor\r
- github.com/open-ness/EMCO/src/rsync => ../rsync\r
- github.com/open-ness/EMCO/src/orchestrator => ../vendor/github.com/open-ness/EMCO/src/orchestrator\r
- go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5 // 17cef6e3e9d5 is the SHA for git tag v3.4.12\r
- k8s.io/api => k8s.io/api v0.19.4\r
- k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.19.4\r
- k8s.io/apimachinery => k8s.io/apimachinery v0.19.4\r
- k8s.io/apiserver => k8s.io/apiserver v0.19.4\r
- k8s.io/cli-runtime => k8s.io/cli-runtime v0.19.4\r
- k8s.io/client-go => k8s.io/client-go v0.19.4\r
- k8s.io/cloud-provider => k8s.io/cloud-provider v0.19.4\r
- k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.19.4\r
- k8s.io/code-generator => k8s.io/code-generator v0.19.4\r
- k8s.io/component-base => k8s.io/component-base v0.19.4\r
- k8s.io/cri-api => k8s.io/cri-api v0.19.4\r
- k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.19.4\r
- k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.19.4\r
- k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.19.4\r
- k8s.io/kube-proxy => k8s.io/kube-proxy v0.19.4\r
- k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.19.4\r
- k8s.io/kubectl => k8s.io/kubectl v0.19.4\r
- k8s.io/kubelet => k8s.io/kubelet v0.19.4\r
- k8s.io/kubernetes => github.com/kubernetes/kubernetes v1.19.4\r
- k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.19.4\r
- k8s.io/metrics => k8s.io/metrics v0.19.4\r
- k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.19.4\r
-)\r
+module github.com/open-ness/EMCO/src/rsync
+
+go 1.13
+
+require (
+ github.com/ghodss/yaml v1.0.0
+ github.com/golang/mock v1.3.1
+ github.com/golang/protobuf v1.4.2
+ github.com/jonboulle/clockwork v0.1.0
+ github.com/open-ness/EMCO/src/monitor v0.0.0-00010101000000-000000000000
+ github.com/open-ness/EMCO/src/orchestrator v0.0.0-00010101000000-000000000000
+ github.com/pkg/errors v0.9.1
+ github.com/sirupsen/logrus v1.7.0
+ golang.org/x/net v0.0.0-20200707034311-ab3426394381
+ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
+ google.golang.org/grpc v1.28.0
+ google.golang.org/protobuf v1.24.0
+ k8s.io/api v0.20.2
+ k8s.io/apiextensions-apiserver v0.20.2
+ k8s.io/apimachinery v0.20.2
+ k8s.io/cli-runtime v0.20.2
+ k8s.io/client-go v12.0.0+incompatible
+ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd
+ k8s.io/kubectl v0.20.2
+)
+
+replace (
+ github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.7.0
+ github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d
+ github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
+ github.com/open-ness/EMCO/src/monitor => ../monitor
+ github.com/open-ness/EMCO/src/orchestrator => ../vendor/github.com/open-ness/EMCO/src/orchestrator
+ github.com/open-ness/EMCO/src/rsync => ../rsync
+ go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5 // 17cef6e3e9d5 is the SHA for git tag v3.4.12
+ helm.sh/helm/v3 => helm.sh/helm/v3 v3.5.3
+ k8s.io/api => k8s.io/api v0.19.4
+ k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.19.4
+ k8s.io/apimachinery => k8s.io/apimachinery v0.19.4
+ k8s.io/apiserver => k8s.io/apiserver v0.19.4
+ k8s.io/cli-runtime => k8s.io/cli-runtime v0.19.4
+ k8s.io/client-go => k8s.io/client-go v0.19.4
+ k8s.io/cloud-provider => k8s.io/cloud-provider v0.19.4
+ k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.19.4
+ k8s.io/code-generator => k8s.io/code-generator v0.19.4
+ k8s.io/component-base => k8s.io/component-base v0.19.4
+ k8s.io/cri-api => k8s.io/cri-api v0.19.4
+ k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.19.4
+ k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.19.4
+ k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.19.4
+ k8s.io/kube-proxy => k8s.io/kube-proxy v0.19.4
+ k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.19.4
+ k8s.io/kubectl => k8s.io/kubectl v0.19.4
+ k8s.io/kubelet => k8s.io/kubelet v0.19.4
+ k8s.io/kubernetes => github.com/kubernetes/kubernetes v1.19.4
+ k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.19.4
+ k8s.io/metrics => k8s.io/metrics v0.19.4
+ k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.19.4
+)
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
-bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v23.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
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/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
-github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
-github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
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/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
+github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
-github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
-github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
-github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
+github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
-github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
+github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
+github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
-github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk=
+github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
-github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/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/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
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/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
-github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
-github.com/aws/aws-sdk-go v1.6.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
+github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
+github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
-github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
-github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/brancz/gojsontoyaml v0.0.0-20191212081931-bf2969bbd742/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0=
github.com/brancz/kube-rbac-proxy v0.5.0/go.mod h1:cL2VjiIFGS90Cjh5ZZ8+It6tMcBt8rwvuw2J6Mamnl0=
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
-github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
-github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
-github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
-github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
-github.com/cilium/ebpf v0.0.0-20200601085316-9f1617e5c574/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
-github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
-github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
-github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
+github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
-github.com/containerd/ttrpc v1.0.0/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
-github.com/containerd/typeurl v1.0.0/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
-github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/coredns/corefile-migration v1.0.10/go.mod h1:RMy/mXdeDlYwzt0vdMEJvT2hGJ2I86/eO0UdXmH9XNI=
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo=
-github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+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-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
-github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
-github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
+github.com/deislabs/oras v0.10.0/go.mod h1:N1UzE7rBa9qLyN4l8IlBTxc2PkrRcKgWQ3HTJvRnJRE=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v20.10.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
-github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v1.4.2-0.20200309214505-aa6a9891b09c/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
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 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
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 h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
github.com/evanphx/json-patch v4.1.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/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
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/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
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-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M=
-github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-ini/ini v1.9.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
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/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY=
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-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
+github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
+github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
+github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=
+github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
+github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
github.com/gobuffalo/flect v0.2.1/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
+github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
+github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
+github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
+github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
+github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
+github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
+github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
+github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
+github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
+github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
+github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
+github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc=
+github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
-github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/cadvisor v0.37.0/go.mod h1:OhDE+goNVel0eGY8mR7Ifq1QUI1in5vJBIgIpcajK/I=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
-github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
-github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
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/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k=
-github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o=
-github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
-github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
-github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
+github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
+github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
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/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
+github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
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/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
-github.com/kubernetes/kubernetes v0.19.2/go.mod h1:uy4KkZ3U8byb0owsXQji5MEZjKCNMrl6ldqCSolS7/I=
-github.com/kubernetes/kubernetes v1.19.4/go.mod h1:yhT1/ltQajQsha3tnYc9QPFYSumGM45nlZdjf7WqE1A=
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
+github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.0/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY=
-github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA=
-github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04=
-github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk=
-github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao=
-github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
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/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
+github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
-github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
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-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
-github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU=
github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0=
-github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
-github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
-github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
+github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
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/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/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3DnAZsJsoaE=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
-github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
-github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
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/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
-github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
-github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v0.0.0-20170117200651-66bb6560562f/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc90.0.20200616040943-82d2fa4eb069/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8=
-github.com/opencontainers/runc v1.0.0-rc91.0.20200707015106-819fcc687efb/go.mod h1:ZuXhqlr4EiRYgDrBDNfSbE4+n9JX4+V107NwAmF7sZA=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
-github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
-github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII=
github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/operator-framework/api v0.3.7-0.20200602203552-431198de9fc2/go.mod h1:Xbje9x0SHmh0nihE21kpesB38vk3cyxnE6JdDS8Jo1Q=
github.com/operator-framework/api v0.3.8/go.mod h1:Xbje9x0SHmh0nihE21kpesB38vk3cyxnE6JdDS8Jo1Q=
github.com/operator-framework/operator-registry v1.12.6-0.20200611222234-275301b779f8/go.mod h1:loVINznYhgBIkmv83kU4yee88RS0BBk+hqOw9r4bhJk=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
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/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.2.0/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI=
github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
-github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
-github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
-github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc=
-github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
-github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
+github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
-github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
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 v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc=
-github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
-github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
-github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
-github.com/vishvananda/netns v0.0.0-20200520041808-52d707b772fe/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
-github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
-github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5 h1:Gqga3zA9tdAcfqobUGjSoCob5L3f8Dt5EuOp3ihNZko=
go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8=
-go.etcd.io/etcd v3.3.12+incompatible h1:V6PRYRGpU4k5EajJaaj/GL3hqIdzyPnBU8aPUp+35yw=
-go.etcd.io/etcd v3.3.12+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.0 h1:aeOqSrhl9eDRAap/3T5pCfMBEBxZ0vuXBP+RMtp2KX8=
go.mongodb.org/mongo-driver v1.1.0/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 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8=
+go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
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-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
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-20190412183630-56d357773e84/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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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-20180823144017-11551d06cbcc/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-20181122145206-62eef0e2fa9b/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-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/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-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
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.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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-20180828015842-6cd1fcedba52/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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190118193359-16909d206f00/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
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-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191030203535-5e247c9ad0a0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b h1:AFZdJUT7jJYXQEC29hYH/WZkoV7+KhwxQGmdZ19yYoY=
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto=
gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU=
-gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
-gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
-gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
-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=
-gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.1/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
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/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
-gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
gopkg.in/imdario/mergo.v0 v0.3.7/go.mod h1:9qPP6AGrlC1G2PTNXko614FwGZvorN7MiBU0Eppok+U=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
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/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.1.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
-helm.sh/helm/v3 v3.2.4/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
+gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
+helm.sh/helm/v3 v3.5.3/go.mod h1:Tv6yZjudrwek+Jhm0DSjZgM1zzPhkhd7avb7tc3lIwU=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
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.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
-k8s.io/api v0.19.2 h1:q+/krnHWKsL7OBZg/rxnycsl9569Pud76UJ77MvKXms=
-k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI=
k8s.io/api v0.19.4 h1:I+1I4cgJYuCDgiLNjKx7SLmIbwgj9w7N7Zr5vSIdwpo=
k8s.io/api v0.19.4/go.mod h1:SbtJ2aHCItirzdJ36YslycFNzWADYH3tgOhvBEFtZAk=
-k8s.io/apiextensions-apiserver v0.19.2 h1:oG84UwiDsVDu7dlsGQs5GySmQHCzMhknfhFExJMz9tA=
-k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg=
k8s.io/apiextensions-apiserver v0.19.4 h1:D9ak9T012tb3vcGFWYmbQuj9SCC8YM4zhA4XZqsAQC4=
k8s.io/apiextensions-apiserver v0.19.4/go.mod h1:B9rpH/nu4JBCtuUp3zTTk8DEjZUupZTBEec7/2zNRYw=
-k8s.io/apimachinery v0.19.2 h1:5Gy9vQpAGTKHPVOh5c4plE274X8D/6cuEiTO2zve7tc=
-k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
k8s.io/apimachinery v0.19.4 h1:+ZoddM7nbzrDCp0T3SWnyxqf8cbWPT2fkZImoyvHUG0=
k8s.io/apimachinery v0.19.4/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
-k8s.io/apiserver v0.19.2/go.mod h1:FreAq0bJ2vtZFj9Ago/X0oNGC51GfubKK/ViOKfVAOA=
k8s.io/apiserver v0.19.4/go.mod h1:X8WRHCR1UGZDd7HpV0QDc1h/6VbbpAeAGyxSh8yzZXw=
k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA=
-k8s.io/cli-runtime v0.19.2 h1:d4uOtKhy3ImdaKqZJ8yQgLrdtUwsJLfP4Dw7L/kVPOo=
-k8s.io/cli-runtime v0.19.2/go.mod h1:CMynmJM4Yf02TlkbhKxoSzi4Zf518PukJ5xep/NaNeY=
k8s.io/cli-runtime v0.19.4 h1:FPpoqFbWsFzRbZNRI+o/+iiLFmWMYTmBueIj3OaNVTI=
k8s.io/cli-runtime v0.19.4/go.mod h1:m8G32dVbKOeaX1foGhleLEvNd6REvU7YnZyWn5//9rw=
-k8s.io/client-go v0.19.2 h1:gMJuU3xJZs86L1oQ99R4EViAADUPMHHtS9jFshasHSc=
-k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA=
k8s.io/client-go v0.19.4 h1:85D3mDNoLF+xqpyE9Dh/OtrJDyJrSRKkHmDXIbEzer8=
k8s.io/client-go v0.19.4/go.mod h1:ZrEy7+wj9PjH5VMBCuu/BDlvtUAku0oVFk4MmnW9mWA=
-k8s.io/cloud-provider v0.19.2/go.mod h1:aj+g++cXa2EcXhwXPpqf81wNGxtXxAZjvPoIFjMRtIc=
-k8s.io/cloud-provider v0.19.4/go.mod h1:NZGs+2FmZ9PUmhXxXJmAwmiDjmPSc+uqGHUAvlZRXxo=
-k8s.io/cluster-bootstrap v0.19.2/go.mod h1:bzngsppPfdt9vAHUnDIEoMNsxD2b6XArVVH/W9PDDFk=
-k8s.io/cluster-bootstrap v0.19.4/go.mod h1:6+8sq9PmyEmFI61YdU7/5ANx+net3usE7Hq0tJvR3D8=
-k8s.io/code-generator v0.19.2/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
k8s.io/code-generator v0.19.4/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
-k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo=
k8s.io/component-base v0.19.4/go.mod h1:ZzuSLlsWhajIDEkKF73j64Gz/5o0AgON08FgRbEPI70=
-k8s.io/cri-api v0.19.2/go.mod h1:UN/iU9Ua0iYdDREBXNE9vqCJ7MIh/FW3VIL0d8pw7Fw=
-k8s.io/cri-api v0.19.4/go.mod h1:UN/iU9Ua0iYdDREBXNE9vqCJ7MIh/FW3VIL0d8pw7Fw=
-k8s.io/csi-translation-lib v0.19.2/go.mod h1:9V3DYlJ6reyKD+/S/JrFyk/j0N1i8FCQYukch0JbNew=
-k8s.io/csi-translation-lib v0.19.4/go.mod h1:Zqw8qVIHp6OU65hvIYeOlkMwHLpKy72h3P15AkY90W0=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM=
-k8s.io/helm v2.14.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI=
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.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/kube-aggregator v0.19.2/go.mod h1:wVsjy6OTeUrWkgG9WVsGftnjpm8JIY0vJV7LH2j4nhM=
-k8s.io/kube-aggregator v0.19.4/go.mod h1:cTkvun110194d797AuThyydBBlgm+cKIFUeS2uzGJfU=
-k8s.io/kube-controller-manager v0.19.2/go.mod h1:29rfd3qO+zmDKPWyBYYEBw5487tHD4T22Hp4oNqiA18=
-k8s.io/kube-controller-manager v0.19.4/go.mod h1:39Dh9ygYryrvBn6PCeGJRK7qHB0SjSOPmv32h2wT7Kc=
+k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
+k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29 h1:NeQXVJ2XFSkRoPzRo8AId01ZER+j8oV4SZADT4iBOXQ=
-k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
-k8s.io/kube-proxy v0.19.2/go.mod h1:/07XChnL0EkYAQyZ7noQuyPYX5QOUBQECa9dsm9ScyY=
-k8s.io/kube-proxy v0.19.4/go.mod h1:HqXWMgFOJQB0geLBXeMn2e5k9864NM/t3wrHxJjqqrk=
-k8s.io/kube-scheduler v0.19.2/go.mod h1:Mh/QNfmP0eqt7JtNUyIAsGhU2zO4j1EWel8TFizxZKo=
-k8s.io/kube-scheduler v0.19.4/go.mod h1:r0SdH7fwIKyA/MURcRS4jNjTjfBEju3oIBll0Dxqjj4=
+k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c=
+k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E=
-k8s.io/kubectl v0.19.2 h1:/Dxz9u7S0GnchLA6Avqi5k1qhZH4Fusgecj8dHsSnbk=
-k8s.io/kubectl v0.19.2/go.mod h1:4ib3oj5ma6gF95QukTvC7ZBMxp60+UEAhDPjLuBIrV4=
k8s.io/kubectl v0.19.4 h1:XFrHibf5fS4Ot8h3EnzdVsKrYj+pndlzKbwPkfra5hI=
k8s.io/kubectl v0.19.4/go.mod h1:XPmlu4DJEYgD83pvZFeKF8+MSvGnYGqunbFSrJsqHv0=
-k8s.io/kubelet v0.19.2/go.mod h1:FHHoByVWzh6kNaarXaDPAa751Oz6REcOVRyFT84L1Is=
-k8s.io/kubelet v0.19.4/go.mod h1:zJnPeb7nJCRvtAwxJhe9fFCtMLXL3cXbQiczPmpDrLU=
-k8s.io/legacy-cloud-providers v0.19.2/go.mod h1:++wIKZl+1DvQ5i5y1T2ZzwYRkLFuhsZ/SIEivHsM9ro=
-k8s.io/legacy-cloud-providers v0.19.4/go.mod h1:/zI3R0GKwt29cn4Xaf2u5aM3tiWvQk7YqJk/PNwUp6Y=
-k8s.io/metrics v0.19.2/go.mod h1:IlLaAGXN0q7yrtB+SV0q3JIraf6VtlDr+iuTcX21fCU=
k8s.io/metrics v0.19.4/go.mod h1:a0gvAzrxQPw2ouBqnXI7X9qlggpPkKAFgWU/Py+KZiU=
-k8s.io/sample-apiserver v0.19.2/go.mod h1:XZxHsGPvUkjzos8B/lhbM4REthLt4tRMfkhN2CRXCGs=
-k8s.io/sample-apiserver v0.19.4/go.mod h1:W6CbyItC0Hz0q1lLsHIWeRwSuijevDkk/P+txorhqy4=
-k8s.io/system-validators v1.1.2/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
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-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-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=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
-rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0=
sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM=
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
-sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "k8s.io/apimachinery/pkg/api/errors"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/apimachinery/pkg/types"\r
- "k8s.io/cli-runtime/pkg/resource"\r
- "k8s.io/kubectl/pkg/util"\r
-)\r
-\r
-// Apply creates a resource with the given content\r
-func (c *Client) Apply(content []byte) error {\r
- r := c.ResultForContent(content, nil)\r
- return c.ApplyResource(r)\r
-}\r
-\r
-// ApplyFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs\r
-func (c *Client) ApplyFiles(filenames ...string) error {\r
- r := c.ResultForFilenameParam(filenames, nil)\r
- return c.ApplyResource(r)\r
-}\r
-\r
-// ApplyResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`\r
-func (c *Client) ApplyResource(r *resource.Result) error {\r
- if err := r.Err(); err != nil {\r
- return err\r
- }\r
-\r
- // Is ServerSideApply requested\r
- if c.ServerSideApply {\r
- return r.Visit(serverSideApply)\r
- }\r
-\r
- return r.Visit(apply)\r
-}\r
-\r
-func apply(info *resource.Info, err error) error {\r
- if err != nil {\r
- return failedTo("apply", info, err)\r
- }\r
-\r
- // If it does not exists, just create it\r
- current, err := resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)\r
- if err != nil {\r
- if !errors.IsNotFound(err) {\r
- return failedTo("retrieve current configuration", info, err)\r
- }\r
- if err := util.CreateApplyAnnotation(info.Object, unstructured.UnstructuredJSONScheme); err != nil {\r
- return failedTo("set annotation", info, err)\r
- }\r
- return create(info, nil)\r
- }\r
-\r
- // If exists, patch it\r
- return patch(info, current)\r
-}\r
-\r
-func serverSideApply(info *resource.Info, err error) error {\r
- if err != nil {\r
- return failedTo("serverside apply", info, err)\r
- }\r
-\r
- data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, info.Object)\r
- if err != nil {\r
- return failedTo("encode for the serverside apply", info, err)\r
- }\r
-\r
- options := metav1.PatchOptions{\r
- // TODO: Find out how to get the force conflict flag\r
- // Force: &forceConflicts,\r
- // FieldManager: FieldManager,\r
- }\r
- obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.ApplyPatchType, data, &options)\r
- if err != nil {\r
- return failedTo("serverside patch", info, err)\r
- }\r
- info.Refresh(obj, true)\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/cli-runtime/pkg/resource"
+ "k8s.io/kubectl/pkg/util"
+)
+
+// Apply creates a resource with the given content
+func (c *Client) Apply(content []byte) error {
+ r := c.ResultForContent(content, nil)
+ return c.ApplyResource(r)
+}
+
+// ApplyFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs
+func (c *Client) ApplyFiles(filenames ...string) error {
+ r := c.ResultForFilenameParam(filenames, nil)
+ return c.ApplyResource(r)
+}
+
+// ApplyResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`
+func (c *Client) ApplyResource(r *resource.Result) error {
+ if err := r.Err(); err != nil {
+ return err
+ }
+
+ // Is ServerSideApply requested
+ if c.ServerSideApply {
+ return r.Visit(serverSideApply)
+ }
+
+ return r.Visit(apply)
+}
+
+func apply(info *resource.Info, err error) error {
+ if err != nil {
+ return failedTo("apply", info, err)
+ }
+
+ // If it does not exists, just create it
+ current, err := resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)
+ if err != nil {
+ if !errors.IsNotFound(err) {
+ return failedTo("retrieve current configuration", info, err)
+ }
+ if err := util.CreateApplyAnnotation(info.Object, unstructured.UnstructuredJSONScheme); err != nil {
+ return failedTo("set annotation", info, err)
+ }
+ return create(info, nil)
+ }
+
+ // If exists, patch it
+ return patch(info, current)
+}
+
+func serverSideApply(info *resource.Info, err error) error {
+ if err != nil {
+ return failedTo("serverside apply", info, err)
+ }
+
+ data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, info.Object)
+ if err != nil {
+ return failedTo("encode for the serverside apply", info, err)
+ }
+
+ options := metav1.PatchOptions{
+ // TODO: Find out how to get the force conflict flag
+ // Force: &forceConflicts,
+ // FieldManager: FieldManager,
+ }
+ obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.ApplyPatchType, data, &options)
+ if err != nil {
+ return failedTo("serverside patch", info, err)
+ }
+ info.Refresh(obj, true)
+ return nil
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-package client\r
-\r
-import (\r
- "context"\r
- "encoding/json"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext/subresources"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- pkgerrors "github.com/pkg/errors"\r
- certificatesv1beta1 "k8s.io/api/certificates/v1beta1"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
-)\r
-\r
-func (c *Client) Approve(name string, sa []byte) error {\r
-\r
- var a subresources.ApprovalSubresource\r
- err := json.Unmarshal(sa, &a)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "An error occurred while parsing the approval Subresource.")\r
- }\r
- csr, err := c.Clientset.CertificatesV1beta1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{})\r
- if err != nil {\r
- return err\r
- }\r
- var timePtr metav1.Time\r
- str := []string{a.LastUpdateTime}\r
- if err = metav1.Convert_Slice_string_To_v1_Time(&str, &timePtr, nil); err != nil {\r
- return pkgerrors.Wrap(err, "An error occurred while converting time from string.")\r
- }\r
- // Update CSR with Conditions\r
- csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{\r
- Type: certificatesv1beta1.RequestConditionType(a.Type),\r
- Reason: a.Reason,\r
- Message: a.Message,\r
- LastUpdateTime: timePtr,\r
- })\r
- // CSR Approval\r
- _, err = c.Clientset.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{})\r
- if err != nil {\r
- logutils.Error("Failed to UpdateApproval", logutils.Fields{\r
- "error": err,\r
- "resource": name,\r
- })\r
- return err\r
- }\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package client
+
+import (
+ "context"
+ "encoding/json"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext/subresources"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pkgerrors "github.com/pkg/errors"
+ certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func (c *Client) Approve(name string, sa []byte) error {
+
+ var a subresources.ApprovalSubresource
+ err := json.Unmarshal(sa, &a)
+ if err != nil {
+ return pkgerrors.Wrap(err, "An error occurred while parsing the approval Subresource.")
+ }
+ csr, err := c.Clientset.CertificatesV1beta1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{})
+ if err != nil {
+ return err
+ }
+ var timePtr metav1.Time
+ str := []string{a.LastUpdateTime}
+ if err = metav1.Convert_Slice_string_To_v1_Time(&str, &timePtr, nil); err != nil {
+ return pkgerrors.Wrap(err, "An error occurred while converting time from string.")
+ }
+ // Update CSR with Conditions
+ csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{
+ Type: certificatesv1beta1.RequestConditionType(a.Type),
+ Reason: a.Reason,
+ Message: a.Message,
+ LastUpdateTime: timePtr,
+ })
+ // CSR Approval
+ _, err = c.Clientset.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{})
+ if err != nil {
+ logutils.Error("Failed to UpdateApproval", logutils.Fields{
+ "error": err,
+ "resource": name,
+ })
+ return err
+ }
+ return nil
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "bytes"\r
- "fmt"\r
- "io"\r
-\r
- v1 "k8s.io/api/core/v1"\r
- "k8s.io/cli-runtime/pkg/resource"\r
- "k8s.io/client-go/kubernetes"\r
- "k8s.io/kubectl/pkg/validation"\r
-)\r
-\r
-// DefaultValidation default action to validate. If `true` all resources by\r
-// default will be validated.\r
-const DefaultValidation = false\r
-\r
-// Client is a kubernetes client, like `kubectl`\r
-type Client struct {\r
- Clientset *kubernetes.Clientset\r
- factory *factory\r
- validator validation.Schema\r
- namespace string\r
- enforceNamespace bool\r
- forceConflicts bool\r
- ServerSideApply bool\r
-}\r
-\r
-// Result is an alias for the Kubernetes CLI runtime resource.Result\r
-type Result = resource.Result\r
-\r
-// BuilderOptions parameters to create a Resource Builder\r
-type BuilderOptions struct {\r
- Unstructured bool\r
- Validate bool\r
- Namespace string\r
- LabelSelector string\r
- FieldSelector string\r
- All bool\r
- AllNamespaces bool\r
-}\r
-\r
-// NewBuilderOptions creates a BuilderOptions with the default values for\r
-// the parameters to create a Resource Builder\r
-func NewBuilderOptions() *BuilderOptions {\r
- return &BuilderOptions{\r
- Unstructured: true,\r
- Validate: true,\r
- }\r
-}\r
-\r
-// NewE creates a kubernetes client, returns an error if fail\r
-func NewE(context, kubeconfig string, ns string) (*Client, error) {\r
- var namespace string\r
- var enforceNamespace bool\r
- var err error\r
- factory := newFactory(context, kubeconfig)\r
-\r
- // If `true` it will always validate the given objects/resources\r
- // Unless something different is specified in the NewBuilderOptions\r
- validator, _ := factory.Validator(DefaultValidation)\r
-\r
- if ns == "" {\r
- namespace, enforceNamespace, err = factory.ToRawKubeConfigLoader().Namespace()\r
- if err != nil {\r
- namespace = v1.NamespaceDefault\r
- enforceNamespace = true\r
- }\r
- } else {\r
- namespace = ns\r
- enforceNamespace = false\r
- }\r
- clientset, err := factory.KubernetesClientSet()\r
- if err != nil {\r
- return nil, err\r
- }\r
- if clientset == nil {\r
- return nil, fmt.Errorf("cannot create a clientset from given context and kubeconfig")\r
- }\r
-\r
- return &Client{\r
- factory: factory,\r
- Clientset: clientset,\r
- validator: validator,\r
- namespace: namespace,\r
- enforceNamespace: enforceNamespace,\r
- }, nil\r
-}\r
-\r
-// New creates a kubernetes client\r
-func New(context, kubeconfig string, namespace string) *Client {\r
- client, _ := NewE(context, kubeconfig, namespace)\r
- return client\r
-}\r
-\r
-// Builder creates a resource builder\r
-func (c *Client) builder(opt *BuilderOptions) *resource.Builder {\r
- validator := c.validator\r
- namespace := c.namespace\r
-\r
- if opt == nil {\r
- opt = NewBuilderOptions()\r
- } else {\r
- if opt.Validate != DefaultValidation {\r
- validator, _ = c.factory.Validator(opt.Validate)\r
- }\r
- if opt.Namespace != "" {\r
- namespace = opt.Namespace\r
- }\r
- }\r
-\r
- b := c.factory.NewBuilder()\r
- if opt.Unstructured {\r
- b = b.Unstructured()\r
- }\r
-\r
- return b.\r
- Schema(validator).\r
- ContinueOnError().\r
- NamespaceParam(namespace).DefaultNamespace()\r
-}\r
-\r
-// ResultForFilenameParam returns the builder results for the given list of files or URLs\r
-func (c *Client) ResultForFilenameParam(filenames []string, opt *BuilderOptions) *Result {\r
- filenameOptions := &resource.FilenameOptions{\r
- Recursive: false,\r
- Filenames: filenames,\r
- }\r
-\r
- return c.builder(opt).\r
- FilenameParam(c.enforceNamespace, filenameOptions).\r
- Flatten().\r
- Do()\r
-}\r
-\r
-// ResultForReader returns the builder results for the given reader\r
-func (c *Client) ResultForReader(r io.Reader, opt *BuilderOptions) *Result {\r
- return c.builder(opt).\r
- Stream(r, "").\r
- Flatten().\r
- Do()\r
-}\r
-\r
-// func (c *Client) ResultForName(opt *BuilderOptions, names ...string) *Result {\r
-// return c.builder(opt).\r
-// LabelSelectorParam(opt.LabelSelector).\r
-// FieldSelectorParam(opt.FieldSelector).\r
-// SelectAllParam(opt.All).\r
-// AllNamespaces(opt.AllNamespaces).\r
-// ResourceTypeOrNameArgs(false, names...).RequireObject(false).\r
-// Flatten().\r
-// Do()\r
-// }\r
-\r
-// ResultForContent returns the builder results for the given content\r
-func (c *Client) ResultForContent(content []byte, opt *BuilderOptions) *Result {\r
- b := bytes.NewBuffer(content)\r
- return c.ResultForReader(b, opt)\r
-}\r
-\r
-func failedTo(action string, info *resource.Info, err error) error {\r
- var resKind string\r
- if info.Mapping != nil {\r
- resKind = info.Mapping.GroupVersionKind.Kind + " "\r
- }\r
-\r
- return fmt.Errorf("cannot %s object Kind: %q, Name: %q, Namespace: %q. %s", action, resKind, info.Name, info.Namespace, err)\r
-}\r
-\r
-// IsReachable tests connectivity to the cluster\r
-func (c *Client) IsReachable() error {\r
- client, _ := c.factory.KubernetesClientSet()\r
- _, err := client.ServerVersion()\r
- if err != nil {\r
- return fmt.Errorf("Kubernetes cluster unreachable")\r
- }\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+
+ v1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/cli-runtime/pkg/resource"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/kubectl/pkg/validation"
+
+ resapi "k8s.io/apimachinery/pkg/api/resource"
+)
+
+// DefaultValidation default action to validate. If `true` all resources by
+// default will be validated.
+const DefaultValidation = false
+
+// Client is a kubernetes client, like `kubectl`
+type Client struct {
+ Clientset kubernetes.Interface
+ DynamicClient dynamic.Interface
+ RestMapper meta.RESTMapper
+ factory *factory
+ validator validation.Schema
+ namespace string
+ enforceNamespace bool
+ forceConflicts bool
+ ServerSideApply bool
+}
+
+// Result is an alias for the Kubernetes CLI runtime resource.Result
+type Result = resource.Result
+
+// BuilderOptions parameters to create a Resource Builder
+type BuilderOptions struct {
+ Unstructured bool
+ Validate bool
+ Namespace string
+ LabelSelector string
+ FieldSelector string
+ All bool
+ AllNamespaces bool
+}
+
+// NewBuilderOptions creates a BuilderOptions with the default values for
+// the parameters to create a Resource Builder
+func NewBuilderOptions() *BuilderOptions {
+ return &BuilderOptions{
+ Unstructured: true,
+ Validate: true,
+ }
+}
+
+// NewE creates a kubernetes client, returns an error if fail
+func NewE(context, kubeconfig string, ns string) (*Client, error) {
+ var namespace string
+ var enforceNamespace bool
+ var err error
+ factory := newFactory(context, kubeconfig)
+
+ // If `true` it will always validate the given objects/resources
+ // Unless something different is specified in the NewBuilderOptions
+ validator, _ := factory.Validator(DefaultValidation)
+
+ if ns == "" {
+ namespace, enforceNamespace, err = factory.ToRawKubeConfigLoader().Namespace()
+ if err != nil {
+ namespace = v1.NamespaceDefault
+ enforceNamespace = true
+ }
+ } else {
+ namespace = ns
+ enforceNamespace = false
+ }
+
+ clientset, err := factory.KubernetesClientSet()
+ if err != nil {
+ return nil, err
+ }
+ if clientset == nil {
+ return nil, fmt.Errorf("cannot create a clientset from given context and kubeconfig")
+ }
+
+ dynamicClient, err := factory.DynamicClient()
+ if err != nil {
+ return nil, err
+ }
+ if dynamicClient == nil {
+ return nil, fmt.Errorf("cannot create a dynamic client from given context and kubeconfig")
+ }
+
+ restMapper, err := factory.ToRESTMapper()
+ if err != nil {
+ return nil, err
+ }
+ if restMapper == nil {
+ return nil, fmt.Errorf("cannot create a restMapper from given context and kubeconfig")
+ }
+
+ return &Client{
+ factory: factory,
+ Clientset: clientset,
+ DynamicClient: dynamicClient,
+ RestMapper: restMapper,
+ validator: validator,
+ namespace: namespace,
+ enforceNamespace: enforceNamespace,
+ }, nil
+}
+
+// New creates a kubernetes client
+func New(context, kubeconfig string, namespace string) *Client {
+ client, _ := NewE(context, kubeconfig, namespace)
+ return client
+}
+
+// Builder creates a resource builder
+func (c *Client) builder(opt *BuilderOptions) *resource.Builder {
+ validator := c.validator
+ namespace := c.namespace
+
+ if opt == nil {
+ opt = NewBuilderOptions()
+ } else {
+ if opt.Validate != DefaultValidation {
+ validator, _ = c.factory.Validator(opt.Validate)
+ }
+ if opt.Namespace != "" {
+ namespace = opt.Namespace
+ }
+ }
+
+ b := c.factory.NewBuilder()
+ if opt.Unstructured {
+ b = b.Unstructured()
+ }
+
+ return b.
+ Schema(validator).
+ ContinueOnError().
+ NamespaceParam(namespace).DefaultNamespace()
+}
+
+// ResultForFilenameParam returns the builder results for the given list of files or URLs
+func (c *Client) ResultForFilenameParam(filenames []string, opt *BuilderOptions) *Result {
+ filenameOptions := &resource.FilenameOptions{
+ Recursive: false,
+ Filenames: filenames,
+ }
+
+ return c.builder(opt).
+ FilenameParam(c.enforceNamespace, filenameOptions).
+ Flatten().
+ Do()
+}
+
+// ResultForReader returns the builder results for the given reader
+func (c *Client) ResultForReader(r io.Reader, opt *BuilderOptions) *Result {
+ return c.builder(opt).
+ Stream(r, "").
+ Flatten().
+ Do()
+}
+
+// func (c *Client) ResultForName(opt *BuilderOptions, names ...string) *Result {
+// return c.builder(opt).
+// LabelSelectorParam(opt.LabelSelector).
+// FieldSelectorParam(opt.FieldSelector).
+// SelectAllParam(opt.All).
+// AllNamespaces(opt.AllNamespaces).
+// ResourceTypeOrNameArgs(false, names...).RequireObject(false).
+// Flatten().
+// Do()
+// }
+
+// ResultForContent returns the builder results for the given content
+func (c *Client) ResultForContent(content []byte, opt *BuilderOptions) *Result {
+ b := bytes.NewBuffer(content)
+ return c.ResultForReader(b, opt)
+}
+
+func failedTo(action string, info *resource.Info, err error) error {
+ var resKind string
+ if info.Mapping != nil {
+ resKind = info.Mapping.GroupVersionKind.Kind + " "
+ }
+
+ return fmt.Errorf("cannot %s object Kind: %q, Name: %q, Namespace: %q. %s", action, resKind, info.Name, info.Namespace, err)
+}
+
+// IsReachable tests connectivity to the cluster
+func (c *Client) IsReachable() error {
+ client, err := c.factory.KubernetesClientSet()
+ if err != nil {
+ return fmt.Errorf("Kubernetes cluster unreachable")
+ }
+ _, err = client.ServerVersion()
+ if err != nil {
+ return fmt.Errorf("Kubernetes cluster unreachable")
+ }
+ return nil
+}
+
+// PopulateResourceListV1WithDefValues takes strings of form <resourceName1>=<value1>,<resourceName1>=<value2>
+// and returns ResourceList.
+func PopulateResourceListV1WithDefValues(spec string) (v1.ResourceList, error) {
+ // empty input gets a nil response to preserve generator test expected behaviors
+ if spec == "" {
+ return nil, nil
+ }
+
+ result := v1.ResourceList{}
+ resourceStatements := strings.Split(spec, ",")
+ for _, resourceStatement := range resourceStatements {
+ parts := strings.Split(resourceStatement, "=")
+ if len(parts) != 2 {
+ return nil, fmt.Errorf("PopulateResourceListV1WithDefValues .. Invalid argument syntax %v, expected <resource>=<value>", resourceStatement)
+ }
+ resourceName := v1.ResourceName(parts[0])
+ resourceQuantity, err := resapi.ParseQuantity(parts[1])
+ if err != nil {
+ return nil, err
+ }
+ result[resourceName] = resourceQuantity
+ }
+ return result, nil
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "k8s.io/cli-runtime/pkg/resource"\r
-)\r
-\r
-// Create creates a resource with the given content\r
-func (c *Client) Create(content []byte) error {\r
- r := c.ResultForContent(content, nil)\r
- return c.CreateResource(r)\r
-}\r
-\r
-// CreateFile creates a resource with the given content\r
-func (c *Client) CreateFile(filenames ...string) error {\r
- r := c.ResultForFilenameParam(filenames, nil)\r
- return c.CreateResource(r)\r
-}\r
-\r
-// CreateResource creates the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`\r
-func (c *Client) CreateResource(r *resource.Result) error {\r
- if err := r.Err(); err != nil {\r
- return err\r
- }\r
- return r.Visit(create)\r
-}\r
-\r
-func create(info *resource.Info, err error) error {\r
- if err != nil {\r
- return failedTo("create", info, err)\r
- }\r
-\r
- // TODO: If will be allow to do create then apply, here must be added the annotation as in Apply/Patch\r
-\r
- obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)\r
- if err != nil {\r
- return failedTo("create", info, err)\r
- }\r
- info.Refresh(obj, true)\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "k8s.io/cli-runtime/pkg/resource"
+)
+
+// Create creates a resource with the given content
+func (c *Client) Create(content []byte) error {
+ r := c.ResultForContent(content, nil)
+ return c.CreateResource(r)
+}
+
+// CreateFile creates a resource with the given content
+func (c *Client) CreateFile(filenames ...string) error {
+ r := c.ResultForFilenameParam(filenames, nil)
+ return c.CreateResource(r)
+}
+
+// CreateResource creates the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`
+func (c *Client) CreateResource(r *resource.Result) error {
+ if err := r.Err(); err != nil {
+ return err
+ }
+ return r.Visit(create)
+}
+
+func create(info *resource.Info, err error) error {
+ if err != nil {
+ return failedTo("create", info, err)
+ }
+
+ // TODO: If will be allow to do create then apply, here must be added the annotation as in Apply/Patch
+
+ obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
+ if err != nil {
+ return failedTo("create", info, err)
+ }
+ info.Refresh(obj, true)
+
+ return nil
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/cli-runtime/pkg/resource"\r
-)\r
-\r
-const (\r
- // Period of time in seconds given to the resource to terminate gracefully when delete it (used when require to recreate the resource). Ignored if negative. Set to 1 for immediate shutdown. Can only be set to 0 when force is true (force deletion)\r
- gracePeriod = -1\r
- // If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController).\r
- cascade = true\r
-)\r
-\r
-// Delete creates a resource with the given content\r
-func (c *Client) Delete(content []byte) error {\r
- r := c.ResultForContent(content, nil)\r
- return c.DeleteResource(r)\r
-}\r
-\r
-// DeleteFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs\r
-func (c *Client) DeleteFiles(filenames ...string) error {\r
- r := c.ResultForFilenameParam(filenames, nil)\r
- return c.DeleteResource(r)\r
-}\r
-\r
-// DeleteResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`\r
-func (c *Client) DeleteResource(r *resource.Result) error {\r
- if err := r.Err(); err != nil {\r
- return err\r
- }\r
- return r.Visit(delete)\r
-}\r
-\r
-func delete(info *resource.Info, err error) error {\r
- if err != nil {\r
- return failedTo("delete", info, err)\r
- }\r
-\r
- // TODO: Background or Foreground?\r
- // policy := metav1.DeletePropagationForeground\r
- policy := metav1.DeletePropagationBackground\r
- options := metav1.DeleteOptions{\r
- PropagationPolicy: &policy,\r
- }\r
-\r
- if _, err := deleteWithOptions(info, &options); err != nil {\r
- return failedTo("delete", info, err)\r
- }\r
- return nil\r
-}\r
-\r
-func defaultDeleteOptions() *metav1.DeleteOptions {\r
- // TODO: Change DryRun value when DryRun is implemented\r
- dryRun := false\r
-\r
- options := &metav1.DeleteOptions{}\r
- if gracePeriod >= 0 {\r
- options = metav1.NewDeleteOptions(int64(gracePeriod))\r
- }\r
-\r
- if dryRun {\r
- options.DryRun = []string{metav1.DryRunAll}\r
- }\r
-\r
- // TODO: Background or Foreground?\r
- // policy := metav1.DeletePropagationBackground\r
- policy := metav1.DeletePropagationForeground\r
- if !cascade {\r
- policy = metav1.DeletePropagationOrphan\r
- }\r
- options.PropagationPolicy = &policy\r
-\r
- return options\r
-}\r
-\r
-func deleteWithOptions(info *resource.Info, options *metav1.DeleteOptions) (runtime.Object, error) {\r
- if options == nil {\r
- options = defaultDeleteOptions()\r
- }\r
- return resource.NewHelper(info.Client, info.Mapping).DeleteWithOptions(info.Namespace, info.Name, options)\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/cli-runtime/pkg/resource"
+)
+
+const (
+ // Period of time in seconds given to the resource to terminate gracefully when delete it (used when require to recreate the resource). Ignored if negative. Set to 1 for immediate shutdown. Can only be set to 0 when force is true (force deletion)
+ gracePeriod = -1
+ // If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController).
+ cascade = true
+)
+
+// Delete creates a resource with the given content
+func (c *Client) Delete(content []byte) error {
+ r := c.ResultForContent(content, nil)
+ return c.DeleteResource(r)
+}
+
+// DeleteFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs
+func (c *Client) DeleteFiles(filenames ...string) error {
+ r := c.ResultForFilenameParam(filenames, nil)
+ return c.DeleteResource(r)
+}
+
+// DeleteResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`
+func (c *Client) DeleteResource(r *resource.Result) error {
+ if err := r.Err(); err != nil {
+ return err
+ }
+ return r.Visit(delete)
+}
+
+func delete(info *resource.Info, err error) error {
+ if err != nil {
+ return failedTo("delete", info, err)
+ }
+
+ // TODO: Background or Foreground?
+ // policy := metav1.DeletePropagationForeground
+ policy := metav1.DeletePropagationBackground
+ options := metav1.DeleteOptions{
+ PropagationPolicy: &policy,
+ }
+
+ if _, err := deleteWithOptions(info, &options); err != nil {
+ return failedTo("delete", info, err)
+ }
+ return nil
+}
+
+func defaultDeleteOptions() *metav1.DeleteOptions {
+ // TODO: Change DryRun value when DryRun is implemented
+ dryRun := false
+
+ options := &metav1.DeleteOptions{}
+ if gracePeriod >= 0 {
+ options = metav1.NewDeleteOptions(int64(gracePeriod))
+ }
+
+ if dryRun {
+ options.DryRun = []string{metav1.DryRunAll}
+ }
+
+ // TODO: Background or Foreground?
+ // policy := metav1.DeletePropagationBackground
+ policy := metav1.DeletePropagationForeground
+ if !cascade {
+ policy = metav1.DeletePropagationOrphan
+ }
+ options.PropagationPolicy = &policy
+
+ return options
+}
+
+func deleteWithOptions(info *resource.Info, options *metav1.DeleteOptions) (runtime.Object, error) {
+ if options == nil {
+ options = defaultDeleteOptions()
+ }
+ return resource.NewHelper(info.Client, info.Mapping).DeleteWithOptions(info.Namespace, info.Name, options)
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "path/filepath"\r
- "regexp"\r
- "strings"\r
- "sync"\r
- "time"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
- apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"\r
- apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"\r
- "k8s.io/apimachinery/pkg/api/meta"\r
- "k8s.io/apimachinery/pkg/runtime/schema"\r
- "k8s.io/cli-runtime/pkg/genericclioptions"\r
- "k8s.io/cli-runtime/pkg/resource"\r
- "k8s.io/client-go/discovery"\r
- diskcached "k8s.io/client-go/discovery/cached/disk"\r
- "k8s.io/client-go/dynamic"\r
- "k8s.io/client-go/kubernetes"\r
- "k8s.io/client-go/kubernetes/scheme"\r
- "k8s.io/client-go/rest"\r
- "k8s.io/client-go/restmapper"\r
- "k8s.io/client-go/tools/clientcmd"\r
- "k8s.io/client-go/util/homedir"\r
- "k8s.io/kubectl/pkg/util/openapi"\r
- openapivalidation "k8s.io/kubectl/pkg/util/openapi/validation"\r
- "k8s.io/kubectl/pkg/validation"\r
-)\r
-\r
-// factory implements the kubectl Factory interface which also requieres to\r
-// implement the genericclioptions.RESTClientGetter interface.\r
-// The Factory inerface provides abstractions that allow the Kubectl command to\r
-// be extended across multiple types of resources and different API sets.\r
-type factory struct {\r
- KubeConfig string\r
- Context string\r
- initOpenAPIGetterOnce sync.Once\r
- openAPIGetter openapi.Getter\r
-}\r
-\r
-// If multiple clients are created, this sync.once make sure the CRDs are added\r
-// only once into the API extensions v1 and v1beta schemes\r
-var addToSchemeOnce sync.Once\r
-\r
-var _ genericclioptions.RESTClientGetter = &factory{}\r
-\r
-// newFactory creates a new client factory which encapsulate a REST client getter\r
-func newFactory(context, kubeconfig string) *factory {\r
- factory := &factory{\r
- KubeConfig: kubeconfig,\r
- Context: context,\r
- }\r
-\r
- // From: helm/pkg/kube/client.go > func New()\r
- // Add CRDs to the scheme. They are missing by default.\r
- addToSchemeOnce.Do(func() {\r
- if err := apiextv1.AddToScheme(scheme.Scheme); err != nil {\r
- panic(err)\r
- }\r
- if err := apiextv1beta1.AddToScheme(scheme.Scheme); err != nil {\r
- panic(err)\r
- }\r
- })\r
-\r
- return factory\r
-}\r
-\r
-// BuildRESTConfig builds a kubernetes REST client factory using the following\r
-// rules from ToRawKubeConfigLoader()\r
-// func BuildRESTConfig(context, kubeconfig string) (*rest.Config, error) {\r
-// return newFactory(context, kubeconfig).ToRESTConfig()\r
-// }\r
-\r
-// ToRESTConfig creates a kubernetes REST client factory.\r
-// It's required to implement the interface genericclioptions.RESTClientGetter\r
-func (f *factory) ToRESTConfig() (*rest.Config, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults()\r
- config, err := f.ToRawKubeConfigLoader().ClientConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- if config.GroupVersion == nil {\r
- config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}\r
- }\r
- if config.APIPath == "" {\r
- config.APIPath = "/api"\r
- }\r
- if config.NegotiatedSerializer == nil {\r
- // This codec config ensures the resources are not converted. Therefore, resources\r
- // will not be round-tripped through internal versions. Defaulting does not happen\r
- // on the client.\r
- config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()\r
- }\r
-\r
- rest.SetKubernetesDefaults(config)\r
- return config, nil\r
-}\r
-\r
-// ToRawKubeConfigLoader creates a client factory using the following rules:\r
-// 1. builds from the given kubeconfig path, if not empty\r
-// 2. use the in cluster factory if running in-cluster\r
-// 3. gets the factory from KUBECONFIG env var\r
-// 4. Uses $HOME/.kube/factory\r
-// It's required to implement the interface genericclioptions.RESTClientGetter\r
-func (f *factory) ToRawKubeConfigLoader() clientcmd.ClientConfig {\r
- loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()\r
- loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig\r
- if len(f.KubeConfig) != 0 {\r
- loadingRules.ExplicitPath = f.KubeConfig\r
- }\r
- configOverrides := &clientcmd.ConfigOverrides{\r
- ClusterDefaults: clientcmd.ClusterDefaults,\r
- }\r
- if len(f.Context) != 0 {\r
- configOverrides.CurrentContext = f.Context\r
- }\r
-\r
- return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)\r
-}\r
-\r
-// overlyCautiousIllegalFileCharacters matches characters that *might* not be supported. Windows is really restrictive, so this is really restrictive\r
-var overlyCautiousIllegalFileCharacters = regexp.MustCompile(`[^(\w/\.)]`)\r
-\r
-// ToDiscoveryClient returns a CachedDiscoveryInterface using a computed RESTConfig\r
-// It's required to implement the interface genericclioptions.RESTClientGetter\r
-func (f *factory) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {\r
- // From: k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go > func (*configFlags) ToDiscoveryClient()\r
- factory, err := f.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
- factory.Burst = 100\r
- defaultHTTPCacheDir := filepath.Join(homedir.HomeDir(), ".kube", "http-cache")\r
-\r
- // takes the parentDir and the host and comes up with a "usually non-colliding" name for the discoveryCacheDir\r
- parentDir := filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery")\r
- // strip the optional scheme from host if its there:\r
- schemelessHost := strings.Replace(strings.Replace(factory.Host, "https://", "", 1), "http://", "", 1)\r
- // now do a simple collapse of non-AZ09 characters. Collisions are possible but unlikely. Even if we do collide the problem is short lived\r
- safeHost := overlyCautiousIllegalFileCharacters.ReplaceAllString(schemelessHost, "_")\r
- discoveryCacheDir := filepath.Join(parentDir, safeHost)\r
-\r
- return diskcached.NewCachedDiscoveryClientForConfig(factory, discoveryCacheDir, defaultHTTPCacheDir, time.Duration(10*time.Minute))\r
-}\r
-\r
-// ToRESTMapper returns a mapper\r
-// It's required to implement the interface genericclioptions.RESTClientGetter\r
-func (f *factory) ToRESTMapper() (meta.RESTMapper, error) {\r
- // From: k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go > func (*configFlags) ToRESTMapper()\r
- discoveryClient, err := f.ToDiscoveryClient()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- mapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)\r
- expander := restmapper.NewShortcutExpander(mapper, discoveryClient)\r
- return expander, nil\r
-}\r
-\r
-// KubernetesClientSet creates a kubernetes clientset from the configuration\r
-// It's required to implement the Factory interface\r
-func (f *factory) KubernetesClientSet() (*kubernetes.Clientset, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) KubernetesClientSet()\r
- factory, err := f.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
- return kubernetes.NewForConfig(factory)\r
-}\r
-\r
-// DynamicClient creates a dynamic client from the configuration\r
-// It's required to implement the Factory interface\r
-func (f *factory) DynamicClient() (dynamic.Interface, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) DynamicClient()\r
- factory, err := f.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
- return dynamic.NewForConfig(factory)\r
-}\r
-\r
-// NewBuilder returns a new resource builder for structured api objects.\r
-// It's required to implement the Factory interface\r
-func (f *factory) NewBuilder() *resource.Builder {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) NewBuilder()\r
- return resource.NewBuilder(f)\r
-}\r
-\r
-// RESTClient creates a REST client from the configuration\r
-// It's required to implement the Factory interface\r
-func (f *factory) RESTClient() (*rest.RESTClient, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) RESTClient()\r
- factory, err := f.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
- return rest.RESTClientFor(factory)\r
-}\r
-\r
-func (f *factory) configForMapping(mapping *meta.RESTMapping) (*rest.Config, error) {\r
- factory, err := f.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- gvk := mapping.GroupVersionKind\r
- factory.APIPath = "/apis"\r
- if gvk.Group == corev1.GroupName {\r
- factory.APIPath = "/api"\r
- }\r
- gv := gvk.GroupVersion()\r
- factory.GroupVersion = &gv\r
-\r
- return factory, nil\r
-}\r
-\r
-// ClientForMapping creates a resource REST client from the given mappings\r
-// It's required to implement the Factory interface\r
-func (f *factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) ClientForMapping()\r
- factory, err := f.configForMapping(mapping)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- return rest.RESTClientFor(factory)\r
-}\r
-\r
-// UnstructuredClientForMapping creates a unstructured resource REST client from the given mappings\r
-// It's required to implement the Factory interface\r
-func (f *factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) UnstructuredClientForMapping()\r
- factory, err := f.configForMapping(mapping)\r
- if err != nil {\r
- return nil, err\r
- }\r
- factory.ContentConfig = resource.UnstructuredPlusDefaultContentConfig()\r
-\r
- return rest.RESTClientFor(factory)\r
-}\r
-\r
-// Validator returns a schema that can validate objects stored on disk.\r
-// It's required to implement the Factory interface\r
-func (f *factory) Validator(validate bool) (validation.Schema, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) Validator(bool)\r
- if !validate {\r
- return validation.NullSchema{}, nil\r
- }\r
-\r
- resources, err := f.OpenAPISchema()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- return validation.ConjunctiveSchema{\r
- openapivalidation.NewSchemaValidation(resources),\r
- validation.NoDoubleKeySchema{},\r
- }, nil\r
-}\r
-\r
-// OpenAPISchema returns metadata and structural information about Kubernetes object definitions.\r
-// It's required to implement the Factory interface\r
-func (f *factory) OpenAPISchema() (openapi.Resources, error) {\r
- // From: k8s.io/kubectl/pkg/cmd/util/factory_client-access.go > func (*factoryImpl) OpenAPISchema()\r
- discovery, err := f.ToDiscoveryClient()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- f.initOpenAPIGetterOnce.Do(func() {\r
- // Create the caching OpenAPIGetter\r
- f.openAPIGetter = openapi.NewOpenAPIGetter(discovery)\r
- })\r
-\r
- // Delegate to the OpenAPIGetter\r
- return f.openAPIGetter.Get()\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "os"
+ "regexp"
+ "sync"
+ "time"
+
+ corev1 "k8s.io/api/core/v1"
+ apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+ apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/cli-runtime/pkg/genericclioptions"
+ "k8s.io/cli-runtime/pkg/resource"
+ "k8s.io/client-go/discovery"
+ diskcached "k8s.io/client-go/discovery/cached/disk"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/kubernetes/scheme"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/restmapper"
+ "k8s.io/client-go/tools/clientcmd"
+ "k8s.io/kubectl/pkg/util/openapi"
+ openapivalidation "k8s.io/kubectl/pkg/util/openapi/validation"
+ "k8s.io/kubectl/pkg/validation"
+)
+
+// factory implements the kubectl Factory interface which also requieres to
+// implement the genericclioptions.RESTClientGetter interface.
+// The Factory interface provides abstractions that allow the Kubectl command to
+// be extended across multiple types of resources and different API sets.
+type factory struct {
+ KubeConfig string
+ Context string
+ initOpenAPIGetterOnce sync.Once
+ openAPIGetter openapi.Getter
+}
+
+// If multiple clients are created, this sync.once make sure the CRDs are added
+// only once into the API extensions v1 and v1beta schemes
+var addToSchemeOnce sync.Once
+
+var _ genericclioptions.RESTClientGetter = &factory{}
+
+// newFactory creates a new client factory which encapsulate a REST client getter
+func newFactory(context, kubeconfig string) *factory {
+ factory := &factory{
+ KubeConfig: kubeconfig,
+ Context: context,
+ }
+
+ // From: helm/pkg/kube/client.go > func New()
+ // Add CRDs to the scheme. They are missing by default.
+ addToSchemeOnce.Do(func() {
+ if err := apiextv1.AddToScheme(scheme.Scheme); err != nil {
+ panic(err)
+ }
+ if err := apiextv1beta1.AddToScheme(scheme.Scheme); err != nil {
+ panic(err)
+ }
+ })
+
+ return factory
+}
+
+// BuildRESTConfig builds a kubernetes REST client factory using the following
+// rules from ToRawKubeConfigLoader()
+// func BuildRESTConfig(context, kubeconfig string) (*rest.Config, error) {
+// return newFactory(context, kubeconfig).ToRESTConfig()
+// }
+
+// ToRESTConfig creates a kubernetes REST client factory.
+// It's required to implement the interface genericclioptions.RESTClientGetter
+func (f *factory) ToRESTConfig() (*rest.Config, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults()
+ config, err := f.ToRawKubeConfigLoader().ClientConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ if config.GroupVersion == nil {
+ config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}
+ }
+ if config.APIPath == "" {
+ config.APIPath = "/api"
+ }
+ if config.NegotiatedSerializer == nil {
+ // This codec config ensures the resources are not converted. Therefore, resources
+ // will not be round-tripped through internal versions. Defaulting does not happen
+ // on the client.
+ config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
+ }
+
+ rest.SetKubernetesDefaults(config)
+ return config, nil
+}
+
+// ToRawKubeConfigLoader creates a client factory using the following rules:
+// 1. builds from the given kubeconfig path, if not empty
+// 2. use the in cluster factory if running in-cluster
+// 3. gets the factory from KUBECONFIG env var
+// 4. Uses $HOME/.kube/factory
+// It's required to implement the interface genericclioptions.RESTClientGetter
+func (f *factory) ToRawKubeConfigLoader() clientcmd.ClientConfig {
+ loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
+ loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig
+ if len(f.KubeConfig) != 0 {
+ loadingRules.ExplicitPath = f.KubeConfig
+ }
+ configOverrides := &clientcmd.ConfigOverrides{
+ ClusterDefaults: clientcmd.ClusterDefaults,
+ }
+ if len(f.Context) != 0 {
+ configOverrides.CurrentContext = f.Context
+ }
+
+ return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
+}
+
+// overlyCautiousIllegalFileCharacters matches characters that *might* not be supported. Windows is really restrictive, so this is really restrictive
+var overlyCautiousIllegalFileCharacters = regexp.MustCompile(`[^(\w/\.)]`)
+
+// ToDiscoveryClient returns a CachedDiscoveryInterface using a computed RESTConfig
+// It's required to implement the interface genericclioptions.RESTClientGetter
+func (f *factory) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
+ // From: k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go > func (*configFlags) ToDiscoveryClient()
+ factory, err := f.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+ factory.Burst = 100
+
+ return diskcached.NewCachedDiscoveryClientForConfig(factory, os.TempDir(), "", time.Duration(10*time.Minute))
+}
+
+// ToRESTMapper returns a mapper
+// It's required to implement the interface genericclioptions.RESTClientGetter
+func (f *factory) ToRESTMapper() (meta.RESTMapper, error) {
+ // From: k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go > func (*configFlags) ToRESTMapper()
+ discoveryClient, err := f.ToDiscoveryClient()
+ if err != nil {
+ return nil, err
+ }
+
+ mapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)
+ return mapper, nil
+}
+
+// KubernetesClientSet creates a kubernetes clientset from the configuration
+// It's required to implement the Factory interface
+func (f *factory) KubernetesClientSet() (*kubernetes.Clientset, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) KubernetesClientSet()
+ factory, err := f.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+ return kubernetes.NewForConfig(factory)
+}
+
+// DynamicClient creates a dynamic client from the configuration
+// It's required to implement the Factory interface
+func (f *factory) DynamicClient() (dynamic.Interface, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) DynamicClient()
+ factory, err := f.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+ return dynamic.NewForConfig(factory)
+}
+
+// NewBuilder returns a new resource builder for structured api objects.
+// It's required to implement the Factory interface
+func (f *factory) NewBuilder() *resource.Builder {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) NewBuilder()
+ return resource.NewBuilder(f)
+}
+
+// RESTClient creates a REST client from the configuration
+// It's required to implement the Factory interface
+func (f *factory) RESTClient() (*rest.RESTClient, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) RESTClient()
+ factory, err := f.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+ return rest.RESTClientFor(factory)
+}
+
+func (f *factory) configForMapping(mapping *meta.RESTMapping) (*rest.Config, error) {
+ factory, err := f.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ gvk := mapping.GroupVersionKind
+ factory.APIPath = "/apis"
+ if gvk.Group == corev1.GroupName {
+ factory.APIPath = "/api"
+ }
+ gv := gvk.GroupVersion()
+ factory.GroupVersion = &gv
+
+ return factory, nil
+}
+
+// ClientForMapping creates a resource REST client from the given mappings
+// It's required to implement the Factory interface
+func (f *factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) ClientForMapping()
+ factory, err := f.configForMapping(mapping)
+ if err != nil {
+ return nil, err
+ }
+
+ return rest.RESTClientFor(factory)
+}
+
+// UnstructuredClientForMapping creates a unstructured resource REST client from the given mappings
+// It's required to implement the Factory interface
+func (f *factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) UnstructuredClientForMapping()
+ factory, err := f.configForMapping(mapping)
+ if err != nil {
+ return nil, err
+ }
+ factory.ContentConfig = resource.UnstructuredPlusDefaultContentConfig()
+
+ return rest.RESTClientFor(factory)
+}
+
+// Validator returns a schema that can validate objects stored on disk.
+// It's required to implement the Factory interface
+func (f *factory) Validator(validate bool) (validation.Schema, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client_access.go > func (*factoryImpl) Validator(bool)
+ if !validate {
+ return validation.NullSchema{}, nil
+ }
+
+ resources, err := f.OpenAPISchema()
+ if err != nil {
+ return nil, err
+ }
+
+ return validation.ConjunctiveSchema{
+ openapivalidation.NewSchemaValidation(resources),
+ validation.NoDoubleKeySchema{},
+ }, nil
+}
+
+// OpenAPISchema returns metadata and structural information about Kubernetes object definitions.
+// It's required to implement the Factory interface
+func (f *factory) OpenAPISchema() (openapi.Resources, error) {
+ // From: k8s.io/kubectl/pkg/cmd/util/factory_client-access.go > func (*factoryImpl) OpenAPISchema()
+ discovery, err := f.ToDiscoveryClient()
+ if err != nil {
+ return nil, err
+ }
+
+ f.initOpenAPIGetterOnce.Do(func() {
+ // Create the caching OpenAPIGetter
+ f.openAPIGetter = openapi.NewOpenAPIGetter(discovery)
+ })
+
+ // Delegate to the OpenAPIGetter
+ return f.openAPIGetter.Get()
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package client
+
+import (
+ "context"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes/fake"
+)
+
+// NewKubeFakeClient returns a fake kube client object
+func NewKubeFakeClient() (*Client, error) {
+ log.Info("NewKubeFakeClient .. start", nil)
+
+ var kl Client
+ kl.Clientset = fake.NewSimpleClientset()
+
+ // populate mock node1 with resources for cluster-1
+ var node1 corev1.Node
+ node1.Name = "emco-cluster-node-1"
+ node1.ClusterName = "emco-cluster-1"
+ resList := "cpu=10,qat.intel.com/generic=10,memory=5G,pods=10,services=7"
+ nodeLabels := map[string]string{"feature.node.kubernetes.io/intel_qat": "true", "feature.node.kubernetes.io/pci-0300_1a03.present": "true", "feature.node.kubernetes.io/intel_qat/v3": "true"}
+ resourceQuotaSpecList, _ := PopulateResourceListV1WithDefValues(resList)
+ node1.Status.Allocatable = resourceQuotaSpecList
+ node1.Status.Capacity = resourceQuotaSpecList
+ node1.Labels = nodeLabels
+ kl.Clientset.CoreV1().Nodes().Create(context.TODO(), &node1, metav1.CreateOptions{})
+
+ // populate mock node2 with resources for cluster-1
+ var node2 corev1.Node
+ node2.Name = "emco-cluster-node-2"
+ node2.ClusterName = "emco-cluster-1"
+ resList = "cpu=5,qat.intel.com/generic=15,memory=10G,pods=5,services=5"
+ nodeLabels = map[string]string{"feature.node.kubernetes.io/intel_qat": "true", "feature.node.kubernetes.io/pci-0300_1a03.present": "true", "feature.node.kubernetes.io/intel_qat.device": "c6xx"}
+ resourceQuotaSpecList, _ = PopulateResourceListV1WithDefValues(resList)
+ node2.Status.Allocatable = resourceQuotaSpecList
+ node2.Status.Capacity = resourceQuotaSpecList
+ node2.Labels = nodeLabels
+ kl.Clientset.CoreV1().Nodes().Create(context.TODO(), &node2, metav1.CreateOptions{})
+
+ // populate mock node1 with resources for cluster-2
+ var node3 corev1.Node
+ node3.Name = "emco-cluster-2-node-1"
+ node3.ClusterName = "emco-cluster-2"
+ resList = "cpu=15,qat.intel.com/generic=2,memory=1G,pods=5,services=2"
+ nodeLabels = map[string]string{"feature.node.kubernetes.io/intel_qat": "true", "feature.node.kubernetes.io/pci-0300_1a03.present": "true", "feature.node.kubernetes.io/intel_qat/v3": "true"}
+ resourceQuotaSpecList, _ = PopulateResourceListV1WithDefValues(resList)
+ node3.Status.Allocatable = resourceQuotaSpecList
+ node3.Status.Capacity = resourceQuotaSpecList
+ node3.Labels = nodeLabels
+ kl.Clientset.CoreV1().Nodes().Create(context.TODO(), &node3, metav1.CreateOptions{})
+
+ // populate mock node2 with resources for cluster-2
+ var node4 corev1.Node
+ node4.Name = "emco-cluster-2-node-2"
+ node4.ClusterName = "emco-cluster-2"
+ resList = "cpu=10,qat.intel.com/generic=1,memory=2G,pods=2,services=2"
+ nodeLabels = map[string]string{"feature.node.kubernetes.io/intel_qat": "true", "feature.node.kubernetes.io/pci-0300_1a03.present": "true", "feature.node.kubernetes.io/intel_qat.device": "c6xx"}
+ resourceQuotaSpecList, _ = PopulateResourceListV1WithDefValues(resList)
+ node4.Status.Allocatable = resourceQuotaSpecList
+ node4.Status.Capacity = resourceQuotaSpecList
+ node4.Labels = nodeLabels
+ kl.Clientset.CoreV1().Nodes().Create(context.TODO(), &node4, metav1.CreateOptions{})
+
+ log.Info("NewKubeFakeClient .. end", nil)
+ return &kl, nil
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2021 Intel Corporation
+
+package client
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// ReadResource is structure used for reading resource
+type ReadResource struct {
+ Gvk schema.GroupVersionKind `json:"GVK,omitempty"`
+ Name string `json:"name,omitempty"`
+ Namespace string `json:"namespace,omitempty"`
+}
+
+// Get gets the resource from the remote cluster
+func (c *Client) Get(gvkRes []byte, namespace string) ([]byte, error) {
+
+ var g ReadResource
+ var ns string
+
+ err := json.Unmarshal(gvkRes, &g)
+ if err != nil {
+ return nil, fmt.Errorf("Invalid read resource %v", err)
+ }
+
+ if namespace == "default" && g.Namespace != "" {
+ ns = g.Namespace
+ } else {
+ ns = namespace
+ }
+ // Create a mapper for the GVK
+ mapping, err := c.RestMapper.RESTMapping(schema.GroupKind{
+ Group: g.Gvk.Group,
+ Kind: g.Gvk.Kind,
+ }, g.Gvk.Version)
+ if err != nil {
+ return nil, fmt.Errorf("RESTMapping for GVK failed %v", err)
+ }
+ gvr := mapping.Resource
+ opts := metav1.GetOptions{}
+ var unstruct *unstructured.Unstructured
+ // Handle based on namespace scopped GVK or not
+ switch mapping.Scope.Name() {
+ case meta.RESTScopeNameNamespace:
+ unstruct, err = c.DynamicClient.Resource(gvr).Namespace(ns).Get(context.TODO(), g.Name, opts)
+ case meta.RESTScopeNameRoot:
+ unstruct, err = c.DynamicClient.Resource(gvr).Get(context.TODO(), g.Name, opts)
+ default:
+ return nil, fmt.Errorf("RESTScopeName for GVK failed %v, %s", err, g.Gvk.String())
+ }
+ if err != nil {
+ return nil, fmt.Errorf("Getting getting RESTScopeName %v", err)
+ }
+
+ b, err := unstruct.MarshalJSON()
+ if err != nil {
+ return nil, fmt.Errorf("Failed unstruct MarshalJSON %v", err)
+ }
+ return b, nil
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "context"\r
-\r
- v1 "k8s.io/api/core/v1"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
-)\r
-\r
-// CreateNamespace creates a namespace with the given name\r
-func (c *Client) CreateNamespace(namespace string) error {\r
- ns := &v1.Namespace{\r
- ObjectMeta: metav1.ObjectMeta{\r
- Name: namespace,\r
- Labels: map[string]string{\r
- "name": namespace,\r
- },\r
- },\r
- }\r
- _, err := c.Clientset.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})\r
- // if errors.IsAlreadyExists(err) {\r
- // // If it failed because the NS is already there, then do not return such error\r
- // return nil\r
- // }\r
-\r
- return err\r
-}\r
-\r
-// DeleteNamespace deletes the namespace with the given name\r
-func (c *Client) DeleteNamespace(namespace string) error {\r
- return c.Clientset.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{})\r
-}\r
-\r
-// NodesReady returns the number of nodes ready\r
-func (c *Client) NodesReady() (ready int, total int, err error) {\r
- nodes, err := c.Clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})\r
- if err != nil {\r
- return 0, 0, err\r
- }\r
- total = len(nodes.Items)\r
- if total == 0 {\r
- return 0, 0, nil\r
- }\r
- for _, n := range nodes.Items {\r
- for _, c := range n.Status.Conditions {\r
- if c.Type == "Ready" && c.Status == "True" {\r
- ready++\r
- break\r
- }\r
- }\r
- }\r
-\r
- return ready, len(nodes.Items), nil\r
-}\r
-\r
-// Version returns the cluster version. It can be used to verify if the cluster\r
-// is reachable. It will return an error if failed to connect.\r
-func (c *Client) Version() (string, error) {\r
- v, err := c.Clientset.ServerVersion()\r
- if err != nil {\r
- return "", err\r
- }\r
-\r
- return v.String(), nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "context"
+ "errors"
+
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes"
+)
+
+// CreateNamespace creates a namespace with the given name
+func (c *Client) CreateNamespace(namespace string) error {
+ ns := &v1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: namespace,
+ Labels: map[string]string{
+ "name": namespace,
+ },
+ },
+ }
+ _, err := c.Clientset.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
+ // if errors.IsAlreadyExists(err) {
+ // // If it failed because the NS is already there, then do not return such error
+ // return nil
+ // }
+
+ return err
+}
+
+// DeleteNamespace deletes the namespace with the given name
+func (c *Client) DeleteNamespace(namespace string) error {
+ return c.Clientset.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{})
+}
+
+// NodesReady returns the number of nodes ready
+func (c *Client) NodesReady() (ready int, total int, err error) {
+ nodes, err := c.Clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
+ if err != nil {
+ return 0, 0, err
+ }
+ total = len(nodes.Items)
+ if total == 0 {
+ return 0, 0, nil
+ }
+ for _, n := range nodes.Items {
+ for _, c := range n.Status.Conditions {
+ if c.Type == "Ready" && c.Status == "True" {
+ ready++
+ break
+ }
+ }
+ }
+
+ return ready, len(nodes.Items), nil
+}
+
+// GetMasterNodeIP returns the master node IP of the deployed app
+func (c *Client) GetMasterNodeIP() (nodeIP string, err error) {
+
+ ip := ""
+ nodes, err := c.Clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
+ if err != nil {
+ return ip, err
+ }
+ total := len(nodes.Items)
+ if total == 0 {
+ return ip, nil
+ }
+ for _, item := range nodes.Items {
+ for _, address := range item.Status.Addresses {
+ // This gives the ip address of the master node
+ ip = address.Address
+ break
+ }
+ break
+ }
+
+ return ip, nil
+}
+
+// Version returns the cluster version. It can be used to verify if the cluster
+// is reachable. It will return an error if failed to connect.
+func (c *Client) Version() (string, error) {
+ cl, ok := (c.Clientset.(*kubernetes.Clientset))
+ if ok {
+ v, err := cl.ServerVersion()
+ if err != nil {
+ return "", err
+ }
+ return v.String(), nil
+ }
+ return "", errors.New("error in getting client")
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "fmt"\r
- "os"\r
- "time"\r
-\r
- "github.com/jonboulle/clockwork"\r
- corev1 "k8s.io/api/core/v1"\r
- "k8s.io/apimachinery/pkg/api/errors"\r
- "k8s.io/apimachinery/pkg/api/meta"\r
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/apimachinery/pkg/types"\r
- "k8s.io/apimachinery/pkg/util/jsonmergepatch"\r
- "k8s.io/apimachinery/pkg/util/mergepatch"\r
- "k8s.io/apimachinery/pkg/util/strategicpatch"\r
- "k8s.io/apimachinery/pkg/util/wait"\r
- "k8s.io/cli-runtime/pkg/resource"\r
- oapi "k8s.io/kube-openapi/pkg/util/proto"\r
- "k8s.io/kubectl/pkg/scheme"\r
- "k8s.io/kubectl/pkg/util"\r
- "k8s.io/kubectl/pkg/util/openapi"\r
-)\r
-\r
-const (\r
- // overwrite if true, automatically resolve conflicts between the modified and live configuration by using values from the modified configuration\r
- overwrite = true\r
- // maxPatchRetry is the maximum number of conflicts retry for during a patch operation before returning failure\r
- maxPatchRetry = 5\r
- // backOffPeriod is the period to back off when apply patch results in error.\r
- backOffPeriod = 1 * time.Second\r
- // how many times we can retry before back off\r
- triesBeforeBackOff = 1\r
- // force if true, immediately remove resources from API and bypass graceful deletion. Note that immediate deletion of some resources may result in inconsistency or data loss and requires confirmation.\r
- force = false\r
- // timeout waiting for the resource to be delete if it needs to be recreated\r
- timeout = 0\r
-)\r
-\r
-// patch tries to patch an OpenAPI resource\r
-func patch(info *resource.Info, current runtime.Object) error {\r
- // From: k8s.io/kubectl/pkg/cmd/apply/apply.go & patcher.go\r
- modified, err := util.GetModifiedConfiguration(info.Object, true, unstructured.UnstructuredJSONScheme)\r
- if err != nil {\r
- return fmt.Errorf("retrieving modified configuration. %s", err)\r
- }\r
-\r
- metadata, _ := meta.Accessor(current)\r
- annotationMap := metadata.GetAnnotations()\r
- if _, ok := annotationMap[corev1.LastAppliedConfigAnnotation]; !ok {\r
- // TODO: Find what to do with the warnings, they should not be printed\r
- fmt.Fprintf(os.Stderr, "Warning: apply should be used on resource created by apply")\r
- }\r
-\r
- patchBytes, patchObject, err := patchSimple(current, modified, info)\r
-\r
- var getErr error\r
- for i := 1; i <= maxPatchRetry && errors.IsConflict(err); i++ {\r
- if i > triesBeforeBackOff {\r
- clockwork.NewRealClock().Sleep(backOffPeriod)\r
- }\r
- current, getErr = resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)\r
- if getErr != nil {\r
- return getErr\r
- }\r
- patchBytes, patchObject, err = patchSimple(current, modified, info)\r
- }\r
- if err != nil && (errors.IsConflict(err) || errors.IsInvalid(err)) && force {\r
- patchBytes, patchObject, err = deleteAndCreate(info, patchBytes)\r
- }\r
-\r
- info.Refresh(patchObject, true)\r
-\r
- return nil\r
-}\r
-\r
-func patchSimple(currentObj runtime.Object, modified []byte, info *resource.Info) ([]byte, runtime.Object, error) {\r
- // Serialize the current configuration of the object from the server.\r
- current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, currentObj)\r
- if err != nil {\r
- return nil, nil, fmt.Errorf("serializing current configuration. %s", err)\r
- }\r
-\r
- // Retrieve the original configuration of the object from the annotation.\r
- original, err := util.GetOriginalConfiguration(currentObj)\r
- if err != nil {\r
- return nil, nil, fmt.Errorf("retrieving original configuration. %s", err)\r
- }\r
-\r
- var patchType types.PatchType\r
- var patch []byte\r
- var lookupPatchMeta strategicpatch.LookupPatchMeta\r
- var schema oapi.Schema\r
-\r
- // Create the versioned struct from the type defined in the restmapping\r
- // (which is the API version we'll be submitting the patch to)\r
- versionedObject, err := scheme.Scheme.New(info.Mapping.GroupVersionKind)\r
-\r
- // DEBUG:\r
- // fmt.Printf("Modified: %v\n", string(modified))\r
- // fmt.Printf("Current: %v\n", string(current))\r
- // fmt.Printf("Original: %v\n", string(original))\r
- // fmt.Printf("versionedObj: %v\n", versionedObject)\r
- // fmt.Printf("Error: %+v\nIsNotRegisteredError: %t\n", err, runtime.IsNotRegisteredError(err))\r
-\r
- switch {\r
- case runtime.IsNotRegisteredError(err):\r
- // fall back to generic JSON merge patch\r
- patchType = types.MergePatchType\r
- preconditions := []mergepatch.PreconditionFunc{mergepatch.RequireKeyUnchanged("apiVersion"),\r
- mergepatch.RequireKeyUnchanged("kind"), mergepatch.RequireMetadataKeyUnchanged("name")}\r
- patch, err = jsonmergepatch.CreateThreeWayJSONMergePatch(original, modified, current, preconditions...)\r
- if err != nil {\r
- if mergepatch.IsPreconditionFailed(err) {\r
- return nil, nil, fmt.Errorf("At least one of apiVersion, kind and name was changed")\r
- }\r
- return nil, nil, fmt.Errorf("creating patch. %s", err)\r
- }\r
- case err != nil:\r
- return nil, nil, fmt.Errorf("getting instance of versioned object. %s", err)\r
- case err == nil:\r
- // Compute a three way strategic merge patch to send to server.\r
- patchType = types.StrategicMergePatchType\r
-\r
- // Try to use openapi first if the openapi spec is available and can successfully calculate the patch.\r
- // Otherwise, fall back to baked-in types.\r
- var openapiSchema openapi.Resources\r
- if openapiSchema != nil {\r
- if schema = openapiSchema.LookupResource(info.Mapping.GroupVersionKind); schema != nil {\r
- lookupPatchMeta = strategicpatch.PatchMetaFromOpenAPI{Schema: schema}\r
- if openapiPatch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, lookupPatchMeta, overwrite); err == nil {\r
- patchType = types.StrategicMergePatchType\r
- patch = openapiPatch\r
- // TODO: In case it's necessary to report warnings\r
- // } else {\r
- // log.Printf("Warning: error calculating patch from openapi spec: %s", err)\r
- }\r
- }\r
- }\r
-\r
- if patch == nil {\r
- lookupPatchMeta, err = strategicpatch.NewPatchMetaFromStruct(versionedObject)\r
- if err != nil {\r
- return nil, nil, fmt.Errorf("creating patch. %s", err)\r
- }\r
- patch, err = strategicpatch.CreateThreeWayMergePatch(original, modified, current, lookupPatchMeta, overwrite)\r
- if err != nil {\r
- return nil, nil, fmt.Errorf("creating patch. %s", err)\r
- }\r
- }\r
- }\r
-\r
- if string(patch) == "{}" {\r
- return patch, currentObj, nil\r
- }\r
-\r
- patchedObj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, patchType, patch, nil)\r
- return patch, patchedObj, err\r
-}\r
-\r
-func deleteAndCreate(info *resource.Info, modified []byte) ([]byte, runtime.Object, error) {\r
- delOptions := defaultDeleteOptions()\r
- if _, err := deleteWithOptions(info, delOptions); err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- helper := resource.NewHelper(info.Client, info.Mapping)\r
-\r
- // TODO: make a waiter and use it\r
- if err := wait.PollImmediate(1*time.Second, time.Duration(timeout), func() (bool, error) {\r
- if _, err := helper.Get(info.Namespace, info.Name); !errors.IsNotFound(err) {\r
- return false, err\r
- }\r
- return true, nil\r
- }); err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- // TODO: Check what GetModifiedConfiguration does, this could be an encode - decode waste of time\r
- // modified, err := util.GetModifiedConfiguration(info.Object, true, unstructured.UnstructuredJSONScheme)\r
- // if err != nil {\r
- // return nil, nil, fmt.Errorf("retrieving modified configuration. %s", err)\r
- // }\r
- versionedObject, _, err := unstructured.UnstructuredJSONScheme.Decode(modified, nil, nil)\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- createdObject, err := helper.Create(info.Namespace, true, versionedObject)\r
- if err != nil {\r
- // restore the original object if we fail to create the new one\r
- // but still propagate and advertise error to user\r
- recreated, recreateErr := helper.Create(info.Namespace, true, info.Object)\r
- if recreateErr != nil {\r
- err = fmt.Errorf("An error occurred force-replacing the existing object with the newly provided one. %v.\n\nAdditionally, an error occurred attempting to restore the original object: %v", err, recreateErr)\r
- } else {\r
- createdObject = recreated\r
- }\r
- }\r
- return modified, createdObject, err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/jonboulle/clockwork"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/util/jsonmergepatch"
+ "k8s.io/apimachinery/pkg/util/mergepatch"
+ "k8s.io/apimachinery/pkg/util/strategicpatch"
+ "k8s.io/apimachinery/pkg/util/wait"
+ "k8s.io/cli-runtime/pkg/resource"
+ oapi "k8s.io/kube-openapi/pkg/util/proto"
+ "k8s.io/kubectl/pkg/scheme"
+ "k8s.io/kubectl/pkg/util"
+ "k8s.io/kubectl/pkg/util/openapi"
+)
+
+const (
+ // overwrite if true, automatically resolve conflicts between the modified and live configuration by using values from the modified configuration
+ overwrite = true
+ // maxPatchRetry is the maximum number of conflicts retry for during a patch operation before returning failure
+ maxPatchRetry = 5
+ // backOffPeriod is the period to back off when apply patch results in error.
+ backOffPeriod = 1 * time.Second
+ // how many times we can retry before back off
+ triesBeforeBackOff = 1
+ // force if true, immediately remove resources from API and bypass graceful deletion. Note that immediate deletion of some resources may result in inconsistency or data loss and requires confirmation.
+ force = false
+ // timeout waiting for the resource to be delete if it needs to be recreated
+ timeout = 0
+)
+
+// patch tries to patch an OpenAPI resource
+func patch(info *resource.Info, current runtime.Object) error {
+ // From: k8s.io/kubectl/pkg/cmd/apply/apply.go & patcher.go
+ modified, err := util.GetModifiedConfiguration(info.Object, true, unstructured.UnstructuredJSONScheme)
+ if err != nil {
+ return fmt.Errorf("retrieving modified configuration. %s", err)
+ }
+
+ metadata, _ := meta.Accessor(current)
+ annotationMap := metadata.GetAnnotations()
+ if _, ok := annotationMap[corev1.LastAppliedConfigAnnotation]; !ok {
+ // TODO: Find what to do with the warnings, they should not be printed
+ fmt.Fprintf(os.Stderr, "Warning: apply should be used on resource created by apply")
+ }
+
+ patchBytes, patchObject, err := patchSimple(current, modified, info)
+
+ var getErr error
+ for i := 1; i <= maxPatchRetry && errors.IsConflict(err); i++ {
+ if i > triesBeforeBackOff {
+ clockwork.NewRealClock().Sleep(backOffPeriod)
+ }
+ current, getErr = resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)
+ if getErr != nil {
+ return getErr
+ }
+ patchBytes, patchObject, err = patchSimple(current, modified, info)
+ }
+ if err != nil && (errors.IsConflict(err) || errors.IsInvalid(err)) && force {
+ patchBytes, patchObject, err = deleteAndCreate(info, patchBytes)
+ }
+
+ info.Refresh(patchObject, true)
+
+ return nil
+}
+
+func patchSimple(currentObj runtime.Object, modified []byte, info *resource.Info) ([]byte, runtime.Object, error) {
+ // Serialize the current configuration of the object from the server.
+ current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, currentObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("serializing current configuration. %s", err)
+ }
+
+ // Retrieve the original configuration of the object from the annotation.
+ original, err := util.GetOriginalConfiguration(currentObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("retrieving original configuration. %s", err)
+ }
+
+ var patchType types.PatchType
+ var patch []byte
+ var lookupPatchMeta strategicpatch.LookupPatchMeta
+ var schema oapi.Schema
+
+ // Create the versioned struct from the type defined in the restmapping
+ // (which is the API version we'll be submitting the patch to)
+ versionedObject, err := scheme.Scheme.New(info.Mapping.GroupVersionKind)
+
+ // DEBUG:
+ // fmt.Printf("Modified: %v\n", string(modified))
+ // fmt.Printf("Current: %v\n", string(current))
+ // fmt.Printf("Original: %v\n", string(original))
+ // fmt.Printf("versionedObj: %v\n", versionedObject)
+ // fmt.Printf("Error: %+v\nIsNotRegisteredError: %t\n", err, runtime.IsNotRegisteredError(err))
+
+ switch {
+ case runtime.IsNotRegisteredError(err):
+ // fall back to generic JSON merge patch
+ patchType = types.MergePatchType
+ preconditions := []mergepatch.PreconditionFunc{mergepatch.RequireKeyUnchanged("apiVersion"),
+ mergepatch.RequireKeyUnchanged("kind"), mergepatch.RequireMetadataKeyUnchanged("name")}
+ patch, err = jsonmergepatch.CreateThreeWayJSONMergePatch(original, modified, current, preconditions...)
+ if err != nil {
+ if mergepatch.IsPreconditionFailed(err) {
+ return nil, nil, fmt.Errorf("At least one of apiVersion, kind and name was changed")
+ }
+ return nil, nil, fmt.Errorf("creating patch. %s", err)
+ }
+ case err != nil:
+ return nil, nil, fmt.Errorf("getting instance of versioned object. %s", err)
+ case err == nil:
+ // Compute a three way strategic merge patch to send to server.
+ patchType = types.StrategicMergePatchType
+
+ // Try to use openapi first if the openapi spec is available and can successfully calculate the patch.
+ // Otherwise, fall back to baked-in types.
+ var openapiSchema openapi.Resources
+ if openapiSchema != nil {
+ if schema = openapiSchema.LookupResource(info.Mapping.GroupVersionKind); schema != nil {
+ lookupPatchMeta = strategicpatch.PatchMetaFromOpenAPI{Schema: schema}
+ if openapiPatch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, lookupPatchMeta, overwrite); err == nil {
+ patchType = types.StrategicMergePatchType
+ patch = openapiPatch
+ // TODO: In case it's necessary to report warnings
+ // } else {
+ // log.Printf("Warning: error calculating patch from openapi spec: %s", err)
+ }
+ }
+ }
+
+ if patch == nil {
+ lookupPatchMeta, err = strategicpatch.NewPatchMetaFromStruct(versionedObject)
+ if err != nil {
+ return nil, nil, fmt.Errorf("creating patch. %s", err)
+ }
+ patch, err = strategicpatch.CreateThreeWayMergePatch(original, modified, current, lookupPatchMeta, overwrite)
+ if err != nil {
+ return nil, nil, fmt.Errorf("creating patch. %s", err)
+ }
+ }
+ }
+
+ if string(patch) == "{}" {
+ return patch, currentObj, nil
+ }
+
+ patchedObj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, patchType, patch, nil)
+ return patch, patchedObj, err
+}
+
+func deleteAndCreate(info *resource.Info, modified []byte) ([]byte, runtime.Object, error) {
+ delOptions := defaultDeleteOptions()
+ if _, err := deleteWithOptions(info, delOptions); err != nil {
+ return nil, nil, err
+ }
+
+ helper := resource.NewHelper(info.Client, info.Mapping)
+
+ // TODO: make a waiter and use it
+ if err := wait.PollImmediate(1*time.Second, time.Duration(timeout), func() (bool, error) {
+ if _, err := helper.Get(info.Namespace, info.Name); !errors.IsNotFound(err) {
+ return false, err
+ }
+ return true, nil
+ }); err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: Check what GetModifiedConfiguration does, this could be an encode - decode waste of time
+ // modified, err := util.GetModifiedConfiguration(info.Object, true, unstructured.UnstructuredJSONScheme)
+ // if err != nil {
+ // return nil, nil, fmt.Errorf("retrieving modified configuration. %s", err)
+ // }
+ versionedObject, _, err := unstructured.UnstructuredJSONScheme.Decode(modified, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ createdObject, err := helper.Create(info.Namespace, true, versionedObject)
+ if err != nil {
+ // restore the original object if we fail to create the new one
+ // but still propagate and advertise error to user
+ recreated, recreateErr := helper.Create(info.Namespace, true, info.Object)
+ if recreateErr != nil {
+ err = fmt.Errorf("An error occurred force-replacing the existing object with the newly provided one. %v.\n\nAdditionally, an error occurred attempting to restore the original object: %v", err, recreateErr)
+ } else {
+ createdObject = recreated
+ }
+ }
+ return modified, createdObject, err
+}
-/*\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-// Based on Code: https://github.com/johandry/klient\r
-package client\r
-\r
-import (\r
- "k8s.io/cli-runtime/pkg/resource"\r
-)\r
-\r
-// Replace creates a resource with the given content\r
-func (c *Client) Replace(content []byte) error {\r
- r := c.ResultForContent(content, nil)\r
- return c.ReplaceResource(r)\r
-}\r
-\r
-// ReplaceFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs\r
-func (c *Client) ReplaceFiles(filenames ...string) error {\r
- r := c.ResultForFilenameParam(filenames, nil)\r
- return c.ReplaceResource(r)\r
-}\r
-\r
-// ReplaceResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`\r
-func (c *Client) ReplaceResource(r *resource.Result) error {\r
- if err := r.Err(); err != nil {\r
- return err\r
- }\r
- return r.Visit(replace)\r
-}\r
-\r
-func replace(info *resource.Info, err error) error {\r
- if err != nil {\r
- return failedTo("replace", info, err)\r
- }\r
-\r
- obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, info.Object)\r
- if err != nil {\r
- return failedTo("replace", info, err)\r
- }\r
- info.Refresh(obj, true)\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ "k8s.io/cli-runtime/pkg/resource"
+)
+
+// Replace creates a resource with the given content
+func (c *Client) Replace(content []byte) error {
+ r := c.ResultForContent(content, nil)
+ return c.ReplaceResource(r)
+}
+
+// ReplaceFiles create the resource(s) from the given filenames (file, directory or STDIN) or HTTP URLs
+func (c *Client) ReplaceFiles(filenames ...string) error {
+ r := c.ResultForFilenameParam(filenames, nil)
+ return c.ReplaceResource(r)
+}
+
+// ReplaceResource applies the given resource. Create the resources with `ResultForFilenameParam` or `ResultForContent`
+func (c *Client) ReplaceResource(r *resource.Result) error {
+ if err := r.Err(); err != nil {
+ return err
+ }
+ return r.Visit(replace)
+}
+
+func replace(info *resource.Info, err error) error {
+ if err != nil {
+ return failedTo("replace", info, err)
+ }
+
+ obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, info.Object)
+ if err != nil {
+ return failedTo("replace", info, err)
+ }
+ info.Refresh(obj, true)
+
+ return nil
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package client
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ resourcehelper "k8s.io/kubectl/pkg/util/resource"
+)
+
+var (
+ // ErrLoggerInternal is returned when an error occurs due to the logger
+ ErrLoggerInternal = errors.New("internal logger error")
+)
+
+// GetNodeLabels .. Fetch labels published by the K8s node
+func (c *Client) GetNodeLabels(ctx context.Context) (map[string](map[string]string), error) {
+ log.Info("Get Node Labels list", nil)
+
+ var nodeLabelMap = make(map[string](map[string]string))
+ // iterate through Node Labels
+ nodes, _ := c.Clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
+ for _, node := range nodes.Items {
+ log.Info("GetNodeLabels .. Node Labels", log.Fields{"kube_cluster_name": node.GetClusterName(), "kube_node_name": node.Name, "node_labels": node.Labels})
+ nodeLabelMap[node.Name] = node.Labels
+ }
+
+ return nodeLabelMap, nil
+}
+
+// GetClusterNodes lists all the nodes deployed on the cluster
+func (c *Client) GetClusterNodes(ctx context.Context) (*corev1.NodeList, error) {
+
+ log.Info("GetClusterNodes .. start", nil)
+
+ // access the node APIs
+ nodeList, err := c.Clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
+ if err != nil {
+ log.Error("Kube client: Error in listing nodes", log.Fields{"Error": err.Error()})
+ return nil, fmt.Errorf("Kube client: Error in listing nodes - %s", ErrLoggerInternal)
+ }
+ if len(nodeList.Items) < 1 {
+ log.Warn("Can't find any Nodes in the cluster", nil)
+ return nil, fmt.Errorf("Kube client: Can't find any Nodes in the cluster - %s", ErrLoggerInternal)
+ }
+
+ log.Info("GetClusterNodes .. end", log.Fields{"kube_cluster_name": nodeList.Items[0].ClusterName, "kube_nodes_count": len(nodeList.Items), "kube_node_1_name": nodeList.Items[0].GetName()})
+ return nodeList, nil
+}
+
+// GetPodList lists all the pods deployed on the node
+func (c *Client) GetPodList(ctx context.Context, nodeName string) (*corev1.PodList, error) {
+
+ log.Info("Get Pods list", nil)
+ // TODO: Call with the correct namespace. Empty string passed for default namespace in Pods()
+ podList, err := c.Clientset.CoreV1().Pods("").List(ctx, metav1.ListOptions{FieldSelector: "spec.nodeName=" + nodeName})
+ if err != nil {
+ log.Error("Kube client: Error in listing pods", log.Fields{"Error": err.Error()})
+ return nil, fmt.Errorf("Kube client: Error in listing pods - %s", ErrLoggerInternal)
+ }
+
+ return podList, nil
+}
+
+// GetPodsTotalRequestsAndLimits ... Get resource total requests/limits (including running instances)
+func (c *Client) GetPodsTotalRequestsAndLimits(ctx context.Context, podList *corev1.PodList) (map[corev1.ResourceName]resource.Quantity, map[corev1.ResourceName]resource.Quantity, error) {
+ reqs, limits := map[corev1.ResourceName]resource.Quantity{}, map[corev1.ResourceName]resource.Quantity{}
+
+ log.Info("Get pod total requests and limits", nil)
+
+ for _, pod := range podList.Items {
+ podReqs, podLimits := resourcehelper.PodRequestsAndLimits(&pod)
+ for podReqName, podReqValue := range podReqs {
+ if value, ok := reqs[podReqName]; !ok {
+ reqs[podReqName] = podReqValue.DeepCopy()
+ } else {
+ value.Add(podReqValue)
+ reqs[podReqName] = value
+ }
+ }
+ for podLimitName, podLimitValue := range podLimits {
+ if value, ok := limits[podLimitName]; !ok {
+ limits[podLimitName] = podLimitValue.DeepCopy()
+ } else {
+ value.Add(podLimitValue)
+ limits[podLimitName] = value
+ }
+ }
+ }
+ return reqs, limits, nil
+}
+
+// GetAvailableNodeResources returns the Resource available in the cluster(after dedecting running pods resource requirements)
+func (c *Client) GetAvailableNodeResources(ctx context.Context, resName string) (int64, int64, map[string]int64, error) {
+ var availableAfterResourceReqs int64
+ var availableAfterResourceLimits int64
+
+ log.Info("GetAvailableNodeResources .. start", log.Fields{"resName": resName})
+
+ // Accounting for available resource on all nodes in the cluster
+ nodeList, nodeErr := c.GetClusterNodes(ctx)
+ if nodeErr != nil {
+ log.Error("Unable to fetch Cluster nodes list", log.Fields{"err": nodeErr})
+ return availableAfterResourceReqs, availableAfterResourceLimits, nil, fmt.Errorf("Unable to fetch Cluster nodes list - %s", nodeErr)
+ }
+
+ var nodeResourceMap = make(map[string]int64)
+ for _, node := range nodeList.Items {
+ // Get nonterminated pods list for the node
+ podList, podErr := c.GetPodList(ctx, node.GetName())
+ if podErr != nil {
+ log.Error("Unable to fetch list of pods", log.Fields{"err": podErr})
+ return availableAfterResourceReqs, availableAfterResourceLimits, nil, fmt.Errorf("Unable to initialize kube client - %s", podErr)
+ }
+ // Get all committed resources for pods
+ reqs, limits, _ := c.GetPodsTotalRequestsAndLimits(ctx, podList)
+ resReqs, resLimits := reqs[corev1.ResourceName(resName)], limits[corev1.ResourceName(resName)]
+
+ // availableAfterResourceReqs is Resource available after deducting active pod and system daemon Resource requests
+ // availableAfterResourceLimits is Resource available after deducting active pod and system daemon Resource limits
+ // Limit can be negative for over committed Resources
+
+ if val, ok := node.Status.Allocatable[corev1.ResourceName(resName)]; ok {
+ availableAfterResourceReqs += (val.Value() - resReqs.MilliValue()/1000)
+ nodeResourceMap[node.Name] = (val.Value() - resReqs.MilliValue()/1000)
+ availableAfterResourceLimits += (val.Value() - resLimits.MilliValue()/1000)
+
+ log.Info("GetAvailableNodeResources info => ", log.Fields{
+ "res_name": resName,
+ "node_name": node.Name,
+ "cluster_name": node.GetClusterName(),
+ "resAllocatedToPodsRequest(milli)": resReqs.MilliValue(),
+ "resAllocatedToPodsLimit(milli)": resLimits.MilliValue(),
+ "allocatableRes(milli)": (val.Value() * 1000)})
+ }
+ }
+
+ log.Info("GetAvailableNodeResources .. end",
+ log.Fields{"res_name": resName,
+ "availableAfterResourceReqs": availableAfterResourceReqs,
+ "availableAfterResourceLimits": availableAfterResourceLimits,
+ "nodeResourceMap": nodeResourceMap})
+
+ return availableAfterResourceReqs, availableAfterResourceLimits, nodeResourceMap, nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package connector\r
-\r
-import (\r
- "encoding/base64"\r
- "fmt"\r
- "os"\r
- "strings"\r
- "sync"\r
-\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- kubeclient "github.com/open-ness/EMCO/src/rsync/pkg/client"\r
- "github.com/open-ness/EMCO/src/rsync/pkg/db"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type Connector struct {\r
- cid string\r
- Clients map[string]*kubeclient.Client\r
- sync.Mutex\r
-}\r
-\r
-const basePath string = "/tmp/rsync/"\r
-\r
-// Init connector for an app context\r
-func Init(id interface{}) *Connector {\r
- c := make(map[string]*kubeclient.Client)\r
- str := fmt.Sprintf("%v", id)\r
- return &Connector{\r
- Clients: c,\r
- cid: str,\r
- }\r
-}\r
-\r
-// GetKubeConfig uses the connectivity client to get the kubeconfig based on the name\r
-// of the clustername.\r
-func GetKubeConfig(clustername string, level string, namespace string) ([]byte, error) {\r
- if !strings.Contains(clustername, "+") {\r
- return nil, pkgerrors.New("Not a valid cluster name")\r
- }\r
- strs := strings.Split(clustername, "+")\r
- if len(strs) != 2 {\r
- return nil, pkgerrors.New("Not a valid cluster name")\r
- }\r
-\r
- ccc := db.NewCloudConfigClient()\r
-\r
- cconfig, err := ccc.GetCloudConfig(strs[0], strs[1], level, namespace)\r
- if err != nil {\r
- return nil, pkgerrors.New("Get kubeconfig failed")\r
- }\r
- log.Info("Successfully looked up CloudConfig", log.Fields{".Provider": cconfig.Provider, ".Cluster": cconfig.Cluster, ".Level": cconfig.Level, ".Namespace": cconfig.Namespace})\r
-\r
- dec, err := base64.StdEncoding.DecodeString(cconfig.Config)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return dec, nil\r
-}\r
-\r
-// GetClient returns client for the cluster\r
-func (c *Connector) GetClient(cluster string, level string, namespace string) (*kubeclient.Client, error) {\r
- c.Lock()\r
- defer c.Unlock()\r
-\r
- client, ok := c.Clients[cluster]\r
- if !ok {\r
- // Get file from DB\r
- dec, err := GetKubeConfig(cluster, level, namespace)\r
- if err != nil {\r
- return nil, err\r
- }\r
- var kubeConfigPath string = basePath + c.cid + "/" + cluster + "/"\r
- if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {\r
- err = os.MkdirAll(kubeConfigPath, 0700)\r
- if err != nil {\r
- return nil, err\r
- }\r
- }\r
- kubeConfig := kubeConfigPath + "config"\r
- f, err := os.Create(kubeConfig)\r
- if err != nil {\r
- return nil, err\r
- }\r
- _, err = f.Write(dec)\r
- if err != nil {\r
- return nil, err\r
- }\r
- client = kubeclient.New("", kubeConfig, namespace)\r
- if client != nil {\r
- c.Clients[cluster] = client\r
- }\r
- }\r
- return client, nil\r
-}\r
-\r
-func (c *Connector) GetClientWithRetry(cluster string, level string, namespace string) (*kubeclient.Client, error) {\r
- client, err := c.GetClient(cluster, level, namespace)\r
- if err != nil {\r
- return nil, err\r
- }\r
- if err = client.IsReachable(); err != nil {\r
- return nil, err // TODO: Add retry\r
- }\r
- return client, nil\r
-}\r
-\r
-func (c *Connector) RemoveClient() {\r
- c.Lock()\r
- defer c.Unlock()\r
- err := os.RemoveAll(basePath + "/" + c.cid)\r
- if err != nil {\r
- log.Error("Warning: Deleting kubepath", log.Fields{"err": err})\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package connector
+
+import (
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "os"
+ "strings"
+ "sync"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ kubeclient "github.com/open-ness/EMCO/src/rsync/pkg/client"
+ "github.com/open-ness/EMCO/src/rsync/pkg/db"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// IsTestKubeClient .. global variable used during unit-tests to check whether a fake kube client object has to be instantiated
+var IsTestKubeClient bool = false
+
+type Connector struct {
+ cid string
+ Clients map[string]*kubeclient.Client
+ sync.Mutex
+}
+
+const basePath string = "/tmp/rsync/"
+
+// Init connector for an app context
+func Init(id interface{}) *Connector {
+ c := make(map[string]*kubeclient.Client)
+ str := fmt.Sprintf("%v", id)
+ return &Connector{
+ Clients: c,
+ cid: str,
+ }
+}
+
+// GetKubeConfig uses the connectivity client to get the kubeconfig based on the name
+// of the clustername.
+func GetKubeConfig(clustername string, level string, namespace string) ([]byte, error) {
+ if !strings.Contains(clustername, "+") {
+ return nil, pkgerrors.New("Not a valid cluster name")
+ }
+ strs := strings.Split(clustername, "+")
+ if len(strs) != 2 {
+ return nil, pkgerrors.New("Not a valid cluster name")
+ }
+
+ ccc := db.NewCloudConfigClient()
+
+ cconfig, err := ccc.GetCloudConfig(strs[0], strs[1], level, namespace)
+ if err != nil {
+ return nil, pkgerrors.New("Get kubeconfig failed")
+ }
+ log.Info("Successfully looked up CloudConfig", log.Fields{".Provider": cconfig.Provider, ".Cluster": cconfig.Cluster, ".Level": cconfig.Level, ".Namespace": cconfig.Namespace})
+
+ dec, err := base64.StdEncoding.DecodeString(cconfig.Config)
+ if err != nil {
+ return nil, err
+ }
+ return dec, nil
+}
+
+// GetClient returns client for the cluster
+func (c *Connector) GetClient(cluster string, level string, namespace string) (*kubeclient.Client, error) {
+ c.Lock()
+ defer c.Unlock()
+
+ // Check if Fake kube client is required(it's true for unit tests)
+ log.Info("GetClient .. start", log.Fields{"IsTestKubeClient": fmt.Sprintf("%v", IsTestKubeClient)})
+ if IsTestKubeClient {
+ return kubeclient.NewKubeFakeClient()
+ }
+
+ client, ok := c.Clients[cluster]
+ if !ok {
+ // Get file from DB
+ dec, err := GetKubeConfig(cluster, level, namespace)
+ if err != nil {
+ return nil, err
+ }
+ var kubeConfigPath string = basePath + c.cid + "/" + cluster + "/"
+ if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
+ err = os.MkdirAll(kubeConfigPath, 0700)
+ if err != nil {
+ return nil, err
+ }
+ }
+ kubeConfig := kubeConfigPath + "config"
+ f, err := os.Create(kubeConfig)
+ if err != nil {
+ return nil, err
+ }
+ _, err = f.Write(dec)
+ if err != nil {
+ return nil, err
+ }
+ client = kubeclient.New("", kubeConfig, namespace)
+ if client != nil {
+ c.Clients[cluster] = client
+ } else {
+ return nil, errors.New("failed to connect with the cluster")
+ }
+ }
+ return client, nil
+}
+
+func (c *Connector) GetClientWithRetry(cluster string, level string, namespace string) (*kubeclient.Client, error) {
+ client, err := c.GetClient(cluster, level, namespace)
+ if err != nil {
+ return nil, err
+ }
+ if err = client.IsReachable(); err != nil {
+ return nil, err // TODO: Add retry
+ }
+ return client, nil
+}
+
+func (c *Connector) RemoveClient() {
+ c.Lock()
+ defer c.Unlock()
+ err := os.RemoveAll(basePath + "/" + c.cid)
+ if err != nil {
+ log.Error("Warning: Deleting kubepath", log.Fields{"err": err})
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package context\r
-\r
-import (\r
- "context"\r
- "encoding/json"\r
- "fmt"\r
- "strconv"\r
- "strings"\r
- "sync"\r
- "time"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus"\r
- kubeclient "github.com/open-ness/EMCO/src/rsync/pkg/client"\r
- connector "github.com/open-ness/EMCO/src/rsync/pkg/connector"\r
- utils "github.com/open-ness/EMCO/src/rsync/pkg/internal"\r
- status "github.com/open-ness/EMCO/src/rsync/pkg/status"\r
- pkgerrors "github.com/pkg/errors"\r
- "golang.org/x/sync/errgroup"\r
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"\r
-)\r
-\r
-type CompositeAppContext struct {\r
- cid interface{}\r
- chans []chan bool\r
- mutex sync.Mutex\r
-}\r
-\r
-func getMaxRetries() int {\r
- s := config.GetConfiguration().MaxRetries\r
- if s == "" {\r
- return -1\r
- }\r
- maxRetries, err := strconv.Atoi(s)\r
- if err != nil {\r
- return -1\r
- } else {\r
- if maxRetries < 0 {\r
- return -1\r
- }\r
- }\r
- return maxRetries\r
-}\r
-\r
-func getRes(ac appcontext.AppContext, name string, app string, cluster string) ([]byte, interface{}, error) {\r
- var byteRes []byte\r
- rh, err := ac.GetResourceHandle(app, cluster, name)\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
- sh, err := ac.GetLevelHandle(rh, "status")\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
- resval, err := ac.GetValue(rh)\r
- if err != nil {\r
- return nil, sh, err\r
- }\r
- if resval != "" {\r
- result := strings.Split(name, "+")\r
- if result[0] == "" {\r
- return nil, sh, pkgerrors.Errorf("Resource name is nil %s:", name)\r
- }\r
- byteRes = []byte(fmt.Sprintf("%v", resval.(interface{})))\r
- } else {\r
- return nil, sh, pkgerrors.Errorf("Resource value is nil %s", name)\r
- }\r
- return byteRes, sh, nil\r
-}\r
-\r
-func getSubResApprove(ac appcontext.AppContext, name string, app string, cluster string) ([]byte, interface{}, error) {\r
- var byteRes []byte\r
- rh, err := ac.GetResourceHandle(app, cluster, name)\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
- sh, err := ac.GetLevelHandle(rh, "subresource/approval")\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
- resval, err := ac.GetValue(sh)\r
- if err != nil {\r
- return nil, sh, err\r
- }\r
- if resval != "" {\r
- byteRes = []byte(fmt.Sprintf("%v", resval.(interface{})))\r
- } else {\r
- return nil, sh, pkgerrors.Errorf("SubResource value is nil %s", name)\r
- }\r
- return byteRes, sh, nil\r
-}\r
-\r
-func terminateResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {\r
- res, sh, err := getRes(ac, name, app, cluster)\r
- if err != nil {\r
- if sh != nil {\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})\r
- }\r
- return err\r
- }\r
- if err := c.Delete(res); err != nil {\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})\r
- logutils.Error("Failed to delete res", logutils.Fields{\r
- "error": err,\r
- "resource": name,\r
- })\r
- return err\r
- }\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Deleted})\r
- logutils.Info("Deleted::", logutils.Fields{\r
- "cluster": cluster,\r
- "resource": name,\r
- })\r
- return nil\r
-}\r
-\r
-func instantiateResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {\r
- res, sh, err := getRes(ac, name, app, cluster)\r
- if err != nil {\r
- if sh != nil {\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})\r
- }\r
- return err\r
- }\r
- //Decode the yaml to create a runtime.Object\r
- unstruct := &unstructured.Unstructured{}\r
- //Ignore the returned obj as we expect the data in unstruct\r
- _, err = utils.DecodeYAMLData(string(res), unstruct)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Decode deployment object error")\r
- }\r
-\r
- //Add the tracking label to all resources created here\r
- labels := unstruct.GetLabels()\r
- //Check if labels exist for this object\r
- if labels == nil {\r
- labels = map[string]string{}\r
- }\r
- //labels[config.GetConfiguration().KubernetesLabelName] = client.GetInstanceID()\r
- labels["emco/deployment-id"] = label\r
- unstruct.SetLabels(labels)\r
-\r
- // This checks if the resource we are creating has a podSpec in it\r
- // Eg: Deployment, StatefulSet, Job etc..\r
- // If a PodSpec is found, the label will be added to it too.\r
- //connector.TagPodsIfPresent(unstruct, client.GetInstanceID())\r
- utils.TagPodsIfPresent(unstruct, label)\r
- b, err := unstruct.MarshalJSON()\r
- if err != nil {\r
- logutils.Error("Failed to MarshalJSON", logutils.Fields{\r
- "error": err,\r
- "resource": name,\r
- })\r
- return err\r
- }\r
- if err := c.Apply(b); err != nil {\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})\r
- logutils.Error("Failed to apply res", logutils.Fields{\r
- "error": err,\r
- "resource": name,\r
- })\r
- return err\r
- }\r
- ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Applied})\r
- logutils.Info("Installed::", logutils.Fields{\r
- "cluster": cluster,\r
- "resource": name,\r
- })\r
-\r
- // Currently only subresource supported is approval\r
- subres, _, err := getSubResApprove(ac, name, app, cluster)\r
- if err == nil {\r
- result := strings.Split(name, "+")\r
- if result[0] == "" {\r
- return pkgerrors.Errorf("Resource name is nil %s:", name)\r
- }\r
- logutils.Info("Approval Subresource::", logutils.Fields{\r
- "cluster": cluster,\r
- "resource": result[0],\r
- "approval": string(subres),\r
- })\r
- err = c.Approve(result[0], subres)\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-func updateResourceStatus(ac appcontext.AppContext, resState resourcestatus.ResourceStatus, app string, cluster string, aov map[string][]string) error {\r
-\r
- for _, res := range aov["resorder"] {\r
-\r
- rh, err := ac.GetResourceHandle(app, cluster, res)\r
- if err != nil {\r
- return err\r
- }\r
- sh, err := ac.GetLevelHandle(rh, "status")\r
- if err != nil {\r
- return err\r
- }\r
-\r
- s, err := ac.GetValue(sh)\r
- if err != nil {\r
- return err\r
- }\r
- rStatus := resourcestatus.ResourceStatus{}\r
- js, err := json.Marshal(s)\r
- if err != nil {\r
- return err\r
- }\r
- err = json.Unmarshal(js, &rStatus)\r
- if err != nil {\r
- return err\r
- }\r
- // no need to update a status that has reached a 'done' status\r
- if rStatus.Status == resourcestatus.RsyncStatusEnum.Deleted ||\r
- rStatus.Status == resourcestatus.RsyncStatusEnum.Applied ||\r
- rStatus.Status == resourcestatus.RsyncStatusEnum.Failed {\r
- continue\r
- }\r
-\r
- err = ac.UpdateStatusValue(sh, resState)\r
- if err != nil {\r
- return err\r
- }\r
- }\r
-\r
- return nil\r
-\r
-}\r
-\r
-// return true if all resources have reached a 'done' status - e.g. Applied, Deleted or Failed\r
-func allResourcesDone(ac appcontext.AppContext, app string, cluster string, aov map[string][]string) bool {\r
-\r
- for _, res := range aov["resorder"] {\r
-\r
- rh, err := ac.GetResourceHandle(app, cluster, res)\r
- if err != nil {\r
- return false\r
- }\r
- sh, err := ac.GetLevelHandle(rh, "status")\r
- if err != nil {\r
- return false\r
- }\r
-\r
- s, err := ac.GetValue(sh)\r
- if err != nil {\r
- return false\r
- }\r
- rStatus := resourcestatus.ResourceStatus{}\r
- js, err := json.Marshal(s)\r
- if err != nil {\r
- return false\r
- }\r
- err = json.Unmarshal(js, &rStatus)\r
- if err != nil {\r
- return false\r
- }\r
- if rStatus.Status != resourcestatus.RsyncStatusEnum.Deleted &&\r
- rStatus.Status != resourcestatus.RsyncStatusEnum.Applied &&\r
- rStatus.Status != resourcestatus.RsyncStatusEnum.Failed {\r
- return false\r
- }\r
- }\r
-\r
- return true\r
-\r
-}\r
-\r
-// Wait for 2 secs\r
-const waitTime = 2\r
-\r
-func waitForClusterReady(instca *CompositeAppContext, ac appcontext.AppContext, acStatus appcontext.AppContextStatus, c *kubeclient.Client, appname string, cluster string, aov map[string][]string) error {\r
-\r
- forceDone := false\r
- timedOut := false\r
- resStateUpdated := false\r
- ch := addChan(instca)\r
-\r
- rch := make(chan error, 1)\r
- checkReachable := func() {\r
- err := c.IsReachable()\r
- rch <- err\r
- }\r
-\r
- go checkReachable()\r
-\r
- maxRetries := getMaxRetries()\r
- retryCnt := 0\r
-Loop:\r
- for {\r
- select {\r
- case rerr := <-rch:\r
- if rerr == nil {\r
- break Loop\r
- } else {\r
- logutils.Info("Cluster is not reachable - keep trying::", logutils.Fields{"cluster": cluster})\r
- }\r
- case <-ch:\r
- statusFailed := resourcestatus.ResourceStatus{\r
- Status: resourcestatus.RsyncStatusEnum.Failed,\r
- }\r
- err := updateResourceStatus(ac, statusFailed, appname, cluster, aov)\r
- if err != nil {\r
- deleteChan(instca, ch)\r
- return err\r
- }\r
- forceDone = true\r
- break Loop\r
- case <-time.After(waitTime * time.Second):\r
- // on first timeout - cluster is apparently not reachable, update resources in\r
- // this group to 'Retrying'\r
- if !resStateUpdated {\r
- statusRetrying := resourcestatus.ResourceStatus{\r
- Status: resourcestatus.RsyncStatusEnum.Retrying,\r
- }\r
- err := updateResourceStatus(ac, statusRetrying, appname, cluster, aov)\r
- if err != nil {\r
- deleteChan(instca, ch)\r
- return err\r
- }\r
- resStateUpdated = true\r
- }\r
-\r
- retryCnt++\r
- if maxRetries >= 0 && retryCnt > maxRetries {\r
- statusFailed := resourcestatus.ResourceStatus{\r
- Status: resourcestatus.RsyncStatusEnum.Failed,\r
- }\r
- err := updateResourceStatus(ac, statusFailed, appname, cluster, aov)\r
- if err != nil {\r
- deleteChan(instca, ch)\r
- return err\r
- }\r
- timedOut = true\r
- break Loop\r
- } else {\r
- go checkReachable()\r
- }\r
- break\r
- }\r
- }\r
-\r
- deleteChan(instca, ch)\r
- if timedOut {\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {\r
- logutils.Error("Terminate retries exceeded max. Application resources may be left in cluster", logutils.Fields{\r
- "cluster": cluster,\r
- "app": appname,\r
- "retries": retryCnt,\r
- })\r
- } else {\r
- logutils.Error("Instantiate retries exceeded max.", logutils.Fields{\r
- "cluster": cluster,\r
- "app": appname,\r
- "retries": retryCnt,\r
- })\r
- }\r
- return pkgerrors.Errorf("Retries exceeded max: " + cluster)\r
- }\r
- if forceDone {\r
- return pkgerrors.Errorf("Termination of rsync cluster retry: " + cluster)\r
- }\r
- return nil\r
-}\r
-\r
-// initializeAppContextStatus sets the initial status of every resource appropriately based on the state of the AppContext\r
-func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {\r
- h, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- return err\r
- }\r
- sh, err := ac.GetLevelHandle(h, "status")\r
- if sh == nil {\r
- _, err = ac.AddLevelValue(h, "status", acStatus)\r
- } else {\r
- err = ac.UpdateValue(sh, acStatus)\r
- }\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-// initializeResourceStatus sets the initial status of every resource appropriately based on the state of the AppContext\r
-func initializeResourceStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {\r
- statusPending := resourcestatus.ResourceStatus{\r
- Status: resourcestatus.RsyncStatusEnum.Pending,\r
- }\r
- statusDeleted := resourcestatus.ResourceStatus{\r
- Status: resourcestatus.RsyncStatusEnum.Deleted,\r
- }\r
-\r
- appsOrder, err := ac.GetAppInstruction("order")\r
- if err != nil {\r
- return err\r
- }\r
- var appList map[string][]string\r
- json.Unmarshal([]byte(appsOrder.(string)), &appList)\r
-\r
- for _, app := range appList["apporder"] {\r
- clusterNames, err := ac.GetClusterNames(app)\r
- if err != nil {\r
- return err\r
- }\r
- for k := 0; k < len(clusterNames); k++ {\r
- cluster := clusterNames[k]\r
- resorder, err := ac.GetResourceInstruction(app, cluster, "order")\r
- if err != nil {\r
- return err\r
- }\r
- var aov map[string][]string\r
- json.Unmarshal([]byte(resorder.(string)), &aov)\r
- for _, res := range aov["resorder"] {\r
- rh, err := ac.GetResourceHandle(app, cluster, res)\r
- if err != nil {\r
- return err\r
- }\r
- sh, err := ac.GetLevelHandle(rh, "status")\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {\r
- if sh == nil {\r
- _, err = ac.AddLevelValue(rh, "status", statusPending)\r
- } else {\r
- err = ac.UpdateStatusValue(sh, statusPending)\r
- }\r
- if err != nil {\r
- return err\r
- }\r
- } else if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {\r
- if sh == nil {\r
- _, err = ac.AddLevelValue(rh, "status", statusDeleted)\r
- } else {\r
- s, err := ac.GetValue(sh)\r
- if err != nil {\r
- return err\r
- }\r
- rStatus := resourcestatus.ResourceStatus{}\r
- js, _ := json.Marshal(s)\r
- json.Unmarshal(js, &rStatus)\r
- if rStatus.Status == resourcestatus.RsyncStatusEnum.Applied {\r
- err = ac.UpdateStatusValue(sh, statusPending)\r
- } else {\r
- err = ac.UpdateStatusValue(sh, statusDeleted)\r
- }\r
- if err != nil {\r
- return err\r
- }\r
- }\r
- } else {\r
- return pkgerrors.Errorf("Error intializing AppContext Resource Statuses")\r
- }\r
- }\r
- }\r
- }\r
- return nil\r
-}\r
-\r
-func addStatusTracker(c *kubeclient.Client, app string, cluster string, label string) error {\r
-\r
- b, err := status.GetStatusCR(label)\r
- if err != nil {\r
- logutils.Error("Failed to get status CR for installing", logutils.Fields{\r
- "error": err,\r
- "label": label,\r
- })\r
- return err\r
- }\r
- // TODO: Check reachability?\r
- if err = c.Apply(b); err != nil {\r
- logutils.Error("Failed to apply status tracker", logutils.Fields{\r
- "error": err,\r
- "cluster": cluster,\r
- "app": app,\r
- "label": label,\r
- })\r
- return err\r
- }\r
- logutils.Info("Status tracker installed::", logutils.Fields{\r
- "cluster": cluster,\r
- "app": app,\r
- "label": label,\r
- })\r
- return nil\r
-}\r
-\r
-func deleteStatusTracker(c *kubeclient.Client, app string, cluster string, label string) error {\r
- b, err := status.GetStatusCR(label)\r
- if err != nil {\r
- logutils.Error("Failed to get status CR for deleting", logutils.Fields{\r
- "error": err,\r
- "label": label,\r
- })\r
- return err\r
- }\r
- if err = c.Delete(b); err != nil {\r
- logutils.Error("Failed to delete res", logutils.Fields{\r
- "error": err,\r
- "app": app,\r
- "label": label,\r
- })\r
- return err\r
- }\r
- logutils.Info("Status tracker deleted::", logutils.Fields{\r
- "cluster": cluster,\r
- "app": app,\r
- "label": label,\r
- })\r
- return nil\r
-}\r
-\r
-func updateEndingAppContextStatus(ac appcontext.AppContext, handle interface{}, failure bool) error {\r
- sh, err := ac.GetLevelHandle(handle, "status")\r
- if err != nil {\r
- return err\r
- }\r
- s, err := ac.GetValue(sh)\r
- if err != nil {\r
- return err\r
- }\r
- acStatus := appcontext.AppContextStatus{}\r
- js, _ := json.Marshal(s)\r
- json.Unmarshal(js, &acStatus)\r
-\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {\r
- if failure {\r
- acStatus.Status = appcontext.AppContextStatusEnum.InstantiateFailed\r
- } else {\r
- acStatus.Status = appcontext.AppContextStatusEnum.Instantiated\r
- }\r
- } else if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {\r
- if failure {\r
- acStatus.Status = appcontext.AppContextStatusEnum.TerminateFailed\r
- } else {\r
- acStatus.Status = appcontext.AppContextStatusEnum.Terminated\r
- }\r
- } else {\r
- return pkgerrors.Errorf("Invalid AppContextStatus %v", acStatus)\r
- }\r
-\r
- err = ac.UpdateValue(sh, acStatus)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-func getAppContextStatus(ac appcontext.AppContext) (*appcontext.AppContextStatus, error) {\r
-\r
- h, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- return nil, err\r
- }\r
- sh, err := ac.GetLevelHandle(h, "status")\r
- if err != nil {\r
- return nil, err\r
- }\r
- s, err := ac.GetValue(sh)\r
- if err != nil {\r
- return nil, err\r
- }\r
- acStatus := appcontext.AppContextStatus{}\r
- js, _ := json.Marshal(s)\r
- json.Unmarshal(js, &acStatus)\r
-\r
- return &acStatus, nil\r
-\r
-}\r
-\r
-type fn func(ac appcontext.AppContext, client *kubeclient.Client, res string, app string, cluster string, label string) error\r
-\r
-type statusfn func(client *kubeclient.Client, app string, cluster string, label string) error\r
-\r
-func addChan(instca *CompositeAppContext) chan bool {\r
-\r
- instca.mutex.Lock()\r
- c := make(chan bool)\r
- instca.chans = append(instca.chans, c)\r
- instca.mutex.Unlock()\r
-\r
- return c\r
-}\r
-\r
-func deleteChan(instca *CompositeAppContext, c chan bool) error {\r
-\r
- var i int\r
- instca.mutex.Lock()\r
- for i = 0; i < len(instca.chans); i++ {\r
- if instca.chans[i] == c {\r
- break\r
- }\r
- }\r
-\r
- if i == len(instca.chans) {\r
- instca.mutex.Unlock()\r
- return pkgerrors.Errorf("Given channel was not found:")\r
- }\r
- instca.chans[i] = instca.chans[len(instca.chans)-1]\r
- instca.chans = instca.chans[:len(instca.chans)-1]\r
- instca.mutex.Unlock()\r
-\r
- return nil\r
-}\r
-\r
-func waitForDone(ac appcontext.AppContext) {\r
- count := 0\r
- for {\r
- time.Sleep(1 * time.Second)\r
- count++\r
- if count == 60*60 {\r
- logutils.Info("Wait for done watcher running..", logutils.Fields{})\r
- count = 0\r
- }\r
- acStatus, err := getAppContextStatus(ac)\r
- if err != nil {\r
- logutils.Error("Failed to get the app context status", logutils.Fields{\r
- "error": err,\r
- })\r
- return\r
- }\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Instantiated ||\r
- acStatus.Status == appcontext.AppContextStatusEnum.InstantiateFailed {\r
- return\r
- }\r
- }\r
- return\r
-}\r
-\r
-func kickoffRetryWatcher(instca *CompositeAppContext, ac appcontext.AppContext, acStatus appcontext.AppContextStatus, wg *errgroup.Group) {\r
-\r
- wg.Go(func() error {\r
-\r
- var count int\r
-\r
- count = 0\r
- for {\r
- time.Sleep(1 * time.Second)\r
- count++\r
- if count == 60*60 {\r
- logutils.Info("Retry watcher running..", logutils.Fields{})\r
- count = 0\r
- }\r
-\r
- cStatus, err := getAppContextStatus(ac)\r
- if err != nil {\r
- logutils.Error("Failed to get the app context status", logutils.Fields{\r
- "error": err,\r
- })\r
- return err\r
- }\r
- flag, err := getAppContextFlag(ac)\r
- if err != nil {\r
- logutils.Error("Failed to get the stop flag", logutils.Fields{\r
- "error": err,\r
- })\r
- return err\r
- } else {\r
- if flag == true {\r
- instca.mutex.Lock()\r
- for i := 0; i < len(instca.chans); i++ {\r
- instca.chans[i] <- true\r
- logutils.Info("kickoffRetryWatcher - send an exit message", logutils.Fields{})\r
- }\r
- instca.mutex.Unlock()\r
- break\r
- }\r
- }\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {\r
- if cStatus.Status == appcontext.AppContextStatusEnum.Instantiated ||\r
- cStatus.Status == appcontext.AppContextStatusEnum.InstantiateFailed {\r
- break\r
- }\r
- } else {\r
- if cStatus.Status == appcontext.AppContextStatusEnum.Terminated ||\r
- cStatus.Status == appcontext.AppContextStatusEnum.TerminateFailed {\r
- break\r
- }\r
- }\r
-\r
- }\r
- return nil\r
- })\r
-\r
-}\r
-\r
-func getAppContextFlag(ac appcontext.AppContext) (bool, error) {\r
- h, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- return false, err\r
- }\r
- sh, err := ac.GetLevelHandle(h, "stopflag")\r
- if sh == nil {\r
- return false, err\r
- } else {\r
- v, err := ac.GetValue(sh)\r
- if err != nil {\r
- return false, err\r
- } else {\r
- return v.(bool), nil\r
- }\r
- }\r
-}\r
-\r
-func updateAppContextFlag(cid interface{}, sf bool) error {\r
- ac := appcontext.AppContext{}\r
- _, err := ac.LoadAppContext(cid)\r
- if err != nil {\r
- return err\r
- }\r
- hc, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- return err\r
- }\r
- sh, err := ac.GetLevelHandle(hc, "stopflag")\r
- if sh == nil {\r
- _, err = ac.AddLevelValue(hc, "stopflag", sf)\r
- } else {\r
- err = ac.UpdateValue(sh, sf)\r
- }\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-func applyFnComApp(instca *CompositeAppContext, acStatus appcontext.AppContextStatus, f fn, sfn statusfn, breakonError bool) error {\r
- con := connector.Init(instca.cid)\r
- //Cleanup\r
- defer con.RemoveClient()\r
- ac := appcontext.AppContext{}\r
- h, err := ac.LoadAppContext(instca.cid)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // if terminating, wait for all retrying instantiate threads to exit\r
- if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {\r
- waitForDone(ac)\r
- err := updateAppContextFlag(instca.cid, false)\r
- if err != nil {\r
- return err\r
- }\r
- }\r
-\r
- // initialize appcontext status\r
- err = initializeAppContextStatus(ac, acStatus)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- // initialize the resource status values before proceeding with the function\r
- err = initializeResourceStatus(ac, acStatus)\r
- if err != nil {\r
- logutils.Error("", logutils.Fields{"err": err})\r
- return err\r
- }\r
-\r
- appsOrder, err := ac.GetAppInstruction("order")\r
- if err != nil {\r
- return err\r
- }\r
- var appList map[string][]string\r
- json.Unmarshal([]byte(appsOrder.(string)), &appList)\r
- logutils.Info("appsorder ", logutils.Fields{\r
- "appsorder": appsOrder,\r
- "string": appList,\r
- })\r
- id, _ := ac.GetCompositeAppHandle()\r
- g, _ := errgroup.WithContext(context.Background())\r
- wg, _ := errgroup.WithContext(context.Background())\r
- kickoffRetryWatcher(instca, ac, acStatus, wg)\r
-\r
- // get namespace and level of cloudconfig to use for resources\r
- namespace := "default"\r
- level := "0"\r
- appmeta, err := ac.GetCompositeAppMeta()\r
- if err == nil {\r
- namespace = appmeta.Namespace\r
- level = appmeta.Level\r
- }\r
- logutils.Info("CloudConfig for this app will be looked up using level and namespace specified", logutils.Fields{\r
- "level": level,\r
- "namespace": namespace,\r
- })\r
-\r
- // Iterate over all the subapps\r
- for _, app := range appList["apporder"] {\r
- appName := app\r
- results := strings.Split(id.(string), "/")\r
- label := results[2] + "-" + app\r
- g.Go(func() error {\r
- clusterNames, err := ac.GetClusterNames(appName)\r
- if err != nil {\r
- return err\r
- }\r
- // Iterate over all clusters\r
- for k := 0; k < len(clusterNames); k++ {\r
- cluster := clusterNames[k]\r
- err = status.StartClusterWatcher(cluster)\r
- if err != nil {\r
- logutils.Error("Error starting Cluster Watcher", logutils.Fields{\r
- "error": err,\r
- "cluster": cluster,\r
- })\r
- }\r
- g.Go(func() error {\r
- c, err := con.GetClient(cluster, level, namespace)\r
- if err != nil {\r
- logutils.Error("Error in creating kubeconfig client", logutils.Fields{\r
- "error": err,\r
- "cluster": cluster,\r
- "appName": appName,\r
- })\r
- return err\r
- }\r
- resorder, err := ac.GetResourceInstruction(appName, cluster, "order")\r
- if err != nil {\r
- logutils.Error("Resorder error ", logutils.Fields{"error": err})\r
- return err\r
- }\r
- var aov map[string][]string\r
- json.Unmarshal([]byte(resorder.(string)), &aov)\r
- // Keep retrying for reachability\r
- for {\r
- done := allResourcesDone(ac, appName, cluster, aov)\r
- if done {\r
- break\r
- }\r
-\r
- // Wait for cluster to be reachable\r
- err := waitForClusterReady(instca, ac, acStatus, c, appName, cluster, aov)\r
- if err != nil {\r
- // TODO: Add error handling\r
- return err\r
- }\r
- reachable := true\r
- // Handle all resources in order\r
- for i, res := range aov["resorder"] {\r
- err = f(ac, c, res, appName, cluster, label)\r
- if err != nil {\r
- logutils.Error("Error in resource %s: %v", logutils.Fields{\r
- "error": err,\r
- "cluster": cluster,\r
- "resource": res,\r
- })\r
- // If failure is due to reachability issues start retrying\r
- if err = c.IsReachable(); err != nil {\r
- reachable = false\r
- break\r
- }\r
- if breakonError {\r
- // handle status tracking before exiting if at least one resource got handled\r
- if i > 0 {\r
- serr := sfn(c, appName, cluster, label)\r
- if serr != nil {\r
- logutils.Warn("Error handling status tracker", logutils.Fields{"error": serr})\r
- }\r
- }\r
- return err\r
- }\r
- }\r
- }\r
- // Check if the break from loop due to reachabilty issues\r
- if reachable != false {\r
- serr := sfn(c, appName, cluster, label)\r
- if serr != nil {\r
- logutils.Warn("Error handling status tracker", logutils.Fields{"error": serr})\r
- }\r
- // Done processing cluster without errors\r
- return nil\r
- }\r
- }\r
- return nil\r
- })\r
- }\r
- return nil\r
- })\r
- }\r
- // Wait for all subtasks to complete\r
- if err := g.Wait(); err != nil {\r
- uperr := updateEndingAppContextStatus(ac, h, true)\r
- if uperr != nil {\r
- logutils.Error("Encountered error updating AppContext to Failed status", logutils.Fields{"error": uperr})\r
- }\r
- logutils.Error("Encountered error", logutils.Fields{\r
- "error": err,\r
- })\r
- return err\r
- }\r
- err = updateEndingAppContextStatus(ac, h, false)\r
- if err != nil {\r
- logutils.Error("Encountered error updating AppContext status", logutils.Fields{"error": err})\r
- return err\r
- }\r
- if err := wg.Wait(); err != nil {\r
- logutils.Error("Encountered error in watcher thread", logutils.Fields{"error": err})\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-// InstantiateComApp Instantiate Apps in Composite App\r
-func (instca *CompositeAppContext) InstantiateComApp(cid interface{}) error {\r
- instca.cid = cid\r
- instca.chans = []chan bool{}\r
- instca.mutex = sync.Mutex{}\r
- err := updateAppContextFlag(cid, false)\r
- if err != nil {\r
- logutils.Error("Encountered error updating AppContext flag", logutils.Fields{"error": err})\r
- return err\r
- }\r
- go applyFnComApp(instca, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiating},\r
- instantiateResource, addStatusTracker, true)\r
- return nil\r
-}\r
-\r
-// TerminateComApp Terminates Apps in Composite App\r
-func (instca *CompositeAppContext) TerminateComApp(cid interface{}) error {\r
- instca.cid = cid\r
- instca.chans = []chan bool{}\r
- instca.mutex = sync.Mutex{}\r
- err := updateAppContextFlag(cid, true)\r
- if err != nil {\r
- logutils.Error("Encountered error updating AppContext flag", logutils.Fields{"error": err})\r
- return err\r
- }\r
- go applyFnComApp(instca, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Terminating},\r
- terminateResource, deleteStatusTracker, false)\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package context
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus"
+ kubeclient "github.com/open-ness/EMCO/src/rsync/pkg/client"
+ connector "github.com/open-ness/EMCO/src/rsync/pkg/connector"
+ utils "github.com/open-ness/EMCO/src/rsync/pkg/internal"
+ status "github.com/open-ness/EMCO/src/rsync/pkg/status"
+ pkgerrors "github.com/pkg/errors"
+ "golang.org/x/sync/errgroup"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+)
+
+type CompositeAppContext struct {
+ cid interface{}
+ chans []chan bool
+ mutex sync.Mutex
+}
+
+func getMaxRetries() int {
+ s := config.GetConfiguration().MaxRetries
+ if s == "" {
+ return -1
+ }
+ maxRetries, err := strconv.Atoi(s)
+ if err != nil {
+ return -1
+ } else {
+ if maxRetries < 0 {
+ return -1
+ }
+ }
+ return maxRetries
+}
+
+func getRes(ac appcontext.AppContext, name string, app string, cluster string) ([]byte, interface{}, error) {
+ var byteRes []byte
+ rh, err := ac.GetResourceHandle(app, cluster, name)
+ if err != nil {
+ return nil, nil, err
+ }
+ sh, err := ac.GetLevelHandle(rh, "status")
+ if err != nil {
+ return nil, nil, err
+ }
+ resval, err := ac.GetValue(rh)
+ if err != nil {
+ return nil, sh, err
+ }
+ if resval != "" {
+ result := strings.Split(name, "+")
+ if result[0] == "" {
+ return nil, sh, pkgerrors.Errorf("Resource name is nil %s:", name)
+ }
+ byteRes = []byte(fmt.Sprintf("%v", resval.(interface{})))
+ } else {
+ return nil, sh, pkgerrors.Errorf("Resource value is nil %s", name)
+ }
+ return byteRes, sh, nil
+}
+
+func getSubResApprove(ac appcontext.AppContext, name string, app string, cluster string) ([]byte, interface{}, error) {
+ var byteRes []byte
+ rh, err := ac.GetResourceHandle(app, cluster, name)
+ if err != nil {
+ return nil, nil, err
+ }
+ sh, err := ac.GetLevelHandle(rh, "subresource/approval")
+ if err != nil {
+ return nil, nil, err
+ }
+ resval, err := ac.GetValue(sh)
+ if err != nil {
+ return nil, sh, err
+ }
+ if resval != "" {
+ byteRes = []byte(fmt.Sprintf("%v", resval.(interface{})))
+ } else {
+ return nil, sh, pkgerrors.Errorf("SubResource value is nil %s", name)
+ }
+ return byteRes, sh, nil
+}
+
+func terminateResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {
+ res, sh, err := getRes(ac, name, app, cluster)
+ if err != nil {
+ if sh != nil {
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})
+ }
+ return err
+ }
+ if err := c.Delete(res); err != nil {
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})
+ logutils.Error("Failed to delete res", logutils.Fields{
+ "error": err,
+ "resource": name,
+ })
+ return err
+ }
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Deleted})
+ logutils.Info("Deleted::", logutils.Fields{
+ "cluster": cluster,
+ "resource": name,
+ })
+ return nil
+}
+
+func instantiateResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {
+ res, sh, err := getRes(ac, name, app, cluster)
+ if err != nil {
+ if sh != nil {
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})
+ }
+ return err
+ }
+ //Decode the yaml to create a runtime.Object
+ unstruct := &unstructured.Unstructured{}
+ //Ignore the returned obj as we expect the data in unstruct
+ _, err = utils.DecodeYAMLData(string(res), unstruct)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Decode deployment object error")
+ }
+
+ //Add the tracking label to all resources created here
+ labels := unstruct.GetLabels()
+ //Check if labels exist for this object
+ if labels == nil {
+ labels = map[string]string{}
+ }
+ //labels[config.GetConfiguration().KubernetesLabelName] = client.GetInstanceID()
+ labels["emco/deployment-id"] = label
+ unstruct.SetLabels(labels)
+
+ // This checks if the resource we are creating has a podSpec in it
+ // Eg: Deployment, StatefulSet, Job etc..
+ // If a PodSpec is found, the label will be added to it too.
+ //connector.TagPodsIfPresent(unstruct, client.GetInstanceID())
+ utils.TagPodsIfPresent(unstruct, label)
+ b, err := unstruct.MarshalJSON()
+ if err != nil {
+ logutils.Error("Failed to MarshalJSON", logutils.Fields{
+ "error": err,
+ "resource": name,
+ })
+ return err
+ }
+ if err := c.Apply(b); err != nil {
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})
+ logutils.Error("Failed to apply res", logutils.Fields{
+ "error": err,
+ "resource": name,
+ })
+ return err
+ }
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Applied})
+ logutils.Info("Installed::", logutils.Fields{
+ "cluster": cluster,
+ "resource": name,
+ })
+
+ // Currently only subresource supported is approval
+ subres, _, err := getSubResApprove(ac, name, app, cluster)
+ if err == nil {
+ result := strings.Split(name, "+")
+ if result[0] == "" {
+ return pkgerrors.Errorf("Resource name is nil %s:", name)
+ }
+ logutils.Info("Approval Subresource::", logutils.Fields{
+ "cluster": cluster,
+ "resource": result[0],
+ "approval": string(subres),
+ })
+ err = c.Approve(result[0], subres)
+ return err
+ }
+ return nil
+}
+
+func readResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {
+ res, sh, err := getRes(ac, name, app, cluster)
+ if err != nil {
+ if sh != nil {
+ ac.UpdateStatusValue(sh, resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Failed})
+ }
+ return err
+ }
+ namespace := "default"
+ appmeta, err := ac.GetCompositeAppMeta()
+ if err == nil {
+ namespace = appmeta.Namespace
+ }
+ // Get the resource from the cluster
+ b, err := c.Get(res, namespace)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Client Get failed")
+ }
+ // Get the handle for the context/app/cluster/res status object
+ rh, err := ac.GetResourceHandle(app, cluster, name)
+ if err != nil {
+ return err
+ }
+ handle, _ := ac.GetLevelHandle(rh, "definition")
+ // If definition handle was not found, then create it
+ if handle == nil {
+ ac.AddLevelValue(rh, "definition", string(b))
+ } else {
+ ac.UpdateStatusValue(rh, string(b))
+ }
+ return nil
+}
+
+func updateResourceStatus(ac appcontext.AppContext, resState resourcestatus.ResourceStatus, app string, cluster string, aov map[string][]string) error {
+
+ for _, res := range aov["resorder"] {
+
+ rh, err := ac.GetResourceHandle(app, cluster, res)
+ if err != nil {
+ return err
+ }
+ sh, err := ac.GetLevelHandle(rh, "status")
+ if err != nil {
+ return err
+ }
+
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return err
+ }
+ rStatus := resourcestatus.ResourceStatus{}
+ js, err := json.Marshal(s)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(js, &rStatus)
+ if err != nil {
+ return err
+ }
+ // no need to update a status that has reached a 'done' status
+ if rStatus.Status == resourcestatus.RsyncStatusEnum.Deleted ||
+ rStatus.Status == resourcestatus.RsyncStatusEnum.Applied ||
+ rStatus.Status == resourcestatus.RsyncStatusEnum.Failed {
+ continue
+ }
+
+ err = ac.UpdateStatusValue(sh, resState)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+
+}
+
+// return true if all resources have reached a 'done' status - e.g. Applied, Deleted or Failed
+func allResourcesDone(ac appcontext.AppContext, app string, cluster string, aov map[string][]string) bool {
+
+ for _, res := range aov["resorder"] {
+
+ rh, err := ac.GetResourceHandle(app, cluster, res)
+ if err != nil {
+ return false
+ }
+ sh, err := ac.GetLevelHandle(rh, "status")
+ if err != nil {
+ return false
+ }
+
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return false
+ }
+ rStatus := resourcestatus.ResourceStatus{}
+ js, err := json.Marshal(s)
+ if err != nil {
+ return false
+ }
+ err = json.Unmarshal(js, &rStatus)
+ if err != nil {
+ return false
+ }
+ if rStatus.Status != resourcestatus.RsyncStatusEnum.Deleted &&
+ rStatus.Status != resourcestatus.RsyncStatusEnum.Applied &&
+ rStatus.Status != resourcestatus.RsyncStatusEnum.Failed {
+ return false
+ }
+ }
+
+ return true
+
+}
+
+// Wait for 2 secs
+const waitTime = 2
+
+func waitForClusterReady(instca *CompositeAppContext, ac appcontext.AppContext, acStatus appcontext.AppContextStatus, c *kubeclient.Client, appname string, cluster string, aov map[string][]string) error {
+
+ forceDone := false
+ timedOut := false
+ resStateUpdated := false
+ ch := addChan(instca)
+
+ rch := make(chan error, 1)
+ checkReachable := func() {
+ err := c.IsReachable()
+ rch <- err
+ }
+
+ go checkReachable()
+
+ maxRetries := getMaxRetries()
+ retryCnt := 0
+Loop:
+ for {
+ select {
+ case rerr := <-rch:
+ if rerr == nil {
+ break Loop
+ } else {
+ logutils.Info("Cluster is not reachable - keep trying::", logutils.Fields{"cluster": cluster})
+ }
+ case <-ch:
+ statusFailed := resourcestatus.ResourceStatus{
+ Status: resourcestatus.RsyncStatusEnum.Failed,
+ }
+ err := updateResourceStatus(ac, statusFailed, appname, cluster, aov)
+ if err != nil {
+ deleteChan(instca, ch)
+ return err
+ }
+ forceDone = true
+ break Loop
+ case <-time.After(waitTime * time.Second):
+ // on first timeout - cluster is apparently not reachable, update resources in
+ // this group to 'Retrying'
+ if !resStateUpdated {
+ statusRetrying := resourcestatus.ResourceStatus{
+ Status: resourcestatus.RsyncStatusEnum.Retrying,
+ }
+ err := updateResourceStatus(ac, statusRetrying, appname, cluster, aov)
+ if err != nil {
+ deleteChan(instca, ch)
+ return err
+ }
+ resStateUpdated = true
+ }
+
+ retryCnt++
+ if maxRetries >= 0 && retryCnt > maxRetries {
+ statusFailed := resourcestatus.ResourceStatus{
+ Status: resourcestatus.RsyncStatusEnum.Failed,
+ }
+ err := updateResourceStatus(ac, statusFailed, appname, cluster, aov)
+ if err != nil {
+ deleteChan(instca, ch)
+ return err
+ }
+ timedOut = true
+ break Loop
+ } else {
+ go checkReachable()
+ }
+ break
+ }
+ }
+
+ deleteChan(instca, ch)
+ if timedOut {
+ if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {
+ logutils.Error("Terminate retries exceeded max. Application resources may be left in cluster", logutils.Fields{
+ "cluster": cluster,
+ "app": appname,
+ "retries": retryCnt,
+ })
+ } else {
+ logutils.Error("Instantiate retries exceeded max.", logutils.Fields{
+ "cluster": cluster,
+ "app": appname,
+ "retries": retryCnt,
+ })
+ }
+ return pkgerrors.Errorf("Retries exceeded max: " + cluster)
+ }
+ if forceDone {
+ return pkgerrors.Errorf("Termination of rsync cluster retry: " + cluster)
+ }
+ return nil
+}
+
+// initializeAppContextStatus sets the initial status of every resource appropriately based on the state of the AppContext
+func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {
+ h, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return err
+ }
+ sh, err := ac.GetLevelHandle(h, "status")
+ if sh == nil {
+ _, err = ac.AddLevelValue(h, "status", acStatus)
+ } else {
+ err = ac.UpdateValue(sh, acStatus)
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// initializeResourceStatus sets the initial status of every resource appropriately based on the state of the AppContext
+func initializeResourceStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {
+ statusPending := resourcestatus.ResourceStatus{
+ Status: resourcestatus.RsyncStatusEnum.Pending,
+ }
+ statusDeleted := resourcestatus.ResourceStatus{
+ Status: resourcestatus.RsyncStatusEnum.Deleted,
+ }
+
+ appsOrder, err := ac.GetAppInstruction("order")
+ if err != nil {
+ return err
+ }
+ var appList map[string][]string
+ json.Unmarshal([]byte(appsOrder.(string)), &appList)
+
+ for _, app := range appList["apporder"] {
+ clusterNames, err := ac.GetClusterNames(app)
+ if err != nil {
+ return err
+ }
+ for k := 0; k < len(clusterNames); k++ {
+ cluster := clusterNames[k]
+ resorder, err := ac.GetResourceInstruction(app, cluster, "order")
+ if err != nil {
+ return err
+ }
+ var aov map[string][]string
+ json.Unmarshal([]byte(resorder.(string)), &aov)
+ for _, res := range aov["resorder"] {
+ rh, err := ac.GetResourceHandle(app, cluster, res)
+ if err != nil {
+ return err
+ }
+ sh, err := ac.GetLevelHandle(rh, "status")
+ if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {
+ if sh == nil {
+ _, err = ac.AddLevelValue(rh, "status", statusPending)
+ } else {
+ err = ac.UpdateStatusValue(sh, statusPending)
+ }
+ if err != nil {
+ return err
+ }
+ } else if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {
+ if sh == nil {
+ _, err = ac.AddLevelValue(rh, "status", statusDeleted)
+ } else {
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return err
+ }
+ rStatus := resourcestatus.ResourceStatus{}
+ js, _ := json.Marshal(s)
+ json.Unmarshal(js, &rStatus)
+ if rStatus.Status == resourcestatus.RsyncStatusEnum.Applied {
+ err = ac.UpdateStatusValue(sh, statusPending)
+ } else {
+ err = ac.UpdateStatusValue(sh, statusDeleted)
+ }
+ if err != nil {
+ return err
+ }
+ }
+ } else {
+ return pkgerrors.Errorf("Error intializing AppContext Resource Statuses")
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func addStatusTracker(c *kubeclient.Client, app string, cluster string, label string) error {
+
+ b, err := status.GetStatusCR(label)
+ if err != nil {
+ logutils.Error("Failed to get status CR for installing", logutils.Fields{
+ "error": err,
+ "label": label,
+ })
+ return err
+ }
+ // TODO: Check reachability?
+ if err = c.Apply(b); err != nil {
+ logutils.Error("Failed to apply status tracker", logutils.Fields{
+ "error": err,
+ "cluster": cluster,
+ "app": app,
+ "label": label,
+ })
+ return err
+ }
+ logutils.Info("Status tracker installed::", logutils.Fields{
+ "cluster": cluster,
+ "app": app,
+ "label": label,
+ })
+ return nil
+}
+
+func deleteStatusTracker(c *kubeclient.Client, app string, cluster string, label string) error {
+ b, err := status.GetStatusCR(label)
+ if err != nil {
+ logutils.Error("Failed to get status CR for deleting", logutils.Fields{
+ "error": err,
+ "label": label,
+ })
+ return err
+ }
+ if err = c.Delete(b); err != nil {
+ logutils.Error("Failed to delete res", logutils.Fields{
+ "error": err,
+ "app": app,
+ "label": label,
+ })
+ return err
+ }
+ logutils.Info("Status tracker deleted::", logutils.Fields{
+ "cluster": cluster,
+ "app": app,
+ "label": label,
+ })
+ return nil
+}
+
+func updateEndingAppContextStatus(ac appcontext.AppContext, handle interface{}, failure bool) error {
+ sh, err := ac.GetLevelHandle(handle, "status")
+ if err != nil {
+ return err
+ }
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return err
+ }
+ acStatus := appcontext.AppContextStatus{}
+ js, _ := json.Marshal(s)
+ json.Unmarshal(js, &acStatus)
+
+ if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {
+ if failure {
+ acStatus.Status = appcontext.AppContextStatusEnum.InstantiateFailed
+ } else {
+ acStatus.Status = appcontext.AppContextStatusEnum.Instantiated
+ }
+ } else if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {
+ if failure {
+ acStatus.Status = appcontext.AppContextStatusEnum.TerminateFailed
+ } else {
+ acStatus.Status = appcontext.AppContextStatusEnum.Terminated
+ }
+ } else {
+ return pkgerrors.Errorf("Invalid AppContextStatus %v", acStatus)
+ }
+
+ err = ac.UpdateValue(sh, acStatus)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func getAppContextStatus(ac appcontext.AppContext) (*appcontext.AppContextStatus, error) {
+
+ h, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return nil, err
+ }
+ sh, err := ac.GetLevelHandle(h, "status")
+ if err != nil {
+ return nil, err
+ }
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return nil, err
+ }
+ acStatus := appcontext.AppContextStatus{}
+ js, _ := json.Marshal(s)
+ json.Unmarshal(js, &acStatus)
+
+ return &acStatus, nil
+
+}
+
+type fn func(ac appcontext.AppContext, client *kubeclient.Client, res string, app string, cluster string, label string) error
+
+type statusfn func(client *kubeclient.Client, app string, cluster string, label string) error
+
+func addChan(instca *CompositeAppContext) chan bool {
+
+ instca.mutex.Lock()
+ c := make(chan bool)
+ instca.chans = append(instca.chans, c)
+ instca.mutex.Unlock()
+
+ return c
+}
+
+func deleteChan(instca *CompositeAppContext, c chan bool) error {
+
+ var i int
+ instca.mutex.Lock()
+ for i = 0; i < len(instca.chans); i++ {
+ if instca.chans[i] == c {
+ break
+ }
+ }
+
+ if i == len(instca.chans) {
+ instca.mutex.Unlock()
+ return pkgerrors.Errorf("Given channel was not found:")
+ }
+ instca.chans[i] = instca.chans[len(instca.chans)-1]
+ instca.chans = instca.chans[:len(instca.chans)-1]
+ instca.mutex.Unlock()
+
+ return nil
+}
+
+func waitForDone(ac appcontext.AppContext) {
+ count := 0
+ for {
+ time.Sleep(1 * time.Second)
+ count++
+ if count == 60*60 {
+ logutils.Info("Wait for done watcher running..", logutils.Fields{})
+ count = 0
+ }
+ acStatus, err := getAppContextStatus(ac)
+ if err != nil {
+ logutils.Error("Failed to get the app context status", logutils.Fields{
+ "error": err,
+ })
+ return
+ }
+ if acStatus.Status == appcontext.AppContextStatusEnum.Instantiated ||
+ acStatus.Status == appcontext.AppContextStatusEnum.InstantiateFailed {
+ return
+ }
+ }
+
+}
+
+func kickoffRetryWatcher(instca *CompositeAppContext, ac appcontext.AppContext, acStatus appcontext.AppContextStatus, wg *errgroup.Group) {
+
+ wg.Go(func() error {
+
+ var count int
+
+ count = 0
+ for {
+ time.Sleep(1 * time.Second)
+ count++
+ if count == 60*60 {
+ logutils.Info("Retry watcher running..", logutils.Fields{})
+ count = 0
+ }
+
+ cStatus, err := getAppContextStatus(ac)
+ if err != nil {
+ logutils.Error("Failed to get the app context status", logutils.Fields{
+ "error": err,
+ })
+ return err
+ }
+ flag, err := getAppContextFlag(ac)
+ if err != nil {
+ logutils.Error("Failed to get the stop flag", logutils.Fields{
+ "error": err,
+ })
+ return err
+ } else {
+ if flag == true {
+ instca.mutex.Lock()
+ for i := 0; i < len(instca.chans); i++ {
+ instca.chans[i] <- true
+ logutils.Info("kickoffRetryWatcher - send an exit message", logutils.Fields{})
+ }
+ instca.mutex.Unlock()
+ break
+ }
+ }
+ if acStatus.Status == appcontext.AppContextStatusEnum.Instantiating {
+ if cStatus.Status == appcontext.AppContextStatusEnum.Instantiated ||
+ cStatus.Status == appcontext.AppContextStatusEnum.InstantiateFailed {
+ break
+ }
+ } else {
+ if cStatus.Status == appcontext.AppContextStatusEnum.Terminated ||
+ cStatus.Status == appcontext.AppContextStatusEnum.TerminateFailed {
+ break
+ }
+ }
+
+ }
+ return nil
+ })
+
+}
+
+func getAppContextFlag(ac appcontext.AppContext) (bool, error) {
+ h, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return false, err
+ }
+ sh, err := ac.GetLevelHandle(h, "stopflag")
+ if sh == nil {
+ return false, err
+ } else {
+ v, err := ac.GetValue(sh)
+ if err != nil {
+ return false, err
+ } else {
+ return v.(bool), nil
+ }
+ }
+}
+
+func updateAppContextFlag(cid interface{}, sf bool) error {
+ ac := appcontext.AppContext{}
+ _, err := ac.LoadAppContext(cid)
+ if err != nil {
+ return err
+ }
+ hc, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return err
+ }
+ sh, err := ac.GetLevelHandle(hc, "stopflag")
+ if sh == nil {
+ _, err = ac.AddLevelValue(hc, "stopflag", sf)
+ } else {
+ err = ac.UpdateValue(sh, sf)
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func applyFnComApp(instca *CompositeAppContext, acStatus appcontext.AppContextStatus, f fn, sfn statusfn, breakonError bool) error {
+ con := connector.Init(instca.cid)
+ //Cleanup
+ defer con.RemoveClient()
+ ac := appcontext.AppContext{}
+ h, err := ac.LoadAppContext(instca.cid)
+ if err != nil {
+ return err
+ }
+
+ // if terminating, wait for all retrying instantiate threads to exit
+ if acStatus.Status == appcontext.AppContextStatusEnum.Terminating {
+ waitForDone(ac)
+ err := updateAppContextFlag(instca.cid, false)
+ if err != nil {
+ return err
+ }
+ }
+
+ // initialize appcontext status
+ err = initializeAppContextStatus(ac, acStatus)
+ if err != nil {
+ return err
+ }
+
+ // initialize the resource status values before proceeding with the function
+ err = initializeResourceStatus(ac, acStatus)
+ if err != nil {
+ logutils.Error("", logutils.Fields{"err": err})
+ return err
+ }
+
+ appsOrder, err := ac.GetAppInstruction("order")
+ if err != nil {
+ return err
+ }
+ var appList map[string][]string
+ json.Unmarshal([]byte(appsOrder.(string)), &appList)
+ logutils.Info("appsorder ", logutils.Fields{
+ "appsorder": appsOrder,
+ "string": appList,
+ })
+ id, _ := ac.GetCompositeAppHandle()
+ g, _ := errgroup.WithContext(context.Background())
+ wg, _ := errgroup.WithContext(context.Background())
+ kickoffRetryWatcher(instca, ac, acStatus, wg)
+
+ // get namespace and level of cloudconfig to use for resources
+ namespace := "default"
+ level := "0"
+ appmeta, err := ac.GetCompositeAppMeta()
+ if err == nil {
+ namespace = appmeta.Namespace
+ level = appmeta.Level
+ }
+ logutils.Info("CloudConfig for this app will be looked up using level and namespace specified", logutils.Fields{
+ "level": level,
+ "namespace": namespace,
+ })
+
+ // Iterate over all the subapps
+ for _, app := range appList["apporder"] {
+ appName := app
+ results := strings.Split(id.(string), "/")
+ label := results[2] + "-" + app
+ g.Go(func() error {
+ clusterNames, err := ac.GetClusterNames(appName)
+ if err != nil {
+ return err
+ }
+ // Iterate over all clusters
+ for k := 0; k < len(clusterNames); k++ {
+ cluster := clusterNames[k]
+ err = status.StartClusterWatcher(cluster)
+ if err != nil {
+ logutils.Error("Error starting Cluster Watcher", logutils.Fields{
+ "error": err,
+ "cluster": cluster,
+ })
+ }
+ g.Go(func() error {
+ c, err := con.GetClient(cluster, level, namespace)
+ if err != nil {
+ logutils.Error("Error in creating kubeconfig client", logutils.Fields{
+ "error": err,
+ "cluster": cluster,
+ "appName": appName,
+ })
+ return err
+ }
+ resorder, err := ac.GetResourceInstruction(appName, cluster, "order")
+ if err != nil {
+ logutils.Error("Resorder error ", logutils.Fields{"error": err})
+ return err
+ }
+ var aov map[string][]string
+ json.Unmarshal([]byte(resorder.(string)), &aov)
+ // Keep retrying for reachability
+ for {
+ done := allResourcesDone(ac, appName, cluster, aov)
+ if done {
+ break
+ }
+
+ // Wait for cluster to be reachable
+ err := waitForClusterReady(instca, ac, acStatus, c, appName, cluster, aov)
+ if err != nil {
+ // TODO: Add error handling
+ return err
+ }
+ reachable := true
+ // Handle all resources in order
+ for i, res := range aov["resorder"] {
+ err = f(ac, c, res, appName, cluster, label)
+ if err != nil {
+ logutils.Error("Error in resource %s: %v", logutils.Fields{
+ "error": err,
+ "cluster": cluster,
+ "resource": res,
+ })
+ // If failure is due to reachability issues start retrying
+ if err = c.IsReachable(); err != nil {
+ reachable = false
+ break
+ }
+ if breakonError {
+ // handle status tracking before exiting if at least one resource got handled
+ if i > 0 {
+ serr := sfn(c, appName, cluster, label)
+ if serr != nil {
+ logutils.Warn("Error handling status tracker", logutils.Fields{"error": serr})
+ }
+ }
+ return err
+ }
+ }
+ }
+ // Check if the break from loop due to reachabilty issues
+ if reachable != false {
+ serr := sfn(c, appName, cluster, label)
+ if serr != nil {
+ logutils.Warn("Error handling status tracker", logutils.Fields{"error": serr})
+ }
+ // Done processing cluster without errors
+ return nil
+ }
+ }
+ return nil
+ })
+ }
+ return nil
+ })
+ }
+ // Wait for all subtasks to complete
+ if err := g.Wait(); err != nil {
+ uperr := updateEndingAppContextStatus(ac, h, true)
+ if uperr != nil {
+ logutils.Error("Encountered error updating AppContext to Failed status", logutils.Fields{"error": uperr})
+ }
+ logutils.Error("Encountered error", logutils.Fields{
+ "error": err,
+ })
+ return err
+ }
+ err = updateEndingAppContextStatus(ac, h, false)
+ if err != nil {
+ logutils.Error("Encountered error updating AppContext status", logutils.Fields{"error": err})
+ return err
+ }
+ if err := wg.Wait(); err != nil {
+ logutils.Error("Encountered error in watcher thread", logutils.Fields{"error": err})
+ return err
+ }
+ return nil
+}
+
+// InstantiateComApp Instantiate Apps in Composite App
+func (instca *CompositeAppContext) InstantiateComApp(cid interface{}) error {
+ instca.cid = cid
+ instca.chans = []chan bool{}
+ instca.mutex = sync.Mutex{}
+ err := updateAppContextFlag(cid, false)
+ if err != nil {
+ logutils.Error("Encountered error updating AppContext flag", logutils.Fields{"error": err})
+ return err
+ }
+ go applyFnComApp(instca, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiating},
+ instantiateResource, addStatusTracker, true)
+
+ return nil
+}
+
+// TerminateComApp Terminates Apps in Composite App
+func (instca *CompositeAppContext) TerminateComApp(cid interface{}) error {
+ instca.cid = cid
+ instca.chans = []chan bool{}
+ instca.mutex = sync.Mutex{}
+ err := updateAppContextFlag(cid, true)
+ if err != nil {
+ logutils.Error("Encountered error updating AppContext flag", logutils.Fields{"error": err})
+ return err
+ }
+ go applyFnComApp(instca, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Terminating},
+ terminateResource, deleteStatusTracker, false)
+ return nil
+}
+
+func (instca *CompositeAppContext) ReadComApp(cid interface{}) error {
+ instca.cid = cid
+ instca.chans = []chan bool{}
+ instca.mutex = sync.Mutex{}
+ err := updateAppContextFlag(cid, false)
+ if err != nil {
+ logutils.Error("Encountered error updating AppContext flag", logutils.Fields{"error": err})
+ return err
+ }
+ go applyFnComApp(instca, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiating},
+ readResource, addStatusTracker, true)
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type clientDbInfo struct {\r
- storeName string // name of the mongodb collection to use for client documents\r
- tagNamespace string // attribute key name for the namespace section of a CloudConfig\r
- tagConfig string // attribute key name for the kubeconfig section of a CloudConfig\r
-}\r
-\r
-// ClusterKey is the key structure that is used in the database\r
-type CloudConfigKey struct {\r
- Provider string `json:"provider"`\r
- Cluster string `json:"cluster"`\r
- Level string `json:"level"`\r
- Namespace string `json:"namespace"`\r
-}\r
-\r
-// CloudConfig contains the parameters that specify access to a cloud at any level\r
-type CloudConfig struct {\r
- Provider string `json:"provider"`\r
- Cluster string `json:"cluster"`\r
- Level string `json:"level"`\r
- Namespace string `json:"namespace"`\r
- Config string `json:"config"`\r
-}\r
-\r
-type KubeConfig struct {\r
- Config string `json:"config"`\r
-}\r
-\r
-// CloudConfigManager is an interface that exposes the Cloud Config functionality\r
-type CloudConfigManager interface {\r
- GetCloudConfig(provider string, cluster string, level string, namespace string) (CloudConfig, error)\r
- CreateCloudConfig(provider string, cluster string, level string, namespace string, config string) (CloudConfig, error)\r
- GetNamespace(provider string, cluster string) (CloudConfig, error) // level-0 only\r
- SetNamespace(provider string, cluster string, namespace string) (CloudConfig, error) // level-0 only\r
- DeleteCloudConfig(provider string, cluster string, level string, namespace string) error\r
-}\r
-\r
-// CloudConfigClient implements CloudConfigManager\r
-// It will also be used to maintain some localized state\r
-type CloudConfigClient struct {\r
- db clientDbInfo\r
-}\r
-\r
-// NewCloudConfigClient returns an instance of the CloudConfigClient\r
-// which implements CloudConfigManager\r
-func NewCloudConfigClient() *CloudConfigClient {\r
- return &CloudConfigClient{\r
- db: clientDbInfo{\r
- storeName: "cloudconfig",\r
- tagNamespace: "namespace",\r
- tagConfig: "config",\r
- },\r
- }\r
-}\r
-\r
-func unmarshal(values [][]byte) (KubeConfig, error) {\r
- if values != nil {\r
- kc := KubeConfig{}\r
- err := db.DBconn.Unmarshal(values[0], &kc)\r
- if err != nil {\r
- log.Error("Failed unmarshaling Value", log.Fields{})\r
- return KubeConfig{}, pkgerrors.Wrap(err, "Failed unmarshaling Value")\r
- }\r
- return kc, nil\r
- }\r
- log.Info("DB values is nil", log.Fields{})\r
- return KubeConfig{}, pkgerrors.New("DB values is nil")\r
-}\r
-\r
-// GetCloudConfig allows to get an existing cloud config entry\r
-func (c *CloudConfigClient) GetCloudConfig(provider string, cluster string, level string, namespace string) (CloudConfig, error) {\r
-\r
- key := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: level,\r
- Namespace: namespace,\r
- }\r
-\r
- values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagConfig)\r
- if err != nil {\r
- log.Error("Finding CloudConfig failed", log.Fields{})\r
- return CloudConfig{}, pkgerrors.Wrap(err, "Finding CloudConfig failed")\r
- }\r
-\r
- kc, err := unmarshal(values)\r
- if err != nil {\r
- return CloudConfig{}, err\r
- }\r
-\r
- cc := CloudConfig{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: level,\r
- Namespace: namespace,\r
- Config: kc.Config,\r
- }\r
-\r
- return cc, nil\r
-}\r
-\r
-// CreateCloudConfig allows to create a new cloud config entry to hold a kubeconfig for access\r
-func (c *CloudConfigClient) CreateCloudConfig(provider string, cluster string, level string, namespace string, config string) (CloudConfig, error) {\r
-\r
- key := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: level,\r
- Namespace: namespace,\r
- }\r
-\r
- kc := KubeConfig{\r
- Config: config,\r
- }\r
-\r
- // check if it already exists\r
- _, err := c.GetCloudConfig(provider, cluster, level, namespace)\r
- if err == nil {\r
- log.Error("CloudConfig already exists", log.Fields{})\r
- return CloudConfig{}, pkgerrors.New("CloudConfig already exists")\r
- }\r
-\r
- err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagConfig, kc)\r
- if err != nil {\r
- log.Error("Failure inserting CloudConfig", log.Fields{})\r
- return CloudConfig{}, pkgerrors.Wrap(err, "Failure inserting CloudConfig")\r
- }\r
-\r
- cc := CloudConfig{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: level,\r
- Namespace: namespace,\r
- Config: config,\r
- }\r
-\r
- return cc, nil\r
-}\r
-\r
-// SetNamespace is only for L0 cloud configs and allows to set/reset current namespace name\r
-func (c *CloudConfigClient) SetNamespace(provider string, cluster string, namespace string) error {\r
- key := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: "0", // always going to be level 0 if we're (un)setting a namespace name\r
- Namespace: "", // we don't care about the current name for now\r
- }\r
-\r
- // check if CloudConfig exists and also get the current namespace name\r
- values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagNamespace)\r
- if err != nil {\r
- log.Error("Could not fetch the CloudConfig so not updating", log.Fields{})\r
- return pkgerrors.Wrap(err, "Could not fetch the CloudConfig so not updating")\r
- }\r
-\r
- newkey := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: "0", // always going to be level 0 if we're (un)setting a namespace name\r
- Namespace: string(values[0]), // use current namespace name as the final key to update the namespace\r
- }\r
- err = db.DBconn.Insert(c.db.storeName, newkey, nil, c.db.tagNamespace, namespace)\r
- if err != nil {\r
- log.Error("Could not update the namespace of the CloudConfig", log.Fields{})\r
- return pkgerrors.Wrap(err, "Could not update the namespace of the CloudConfig")\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// GetNamespace is only for L0 cloud configs and allows fetching the current namespace name\r
-func (c *CloudConfigClient) GetNamespace(provider string, cluster string) (string, error) {\r
- key := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: "0", // always going to be level 0 if getting a namespace name without ambiguity\r
- Namespace: "", // we don't care about the current name\r
- }\r
-\r
- // check if CloudConfig exists and also get the current namespace name\r
- values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagNamespace)\r
- if err != nil {\r
- log.Error("Could not fetch the CloudConfig so can't return namespace", log.Fields{})\r
- return "", pkgerrors.Wrap(err, "Could not fetch the CloudConfig so can't return namespace")\r
- }\r
- if len(values) > 1 {\r
- log.Error("Multiple CloudConfigs were returned, which was unexpected", log.Fields{})\r
- return "", pkgerrors.New("Multiple CloudConfigs were returned, which was unexpected")\r
- }\r
- if len(values) == 0 {\r
- log.Error("No CloudConfig was returned", log.Fields{})\r
- return "", pkgerrors.New("No CloudConfig was returned") // error message is evaluated at calling function, don't change\r
- }\r
-\r
- return string(values[0]), nil\r
-}\r
-\r
-// DeleteCloudConfig deletes a cloud config entry\r
-func (c *CloudConfigClient) DeleteCloudConfig(provider string, cluster string, level string, namespace string) error {\r
- key := CloudConfigKey{\r
- Provider: provider,\r
- Cluster: cluster,\r
- Level: level,\r
- Namespace: namespace,\r
- }\r
-\r
- // check if it doesn't exist\r
- _, err := c.GetCloudConfig(provider, cluster, level, namespace)\r
- if err != nil {\r
- log.Error("Could not fetch the CloudConfig so not deleting", log.Fields{})\r
- return pkgerrors.New("Could not fetch the CloudConfig so not deleting")\r
- }\r
-\r
- err = db.DBconn.Remove(c.db.storeName, key)\r
- if err != nil {\r
- log.Error("Could not delete the CloudConfig", log.Fields{})\r
- return pkgerrors.Wrap(err, "Could not delete the CloudConfig")\r
- }\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+type clientDbInfo struct {
+ storeName string // name of the mongodb collection to use for client documents
+ tagNamespace string // attribute key name for the namespace section of a CloudConfig
+ tagConfig string // attribute key name for the kubeconfig section of a CloudConfig
+}
+
+// ClusterKey is the key structure that is used in the database
+type CloudConfigKey struct {
+ Provider string `json:"provider"`
+ Cluster string `json:"cluster"`
+ Level string `json:"level"`
+ Namespace string `json:"namespace"`
+}
+
+// CloudConfig contains the parameters that specify access to a cloud at any level
+type CloudConfig struct {
+ Provider string `json:"provider"`
+ Cluster string `json:"cluster"`
+ Level string `json:"level"`
+ Namespace string `json:"namespace"`
+ Config string `json:"config"`
+}
+
+type KubeConfig struct {
+ Config string `json:"config"`
+}
+
+// CloudConfigManager is an interface that exposes the Cloud Config functionality
+type CloudConfigManager interface {
+ GetCloudConfig(provider string, cluster string, level string, namespace string) (CloudConfig, error)
+ CreateCloudConfig(provider string, cluster string, level string, namespace string, config string) (CloudConfig, error)
+ GetNamespace(provider string, cluster string) (CloudConfig, error) // level-0 only
+ SetNamespace(provider string, cluster string, namespace string) (CloudConfig, error) // level-0 only
+ DeleteCloudConfig(provider string, cluster string, level string, namespace string) error
+}
+
+// CloudConfigClient implements CloudConfigManager
+// It will also be used to maintain some localized state
+type CloudConfigClient struct {
+ db clientDbInfo
+}
+
+// NewCloudConfigClient returns an instance of the CloudConfigClient
+// which implements CloudConfigManager
+func NewCloudConfigClient() *CloudConfigClient {
+ return &CloudConfigClient{
+ db: clientDbInfo{
+ storeName: "cloudconfig",
+ tagNamespace: "namespace",
+ tagConfig: "config",
+ },
+ }
+}
+
+func unmarshal(values [][]byte) (KubeConfig, error) {
+ if values != nil {
+ kc := KubeConfig{}
+ err := db.DBconn.Unmarshal(values[0], &kc)
+ if err != nil {
+ log.Error("Failed unmarshaling Value", log.Fields{})
+ return KubeConfig{}, pkgerrors.Wrap(err, "Failed unmarshaling Value")
+ }
+ return kc, nil
+ }
+ log.Info("DB values is nil", log.Fields{})
+ return KubeConfig{}, pkgerrors.New("DB values is nil")
+}
+
+// GetCloudConfig allows to get an existing cloud config entry
+func (c *CloudConfigClient) GetCloudConfig(provider string, cluster string, level string, namespace string) (CloudConfig, error) {
+
+ key := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: level,
+ Namespace: namespace,
+ }
+
+ values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagConfig)
+ if err != nil {
+ log.Error("Finding CloudConfig failed", log.Fields{})
+ return CloudConfig{}, pkgerrors.Wrap(err, "Finding CloudConfig failed")
+ }
+
+ kc, err := unmarshal(values)
+ if err != nil {
+ return CloudConfig{}, err
+ }
+
+ cc := CloudConfig{
+ Provider: provider,
+ Cluster: cluster,
+ Level: level,
+ Namespace: namespace,
+ Config: kc.Config,
+ }
+
+ return cc, nil
+}
+
+// CreateCloudConfig allows to create a new cloud config entry to hold a kubeconfig for access
+func (c *CloudConfigClient) CreateCloudConfig(provider string, cluster string, level string, namespace string, config string) (CloudConfig, error) {
+
+ key := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: level,
+ Namespace: namespace,
+ }
+
+ kc := KubeConfig{
+ Config: config,
+ }
+
+ // check if it already exists
+ _, err := c.GetCloudConfig(provider, cluster, level, namespace)
+ if err == nil {
+ log.Error("CloudConfig already exists", log.Fields{})
+ return CloudConfig{}, pkgerrors.New("CloudConfig already exists")
+ }
+
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagConfig, kc)
+ if err != nil {
+ log.Error("Failure inserting CloudConfig", log.Fields{})
+ return CloudConfig{}, pkgerrors.Wrap(err, "Failure inserting CloudConfig")
+ }
+
+ cc := CloudConfig{
+ Provider: provider,
+ Cluster: cluster,
+ Level: level,
+ Namespace: namespace,
+ Config: config,
+ }
+
+ return cc, nil
+}
+
+// SetNamespace is only for L0 cloud configs and allows to set/reset current namespace name
+func (c *CloudConfigClient) SetNamespace(provider string, cluster string, namespace string) error {
+ key := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: "0", // always going to be level 0 if we're (un)setting a namespace name
+ Namespace: "", // we don't care about the current name for now
+ }
+
+ // check if CloudConfig exists and also get the current namespace name
+ values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagNamespace)
+ if err != nil {
+ log.Error("Could not fetch the CloudConfig so not updating", log.Fields{})
+ return pkgerrors.Wrap(err, "Could not fetch the CloudConfig so not updating")
+ }
+
+ newkey := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: "0", // always going to be level 0 if we're (un)setting a namespace name
+ Namespace: string(values[0]), // use current namespace name as the final key to update the namespace
+ }
+ err = db.DBconn.Insert(c.db.storeName, newkey, nil, c.db.tagNamespace, namespace)
+ if err != nil {
+ log.Error("Could not update the namespace of the CloudConfig", log.Fields{})
+ return pkgerrors.Wrap(err, "Could not update the namespace of the CloudConfig")
+ }
+
+ return nil
+}
+
+// GetNamespace is only for L0 cloud configs and allows fetching the current namespace name
+func (c *CloudConfigClient) GetNamespace(provider string, cluster string) (string, error) {
+ key := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: "0", // always going to be level 0 if getting a namespace name without ambiguity
+ Namespace: "", // we don't care about the current name
+ }
+
+ // check if CloudConfig exists and also get the current namespace name
+ values, err := db.DBconn.Find(c.db.storeName, key, c.db.tagNamespace)
+ if err != nil {
+ log.Error("Could not fetch the CloudConfig so can't return namespace", log.Fields{})
+ return "", pkgerrors.Wrap(err, "Could not fetch the CloudConfig so can't return namespace")
+ }
+ if len(values) > 1 {
+ log.Error("Multiple CloudConfigs were returned, which was unexpected", log.Fields{})
+ return "", pkgerrors.New("Multiple CloudConfigs were returned, which was unexpected")
+ }
+ if len(values) == 0 {
+ log.Error("No CloudConfig was returned", log.Fields{})
+ return "", pkgerrors.New("No CloudConfig was returned") // error message is evaluated at calling function, don't change
+ }
+
+ return string(values[0]), nil
+}
+
+// DeleteCloudConfig deletes a cloud config entry
+func (c *CloudConfigClient) DeleteCloudConfig(provider string, cluster string, level string, namespace string) error {
+ key := CloudConfigKey{
+ Provider: provider,
+ Cluster: cluster,
+ Level: level,
+ Namespace: namespace,
+ }
+
+ // check if it doesn't exist
+ _, err := c.GetCloudConfig(provider, cluster, level, namespace)
+ if err != nil {
+ log.Error("Could not fetch the CloudConfig so not deleting", log.Fields{})
+ return pkgerrors.New("Could not fetch the CloudConfig so not deleting")
+ }
+
+ err = db.DBconn.Remove(c.db.storeName, key)
+ if err != nil {
+ log.Error("Could not delete the CloudConfig", log.Fields{})
+ return pkgerrors.Wrap(err, "Could not delete the CloudConfig")
+ }
+
+ return nil
+}
-// Code generated by protoc-gen-go. DO NOT EDIT.\r
-// source: installapp.proto\r
-\r
-package installapp\r
-\r
-import (\r
- context "context"\r
- fmt "fmt"\r
- proto "github.com/golang/protobuf/proto"\r
- grpc "google.golang.org/grpc"\r
- codes "google.golang.org/grpc/codes"\r
- status "google.golang.org/grpc/status"\r
- math "math"\r
-)\r
-\r
-// Reference imports to suppress errors if they are not otherwise used.\r
-var _ = proto.Marshal\r
-var _ = fmt.Errorf\r
-var _ = math.Inf\r
-\r
-// This is a compile-time assertion to ensure that this generated file\r
-// is compatible with the proto package it is being compiled against.\r
-// A compilation error at this line likely means your copy of the\r
-// proto package needs to be updated.\r
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package\r
-\r
-type InstallAppRequest struct {\r
- AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`\r
- XXX_NoUnkeyedLiteral struct{} `json:"-"`\r
- XXX_unrecognized []byte `json:"-"`\r
- XXX_sizecache int32 `json:"-"`\r
-}\r
-\r
-func (m *InstallAppRequest) Reset() { *m = InstallAppRequest{} }\r
-func (m *InstallAppRequest) String() string { return proto.CompactTextString(m) }\r
-func (*InstallAppRequest) ProtoMessage() {}\r
-func (*InstallAppRequest) Descriptor() ([]byte, []int) {\r
- return fileDescriptor_e16b1077a28418a8, []int{0}\r
-}\r
-\r
-func (m *InstallAppRequest) XXX_Unmarshal(b []byte) error {\r
- return xxx_messageInfo_InstallAppRequest.Unmarshal(m, b)\r
-}\r
-func (m *InstallAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\r
- return xxx_messageInfo_InstallAppRequest.Marshal(b, m, deterministic)\r
-}\r
-func (m *InstallAppRequest) XXX_Merge(src proto.Message) {\r
- xxx_messageInfo_InstallAppRequest.Merge(m, src)\r
-}\r
-func (m *InstallAppRequest) XXX_Size() int {\r
- return xxx_messageInfo_InstallAppRequest.Size(m)\r
-}\r
-func (m *InstallAppRequest) XXX_DiscardUnknown() {\r
- xxx_messageInfo_InstallAppRequest.DiscardUnknown(m)\r
-}\r
-\r
-var xxx_messageInfo_InstallAppRequest proto.InternalMessageInfo\r
-\r
-func (m *InstallAppRequest) GetAppContext() string {\r
- if m != nil {\r
- return m.AppContext\r
- }\r
- return ""\r
-}\r
-\r
-type InstallAppResponse struct {\r
- AppContextInstalled bool `protobuf:"varint,1,opt,name=app_context_installed,json=appContextInstalled,proto3" json:"app_context_installed,omitempty"`\r
- AppContextInstallMessage string `protobuf:"bytes,2,opt,name=app_context_install_message,json=appContextInstallMessage,proto3" json:"app_context_install_message,omitempty"`\r
- XXX_NoUnkeyedLiteral struct{} `json:"-"`\r
- XXX_unrecognized []byte `json:"-"`\r
- XXX_sizecache int32 `json:"-"`\r
-}\r
-\r
-func (m *InstallAppResponse) Reset() { *m = InstallAppResponse{} }\r
-func (m *InstallAppResponse) String() string { return proto.CompactTextString(m) }\r
-func (*InstallAppResponse) ProtoMessage() {}\r
-func (*InstallAppResponse) Descriptor() ([]byte, []int) {\r
- return fileDescriptor_e16b1077a28418a8, []int{1}\r
-}\r
-\r
-func (m *InstallAppResponse) XXX_Unmarshal(b []byte) error {\r
- return xxx_messageInfo_InstallAppResponse.Unmarshal(m, b)\r
-}\r
-func (m *InstallAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\r
- return xxx_messageInfo_InstallAppResponse.Marshal(b, m, deterministic)\r
-}\r
-func (m *InstallAppResponse) XXX_Merge(src proto.Message) {\r
- xxx_messageInfo_InstallAppResponse.Merge(m, src)\r
-}\r
-func (m *InstallAppResponse) XXX_Size() int {\r
- return xxx_messageInfo_InstallAppResponse.Size(m)\r
-}\r
-func (m *InstallAppResponse) XXX_DiscardUnknown() {\r
- xxx_messageInfo_InstallAppResponse.DiscardUnknown(m)\r
-}\r
-\r
-var xxx_messageInfo_InstallAppResponse proto.InternalMessageInfo\r
-\r
-func (m *InstallAppResponse) GetAppContextInstalled() bool {\r
- if m != nil {\r
- return m.AppContextInstalled\r
- }\r
- return false\r
-}\r
-\r
-func (m *InstallAppResponse) GetAppContextInstallMessage() string {\r
- if m != nil {\r
- return m.AppContextInstallMessage\r
- }\r
- return ""\r
-}\r
-\r
-type UninstallAppRequest struct {\r
- AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`\r
- XXX_NoUnkeyedLiteral struct{} `json:"-"`\r
- XXX_unrecognized []byte `json:"-"`\r
- XXX_sizecache int32 `json:"-"`\r
-}\r
-\r
-func (m *UninstallAppRequest) Reset() { *m = UninstallAppRequest{} }\r
-func (m *UninstallAppRequest) String() string { return proto.CompactTextString(m) }\r
-func (*UninstallAppRequest) ProtoMessage() {}\r
-func (*UninstallAppRequest) Descriptor() ([]byte, []int) {\r
- return fileDescriptor_e16b1077a28418a8, []int{2}\r
-}\r
-\r
-func (m *UninstallAppRequest) XXX_Unmarshal(b []byte) error {\r
- return xxx_messageInfo_UninstallAppRequest.Unmarshal(m, b)\r
-}\r
-func (m *UninstallAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\r
- return xxx_messageInfo_UninstallAppRequest.Marshal(b, m, deterministic)\r
-}\r
-func (m *UninstallAppRequest) XXX_Merge(src proto.Message) {\r
- xxx_messageInfo_UninstallAppRequest.Merge(m, src)\r
-}\r
-func (m *UninstallAppRequest) XXX_Size() int {\r
- return xxx_messageInfo_UninstallAppRequest.Size(m)\r
-}\r
-func (m *UninstallAppRequest) XXX_DiscardUnknown() {\r
- xxx_messageInfo_UninstallAppRequest.DiscardUnknown(m)\r
-}\r
-\r
-var xxx_messageInfo_UninstallAppRequest proto.InternalMessageInfo\r
-\r
-func (m *UninstallAppRequest) GetAppContext() string {\r
- if m != nil {\r
- return m.AppContext\r
- }\r
- return ""\r
-}\r
-\r
-type UninstallAppResponse struct {\r
- AppContextUninstalled bool `protobuf:"varint,1,opt,name=app_context_uninstalled,json=appContextUninstalled,proto3" json:"app_context_uninstalled,omitempty"`\r
- AppContextUninstallMessage string `protobuf:"bytes,2,opt,name=app_context_uninstall_message,json=appContextUninstallMessage,proto3" json:"app_context_uninstall_message,omitempty"`\r
- XXX_NoUnkeyedLiteral struct{} `json:"-"`\r
- XXX_unrecognized []byte `json:"-"`\r
- XXX_sizecache int32 `json:"-"`\r
-}\r
-\r
-func (m *UninstallAppResponse) Reset() { *m = UninstallAppResponse{} }\r
-func (m *UninstallAppResponse) String() string { return proto.CompactTextString(m) }\r
-func (*UninstallAppResponse) ProtoMessage() {}\r
-func (*UninstallAppResponse) Descriptor() ([]byte, []int) {\r
- return fileDescriptor_e16b1077a28418a8, []int{3}\r
-}\r
-\r
-func (m *UninstallAppResponse) XXX_Unmarshal(b []byte) error {\r
- return xxx_messageInfo_UninstallAppResponse.Unmarshal(m, b)\r
-}\r
-func (m *UninstallAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\r
- return xxx_messageInfo_UninstallAppResponse.Marshal(b, m, deterministic)\r
-}\r
-func (m *UninstallAppResponse) XXX_Merge(src proto.Message) {\r
- xxx_messageInfo_UninstallAppResponse.Merge(m, src)\r
-}\r
-func (m *UninstallAppResponse) XXX_Size() int {\r
- return xxx_messageInfo_UninstallAppResponse.Size(m)\r
-}\r
-func (m *UninstallAppResponse) XXX_DiscardUnknown() {\r
- xxx_messageInfo_UninstallAppResponse.DiscardUnknown(m)\r
-}\r
-\r
-var xxx_messageInfo_UninstallAppResponse proto.InternalMessageInfo\r
-\r
-func (m *UninstallAppResponse) GetAppContextUninstalled() bool {\r
- if m != nil {\r
- return m.AppContextUninstalled\r
- }\r
- return false\r
-}\r
-\r
-func (m *UninstallAppResponse) GetAppContextUninstallMessage() string {\r
- if m != nil {\r
- return m.AppContextUninstallMessage\r
- }\r
- return ""\r
-}\r
-\r
-func init() {\r
- proto.RegisterType((*InstallAppRequest)(nil), "InstallAppRequest")\r
- proto.RegisterType((*InstallAppResponse)(nil), "InstallAppResponse")\r
- proto.RegisterType((*UninstallAppRequest)(nil), "UninstallAppRequest")\r
- proto.RegisterType((*UninstallAppResponse)(nil), "UninstallAppResponse")\r
-}\r
-\r
-func init() {\r
- proto.RegisterFile("installapp.proto", fileDescriptor_e16b1077a28418a8)\r
-}\r
-\r
-var fileDescriptor_e16b1077a28418a8 = []byte{\r
- // 246 bytes of a gzipped FileDescriptorProto\r
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0xcc, 0x2b, 0x2e,\r
- 0x49, 0xcc, 0xc9, 0x49, 0x2c, 0x28, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x32, 0xe1, 0x12,\r
- 0xf4, 0x84, 0x88, 0x39, 0x16, 0x14, 0x04, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0xc9, 0x73,\r
- 0x71, 0x27, 0x16, 0x14, 0xc4, 0x27, 0xe7, 0xe7, 0x95, 0xa4, 0x56, 0x94, 0x48, 0x30, 0x2a, 0x30,\r
- 0x6a, 0x70, 0x06, 0x71, 0x25, 0x16, 0x14, 0x38, 0x43, 0x44, 0x94, 0xda, 0x19, 0xb9, 0x84, 0x90,\r
- 0xb5, 0x15, 0x17, 0xe4, 0xe7, 0x15, 0xa7, 0x0a, 0x19, 0x71, 0x89, 0x22, 0xe9, 0x8b, 0x87, 0x5a,\r
- 0x96, 0x9a, 0x02, 0x36, 0x81, 0x23, 0x48, 0x18, 0x61, 0x82, 0x27, 0x4c, 0x4a, 0xc8, 0x96, 0x4b,\r
- 0x1a, 0x8b, 0x9e, 0xf8, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, 0x09, 0x26, 0xb0, 0xdd, 0x12,\r
- 0x18, 0x3a, 0x7d, 0x21, 0xf2, 0x4a, 0x66, 0x5c, 0xc2, 0xa1, 0x79, 0x99, 0xa4, 0xfb, 0x60, 0x22,\r
- 0x23, 0x97, 0x08, 0xaa, 0x46, 0xa8, 0x1f, 0xcc, 0xb8, 0xc4, 0x91, 0xdd, 0x53, 0x9a, 0x87, 0xee,\r
- 0x0b, 0x51, 0x84, 0x29, 0xa1, 0x08, 0x49, 0x21, 0x47, 0x2e, 0x59, 0xac, 0xfa, 0xd0, 0x7c, 0x22,\r
- 0x85, 0x45, 0x37, 0xd4, 0x2f, 0x46, 0x2d, 0x8c, 0x5c, 0x5c, 0x88, 0x08, 0x12, 0x32, 0xe7, 0xe2,\r
- 0x42, 0x84, 0xb1, 0x90, 0x90, 0x1e, 0x46, 0x3c, 0x49, 0x09, 0xeb, 0x61, 0x46, 0x82, 0x12, 0x83,\r
- 0x90, 0x2d, 0x17, 0x0f, 0xb2, 0xd7, 0x84, 0x44, 0xf4, 0xb0, 0x04, 0x91, 0x94, 0xa8, 0x1e, 0x36,\r
- 0xff, 0x2b, 0x31, 0x24, 0xb1, 0x81, 0x53, 0x86, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x14,\r
- 0x31, 0x29, 0x2d, 0x02, 0x00, 0x00,\r
-}\r
-\r
-// Reference imports to suppress errors if they are not otherwise used.\r
-var _ context.Context\r
-var _ grpc.ClientConnInterface\r
-\r
-// This is a compile-time assertion to ensure that this generated file\r
-// is compatible with the grpc package it is being compiled against.\r
-const _ = grpc.SupportPackageIsVersion6\r
-\r
-// InstallappClient is the client API for Installapp service.\r
-//\r
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\r
-type InstallappClient interface {\r
- // Sync\r
- InstallApp(ctx context.Context, in *InstallAppRequest, opts ...grpc.CallOption) (*InstallAppResponse, error)\r
- UninstallApp(ctx context.Context, in *UninstallAppRequest, opts ...grpc.CallOption) (*UninstallAppResponse, error)\r
-}\r
-\r
-type installappClient struct {\r
- cc grpc.ClientConnInterface\r
-}\r
-\r
-func NewInstallappClient(cc grpc.ClientConnInterface) InstallappClient {\r
- return &installappClient{cc}\r
-}\r
-\r
-func (c *installappClient) InstallApp(ctx context.Context, in *InstallAppRequest, opts ...grpc.CallOption) (*InstallAppResponse, error) {\r
- out := new(InstallAppResponse)\r
- err := c.cc.Invoke(ctx, "/installapp/InstallApp", in, out, opts...)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return out, nil\r
-}\r
-\r
-func (c *installappClient) UninstallApp(ctx context.Context, in *UninstallAppRequest, opts ...grpc.CallOption) (*UninstallAppResponse, error) {\r
- out := new(UninstallAppResponse)\r
- err := c.cc.Invoke(ctx, "/installapp/UninstallApp", in, out, opts...)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return out, nil\r
-}\r
-\r
-// InstallappServer is the server API for Installapp service.\r
-type InstallappServer interface {\r
- // Sync\r
- InstallApp(context.Context, *InstallAppRequest) (*InstallAppResponse, error)\r
- UninstallApp(context.Context, *UninstallAppRequest) (*UninstallAppResponse, error)\r
-}\r
-\r
-// UnimplementedInstallappServer can be embedded to have forward compatible implementations.\r
-type UnimplementedInstallappServer struct {\r
-}\r
-\r
-func (*UnimplementedInstallappServer) InstallApp(ctx context.Context, req *InstallAppRequest) (*InstallAppResponse, error) {\r
- return nil, status.Errorf(codes.Unimplemented, "method InstallApp not implemented")\r
-}\r
-func (*UnimplementedInstallappServer) UninstallApp(ctx context.Context, req *UninstallAppRequest) (*UninstallAppResponse, error) {\r
- return nil, status.Errorf(codes.Unimplemented, "method UninstallApp not implemented")\r
-}\r
-\r
-func RegisterInstallappServer(s *grpc.Server, srv InstallappServer) {\r
- s.RegisterService(&_Installapp_serviceDesc, srv)\r
-}\r
-\r
-func _Installapp_InstallApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\r
- in := new(InstallAppRequest)\r
- if err := dec(in); err != nil {\r
- return nil, err\r
- }\r
- if interceptor == nil {\r
- return srv.(InstallappServer).InstallApp(ctx, in)\r
- }\r
- info := &grpc.UnaryServerInfo{\r
- Server: srv,\r
- FullMethod: "/installapp/InstallApp",\r
- }\r
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {\r
- return srv.(InstallappServer).InstallApp(ctx, req.(*InstallAppRequest))\r
- }\r
- return interceptor(ctx, in, info, handler)\r
-}\r
-\r
-func _Installapp_UninstallApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\r
- in := new(UninstallAppRequest)\r
- if err := dec(in); err != nil {\r
- return nil, err\r
- }\r
- if interceptor == nil {\r
- return srv.(InstallappServer).UninstallApp(ctx, in)\r
- }\r
- info := &grpc.UnaryServerInfo{\r
- Server: srv,\r
- FullMethod: "/installapp/UninstallApp",\r
- }\r
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {\r
- return srv.(InstallappServer).UninstallApp(ctx, req.(*UninstallAppRequest))\r
- }\r
- return interceptor(ctx, in, info, handler)\r
-}\r
-\r
-var _Installapp_serviceDesc = grpc.ServiceDesc{\r
- ServiceName: "installapp",\r
- HandlerType: (*InstallappServer)(nil),\r
- Methods: []grpc.MethodDesc{\r
- {\r
- MethodName: "InstallApp",\r
- Handler: _Installapp_InstallApp_Handler,\r
- },\r
- {\r
- MethodName: "UninstallApp",\r
- Handler: _Installapp_UninstallApp_Handler,\r
- },\r
- },\r
- Streams: []grpc.StreamDesc{},\r
- Metadata: "installapp.proto",\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.24.0
+// protoc v3.12.4
+// source: installapp.proto
+
+package installapp
+
+import (
+ context "context"
+ proto "github.com/golang/protobuf/proto"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type InstallAppRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`
+}
+
+func (x *InstallAppRequest) Reset() {
+ *x = InstallAppRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *InstallAppRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InstallAppRequest) ProtoMessage() {}
+
+func (x *InstallAppRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use InstallAppRequest.ProtoReflect.Descriptor instead.
+func (*InstallAppRequest) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *InstallAppRequest) GetAppContext() string {
+ if x != nil {
+ return x.AppContext
+ }
+ return ""
+}
+
+type InstallAppResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContextInstalled bool `protobuf:"varint,1,opt,name=app_context_installed,json=appContextInstalled,proto3" json:"app_context_installed,omitempty"`
+ AppContextInstallMessage string `protobuf:"bytes,2,opt,name=app_context_install_message,json=appContextInstallMessage,proto3" json:"app_context_install_message,omitempty"`
+}
+
+func (x *InstallAppResponse) Reset() {
+ *x = InstallAppResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *InstallAppResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InstallAppResponse) ProtoMessage() {}
+
+func (x *InstallAppResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use InstallAppResponse.ProtoReflect.Descriptor instead.
+func (*InstallAppResponse) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *InstallAppResponse) GetAppContextInstalled() bool {
+ if x != nil {
+ return x.AppContextInstalled
+ }
+ return false
+}
+
+func (x *InstallAppResponse) GetAppContextInstallMessage() string {
+ if x != nil {
+ return x.AppContextInstallMessage
+ }
+ return ""
+}
+
+type UninstallAppRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`
+}
+
+func (x *UninstallAppRequest) Reset() {
+ *x = UninstallAppRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UninstallAppRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UninstallAppRequest) ProtoMessage() {}
+
+func (x *UninstallAppRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UninstallAppRequest.ProtoReflect.Descriptor instead.
+func (*UninstallAppRequest) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *UninstallAppRequest) GetAppContext() string {
+ if x != nil {
+ return x.AppContext
+ }
+ return ""
+}
+
+type UninstallAppResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContextUninstalled bool `protobuf:"varint,1,opt,name=app_context_uninstalled,json=appContextUninstalled,proto3" json:"app_context_uninstalled,omitempty"`
+ AppContextUninstallMessage string `protobuf:"bytes,2,opt,name=app_context_uninstall_message,json=appContextUninstallMessage,proto3" json:"app_context_uninstall_message,omitempty"`
+}
+
+func (x *UninstallAppResponse) Reset() {
+ *x = UninstallAppResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UninstallAppResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UninstallAppResponse) ProtoMessage() {}
+
+func (x *UninstallAppResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UninstallAppResponse.ProtoReflect.Descriptor instead.
+func (*UninstallAppResponse) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *UninstallAppResponse) GetAppContextUninstalled() bool {
+ if x != nil {
+ return x.AppContextUninstalled
+ }
+ return false
+}
+
+func (x *UninstallAppResponse) GetAppContextUninstallMessage() string {
+ if x != nil {
+ return x.AppContextUninstallMessage
+ }
+ return ""
+}
+
+type ReadAppContextRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`
+}
+
+func (x *ReadAppContextRequest) Reset() {
+ *x = ReadAppContextRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReadAppContextRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReadAppContextRequest) ProtoMessage() {}
+
+func (x *ReadAppContextRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReadAppContextRequest.ProtoReflect.Descriptor instead.
+func (*ReadAppContextRequest) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ReadAppContextRequest) GetAppContext() string {
+ if x != nil {
+ return x.AppContext
+ }
+ return ""
+}
+
+type ReadAppContextResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContextReadSuccessful bool `protobuf:"varint,1,opt,name=app_context_read_successful,json=appContextReadSuccessful,proto3" json:"app_context_read_successful,omitempty"`
+ AppContextReadMessage string `protobuf:"bytes,2,opt,name=app_context_read_message,json=appContextReadMessage,proto3" json:"app_context_read_message,omitempty"`
+}
+
+func (x *ReadAppContextResponse) Reset() {
+ *x = ReadAppContextResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_installapp_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReadAppContextResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReadAppContextResponse) ProtoMessage() {}
+
+func (x *ReadAppContextResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_installapp_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReadAppContextResponse.ProtoReflect.Descriptor instead.
+func (*ReadAppContextResponse) Descriptor() ([]byte, []int) {
+ return file_installapp_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ReadAppContextResponse) GetAppContextReadSuccessful() bool {
+ if x != nil {
+ return x.AppContextReadSuccessful
+ }
+ return false
+}
+
+func (x *ReadAppContextResponse) GetAppContextReadMessage() string {
+ if x != nil {
+ return x.AppContextReadMessage
+ }
+ return ""
+}
+
+var File_installapp_proto protoreflect.FileDescriptor
+
+var file_installapp_proto_rawDesc = []byte{
+ 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x11, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70,
+ 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x73,
+ 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+ 0x32, 0x0a, 0x15, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69,
+ 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13,
+ 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c,
+ 0x6c, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x1b, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41,
+ 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
+ 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x14, 0x55,
+ 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+ 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x61,
+ 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x6e, 0x73,
+ 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x1a, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x6e,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x38,
+ 0x0a, 0x15, 0x52, 0x65, 0x61, 0x64, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70,
+ 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x61,
+ 0x64, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x1b, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66,
+ 0x75, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x61, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66,
+ 0x75, 0x6c, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+ 0x74, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+ 0x52, 0x65, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xc9, 0x01, 0x0a, 0x0a,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 0x12, 0x37, 0x0a, 0x0a, 0x49, 0x6e,
+ 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x12, 0x12, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
+ 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x49,
+ 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0c, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
+ 0x41, 0x70, 0x70, 0x12, 0x14, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41,
+ 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x55, 0x6e, 0x69, 0x6e,
+ 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x12, 0x16, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x70, 0x70, 0x43, 0x6f,
+ 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x52,
+ 0x65, 0x61, 0x64, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_installapp_proto_rawDescOnce sync.Once
+ file_installapp_proto_rawDescData = file_installapp_proto_rawDesc
+)
+
+func file_installapp_proto_rawDescGZIP() []byte {
+ file_installapp_proto_rawDescOnce.Do(func() {
+ file_installapp_proto_rawDescData = protoimpl.X.CompressGZIP(file_installapp_proto_rawDescData)
+ })
+ return file_installapp_proto_rawDescData
+}
+
+var file_installapp_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_installapp_proto_goTypes = []interface{}{
+ (*InstallAppRequest)(nil), // 0: InstallAppRequest
+ (*InstallAppResponse)(nil), // 1: InstallAppResponse
+ (*UninstallAppRequest)(nil), // 2: UninstallAppRequest
+ (*UninstallAppResponse)(nil), // 3: UninstallAppResponse
+ (*ReadAppContextRequest)(nil), // 4: ReadAppContextRequest
+ (*ReadAppContextResponse)(nil), // 5: ReadAppContextResponse
+}
+var file_installapp_proto_depIdxs = []int32{
+ 0, // 0: installapp.InstallApp:input_type -> InstallAppRequest
+ 2, // 1: installapp.UninstallApp:input_type -> UninstallAppRequest
+ 4, // 2: installapp.ReadAppContext:input_type -> ReadAppContextRequest
+ 1, // 3: installapp.InstallApp:output_type -> InstallAppResponse
+ 3, // 4: installapp.UninstallApp:output_type -> UninstallAppResponse
+ 5, // 5: installapp.ReadAppContext:output_type -> ReadAppContextResponse
+ 3, // [3:6] is the sub-list for method output_type
+ 0, // [0:3] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_installapp_proto_init() }
+func file_installapp_proto_init() {
+ if File_installapp_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_installapp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*InstallAppRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_installapp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*InstallAppResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_installapp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UninstallAppRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_installapp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UninstallAppResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_installapp_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReadAppContextRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_installapp_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReadAppContextResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_installapp_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 6,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_installapp_proto_goTypes,
+ DependencyIndexes: file_installapp_proto_depIdxs,
+ MessageInfos: file_installapp_proto_msgTypes,
+ }.Build()
+ File_installapp_proto = out.File
+ file_installapp_proto_rawDesc = nil
+ file_installapp_proto_goTypes = nil
+ file_installapp_proto_depIdxs = nil
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConnInterface
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion6
+
+// InstallappClient is the client API for Installapp service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type InstallappClient interface {
+ // Sync
+ InstallApp(ctx context.Context, in *InstallAppRequest, opts ...grpc.CallOption) (*InstallAppResponse, error)
+ UninstallApp(ctx context.Context, in *UninstallAppRequest, opts ...grpc.CallOption) (*UninstallAppResponse, error)
+ ReadAppContext(ctx context.Context, in *ReadAppContextRequest, opts ...grpc.CallOption) (*ReadAppContextResponse, error)
+}
+
+type installappClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewInstallappClient(cc grpc.ClientConnInterface) InstallappClient {
+ return &installappClient{cc}
+}
+
+func (c *installappClient) InstallApp(ctx context.Context, in *InstallAppRequest, opts ...grpc.CallOption) (*InstallAppResponse, error) {
+ out := new(InstallAppResponse)
+ err := c.cc.Invoke(ctx, "/installapp/InstallApp", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *installappClient) UninstallApp(ctx context.Context, in *UninstallAppRequest, opts ...grpc.CallOption) (*UninstallAppResponse, error) {
+ out := new(UninstallAppResponse)
+ err := c.cc.Invoke(ctx, "/installapp/UninstallApp", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *installappClient) ReadAppContext(ctx context.Context, in *ReadAppContextRequest, opts ...grpc.CallOption) (*ReadAppContextResponse, error) {
+ out := new(ReadAppContextResponse)
+ err := c.cc.Invoke(ctx, "/installapp/ReadAppContext", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// InstallappServer is the server API for Installapp service.
+type InstallappServer interface {
+ // Sync
+ InstallApp(context.Context, *InstallAppRequest) (*InstallAppResponse, error)
+ UninstallApp(context.Context, *UninstallAppRequest) (*UninstallAppResponse, error)
+ ReadAppContext(context.Context, *ReadAppContextRequest) (*ReadAppContextResponse, error)
+}
+
+// UnimplementedInstallappServer can be embedded to have forward compatible implementations.
+type UnimplementedInstallappServer struct {
+}
+
+func (*UnimplementedInstallappServer) InstallApp(context.Context, *InstallAppRequest) (*InstallAppResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method InstallApp not implemented")
+}
+func (*UnimplementedInstallappServer) UninstallApp(context.Context, *UninstallAppRequest) (*UninstallAppResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UninstallApp not implemented")
+}
+func (*UnimplementedInstallappServer) ReadAppContext(context.Context, *ReadAppContextRequest) (*ReadAppContextResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ReadAppContext not implemented")
+}
+
+func RegisterInstallappServer(s *grpc.Server, srv InstallappServer) {
+ s.RegisterService(&_Installapp_serviceDesc, srv)
+}
+
+func _Installapp_InstallApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(InstallAppRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(InstallappServer).InstallApp(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/installapp/InstallApp",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(InstallappServer).InstallApp(ctx, req.(*InstallAppRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Installapp_UninstallApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UninstallAppRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(InstallappServer).UninstallApp(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/installapp/UninstallApp",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(InstallappServer).UninstallApp(ctx, req.(*UninstallAppRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Installapp_ReadAppContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ReadAppContextRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(InstallappServer).ReadAppContext(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/installapp/ReadAppContext",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(InstallappServer).ReadAppContext(ctx, req.(*ReadAppContextRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _Installapp_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "installapp",
+ HandlerType: (*InstallappServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "InstallApp",
+ Handler: _Installapp_InstallApp_Handler,
+ },
+ {
+ MethodName: "UninstallApp",
+ Handler: _Installapp_UninstallApp_Handler,
+ },
+ {
+ MethodName: "ReadAppContext",
+ Handler: _Installapp_ReadAppContext_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "installapp.proto",
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-syntax = "proto3";\r
-\r
-service installapp {\r
- // Sync\r
- rpc InstallApp(InstallAppRequest) returns (InstallAppResponse) {\r
- }\r
-\r
- rpc UninstallApp(UninstallAppRequest) returns (UninstallAppResponse) {\r
- }\r
-}\r
-\r
-message InstallAppRequest {\r
- string app_context = 1;\r
-}\r
-\r
-message InstallAppResponse {\r
- bool app_context_installed = 1;\r
- string app_context_install_message = 2;\r
-}\r
-\r
-message UninstallAppRequest {\r
- string app_context = 1;\r
-}\r
-\r
-message UninstallAppResponse {\r
- bool app_context_uninstalled = 1;\r
- string app_context_uninstall_message = 2;\r
-}\r
-\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+syntax = "proto3";
+
+service installapp {
+ // Sync
+ rpc InstallApp(InstallAppRequest) returns (InstallAppResponse) {
+ }
+
+ rpc UninstallApp(UninstallAppRequest) returns (UninstallAppResponse) {
+ }
+
+ rpc ReadAppContext(ReadAppContextRequest) returns (ReadAppContextResponse){
+ }
+
+}
+
+message InstallAppRequest {
+ string app_context = 1;
+}
+
+message InstallAppResponse {
+ bool app_context_installed = 1;
+ string app_context_install_message = 2;
+}
+
+message UninstallAppRequest {
+ string app_context = 1;
+}
+
+message UninstallAppResponse {
+ bool app_context_uninstalled = 1;
+ string app_context_uninstall_message = 2;
+}
+
+message ReadAppContextRequest {
+ string app_context = 1;
+}
+
+message ReadAppContextResponse {
+ bool app_context_read_successful = 1;
+ string app_context_read_message = 2;
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package installappserver\r
-\r
-import (\r
- "context"\r
- "encoding/json"\r
- con "github.com/open-ness/EMCO/src/rsync/pkg/context"\r
- "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"\r
- "log"\r
-)\r
-\r
-type installappServer struct {\r
- installapp.UnimplementedInstallappServer\r
-}\r
-\r
-func (cs *installappServer) InstallApp(ctx context.Context, req *installapp.InstallAppRequest) (*installapp.InstallAppResponse, error) {\r
- installAppReq, _ := json.Marshal(req)\r
- log.Println("GRPC Server received installAppRequest: ", string(installAppReq))\r
-\r
- // Try instantiate the comp app\r
- instca := con.CompositeAppContext{}\r
- err := instca.InstantiateComApp(req.GetAppContext())\r
- if err != nil {\r
- log.Println("Instantiation failed: " + err.Error())\r
- err := instca.TerminateComApp(req.GetAppContext())\r
- if err != nil {\r
- log.Println("Termination failed: " + err.Error())\r
- }\r
- return &installapp.InstallAppResponse{AppContextInstalled: false}, err\r
- }\r
- return &installapp.InstallAppResponse{AppContextInstalled: true}, nil\r
-}\r
-\r
-func (cs *installappServer) UninstallApp(ctx context.Context, req *installapp.UninstallAppRequest) (*installapp.UninstallAppResponse, error) {\r
- uninstallAppReq, _ := json.Marshal(req)\r
- log.Println("GRPC Server received uninstallAppRequest: ", string(uninstallAppReq))\r
-\r
- // Try terminating the comp app here\r
- instca := con.CompositeAppContext{}\r
- err := instca.TerminateComApp(req.GetAppContext())\r
- if err != nil {\r
- log.Println("Termination failed: " + err.Error())\r
- return &installapp.UninstallAppResponse{AppContextUninstalled: false}, err\r
- }\r
-\r
- return &installapp.UninstallAppResponse{AppContextUninstalled: true}, nil\r
-}\r
-\r
-// NewInstallAppServer exported\r
-func NewInstallAppServer() *installappServer {\r
- s := &installappServer{}\r
- return s\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package installappserver
+
+import (
+ "context"
+ "encoding/json"
+ "log"
+
+ con "github.com/open-ness/EMCO/src/rsync/pkg/context"
+ "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"
+)
+
+type installappServer struct {
+ installapp.UnimplementedInstallappServer
+}
+
+func (cs *installappServer) InstallApp(ctx context.Context, req *installapp.InstallAppRequest) (*installapp.InstallAppResponse, error) {
+ installAppReq, _ := json.Marshal(req)
+ log.Println("GRPC Server received installAppRequest: ", string(installAppReq))
+
+ // Try instantiate the comp app
+ instca := con.CompositeAppContext{}
+ err := instca.InstantiateComApp(req.GetAppContext())
+ if err != nil {
+ log.Println("Instantiation failed: " + err.Error())
+ err := instca.TerminateComApp(req.GetAppContext())
+ if err != nil {
+ log.Println("Termination failed: " + err.Error())
+ }
+ return &installapp.InstallAppResponse{AppContextInstalled: false}, err
+ }
+ return &installapp.InstallAppResponse{AppContextInstalled: true}, nil
+}
+
+func (cs *installappServer) UninstallApp(ctx context.Context, req *installapp.UninstallAppRequest) (*installapp.UninstallAppResponse, error) {
+ uninstallAppReq, _ := json.Marshal(req)
+ log.Println("GRPC Server received uninstallAppRequest: ", string(uninstallAppReq))
+
+ // Try terminating the comp app here
+ instca := con.CompositeAppContext{}
+ err := instca.TerminateComApp(req.GetAppContext())
+ if err != nil {
+ log.Println("Termination failed: " + err.Error())
+ return &installapp.UninstallAppResponse{AppContextUninstalled: false}, err
+ }
+
+ return &installapp.UninstallAppResponse{AppContextUninstalled: true}, nil
+}
+
+func (cs *installappServer) ReadAppContext(ctx context.Context, req *installapp.ReadAppContextRequest) (*installapp.ReadAppContextResponse, error) {
+ readAppContext, _ := json.Marshal(req)
+ log.Println("GRPC Server received ReadAppContext: ", string(readAppContext))
+
+ // Try instantiate the comp app
+ instca := con.CompositeAppContext{}
+ err := instca.ReadComApp(req.GetAppContext())
+ if err != nil {
+ log.Println("Termination failed: " + err.Error())
+ return &installapp.ReadAppContextResponse{AppContextReadSuccessful: false, AppContextReadMessage: "AppContext read failed"}, err
+ }
+
+ return &installapp.ReadAppContextResponse{AppContextReadSuccessful: true, AppContextReadMessage: "AppContext read successfully"}, nil
+}
+
+// NewInstallAppServer exported
+func NewInstallAppServer() *installappServer {
+ s := &installappServer{}
+ return s
+}
--- /dev/null
+// Code generated by MockGen. DO NOT EDIT.
+// Source: installapp/installapp.pb.go
+
+// Package mock_installapp is a generated GoMock package.
+package mock_installapp
+
+import (
+ context "context"
+ reflect "reflect"
+
+ gomock "github.com/golang/mock/gomock"
+ installapp "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"
+ grpc "google.golang.org/grpc"
+)
+
+// MockInstallappClient is a mock of InstallappClient interface.
+type MockInstallappClient struct {
+ ctrl *gomock.Controller
+ recorder *MockInstallappClientMockRecorder
+}
+
+// MockInstallappClientMockRecorder is the mock recorder for MockInstallappClient.
+type MockInstallappClientMockRecorder struct {
+ mock *MockInstallappClient
+}
+
+// NewMockInstallappClient creates a new mock instance.
+func NewMockInstallappClient(ctrl *gomock.Controller) *MockInstallappClient {
+ mock := &MockInstallappClient{ctrl: ctrl}
+ mock.recorder = &MockInstallappClientMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockInstallappClient) EXPECT() *MockInstallappClientMockRecorder {
+ return m.recorder
+}
+
+// InstallApp mocks base method.
+func (m *MockInstallappClient) InstallApp(ctx context.Context, in *installapp.InstallAppRequest, opts ...grpc.CallOption) (*installapp.InstallAppResponse, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{ctx, in}
+ for _, a := range opts {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "InstallApp", varargs...)
+ ret0, _ := ret[0].(*installapp.InstallAppResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// InstallApp indicates an expected call of InstallApp.
+func (mr *MockInstallappClientMockRecorder) InstallApp(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{ctx, in}, opts...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallApp", reflect.TypeOf((*MockInstallappClient)(nil).InstallApp), varargs...)
+}
+
+// ReadAppContext mocks base method.
+func (m *MockInstallappClient) ReadAppContext(ctx context.Context, in *installapp.ReadAppContextRequest, opts ...grpc.CallOption) (*installapp.ReadAppContextResponse, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{ctx, in}
+ for _, a := range opts {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "ReadAppContext", varargs...)
+ ret0, _ := ret[0].(*installapp.ReadAppContextResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// ReadAppContext indicates an expected call of ReadAppContext.
+func (mr *MockInstallappClientMockRecorder) ReadAppContext(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{ctx, in}, opts...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadAppContext", reflect.TypeOf((*MockInstallappClient)(nil).ReadAppContext), varargs...)
+}
+
+// UninstallApp mocks base method.
+func (m *MockInstallappClient) UninstallApp(ctx context.Context, in *installapp.UninstallAppRequest, opts ...grpc.CallOption) (*installapp.UninstallAppResponse, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{ctx, in}
+ for _, a := range opts {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "UninstallApp", varargs...)
+ ret0, _ := ret[0].(*installapp.UninstallAppResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// UninstallApp indicates an expected call of UninstallApp.
+func (mr *MockInstallappClientMockRecorder) UninstallApp(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{ctx, in}, opts...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UninstallApp", reflect.TypeOf((*MockInstallappClient)(nil).UninstallApp), varargs...)
+}
+
+// MockInstallappServer is a mock of InstallappServer interface.
+type MockInstallappServer struct {
+ ctrl *gomock.Controller
+ recorder *MockInstallappServerMockRecorder
+}
+
+// MockInstallappServerMockRecorder is the mock recorder for MockInstallappServer.
+type MockInstallappServerMockRecorder struct {
+ mock *MockInstallappServer
+}
+
+// NewMockInstallappServer creates a new mock instance.
+func NewMockInstallappServer(ctrl *gomock.Controller) *MockInstallappServer {
+ mock := &MockInstallappServer{ctrl: ctrl}
+ mock.recorder = &MockInstallappServerMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockInstallappServer) EXPECT() *MockInstallappServerMockRecorder {
+ return m.recorder
+}
+
+// InstallApp mocks base method.
+func (m *MockInstallappServer) InstallApp(arg0 context.Context, arg1 *installapp.InstallAppRequest) (*installapp.InstallAppResponse, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "InstallApp", arg0, arg1)
+ ret0, _ := ret[0].(*installapp.InstallAppResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// InstallApp indicates an expected call of InstallApp.
+func (mr *MockInstallappServerMockRecorder) InstallApp(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallApp", reflect.TypeOf((*MockInstallappServer)(nil).InstallApp), arg0, arg1)
+}
+
+// ReadAppContext mocks base method.
+func (m *MockInstallappServer) ReadAppContext(arg0 context.Context, arg1 *installapp.ReadAppContextRequest) (*installapp.ReadAppContextResponse, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ReadAppContext", arg0, arg1)
+ ret0, _ := ret[0].(*installapp.ReadAppContextResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// ReadAppContext indicates an expected call of ReadAppContext.
+func (mr *MockInstallappServerMockRecorder) ReadAppContext(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadAppContext", reflect.TypeOf((*MockInstallappServer)(nil).ReadAppContext), arg0, arg1)
+}
+
+// UninstallApp mocks base method.
+func (m *MockInstallappServer) UninstallApp(arg0 context.Context, arg1 *installapp.UninstallAppRequest) (*installapp.UninstallAppResponse, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "UninstallApp", arg0, arg1)
+ ret0, _ := ret[0].(*installapp.UninstallAppResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// UninstallApp indicates an expected call of UninstallApp.
+func (mr *MockInstallappServerMockRecorder) UninstallApp(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UninstallApp", reflect.TypeOf((*MockInstallappServer)(nil).UninstallApp), arg0, arg1)
+}
-// Code generated by protoc-gen-go. DO NOT EDIT.\r
-// source: readynotify.proto\r
-\r
-/*\r
-Package readynotify is a generated protocol buffer package.\r
-\r
-It is generated from these files:\r
- readynotify.proto\r
-\r
-It has these top-level messages:\r
- Alert\r
- Topic\r
- Notification\r
-*/\r
-package readynotify\r
-\r
-import proto "github.com/golang/protobuf/proto"\r
-import fmt "fmt"\r
-import math "math"\r
-\r
-import (\r
- context "golang.org/x/net/context"\r
- grpc "google.golang.org/grpc"\r
-)\r
-\r
-// Reference imports to suppress errors if they are not otherwise used.\r
-var _ = proto.Marshal\r
-var _ = fmt.Errorf\r
-var _ = math.Inf\r
-\r
-// This is a compile-time assertion to ensure that this generated file\r
-// is compatible with the proto package it is being compiled against.\r
-// A compilation error at this line likely means your copy of the\r
-// proto package needs to be updated.\r
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\r
-\r
-type Alert struct {\r
- Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`\r
-}\r
-\r
-func (m *Alert) Reset() { *m = Alert{} }\r
-func (m *Alert) String() string { return proto.CompactTextString(m) }\r
-func (*Alert) ProtoMessage() {}\r
-func (*Alert) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }\r
-\r
-func (m *Alert) GetMessage() string {\r
- if m != nil {\r
- return m.Message\r
- }\r
- return ""\r
-}\r
-\r
-type Topic struct {\r
- ClientName string `protobuf:"bytes,1,opt,name=clientName" json:"clientName,omitempty"`\r
- AppContext string `protobuf:"bytes,2,opt,name=appContext" json:"appContext,omitempty"`\r
-}\r
-\r
-func (m *Topic) Reset() { *m = Topic{} }\r
-func (m *Topic) String() string { return proto.CompactTextString(m) }\r
-func (*Topic) ProtoMessage() {}\r
-func (*Topic) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }\r
-\r
-func (m *Topic) GetClientName() string {\r
- if m != nil {\r
- return m.ClientName\r
- }\r
- return ""\r
-}\r
-\r
-func (m *Topic) GetAppContext() string {\r
- if m != nil {\r
- return m.AppContext\r
- }\r
- return ""\r
-}\r
-\r
-type Notification struct {\r
- ClientName string `protobuf:"bytes,1,opt,name=clientName" json:"clientName,omitempty"`\r
- ServerName string `protobuf:"bytes,2,opt,name=serverName" json:"serverName,omitempty"`\r
- AppContext string `protobuf:"bytes,3,opt,name=appContext" json:"appContext,omitempty"`\r
-}\r
-\r
-func (m *Notification) Reset() { *m = Notification{} }\r
-func (m *Notification) String() string { return proto.CompactTextString(m) }\r
-func (*Notification) ProtoMessage() {}\r
-func (*Notification) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }\r
-\r
-func (m *Notification) GetClientName() string {\r
- if m != nil {\r
- return m.ClientName\r
- }\r
- return ""\r
-}\r
-\r
-func (m *Notification) GetServerName() string {\r
- if m != nil {\r
- return m.ServerName\r
- }\r
- return ""\r
-}\r
-\r
-func (m *Notification) GetAppContext() string {\r
- if m != nil {\r
- return m.AppContext\r
- }\r
- return ""\r
-}\r
-\r
-func init() {\r
- proto.RegisterType((*Alert)(nil), "Alert")\r
- proto.RegisterType((*Topic)(nil), "Topic")\r
- proto.RegisterType((*Notification)(nil), "Notification")\r
-}\r
-\r
-// Reference imports to suppress errors if they are not otherwise used.\r
-var _ context.Context\r
-var _ grpc.ClientConn\r
-\r
-// This is a compile-time assertion to ensure that this generated file\r
-// is compatible with the grpc package it is being compiled against.\r
-const _ = grpc.SupportPackageIsVersion4\r
-\r
-// Client API for ReadyNotify service\r
-\r
-type ReadyNotifyClient interface {\r
- Alert(ctx context.Context, in *Topic, opts ...grpc.CallOption) (ReadyNotify_AlertClient, error)\r
-}\r
-\r
-type readyNotifyClient struct {\r
- cc *grpc.ClientConn\r
-}\r
-\r
-func NewReadyNotifyClient(cc *grpc.ClientConn) ReadyNotifyClient {\r
- return &readyNotifyClient{cc}\r
-}\r
-\r
-func (c *readyNotifyClient) Alert(ctx context.Context, in *Topic, opts ...grpc.CallOption) (ReadyNotify_AlertClient, error) {\r
- stream, err := grpc.NewClientStream(ctx, &_ReadyNotify_serviceDesc.Streams[0], c.cc, "/readyNotify/Alert", opts...)\r
- if err != nil {\r
- return nil, err\r
- }\r
- x := &readyNotifyAlertClient{stream}\r
- if err := x.ClientStream.SendMsg(in); err != nil {\r
- return nil, err\r
- }\r
- if err := x.ClientStream.CloseSend(); err != nil {\r
- return nil, err\r
- }\r
- return x, nil\r
-}\r
-\r
-type ReadyNotify_AlertClient interface {\r
- Recv() (*Notification, error)\r
- grpc.ClientStream\r
-}\r
-\r
-type readyNotifyAlertClient struct {\r
- grpc.ClientStream\r
-}\r
-\r
-func (x *readyNotifyAlertClient) Recv() (*Notification, error) {\r
- m := new(Notification)\r
- if err := x.ClientStream.RecvMsg(m); err != nil {\r
- return nil, err\r
- }\r
- return m, nil\r
-}\r
-\r
-// Server API for ReadyNotify service\r
-\r
-type ReadyNotifyServer interface {\r
- Alert(*Topic, ReadyNotify_AlertServer) error\r
-}\r
-\r
-func RegisterReadyNotifyServer(s *grpc.Server, srv ReadyNotifyServer) {\r
- s.RegisterService(&_ReadyNotify_serviceDesc, srv)\r
-}\r
-\r
-func _ReadyNotify_Alert_Handler(srv interface{}, stream grpc.ServerStream) error {\r
- m := new(Topic)\r
- if err := stream.RecvMsg(m); err != nil {\r
- return err\r
- }\r
- return srv.(ReadyNotifyServer).Alert(m, &readyNotifyAlertServer{stream})\r
-}\r
-\r
-type ReadyNotify_AlertServer interface {\r
- Send(*Notification) error\r
- grpc.ServerStream\r
-}\r
-\r
-type readyNotifyAlertServer struct {\r
- grpc.ServerStream\r
-}\r
-\r
-func (x *readyNotifyAlertServer) Send(m *Notification) error {\r
- return x.ServerStream.SendMsg(m)\r
-}\r
-\r
-var _ReadyNotify_serviceDesc = grpc.ServiceDesc{\r
- ServiceName: "readyNotify",\r
- HandlerType: (*ReadyNotifyServer)(nil),\r
- Methods: []grpc.MethodDesc{},\r
- Streams: []grpc.StreamDesc{\r
- {\r
- StreamName: "Alert",\r
- Handler: _ReadyNotify_Alert_Handler,\r
- ServerStreams: true,\r
- },\r
- },\r
- Metadata: "readynotify.proto",\r
-}\r
-\r
-func init() { proto.RegisterFile("readynotify.proto", fileDescriptor0) }\r
-\r
-var fileDescriptor0 = []byte{\r
- // 180 bytes of a gzipped FileDescriptorProto\r
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x4a, 0x4d, 0x4c,\r
- 0xa9, 0xcc, 0xcb, 0x2f, 0xc9, 0x4c, 0xab, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x52, 0xe4,\r
- 0x62, 0x75, 0xcc, 0x49, 0x2d, 0x2a, 0x11, 0x92, 0xe0, 0x62, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c,\r
- 0x4f, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x71, 0x95, 0xdc, 0xb9, 0x58, 0x43, 0xf2,\r
- 0x0b, 0x32, 0x93, 0x85, 0xe4, 0xb8, 0xb8, 0x92, 0x73, 0x32, 0x53, 0xf3, 0x4a, 0xfc, 0x12, 0x73,\r
- 0x61, 0xaa, 0x90, 0x44, 0x40, 0xf2, 0x89, 0x05, 0x05, 0xce, 0xf9, 0x79, 0x25, 0xa9, 0x15, 0x25,\r
- 0x12, 0x4c, 0x10, 0x79, 0x84, 0x88, 0x52, 0x1e, 0x17, 0x8f, 0x1f, 0xc8, 0xee, 0xcc, 0xe4, 0xc4,\r
- 0x92, 0xcc, 0xfc, 0x3c, 0x62, 0xcc, 0x2b, 0x4e, 0x2d, 0x2a, 0x4b, 0x2d, 0x02, 0xcb, 0x43, 0xcd,\r
- 0x43, 0x88, 0xa0, 0xd9, 0xc7, 0x8c, 0x6e, 0x9f, 0x91, 0x3e, 0x17, 0x37, 0xd8, 0xc3, 0x60, 0x4b,\r
- 0x2b, 0x85, 0x14, 0x60, 0x5e, 0x65, 0xd3, 0x03, 0xfb, 0x47, 0x8a, 0x57, 0x0f, 0xd9, 0x39, 0x06,\r
- 0x8c, 0x49, 0x6c, 0xe0, 0x30, 0x31, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xc1, 0xd0, 0x25,\r
- 0x28, 0x01, 0x00, 0x00,\r
-}\r
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: readynotify.proto
+
+package readynotify
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Alert struct {
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Alert) Reset() { *m = Alert{} }
+func (m *Alert) String() string { return proto.CompactTextString(m) }
+func (*Alert) ProtoMessage() {}
+func (*Alert) Descriptor() ([]byte, []int) {
+ return fileDescriptor_readynotify_4470875ae67e1059, []int{0}
+}
+func (m *Alert) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Alert.Unmarshal(m, b)
+}
+func (m *Alert) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Alert.Marshal(b, m, deterministic)
+}
+func (dst *Alert) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Alert.Merge(dst, src)
+}
+func (m *Alert) XXX_Size() int {
+ return xxx_messageInfo_Alert.Size(m)
+}
+func (m *Alert) XXX_DiscardUnknown() {
+ xxx_messageInfo_Alert.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Alert proto.InternalMessageInfo
+
+func (m *Alert) GetMessage() string {
+ if m != nil {
+ return m.Message
+ }
+ return ""
+}
+
+type Topic struct {
+ ClientName string `protobuf:"bytes,1,opt,name=clientName,proto3" json:"clientName,omitempty"`
+ AppContext string `protobuf:"bytes,2,opt,name=appContext,proto3" json:"appContext,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Topic) Reset() { *m = Topic{} }
+func (m *Topic) String() string { return proto.CompactTextString(m) }
+func (*Topic) ProtoMessage() {}
+func (*Topic) Descriptor() ([]byte, []int) {
+ return fileDescriptor_readynotify_4470875ae67e1059, []int{1}
+}
+func (m *Topic) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Topic.Unmarshal(m, b)
+}
+func (m *Topic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Topic.Marshal(b, m, deterministic)
+}
+func (dst *Topic) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Topic.Merge(dst, src)
+}
+func (m *Topic) XXX_Size() int {
+ return xxx_messageInfo_Topic.Size(m)
+}
+func (m *Topic) XXX_DiscardUnknown() {
+ xxx_messageInfo_Topic.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Topic proto.InternalMessageInfo
+
+func (m *Topic) GetClientName() string {
+ if m != nil {
+ return m.ClientName
+ }
+ return ""
+}
+
+func (m *Topic) GetAppContext() string {
+ if m != nil {
+ return m.AppContext
+ }
+ return ""
+}
+
+type Notification struct {
+ ClientName string `protobuf:"bytes,1,opt,name=clientName,proto3" json:"clientName,omitempty"`
+ ServerName string `protobuf:"bytes,2,opt,name=serverName,proto3" json:"serverName,omitempty"`
+ AppContext string `protobuf:"bytes,3,opt,name=appContext,proto3" json:"appContext,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Notification) Reset() { *m = Notification{} }
+func (m *Notification) String() string { return proto.CompactTextString(m) }
+func (*Notification) ProtoMessage() {}
+func (*Notification) Descriptor() ([]byte, []int) {
+ return fileDescriptor_readynotify_4470875ae67e1059, []int{2}
+}
+func (m *Notification) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Notification.Unmarshal(m, b)
+}
+func (m *Notification) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Notification.Marshal(b, m, deterministic)
+}
+func (dst *Notification) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Notification.Merge(dst, src)
+}
+func (m *Notification) XXX_Size() int {
+ return xxx_messageInfo_Notification.Size(m)
+}
+func (m *Notification) XXX_DiscardUnknown() {
+ xxx_messageInfo_Notification.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Notification proto.InternalMessageInfo
+
+func (m *Notification) GetClientName() string {
+ if m != nil {
+ return m.ClientName
+ }
+ return ""
+}
+
+func (m *Notification) GetServerName() string {
+ if m != nil {
+ return m.ServerName
+ }
+ return ""
+}
+
+func (m *Notification) GetAppContext() string {
+ if m != nil {
+ return m.AppContext
+ }
+ return ""
+}
+
+type UnsubscribeResponse struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *UnsubscribeResponse) Reset() { *m = UnsubscribeResponse{} }
+func (m *UnsubscribeResponse) String() string { return proto.CompactTextString(m) }
+func (*UnsubscribeResponse) ProtoMessage() {}
+func (*UnsubscribeResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_readynotify_4470875ae67e1059, []int{3}
+}
+func (m *UnsubscribeResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_UnsubscribeResponse.Unmarshal(m, b)
+}
+func (m *UnsubscribeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_UnsubscribeResponse.Marshal(b, m, deterministic)
+}
+func (dst *UnsubscribeResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsubscribeResponse.Merge(dst, src)
+}
+func (m *UnsubscribeResponse) XXX_Size() int {
+ return xxx_messageInfo_UnsubscribeResponse.Size(m)
+}
+func (m *UnsubscribeResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsubscribeResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsubscribeResponse proto.InternalMessageInfo
+
+func init() {
+ proto.RegisterType((*Alert)(nil), "Alert")
+ proto.RegisterType((*Topic)(nil), "Topic")
+ proto.RegisterType((*Notification)(nil), "Notification")
+ proto.RegisterType((*UnsubscribeResponse)(nil), "UnsubscribeResponse")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// ReadyNotifyClient is the client API for ReadyNotify service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type ReadyNotifyClient interface {
+ Alert(ctx context.Context, in *Topic, opts ...grpc.CallOption) (ReadyNotify_AlertClient, error)
+ Unsubscribe(ctx context.Context, in *Topic, opts ...grpc.CallOption) (*UnsubscribeResponse, error)
+}
+
+type readyNotifyClient struct {
+ cc *grpc.ClientConn
+}
+
+func NewReadyNotifyClient(cc *grpc.ClientConn) ReadyNotifyClient {
+ return &readyNotifyClient{cc}
+}
+
+func (c *readyNotifyClient) Alert(ctx context.Context, in *Topic, opts ...grpc.CallOption) (ReadyNotify_AlertClient, error) {
+ stream, err := c.cc.NewStream(ctx, &_ReadyNotify_serviceDesc.Streams[0], "/readyNotify/Alert", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &readyNotifyAlertClient{stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type ReadyNotify_AlertClient interface {
+ Recv() (*Notification, error)
+ grpc.ClientStream
+}
+
+type readyNotifyAlertClient struct {
+ grpc.ClientStream
+}
+
+func (x *readyNotifyAlertClient) Recv() (*Notification, error) {
+ m := new(Notification)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *readyNotifyClient) Unsubscribe(ctx context.Context, in *Topic, opts ...grpc.CallOption) (*UnsubscribeResponse, error) {
+ out := new(UnsubscribeResponse)
+ err := c.cc.Invoke(ctx, "/readyNotify/Unsubscribe", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// ReadyNotifyServer is the server API for ReadyNotify service.
+type ReadyNotifyServer interface {
+ Alert(*Topic, ReadyNotify_AlertServer) error
+ Unsubscribe(context.Context, *Topic) (*UnsubscribeResponse, error)
+}
+
+func RegisterReadyNotifyServer(s *grpc.Server, srv ReadyNotifyServer) {
+ s.RegisterService(&_ReadyNotify_serviceDesc, srv)
+}
+
+func _ReadyNotify_Alert_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(Topic)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(ReadyNotifyServer).Alert(m, &readyNotifyAlertServer{stream})
+}
+
+type ReadyNotify_AlertServer interface {
+ Send(*Notification) error
+ grpc.ServerStream
+}
+
+type readyNotifyAlertServer struct {
+ grpc.ServerStream
+}
+
+func (x *readyNotifyAlertServer) Send(m *Notification) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _ReadyNotify_Unsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(Topic)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ReadyNotifyServer).Unsubscribe(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/readyNotify/Unsubscribe",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ReadyNotifyServer).Unsubscribe(ctx, req.(*Topic))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _ReadyNotify_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "readyNotify",
+ HandlerType: (*ReadyNotifyServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Unsubscribe",
+ Handler: _ReadyNotify_Unsubscribe_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{
+ {
+ StreamName: "Alert",
+ Handler: _ReadyNotify_Alert_Handler,
+ ServerStreams: true,
+ },
+ },
+ Metadata: "readynotify.proto",
+}
+
+func init() { proto.RegisterFile("readynotify.proto", fileDescriptor_readynotify_4470875ae67e1059) }
+
+var fileDescriptor_readynotify_4470875ae67e1059 = []byte{
+ // 219 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x4a, 0x4d, 0x4c,
+ 0xa9, 0xcc, 0xcb, 0x2f, 0xc9, 0x4c, 0xab, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x52, 0xe4,
+ 0x62, 0x75, 0xcc, 0x49, 0x2d, 0x2a, 0x11, 0x92, 0xe0, 0x62, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c,
+ 0x4f, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x71, 0x95, 0xdc, 0xb9, 0x58, 0x43, 0xf2,
+ 0x0b, 0x32, 0x93, 0x85, 0xe4, 0xb8, 0xb8, 0x92, 0x73, 0x32, 0x53, 0xf3, 0x4a, 0xfc, 0x12, 0x73,
+ 0x61, 0xaa, 0x90, 0x44, 0x40, 0xf2, 0x89, 0x05, 0x05, 0xce, 0xf9, 0x79, 0x25, 0xa9, 0x15, 0x25,
+ 0x12, 0x4c, 0x10, 0x79, 0x84, 0x88, 0x52, 0x1e, 0x17, 0x8f, 0x1f, 0xc8, 0xee, 0xcc, 0xe4, 0xc4,
+ 0x92, 0xcc, 0xfc, 0x3c, 0x62, 0xcc, 0x2b, 0x4e, 0x2d, 0x2a, 0x4b, 0x2d, 0x02, 0xcb, 0x43, 0xcd,
+ 0x43, 0x88, 0xa0, 0xd9, 0xc7, 0x8c, 0x61, 0x9f, 0x28, 0x97, 0x70, 0x68, 0x5e, 0x71, 0x69, 0x52,
+ 0x71, 0x72, 0x51, 0x66, 0x52, 0x6a, 0x50, 0x6a, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x51, 0x02,
+ 0x17, 0x37, 0x38, 0x1c, 0xc0, 0x6e, 0xa9, 0x14, 0x52, 0x82, 0x85, 0x00, 0x9b, 0x1e, 0xd8, 0x9b,
+ 0x52, 0xbc, 0x7a, 0xc8, 0xae, 0x54, 0x62, 0x30, 0x60, 0x14, 0xd2, 0xe5, 0xe2, 0x46, 0x32, 0x09,
+ 0xae, 0x52, 0x44, 0x0f, 0x8b, 0xf9, 0x4a, 0x0c, 0x49, 0x6c, 0xe0, 0xb0, 0x35, 0x06, 0x04, 0x00,
+ 0x00, 0xff, 0xff, 0xca, 0xbd, 0x6c, 0x63, 0x70, 0x01, 0x00, 0x00,
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-syntax = "proto3";\r
-\r
-service readyNotify {\r
- rpc Alert (Topic) returns (stream Notification);\r
-}\r
-\r
-message Alert {\r
- string message = 1;\r
-}\r
-\r
-message Topic {\r
- string clientName = 1;\r
- string appContext = 2;\r
-}\r
-\r
-message Notification {\r
- string clientName = 1;\r
- string serverName = 2;\r
- string appContext = 3;\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+syntax = "proto3";
+
+service readyNotify {
+ rpc Alert (Topic) returns (stream Notification){
+
+ }
+
+ rpc Unsubscribe (Topic) returns (UnsubscribeResponse){
+
+ }
+}
+
+message Alert {
+ string message = 1;
+}
+
+message Topic {
+ string clientName = 1;
+ string appContext = 2;
+}
+
+message Notification {
+ string clientName = 1;
+ string serverName = 2;
+ string appContext = 3;
+}
+
+message UnsubscribeResponse {
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package readynotifyserver\r
-\r
-import (\r
- "encoding/json"\r
- "log"\r
- "strings"\r
- "time"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- pb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type readyNotifyServer struct {\r
- name string\r
- alertStrm map[string]pb.ReadyNotify_AlertServer\r
- appContextId map[string]string\r
-}\r
-\r
-func (s *readyNotifyServer) Alert(topic *pb.Topic, stream pb.ReadyNotify_AlertServer) error {\r
- client := topic.GetClientName()\r
- appContextId := topic.GetAppContext()\r
- log.Printf("[ReadyNotify gRPC] Received an Alert subscription request (%s, %s)", client, appContextId)\r
- s.alertStrm[client] = stream\r
- s.appContextId[client] = appContextId\r
- for {\r
- time.Sleep(3 * time.Second)\r
- for k, v := range s.alertStrm {\r
- appContextId = s.appContextId[k]\r
- logutils.Info("[ReadyNotify gRPC] Checking cluster statuses", logutils.Fields{"appContextId": appContextId})\r
- err := checkAppContext(appContextId)\r
- if err == nil {\r
- logutils.Info("[ReadyNotify gRPC] All clusters' certificates have been issued", logutils.Fields{"appContextId": appContextId})\r
- err = v.Send(&pb.Notification{AppContext: appContextId})\r
- if err != nil {\r
- logutils.Error("[ReadyNotify gRPC] Alert notification back to client failed to be sent", logutils.Fields{"err": err})\r
- } else {\r
- // we're done with this appcontext ID, remove it from map (safe in Go within for loop)\r
- delete(s.alertStrm, k)\r
- }\r
- } else {\r
- logutils.Info("[ReadyNotify gRPC] Not all clusters' certificates have been issued, yet", logutils.Fields{"appContextId": appContextId})\r
- }\r
- }\r
- }\r
-}\r
-\r
-// checkAppContext checks whether the LC from the provided appcontext has had certificates issued by every cluster\r
-func checkAppContext(appContextId string) error {\r
- // Get the contextId from the label (id)\r
- var ac appcontext.AppContext\r
- _, err := ac.LoadAppContext(appContextId)\r
- if err != nil {\r
- logutils.Error("AppContext not found", logutils.Fields{"appContextId": appContextId})\r
- return err\r
- }\r
-\r
- appsOrder, err := ac.GetAppInstruction("order")\r
- if err != nil {\r
- return err\r
- }\r
- var appList map[string][]string\r
- json.Unmarshal([]byte(appsOrder.(string)), &appList)\r
-\r
- for _, app := range appList["apporder"] {\r
- clusterNames, err := ac.GetClusterNames(app)\r
- if err != nil {\r
- return err\r
- }\r
- // iterate over all clusters of appcontext\r
- for k := 0; k < len(clusterNames); k++ {\r
- chandle, err := ac.GetClusterHandle(app, clusterNames[k])\r
- if err != nil {\r
- logutils.Info("Error getting cluster handle", logutils.Fields{"clusterNames[k]": clusterNames[k]})\r
- return err\r
- }\r
- // Get the handle for the cluster status object\r
- handle, _ := ac.GetLevelHandle(chandle, "status")\r
-\r
- clusterStatus, err := ac.GetValue(handle)\r
- if err != nil {\r
- logutils.Error("Couldn't fetch cluster status from its handle", logutils.Fields{"handle": handle})\r
- return err\r
- }\r
- // detect if certificate has been issued - assumes K8s base64-encoded PEM certificate\r
- if strings.Contains(clusterStatus.(string), "certificate\":\"LS0t") {\r
- logutils.Info("Cluster status contains the certificate", logutils.Fields{})\r
- return nil\r
- } else {\r
- logutils.Info("Cluster status doesn't contain the certificate yet", logutils.Fields{})\r
- }\r
- }\r
- }\r
- return pkgerrors.New("Certificates not issued yet")\r
-}\r
-\r
-// NewReadyNotifyServer exported\r
-func NewReadyNotifyServer() *readyNotifyServer {\r
- s := &readyNotifyServer{\r
- name: "readyNotifyServer",\r
- alertStrm: make(map[string]pb.ReadyNotify_AlertServer),\r
- appContextId: make(map[string]string),\r
- }\r
- return s\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020-2021 Intel Corporation
+
+package readynotifyserver
+
+import (
+ "context"
+ "log"
+ "sync"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"
+)
+
+// readyNotifyServer will be initialized by NewReadyNotifyServer() and
+// its lifecycle is valid until all the clients unsubscribed the stream notification channel
+type readyNotifyServer struct {
+ name string
+ // alertNotify contains the map of "appContextID" and "map of client name and stream server"
+ // For Ex: map[12345687:map[[dtc:st1] [dcm:st2]] 456785369:map[[ncm:st3] [dtc:st4]]]
+ alertNotify map[string]map[string]pb.ReadyNotify_AlertServer
+ streamChannel map[pb.ReadyNotify_AlertServer]chan int
+ mutex sync.Mutex
+}
+
+var notifServer *readyNotifyServer
+
+// Alert gets notified when the subscriber subscribes for an appcontext event notification
+func (s *readyNotifyServer) Alert(topic *pb.Topic, stream pb.ReadyNotify_AlertServer) error {
+ client := topic.GetClientName()
+ appContextID := topic.GetAppContext()
+ log.Printf("[ReadyNotify gRPC] Received an Alert subscription request (%s, %s)", client, appContextID)
+
+ // Adding the appContextID entry to the map
+ s.mutex.Lock()
+ if len(s.alertNotify[appContextID]) == 0 {
+ s.alertNotify[appContextID] = make(map[string]pb.ReadyNotify_AlertServer)
+ }
+ s.alertNotify[appContextID][client] = stream
+ s.streamChannel[stream] = make(chan int)
+ c := s.streamChannel[stream]
+ s.mutex.Unlock()
+
+ // Keep stream open
+ for {
+ select {
+ case <-c:
+ log.Printf("[ReadyNotify gRPC] stop channel got triggered for the client = %s\n", client)
+ return nil
+ }
+ }
+}
+
+//SendAppContextNotification sends appcontext back to the subscriber if pending
+func SendAppContextNotification(appContextID string) error {
+ streams := notifServer.alertNotify[appContextID]
+ var err error = nil
+ for _, stream := range streams {
+ err := stream.Send(&pb.Notification{AppContext: appContextID})
+ if err != nil {
+ logutils.Error("[ReadyNotify gRPC] Notification back to client failed to be sent", logutils.Fields{"err": err})
+ // return pkgerrors.New("Notification failed")
+ } else {
+ logutils.Info("[ReadyNotify gRPC] Notified the subscriber about appContext status changes", logutils.Fields{"appContextID": appContextID})
+ }
+ }
+ return err
+}
+
+// Unsubscribe will be called when the subscriber wants to terminate the stream
+func (s *readyNotifyServer) Unsubscribe(ctx context.Context, topic *pb.Topic) (*pb.UnsubscribeResponse, error) {
+
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ for appContextID, clientStreamMap := range s.alertNotify {
+ if appContextID == topic.GetAppContext() {
+ stream := clientStreamMap[topic.ClientName]
+ s.streamChannel[stream] <- 1
+
+ delete(clientStreamMap, topic.ClientName)
+ delete(s.streamChannel, stream)
+ // Delete the outer map's appcontextIDs if there is no inner map contents
+ if len(clientStreamMap) == 0 {
+ delete(s.alertNotify, appContextID)
+ }
+ }
+ }
+
+ return &pb.UnsubscribeResponse{}, nil
+}
+
+// NewReadyNotifyServer will create a new readyNotifyServer and destroys the previous one
+func NewReadyNotifyServer() *readyNotifyServer {
+ s := &readyNotifyServer{
+ name: "readyNotifyServer",
+ alertNotify: make(map[string](map[string]pb.ReadyNotify_AlertServer)),
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ }
+ notifServer = s
+ return s
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package readynotifyserver
+
+import (
+ "context"
+ "reflect"
+ "sync"
+ "testing"
+ "time"
+
+ pb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotify"
+)
+
+func Test_readyNotifyServer_Alert(t *testing.T) {
+ type fields struct {
+ name string
+ alertNotify map[string]map[string]pb.ReadyNotify_AlertServer
+ streamChannel map[pb.ReadyNotify_AlertServer]chan int
+ mutex sync.Mutex
+ alertStrm map[string]pb.ReadyNotify_AlertServer
+ appContextId map[string]string
+ }
+ type args struct {
+ topic *pb.Topic
+ stream pb.ReadyNotify_AlertServer
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ wantErr bool
+ }{
+
+ {
+ name: "empty map",
+ fields: fields{
+ name: "readyNotifyServer",
+ alertNotify: make(map[string](map[string]pb.ReadyNotify_AlertServer)),
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ alertStrm: make(map[string]pb.ReadyNotify_AlertServer),
+ appContextId: make(map[string]string),
+ },
+ args: args{
+ topic: &pb.Topic{
+ ClientName: "dtc",
+ AppContext: "123345",
+ },
+ stream: nil,
+ },
+ wantErr: false,
+ },
+ {
+ name: "map has some contents",
+ fields: fields{
+ name: "readyNotifyServer",
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"123345": {"dtc": nil}},
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ alertStrm: make(map[string]pb.ReadyNotify_AlertServer),
+ appContextId: make(map[string]string),
+ },
+ args: args{
+ topic: &pb.Topic{
+ ClientName: "dtc",
+ AppContext: "123345",
+ },
+ stream: nil,
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ s := &readyNotifyServer{
+ name: tt.fields.name,
+ alertNotify: tt.fields.alertNotify,
+ streamChannel: tt.fields.streamChannel,
+ mutex: tt.fields.mutex,
+ }
+ go func() {
+ time.Sleep(2 * time.Second)
+ s.mutex.Lock()
+ s.streamChannel[nil] <- 1
+ s.mutex.Unlock()
+ }()
+ if err := s.Alert(tt.args.topic, tt.args.stream); (err != nil) != tt.wantErr {
+ t.Errorf("readyNotifyServer.Alert() error = %v, wantErr %v", err, tt.wantErr)
+ }
+
+ })
+ }
+}
+
+func Test_readyNotifyServer_Unsubscribe(t *testing.T) {
+ type fields struct {
+ name string
+ alertNotify map[string]map[string]pb.ReadyNotify_AlertServer
+ streamChannel map[pb.ReadyNotify_AlertServer]chan int
+ mutex sync.Mutex
+ alertStrm map[string]pb.ReadyNotify_AlertServer
+ appContextId map[string]string
+ }
+ type args struct {
+ ctx context.Context
+ topic *pb.Topic
+ }
+ type want struct {
+ alertNotify map[string]map[string]pb.ReadyNotify_AlertServer
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ want want
+ wantErr bool
+ }{
+ {
+ name: "test1: Delete the contents of the map",
+ fields: fields{
+ name: "readyNotifyServer",
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"123345": {"dtc": nil}},
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ alertStrm: make(map[string]pb.ReadyNotify_AlertServer),
+ appContextId: make(map[string]string),
+ },
+ args: args{
+ topic: &pb.Topic{
+ ClientName: "dtc",
+ AppContext: "123345",
+ },
+ },
+ want: want{
+ alertNotify: nil,
+ },
+ wantErr: false,
+ },
+ {
+ name: "Test2: Delete the contents of the map",
+ fields: fields{
+ name: "readyNotifyServer",
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"123345": {"dtc": nil}, "245689": {"dcm": nil}},
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ alertStrm: make(map[string]pb.ReadyNotify_AlertServer),
+ appContextId: make(map[string]string),
+ },
+ args: args{
+ topic: &pb.Topic{
+ ClientName: "dtc",
+ AppContext: "123345",
+ },
+ },
+ want: want{
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"245689": {"dcm": nil}},
+ },
+ wantErr: false,
+ },
+ {
+ name: "Test3: Delete the contents of the map",
+ fields: fields{
+ name: "readyNotifyServer",
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"123345": {"dtc": nil, "dcm": nil}, "245689": {"dcm": nil}},
+ streamChannel: make(map[pb.ReadyNotify_AlertServer]chan int),
+ alertStrm: make(map[string]pb.ReadyNotify_AlertServer),
+ appContextId: make(map[string]string),
+ },
+ args: args{
+ topic: &pb.Topic{
+ ClientName: "dtc",
+ AppContext: "123345",
+ },
+ },
+ want: want{
+ alertNotify: map[string](map[string]pb.ReadyNotify_AlertServer){"123345": {"dcm": nil}, "245689": {"dcm": nil}},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+
+ t.Run(tt.name, func(t *testing.T) {
+ s := &readyNotifyServer{
+ name: tt.fields.name,
+ alertNotify: tt.fields.alertNotify,
+ streamChannel: tt.fields.streamChannel,
+ mutex: tt.fields.mutex,
+ }
+
+ go func() {
+ s.mutex.Lock()
+ s.streamChannel[nil] = make(chan int)
+ c := s.streamChannel[nil]
+ s.mutex.Unlock()
+ for {
+ time.Sleep(5 * time.Second)
+ select {
+ case <-c:
+ break
+ }
+ }
+ }()
+ time.Sleep(2 * time.Second)
+ _, err := s.Unsubscribe(tt.args.ctx, tt.args.topic)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("readyNotifyServer.Unsubscribe() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+
+ s.mutex.Lock()
+ got := s.alertNotify
+ s.mutex.Unlock()
+ if !reflect.DeepEqual(len(got), len(tt.want.alertNotify)) {
+ t.Errorf("readyNotifyServer.Unsubscribe() = %v, want %v", got, tt.want.alertNotify)
+ }
+
+ })
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package grpc\r
-\r
-import (\r
- "os"\r
- "strconv"\r
- "strings"\r
-\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
-)\r
-\r
-const default_host = "localhost"\r
-const default_port = 9031\r
-const default_rsync_name = "rsync"\r
-const ENV_RSYNC_NAME = "RSYNC_NAME"\r
-\r
-func GetServerHostPort() (string, int) {\r
-\r
- // expect name of this rsync program to be in env variable "RSYNC_NAME" - e.g. RSYNC_NAME="rsync"\r
- serviceName := os.Getenv(ENV_RSYNC_NAME)\r
- if serviceName == "" {\r
- serviceName = default_rsync_name\r
- log.Info("Using default name for RSYNC service name", log.Fields{\r
- "Name": serviceName,\r
- })\r
- }\r
-\r
- // expect service name to be in env variable - e.g. RSYNC_SERVICE_HOST\r
- host := os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_HOST")\r
- if host == "" {\r
- host = default_host\r
- log.Info("Using default host for rsync gRPC controller", log.Fields{\r
- "Host": host,\r
- })\r
- }\r
-\r
- // expect service port to be in env variable - e.g. RSYNC_SERVICE_PORT\r
- port, err := strconv.Atoi(os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_PORT"))\r
- if err != nil || port < 0 {\r
- port = default_port\r
- log.Info("Using default port for rsync gRPC controller", log.Fields{\r
- "Port": port,\r
- })\r
- }\r
- return host, port\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package grpc
+
+import (
+ "os"
+ "strconv"
+ "strings"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+)
+
+const default_host = "localhost"
+const default_port = 9031
+const default_rsync_name = "rsync"
+const ENV_RSYNC_NAME = "RSYNC_NAME"
+
+func GetServerHostPort() (string, int) {
+
+ // expect name of this rsync program to be in env variable "RSYNC_NAME" - e.g. RSYNC_NAME="rsync"
+ serviceName := os.Getenv(ENV_RSYNC_NAME)
+ if serviceName == "" {
+ serviceName = default_rsync_name
+ log.Info("Using default name for RSYNC service name", log.Fields{
+ "Name": serviceName,
+ })
+ }
+
+ // expect service name to be in env variable - e.g. RSYNC_SERVICE_HOST
+ host := os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_HOST")
+ if host == "" {
+ host = default_host
+ log.Info("Using default host for rsync gRPC controller", log.Fields{
+ "Host": host,
+ })
+ }
+
+ // expect service port to be in env variable - e.g. RSYNC_SERVICE_PORT
+ port, err := strconv.Atoi(os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_PORT"))
+ if err != nil || port < 0 {
+ port = default_port
+ log.Info("Using default port for rsync gRPC controller", log.Fields{
+ "Port": port,
+ })
+ }
+ return host, port
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package config\r
-\r
-import (\r
- "encoding/json"\r
- "log"\r
- "os"\r
- "reflect"\r
-)\r
-\r
-// Configuration loads up all the values that are used to configure\r
-// backend implementations\r
-type Configuration struct {\r
- CAFile string `json:"ca-file"`\r
- ServerCert string `json:"server-cert"`\r
- ServerKey string `json:"server-key"`\r
- Password string `json:"password"`\r
- DatabaseAddress string `json:"database-address"`\r
- DatabaseType string `json:"database-type"`\r
- PluginDir string `json:"plugin-dir"`\r
- EtcdIP string `json:"etcd-ip"`\r
- EtcdCert string `json:"etcd-cert"`\r
- EtcdKey string `json:"etcd-key"`\r
- EtcdCAFile string `json:"etcd-ca-file"`\r
- ServicePort string `json:"service-port"`\r
- KubernetesLabelName string `json:"kubernetes-label-name"`\r
-}\r
-\r
-// Config is the structure that stores the configuration\r
-var gConfig *Configuration\r
-\r
-// readConfigFile reads the specified smsConfig file to setup some env variables\r
-func readConfigFile(file string) (*Configuration, error) {\r
- f, err := os.Open(file)\r
- if err != nil {\r
- return defaultConfiguration(), err\r
- }\r
- defer f.Close()\r
-\r
- // Setup some defaults here\r
- // If the json file has values in it, the defaults will be overwritten\r
- conf := defaultConfiguration()\r
-\r
- // Read the configuration from json file\r
- decoder := json.NewDecoder(f)\r
- err = decoder.Decode(conf)\r
- if err != nil {\r
- return conf, err\r
- }\r
-\r
- return conf, nil\r
-}\r
-\r
-func defaultConfiguration() *Configuration {\r
- cwd, err := os.Getwd()\r
- if err != nil {\r
- log.Println("Error getting cwd. Using .")\r
- cwd = "."\r
- }\r
-\r
- return &Configuration{\r
- CAFile: "ca.cert",\r
- ServerCert: "server.cert",\r
- ServerKey: "server.key",\r
- Password: "",\r
- DatabaseAddress: "127.0.0.1",\r
- DatabaseType: "mongo",\r
- PluginDir: cwd,\r
- EtcdIP: "127.0.0.1",\r
- EtcdCert: "",\r
- EtcdKey: "",\r
- EtcdCAFile: "",\r
- ServicePort: "9015",\r
- KubernetesLabelName: "k8splugin.io/rb-instance-id",\r
- }\r
-}\r
-\r
-// GetConfiguration returns the configuration for the app.\r
-// It will try to load it if it is not already loaded.\r
-func GetConfiguration() *Configuration {\r
- if gConfig == nil {\r
- conf, err := readConfigFile("k8sconfig.json")\r
- if err != nil {\r
- log.Println("Error loading config file. Using defaults.")\r
- }\r
- gConfig = conf\r
- }\r
-\r
- return gConfig\r
-}\r
-\r
-// SetConfigValue sets a value in the configuration\r
-// This is mostly used to customize the application and\r
-// should be used carefully.\r
-func SetConfigValue(key string, value string) *Configuration {\r
- c := GetConfiguration()\r
- if value == "" || key == "" {\r
- return c\r
- }\r
-\r
- v := reflect.ValueOf(c).Elem()\r
- if v.Kind() == reflect.Struct {\r
- f := v.FieldByName(key)\r
- if f.IsValid() {\r
- if f.CanSet() {\r
- if f.Kind() == reflect.String {\r
- f.SetString(value)\r
- }\r
- }\r
- }\r
- }\r
- return c\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package config
+
+import (
+ "encoding/json"
+ "log"
+ "os"
+ "reflect"
+)
+
+// Configuration loads up all the values that are used to configure
+// backend implementations
+type Configuration struct {
+ CAFile string `json:"ca-file"`
+ ServerCert string `json:"server-cert"`
+ ServerKey string `json:"server-key"`
+ Password string `json:"password"`
+ DatabaseAddress string `json:"database-address"`
+ DatabaseType string `json:"database-type"`
+ PluginDir string `json:"plugin-dir"`
+ EtcdIP string `json:"etcd-ip"`
+ EtcdCert string `json:"etcd-cert"`
+ EtcdKey string `json:"etcd-key"`
+ EtcdCAFile string `json:"etcd-ca-file"`
+ ServicePort string `json:"service-port"`
+ KubernetesLabelName string `json:"kubernetes-label-name"`
+}
+
+// Config is the structure that stores the configuration
+var gConfig *Configuration
+
+// readConfigFile reads the specified smsConfig file to setup some env variables
+func readConfigFile(file string) (*Configuration, error) {
+ f, err := os.Open(file)
+ if err != nil {
+ return defaultConfiguration(), err
+ }
+ defer f.Close()
+
+ // Setup some defaults here
+ // If the json file has values in it, the defaults will be overwritten
+ conf := defaultConfiguration()
+
+ // Read the configuration from json file
+ decoder := json.NewDecoder(f)
+ err = decoder.Decode(conf)
+ if err != nil {
+ return conf, err
+ }
+
+ return conf, nil
+}
+
+func defaultConfiguration() *Configuration {
+ cwd, err := os.Getwd()
+ if err != nil {
+ log.Println("Error getting cwd. Using .")
+ cwd = "."
+ }
+
+ return &Configuration{
+ CAFile: "ca.cert",
+ ServerCert: "server.cert",
+ ServerKey: "server.key",
+ Password: "",
+ DatabaseAddress: "127.0.0.1",
+ DatabaseType: "mongo",
+ PluginDir: cwd,
+ EtcdIP: "127.0.0.1",
+ EtcdCert: "",
+ EtcdKey: "",
+ EtcdCAFile: "",
+ ServicePort: "9015",
+ KubernetesLabelName: "k8splugin.io/rb-instance-id",
+ }
+}
+
+// GetConfiguration returns the configuration for the app.
+// It will try to load it if it is not already loaded.
+func GetConfiguration() *Configuration {
+ if gConfig == nil {
+ conf, err := readConfigFile("k8sconfig.json")
+ if err != nil {
+ log.Println("Error loading config file. Using defaults.")
+ }
+ gConfig = conf
+ }
+
+ return gConfig
+}
+
+// SetConfigValue sets a value in the configuration
+// This is mostly used to customize the application and
+// should be used carefully.
+func SetConfigValue(key string, value string) *Configuration {
+ c := GetConfiguration()
+ if value == "" || key == "" {
+ return c
+ }
+
+ v := reflect.ValueOf(c).Elem()
+ if v.Kind() == reflect.Struct {
+ f := v.FieldByName(key)
+ if f.IsValid() {
+ if f.CanSet() {
+ if f.Kind() == reflect.String {
+ f.SetString(value)
+ }
+ }
+ }
+ }
+ return c
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package utils\r
-\r
-import (\r
- "io/ioutil"\r
- "log"\r
- "os"\r
- "path"\r
-\r
- corev1 "k8s.io/api/core/v1"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/client-go/kubernetes/scheme"\r
-)\r
-\r
-// DecodeYAMLFile reads a YAMl file to extract the Kubernetes object definition\r
-func DecodeYAMLFile(path string, into runtime.Object) (runtime.Object, error) {\r
- if _, err := os.Stat(path); err != nil {\r
- if os.IsNotExist(err) {\r
- return nil, pkgerrors.New("File " + path + " not found")\r
- } else {\r
- return nil, pkgerrors.Wrap(err, "Stat file error")\r
- }\r
- }\r
-\r
- rawBytes, err := ioutil.ReadFile(path)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read YAML file error")\r
- }\r
-\r
- decode := scheme.Codecs.UniversalDeserializer().Decode\r
- obj, _, err := decode(rawBytes, nil, into)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Deserialize YAML error")\r
- }\r
-\r
- return obj, nil\r
-}\r
-\r
-// DecodeYAMLData reads a string to extract the Kubernetes object definition\r
-func DecodeYAMLData(data string, into runtime.Object) (runtime.Object, error) {\r
- decode := scheme.Codecs.UniversalDeserializer().Decode\r
- obj, _, err := decode([]byte(data), nil, into)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Deserialize YAML error")\r
- }\r
-\r
- return obj, nil\r
-}\r
-\r
-//EnsureDirectory makes sure that the directories specified in the path exist\r
-//If not, it will create them, if possible.\r
-func EnsureDirectory(f string) error {\r
- base := path.Dir(f)\r
- _, err := os.Stat(base)\r
- if err != nil && !os.IsNotExist(err) {\r
- return err\r
- }\r
- return os.MkdirAll(base, 0700)\r
-}\r
-\r
-// TagPodsIfPresent finds the PodTemplateSpec from any workload\r
-// object that contains it and changes the spec to include the tag label\r
-func TagPodsIfPresent(unstruct *unstructured.Unstructured, tag string) {\r
-\r
- spec, ok := unstruct.Object["spec"].(map[string]interface{})\r
- if !ok {\r
- log.Println("Error converting spec to map")\r
- return\r
- }\r
-\r
- template, ok := spec["template"].(map[string]interface{})\r
- if !ok {\r
- //log.Println("Error converting template to map")\r
- return\r
- }\r
- log.Println("Apply label in template")\r
- //Attempt to convert the template to a podtemplatespec.\r
- //This is to check if we have any pods being created.\r
- podTemplateSpec := &corev1.PodTemplateSpec{}\r
- err := runtime.DefaultUnstructuredConverter.FromUnstructured(template, podTemplateSpec)\r
- if err != nil {\r
- log.Println("Did not find a podTemplateSpec: " + err.Error())\r
- return\r
- }\r
-\r
- labels := podTemplateSpec.GetLabels()\r
- if labels == nil {\r
- labels = map[string]string{}\r
- }\r
- labels["emco/deployment-id"] = tag\r
- podTemplateSpec.SetLabels(labels)\r
-\r
- updatedTemplate, err := runtime.DefaultUnstructuredConverter.ToUnstructured(podTemplateSpec)\r
-\r
- //Set the label\r
- spec["template"] = updatedTemplate\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package utils
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+
+ corev1 "k8s.io/api/core/v1"
+
+ pkgerrors "github.com/pkg/errors"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes/scheme"
+)
+
+// DecodeYAMLFile reads a YAMl file to extract the Kubernetes object definition
+func DecodeYAMLFile(path string, into runtime.Object) (runtime.Object, error) {
+ if _, err := os.Stat(path); err != nil {
+ if os.IsNotExist(err) {
+ return nil, pkgerrors.New("File " + path + " not found")
+ } else {
+ return nil, pkgerrors.Wrap(err, "Stat file error")
+ }
+ }
+
+ rawBytes, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read YAML file error")
+ }
+
+ decode := scheme.Codecs.UniversalDeserializer().Decode
+ obj, _, err := decode(rawBytes, nil, into)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Deserialize YAML error")
+ }
+
+ return obj, nil
+}
+
+// DecodeYAMLData reads a string to extract the Kubernetes object definition
+func DecodeYAMLData(data string, into runtime.Object) (runtime.Object, error) {
+ decode := scheme.Codecs.UniversalDeserializer().Decode
+ obj, _, err := decode([]byte(data), nil, into)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Deserialize YAML error")
+ }
+
+ return obj, nil
+}
+
+//EnsureDirectory makes sure that the directories specified in the path exist
+//If not, it will create them, if possible.
+func EnsureDirectory(f string) error {
+ base := path.Dir(f)
+ _, err := os.Stat(base)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ return os.MkdirAll(base, 0700)
+}
+
+// TagPodsIfPresent finds the PodTemplateSpec from any workload
+// object that contains it and changes the spec to include the tag label
+func TagPodsIfPresent(unstruct *unstructured.Unstructured, tag string) {
+
+ spec, ok := unstruct.Object["spec"].(map[string]interface{})
+ if !ok {
+ log.Println("Error converting spec to map")
+ return
+ }
+
+ template, ok := spec["template"].(map[string]interface{})
+ if !ok {
+ //log.Println("Error converting template to map")
+ return
+ }
+ log.Println("Apply label in template")
+ //Attempt to convert the template to a podtemplatespec.
+ //This is to check if we have any pods being created.
+ podTemplateSpec := &corev1.PodTemplateSpec{}
+ err := runtime.DefaultUnstructuredConverter.FromUnstructured(template, podTemplateSpec)
+ if err != nil {
+ log.Println("Did not find a podTemplateSpec: " + err.Error())
+ return
+ }
+
+ labels := podTemplateSpec.GetLabels()
+ if labels == nil {
+ labels = map[string]string{}
+ }
+ labels["emco/deployment-id"] = tag
+ podTemplateSpec.SetLabels(labels)
+
+ updatedTemplate, err := runtime.DefaultUnstructuredConverter.ToUnstructured(podTemplateSpec)
+
+ //Set the label
+ spec["template"] = updatedTemplate
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package status\r
-\r
-import (\r
- "encoding/json"\r
- "fmt"\r
- "strings"\r
- "sync"\r
-\r
- yaml "github.com/ghodss/yaml"\r
- pkgerrors "github.com/pkg/errors"\r
- "github.com/sirupsen/logrus"\r
-\r
- v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"\r
- clientset "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"\r
- informers "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions"\r
- appcontext "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"\r
- "github.com/open-ness/EMCO/src/rsync/pkg/connector"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- "k8s.io/client-go/tools/cache"\r
- "k8s.io/client-go/tools/clientcmd"\r
-)\r
-\r
-type channelManager struct {\r
- channels map[string]chan struct{}\r
- sync.Mutex\r
-}\r
-\r
-var channelData channelManager\r
-\r
-const monitorLabel = "emco/deployment-id"\r
-\r
-// HandleStatusUpdate for an application in a cluster\r
-func HandleStatusUpdate(clusterId string, id string, v *v1alpha1.ResourceBundleState) {\r
- // Get the contextId from the label (id)\r
- result := strings.SplitN(id, "-", 2)\r
- logrus.Info("::HandleStatusUpdate id::", id)\r
- logrus.Info("::HandleStatusUpdate result::", result)\r
- if result[0] == "" {\r
- logrus.Info(clusterId, "::label is missing an appcontext identifier::", id)\r
- return\r
- }\r
-\r
- if len(result) != 2 {\r
- logrus.Info(clusterId, "::invalid label format::", id)\r
- return\r
- }\r
-\r
- // Get the app from the label (id)\r
- if result[1] == "" {\r
- logrus.Info(clusterId, "::label is missing an app identifier::", id)\r
- return\r
- }\r
-\r
- // Look up the contextId\r
- var ac appcontext.AppContext\r
- _, err := ac.LoadAppContext(result[0])\r
- if err != nil {\r
- logrus.Info(clusterId, "::App context not found::", result[0], "::Error::", err)\r
- return\r
- }\r
-\r
- // produce yaml representation of the status\r
- vjson, err := json.Marshal(v.Status)\r
- if err != nil {\r
- logrus.Info(clusterId, "::Error marshalling status information::", err)\r
- return\r
- }\r
-\r
- chandle, err := ac.GetClusterHandle(result[1], clusterId)\r
- if err != nil {\r
- logrus.Info(clusterId, "::Error getting cluster handle::", err)\r
- return\r
- }\r
- // Get the handle for the context/app/cluster status object\r
- handle, _ := ac.GetLevelHandle(chandle, "status")\r
-\r
- // If status handle was not found, then create the status object in the appcontext\r
- if handle == nil {\r
- ac.AddLevelValue(chandle, "status", string(vjson))\r
- } else {\r
- ac.UpdateStatusValue(handle, string(vjson))\r
- }\r
-\r
- return\r
-}\r
-\r
-// StartClusterWatcher watches for CR\r
-// configBytes - Kubectl file data\r
-func StartClusterWatcher(clusterId string) error {\r
-\r
- // a cluster watcher always watches the cluster as a whole, so rsync's CloudConfig level\r
- // is 0 and namespace doesn't need to be specified because the result is non-ambiguous\r
- configBytes, err := connector.GetKubeConfig(clusterId, "0", "")\r
- if err != nil {\r
- return err\r
- }\r
-\r
- //key := provider + "+" + name\r
- // Get the lock\r
- channelData.Lock()\r
- defer channelData.Unlock()\r
- // For first time\r
- if channelData.channels == nil {\r
- channelData.channels = make(map[string]chan struct{})\r
- }\r
- _, ok := channelData.channels[clusterId]\r
- if !ok {\r
- // Create Channel\r
- channelData.channels[clusterId] = make(chan struct{})\r
- // Create config\r
- config, err := clientcmd.RESTConfigFromKubeConfig(configBytes)\r
- if err != nil {\r
- logrus.Info(fmt.Sprintf("RESTConfigFromKubeConfig error: %s", err.Error()))\r
- return pkgerrors.Wrap(err, "RESTConfigFromKubeConfig error")\r
- }\r
- k8sClient, err := clientset.NewForConfig(config)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Clientset NewForConfig error")\r
- }\r
- // Create Informer\r
- mInformerFactory := informers.NewSharedInformerFactory(k8sClient, 0)\r
- mInformer := mInformerFactory.K8splugin().V1alpha1().ResourceBundleStates().Informer()\r
- go scheduleStatus(clusterId, channelData.channels[clusterId], mInformer)\r
- }\r
- return nil\r
-}\r
-\r
-// StopClusterWatcher stop watching a cluster\r
-func StopClusterWatcher(clusterId string) {\r
- //key := provider + "+" + name\r
- if channelData.channels != nil {\r
- c, ok := channelData.channels[clusterId]\r
- if ok {\r
- close(c)\r
- }\r
- }\r
-}\r
-\r
-// CloseAllClusterWatchers close all channels\r
-func CloseAllClusterWatchers() {\r
- if channelData.channels == nil {\r
- return\r
- }\r
- // Close all Channels to stop all watchers\r
- for _, e := range channelData.channels {\r
- close(e)\r
- }\r
-}\r
-\r
-// Per Cluster Go routine to watch CR\r
-func scheduleStatus(clusterId string, c <-chan struct{}, s cache.SharedIndexInformer) {\r
- handlers := cache.ResourceEventHandlerFuncs{\r
- AddFunc: func(obj interface{}) {\r
- v, ok := obj.(*v1alpha1.ResourceBundleState)\r
- if ok {\r
- labels := v.GetLabels()\r
- l, ok := labels[monitorLabel]\r
- if ok {\r
- HandleStatusUpdate(clusterId, l, v)\r
- }\r
- }\r
- },\r
- UpdateFunc: func(oldObj, obj interface{}) {\r
- v, ok := obj.(*v1alpha1.ResourceBundleState)\r
- if ok {\r
- labels := v.GetLabels()\r
- l, ok := labels[monitorLabel]\r
- if ok {\r
- HandleStatusUpdate(clusterId, l, v)\r
- }\r
- }\r
- },\r
- DeleteFunc: func(obj interface{}) {\r
- // Ignore it\r
- },\r
- }\r
- s.AddEventHandler(handlers)\r
- s.Run(c)\r
-}\r
-\r
-// GetStatusCR returns a status monitoring customer resource\r
-func GetStatusCR(label string) ([]byte, error) {\r
-\r
- var statusCr v1alpha1.ResourceBundleState\r
-\r
- statusCr.TypeMeta.APIVersion = "k8splugin.io/v1alpha1"\r
- statusCr.TypeMeta.Kind = "ResourceBundleState"\r
- statusCr.SetName(label)\r
-\r
- labels := make(map[string]string)\r
- labels["emco/deployment-id"] = label\r
- statusCr.SetLabels(labels)\r
-\r
- labelSelector, err := metav1.ParseToLabelSelector("emco/deployment-id = " + label)\r
- if err != nil {\r
- return nil, err\r
- }\r
- statusCr.Spec.Selector = labelSelector\r
-\r
- // Marshaling to json then convert to yaml works better than marshaling to yaml\r
- // The 'apiVersion' attribute was marshaling to 'apiversion'\r
- j, err := json.Marshal(&statusCr)\r
- if err != nil {\r
- return nil, err\r
- }\r
- y, err := yaml.JSONToYAML(j)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- return y, nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package status
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+ "sync"
+
+ yaml "github.com/ghodss/yaml"
+ pkgerrors "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+
+ v1alpha1 "github.com/open-ness/EMCO/src/monitor/pkg/apis/k8splugin/v1alpha1"
+ clientset "github.com/open-ness/EMCO/src/monitor/pkg/generated/clientset/versioned"
+ informers "github.com/open-ness/EMCO/src/monitor/pkg/generated/informers/externalversions"
+ appcontext "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"
+ "github.com/open-ness/EMCO/src/rsync/pkg/connector"
+ "github.com/open-ness/EMCO/src/rsync/pkg/grpc/readynotifyserver"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/client-go/tools/clientcmd"
+)
+
+type channelManager struct {
+ channels map[string]chan struct{}
+ sync.Mutex
+}
+
+var channelData channelManager
+
+const monitorLabel = "emco/deployment-id"
+
+// HandleStatusUpdate for an application in a cluster
+func HandleStatusUpdate(clusterId string, id string, v *v1alpha1.ResourceBundleState) {
+ // Get the contextId from the label (id)
+ result := strings.SplitN(id, "-", 2)
+ logrus.Info("::HandleStatusUpdate id::", id)
+ logrus.Info("::HandleStatusUpdate result::", result)
+ if result[0] == "" {
+ logrus.Info(clusterId, "::label is missing an appcontext identifier::", id)
+ return
+ }
+
+ if len(result) != 2 {
+ logrus.Info(clusterId, "::invalid label format::", id)
+ return
+ }
+
+ // Get the app from the label (id)
+ if result[1] == "" {
+ logrus.Info(clusterId, "::label is missing an app identifier::", id)
+ return
+ }
+
+ // Look up the contextId
+ var ac appcontext.AppContext
+ _, err := ac.LoadAppContext(result[0])
+ if err != nil {
+ logrus.Info(clusterId, "::App context not found::", result[0], "::Error::", err)
+ return
+ }
+
+ // Produce yaml representation of the status
+ vjson, err := json.Marshal(v.Status)
+ if err != nil {
+ logrus.Info(clusterId, "::Error marshalling status information::", err)
+ return
+ }
+
+ chandle, err := ac.GetClusterHandle(result[1], clusterId)
+ if err != nil {
+ logrus.Info(clusterId, "::Error getting cluster handle::", err)
+ return
+ }
+ // Get the handle for the context/app/cluster status object
+ handle, _ := ac.GetLevelHandle(chandle, "status")
+
+ // If status handle was not found, then create the status object in the appcontext
+ if handle == nil {
+ ac.AddLevelValue(chandle, "status", string(vjson))
+ } else {
+ ac.UpdateStatusValue(handle, string(vjson))
+ }
+
+ // Send notification to the subscribers
+ err = readynotifyserver.SendAppContextNotification(result[0])
+ if err != nil {
+ logrus.Error(clusterId, "::Error sending ReadyNotify to subscribers::", err)
+ }
+}
+
+// StartClusterWatcher watches for CR
+// configBytes - Kubectl file data
+func StartClusterWatcher(clusterId string) error {
+
+ // a cluster watcher always watches the cluster as a whole, so rsync's CloudConfig level
+ // is 0 and namespace doesn't need to be specified because the result is non-ambiguous
+ configBytes, err := connector.GetKubeConfig(clusterId, "0", "")
+ if err != nil {
+ return err
+ }
+
+ //key := provider + "+" + name
+ // Get the lock
+ channelData.Lock()
+ defer channelData.Unlock()
+ // For first time
+ if channelData.channels == nil {
+ channelData.channels = make(map[string]chan struct{})
+ }
+ _, ok := channelData.channels[clusterId]
+ if !ok {
+ // Create Channel
+ channelData.channels[clusterId] = make(chan struct{})
+ // Create config
+ config, err := clientcmd.RESTConfigFromKubeConfig(configBytes)
+ if err != nil {
+ logrus.Info(fmt.Sprintf("RESTConfigFromKubeConfig error: %s", err.Error()))
+ return pkgerrors.Wrap(err, "RESTConfigFromKubeConfig error")
+ }
+ k8sClient, err := clientset.NewForConfig(config)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Clientset NewForConfig error")
+ }
+ // Create Informer
+ mInformerFactory := informers.NewSharedInformerFactory(k8sClient, 0)
+ mInformer := mInformerFactory.K8splugin().V1alpha1().ResourceBundleStates().Informer()
+ go scheduleStatus(clusterId, channelData.channels[clusterId], mInformer)
+ }
+ return nil
+}
+
+// StopClusterWatcher stop watching a cluster
+func StopClusterWatcher(clusterId string) {
+ //key := provider + "+" + name
+ if channelData.channels != nil {
+ c, ok := channelData.channels[clusterId]
+ if ok {
+ close(c)
+ }
+ }
+}
+
+// CloseAllClusterWatchers close all channels
+func CloseAllClusterWatchers() {
+ if channelData.channels == nil {
+ return
+ }
+ // Close all Channels to stop all watchers
+ for _, e := range channelData.channels {
+ close(e)
+ }
+}
+
+// Per Cluster Go routine to watch CR
+func scheduleStatus(clusterId string, c <-chan struct{}, s cache.SharedIndexInformer) {
+ handlers := cache.ResourceEventHandlerFuncs{
+ AddFunc: func(obj interface{}) {
+ v, ok := obj.(*v1alpha1.ResourceBundleState)
+ if ok {
+ labels := v.GetLabels()
+ l, ok := labels[monitorLabel]
+ if ok {
+ HandleStatusUpdate(clusterId, l, v)
+ }
+ }
+ },
+ UpdateFunc: func(oldObj, obj interface{}) {
+ v, ok := obj.(*v1alpha1.ResourceBundleState)
+ if ok {
+ labels := v.GetLabels()
+ l, ok := labels[monitorLabel]
+ if ok {
+ HandleStatusUpdate(clusterId, l, v)
+ }
+ }
+ },
+ DeleteFunc: func(obj interface{}) {
+ // Ignore it
+ },
+ }
+ s.AddEventHandler(handlers)
+ s.Run(c)
+}
+
+// GetStatusCR returns a status monitoring customer resource
+func GetStatusCR(label string) ([]byte, error) {
+
+ var statusCr v1alpha1.ResourceBundleState
+
+ statusCr.TypeMeta.APIVersion = "k8splugin.io/v1alpha1"
+ statusCr.TypeMeta.Kind = "ResourceBundleState"
+ statusCr.SetName(label)
+
+ labels := make(map[string]string)
+ labels["emco/deployment-id"] = label
+ statusCr.SetLabels(labels)
+
+ labelSelector, err := metav1.ParseToLabelSelector("emco/deployment-id = " + label)
+ if err != nil {
+ return nil, err
+ }
+ statusCr.Spec.Selector = labelSelector
+
+ // Marshaling to json then convert to yaml works better than marshaling to yaml
+ // The 'apiVersion' attribute was marshaling to 'apiversion'
+ j, err := json.Marshal(&statusCr)
+ if err != nil {
+ return nil, err
+ }
+ y, err := yaml.JSONToYAML(j)
+ if err != nil {
+ return nil, err
+ }
+
+ return y, nil
+}
-/*\r
-Copyright 2020 Intel Corporation.\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-\r
-package api\r
-\r
-import (\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
- "github.com/gorilla/mux"\r
-)\r
-\r
-// NewRouter creates a router that registers the various urls that are\r
-// supported\r
-\r
-func createHandlerMapping(\r
- objectClient manager.ControllerObjectManager,\r
- router *mux.Router,\r
- collections string,\r
- resource string ) {\r
- objectHandler := ControllerHandler{client: objectClient}\r
- if objectClient.IsOperationSupported("POST") == true {\r
- router.HandleFunc(\r
- "/" + collections,\r
- objectHandler.createHandler).Methods("POST")\r
- }\r
-\r
- if objectClient.IsOperationSupported("GETS") == true {\r
- router.HandleFunc(\r
- "/" + collections,\r
- objectHandler.getsHandler).Methods("GET")\r
- }\r
-\r
- if objectClient.IsOperationSupported("GET") == true {\r
- router.HandleFunc(\r
- "/" + collections + "/{" + resource + "}",\r
- objectHandler.getHandler).Methods("GET")\r
- }\r
-\r
- if objectClient.IsOperationSupported("DELETE") == true {\r
- router.HandleFunc(\r
- "/" + collections + "/{" + resource + "}",\r
- objectHandler.deleteHandler).Methods("DELETE")\r
- }\r
-\r
- if objectClient.IsOperationSupported("PUT") == true {\r
- router.HandleFunc(\r
- "/" + collections + "/{" + resource + "}",\r
- objectHandler.updateHandler).Methods("PUT")\r
- }\r
-}\r
-\r
-func NewRouter(\r
- overlayObjectClient manager.ControllerObjectManager,\r
- proposalObjectClient manager.ControllerObjectManager,\r
- hubObjectClient manager.ControllerObjectManager,\r
- hubConnObjectClient manager.ControllerObjectManager,\r
- hubDeviceObjectClient manager.ControllerObjectManager,\r
- deviceObjectClient manager.ControllerObjectManager,\r
- deviceConnObjectClient manager.ControllerObjectManager,\r
- ipRangeObjectClient manager.ControllerObjectManager,\r
- certificateObjectClient manager.ControllerObjectManager) *mux.Router {\r
-\r
- router := mux.NewRouter()\r
- ver := "v1"\r
- mgrset := manager.GetManagerset()\r
-\r
- // router\r
- verRouter := router.PathPrefix("/scc/" + ver).Subrouter()\r
- olRouter := verRouter.PathPrefix("/" + manager.OverlayCollection + "/{" + manager.OverlayResource + "}").Subrouter()\r
- hubRouter := olRouter.PathPrefix("/" + manager.HubCollection + "/{" + manager.HubResource + "}").Subrouter()\r
- devRouter := olRouter.PathPrefix("/" + manager.DeviceCollection + "/{" + manager.DeviceResource + "}").Subrouter()\r
-\r
- // overlay API\r
- if overlayObjectClient == nil {\r
- overlayObjectClient = manager.NewOverlayObjectManager()\r
- }\r
- mgrset.Overlay = overlayObjectClient.(*manager.OverlayObjectManager)\r
- createHandlerMapping(overlayObjectClient, verRouter, manager.OverlayCollection, manager.OverlayResource)\r
-\r
- // proposal API\r
- if proposalObjectClient == nil {\r
- proposalObjectClient = manager.NewProposalObjectManager()\r
- }\r
- mgrset.Proposal = proposalObjectClient.(*manager.ProposalObjectManager)\r
- createHandlerMapping(proposalObjectClient, olRouter, manager.ProposalCollection, manager.ProposalResource)\r
-\r
- // hub API\r
- if hubObjectClient == nil {\r
- hubObjectClient = manager.NewHubObjectManager()\r
- }\r
- mgrset.Hub = hubObjectClient.(*manager.HubObjectManager)\r
- createHandlerMapping(hubObjectClient, olRouter, manager.HubCollection, manager.HubResource)\r
-\r
- // hub-connection API\r
- if hubConnObjectClient == nil {\r
- hubConnObjectClient = manager.NewHubConnObjectManager()\r
- }\r
- mgrset.HubConn = hubConnObjectClient.(*manager.HubConnObjectManager)\r
- createHandlerMapping(hubConnObjectClient, hubRouter, manager.ConnectionCollection, manager.ConnectionResource)\r
-\r
- // hub-device API\r
- if hubDeviceObjectClient == nil {\r
- hubDeviceObjectClient = manager.NewHubDeviceObjectManager()\r
- }\r
- mgrset.HubDevice = hubDeviceObjectClient.(*manager.HubDeviceObjectManager)\r
- createHandlerMapping(hubDeviceObjectClient, hubRouter, manager.DeviceCollection, manager.DeviceResource)\r
-\r
- // device API\r
- if deviceObjectClient == nil {\r
- deviceObjectClient = manager.NewDeviceObjectManager()\r
- }\r
- mgrset.Device = deviceObjectClient.(*manager.DeviceObjectManager)\r
- createHandlerMapping(deviceObjectClient, olRouter, manager.DeviceCollection, manager.DeviceResource)\r
-\r
- // device-connection API\r
- if deviceConnObjectClient == nil {\r
- deviceConnObjectClient = manager.NewDeviceConnObjectManager()\r
- }\r
- mgrset.DeviceConn = deviceConnObjectClient.(*manager.DeviceConnObjectManager)\r
- createHandlerMapping(deviceConnObjectClient, devRouter, manager.ConnectionCollection, manager.ConnectionResource)\r
-\r
- // iprange API\r
- if ipRangeObjectClient == nil {\r
- ipRangeObjectClient = manager.NewIPRangeObjectManager()\r
- }\r
- mgrset.IPRange = ipRangeObjectClient.(*manager.IPRangeObjectManager)\r
- createHandlerMapping(ipRangeObjectClient, olRouter, manager.IPRangeCollection, manager.IPRangeResource)\r
-\r
- // certificate API\r
- if certificateObjectClient == nil {\r
- certificateObjectClient = manager.NewCertificateObjectManager()\r
- }\r
- mgrset.Cert = certificateObjectClient.(*manager.CertificateObjectManager)\r
- createHandlerMapping(certificateObjectClient, olRouter, manager.CertCollection, manager.CertResource)\r
-\r
- // Add depedency\r
- overlayObjectClient.AddOwnResManager(proposalObjectClient)\r
- overlayObjectClient.AddOwnResManager(hubObjectClient)\r
- overlayObjectClient.AddOwnResManager(deviceObjectClient)\r
- overlayObjectClient.AddOwnResManager(ipRangeObjectClient)\r
- overlayObjectClient.AddOwnResManager(certificateObjectClient)\r
- hubObjectClient.AddOwnResManager(hubDeviceObjectClient)\r
-\r
- proposalObjectClient.AddDepResManager(overlayObjectClient)\r
- hubObjectClient.AddDepResManager(overlayObjectClient)\r
- deviceObjectClient.AddDepResManager(overlayObjectClient)\r
- ipRangeObjectClient.AddDepResManager(overlayObjectClient)\r
- certificateObjectClient.AddDepResManager(overlayObjectClient)\r
- hubDeviceObjectClient.AddDepResManager(hubObjectClient)\r
- hubConnObjectClient.AddDepResManager(hubObjectClient)\r
- deviceConnObjectClient.AddDepResManager(deviceObjectClient)\r
-\r
- return router\r
-}\r
+/*
+Copyright 2020 Intel Corporation.
+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 api
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/gorilla/mux"
+)
+
+// NewRouter creates a router that registers the various urls that are
+// supported
+
+func createHandlerMapping(
+ objectClient manager.ControllerObjectManager,
+ router *mux.Router,
+ collections string,
+ resource string) {
+ objectHandler := ControllerHandler{client: objectClient}
+ if objectClient.IsOperationSupported("POST") == true {
+ router.HandleFunc(
+ "/"+collections,
+ objectHandler.createHandler).Methods("POST")
+ }
+
+ if objectClient.IsOperationSupported("GETS") == true {
+ router.HandleFunc(
+ "/"+collections,
+ objectHandler.getsHandler).Methods("GET")
+ }
+
+ if objectClient.IsOperationSupported("GET") == true {
+ router.HandleFunc(
+ "/"+collections+"/{"+resource+"}",
+ objectHandler.getHandler).Methods("GET")
+ }
+
+ if objectClient.IsOperationSupported("DELETE") == true {
+ router.HandleFunc(
+ "/"+collections+"/{"+resource+"}",
+ objectHandler.deleteHandler).Methods("DELETE")
+ }
+
+ if objectClient.IsOperationSupported("PUT") == true {
+ router.HandleFunc(
+ "/"+collections+"/{"+resource+"}",
+ objectHandler.updateHandler).Methods("PUT")
+ }
+}
+
+func NewRouter(
+ overlayObjectClient manager.ControllerObjectManager,
+ proposalObjectClient manager.ControllerObjectManager,
+ hubObjectClient manager.ControllerObjectManager,
+ hubConnObjectClient manager.ControllerObjectManager,
+ hubDeviceObjectClient manager.ControllerObjectManager,
+ hubCNFObjectClient manager.ControllerObjectManager,
+ deviceObjectClient manager.ControllerObjectManager,
+ deviceConnObjectClient manager.ControllerObjectManager,
+ deviceCNFObjectClient manager.ControllerObjectManager,
+ ipRangeObjectClient manager.ControllerObjectManager,
+ providerIpRangeObjectClient manager.ControllerObjectManager,
+ certificateObjectClient manager.ControllerObjectManager) *mux.Router {
+
+ router := mux.NewRouter()
+ ver := "v1"
+ mgrset := manager.GetManagerset()
+
+ // router
+ verRouter := router.PathPrefix("/scc/" + ver).Subrouter()
+ providerRouter := router.PathPrefix("/scc/" + ver + "/provider").Subrouter()
+ olRouter := verRouter.PathPrefix("/" + manager.OverlayCollection + "/{" + manager.OverlayResource + "}").Subrouter()
+ hubRouter := olRouter.PathPrefix("/" + manager.HubCollection + "/{" + manager.HubResource + "}").Subrouter()
+ devRouter := olRouter.PathPrefix("/" + manager.DeviceCollection + "/{" + manager.DeviceResource + "}").Subrouter()
+
+ // overlay API
+ if overlayObjectClient == nil {
+ overlayObjectClient = manager.NewOverlayObjectManager()
+ }
+ mgrset.Overlay = overlayObjectClient.(*manager.OverlayObjectManager)
+ createHandlerMapping(overlayObjectClient, verRouter, manager.OverlayCollection, manager.OverlayResource)
+
+ // proposal API
+ if proposalObjectClient == nil {
+ proposalObjectClient = manager.NewProposalObjectManager()
+ }
+ mgrset.Proposal = proposalObjectClient.(*manager.ProposalObjectManager)
+ createHandlerMapping(proposalObjectClient, olRouter, manager.ProposalCollection, manager.ProposalResource)
+
+ // hub API
+ if hubObjectClient == nil {
+ hubObjectClient = manager.NewHubObjectManager()
+ }
+ mgrset.Hub = hubObjectClient.(*manager.HubObjectManager)
+ createHandlerMapping(hubObjectClient, olRouter, manager.HubCollection, manager.HubResource)
+
+ // hub-connection API
+ if hubConnObjectClient == nil {
+ hubConnObjectClient = manager.NewHubConnObjectManager()
+ }
+ mgrset.HubConn = hubConnObjectClient.(*manager.HubConnObjectManager)
+ createHandlerMapping(hubConnObjectClient, hubRouter, manager.ConnectionCollection, manager.ConnectionResource)
+
+ // hub-cnf API
+ if hubCNFObjectClient == nil {
+ hubCNFObjectClient = manager.NewCNFObjectManager(true)
+ }
+ mgrset.HubCNF = hubCNFObjectClient.(*manager.CNFObjectManager)
+ createHandlerMapping(hubCNFObjectClient, hubRouter, manager.CNFCollection, manager.CNFResource)
+
+ // hub-device API
+ if hubDeviceObjectClient == nil {
+ hubDeviceObjectClient = manager.NewHubDeviceObjectManager()
+ }
+ mgrset.HubDevice = hubDeviceObjectClient.(*manager.HubDeviceObjectManager)
+ createHandlerMapping(hubDeviceObjectClient, hubRouter, manager.DeviceCollection, manager.DeviceResource)
+
+ // device API
+ if deviceObjectClient == nil {
+ deviceObjectClient = manager.NewDeviceObjectManager()
+ }
+ mgrset.Device = deviceObjectClient.(*manager.DeviceObjectManager)
+ createHandlerMapping(deviceObjectClient, olRouter, manager.DeviceCollection, manager.DeviceResource)
+
+ // device-connection API
+ if deviceConnObjectClient == nil {
+ deviceConnObjectClient = manager.NewDeviceConnObjectManager()
+ }
+ mgrset.DeviceConn = deviceConnObjectClient.(*manager.DeviceConnObjectManager)
+ createHandlerMapping(deviceConnObjectClient, devRouter, manager.ConnectionCollection, manager.ConnectionResource)
+
+ // device-cnf API
+ if deviceCNFObjectClient == nil {
+ deviceCNFObjectClient = manager.NewCNFObjectManager(false)
+ }
+ mgrset.DeviceCNF = deviceCNFObjectClient.(*manager.CNFObjectManager)
+ createHandlerMapping(deviceCNFObjectClient, devRouter, manager.CNFCollection, manager.CNFResource)
+
+ // provider iprange API
+ if providerIpRangeObjectClient == nil {
+ providerIpRangeObjectClient = manager.NewIPRangeObjectManager(true)
+ }
+ mgrset.ProviderIPRange = providerIpRangeObjectClient.(*manager.IPRangeObjectManager)
+ createHandlerMapping(providerIpRangeObjectClient, providerRouter, manager.IPRangeCollection, manager.IPRangeResource)
+
+ // iprange API
+ if ipRangeObjectClient == nil {
+ ipRangeObjectClient = manager.NewIPRangeObjectManager(false)
+ }
+ mgrset.IPRange = ipRangeObjectClient.(*manager.IPRangeObjectManager)
+ createHandlerMapping(ipRangeObjectClient, olRouter, manager.IPRangeCollection, manager.IPRangeResource)
+
+ // certificate API
+ if certificateObjectClient == nil {
+ certificateObjectClient = manager.NewCertificateObjectManager()
+ }
+ mgrset.Cert = certificateObjectClient.(*manager.CertificateObjectManager)
+ createHandlerMapping(certificateObjectClient, olRouter, manager.CertCollection, manager.CertResource)
+
+ // Add depedency
+ overlayObjectClient.AddOwnResManager(proposalObjectClient)
+ overlayObjectClient.AddOwnResManager(hubObjectClient)
+ overlayObjectClient.AddOwnResManager(deviceObjectClient)
+ overlayObjectClient.AddOwnResManager(ipRangeObjectClient)
+ overlayObjectClient.AddOwnResManager(certificateObjectClient)
+ hubObjectClient.AddOwnResManager(hubDeviceObjectClient)
+ deviceObjectClient.AddOwnResManager(hubDeviceObjectClient)
+
+ proposalObjectClient.AddDepResManager(overlayObjectClient)
+ hubObjectClient.AddDepResManager(overlayObjectClient)
+ deviceObjectClient.AddDepResManager(overlayObjectClient)
+ ipRangeObjectClient.AddDepResManager(overlayObjectClient)
+ certificateObjectClient.AddDepResManager(overlayObjectClient)
+ hubDeviceObjectClient.AddDepResManager(hubObjectClient)
+ hubDeviceObjectClient.AddDepResManager(deviceObjectClient)
+ hubConnObjectClient.AddDepResManager(hubObjectClient)
+ deviceConnObjectClient.AddDepResManager(deviceObjectClient)
+ hubCNFObjectClient.AddDepResManager(hubObjectClient)
+ deviceCNFObjectClient.AddDepResManager(deviceObjectClient)
+
+ return router
+}
-/*\r
-* Copyright 2020 Intel Corporation, Inc\r
-*\r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
-* you may not use this file except in compliance with the License.\r
-* You may obtain a copy of the License at\r
-*\r
-* http://www.apache.org/licenses/LICENSE-2.0\r
-*\r
-* Unless required by applicable law or agreed to in writing, software\r
-* distributed under the License is distributed on an "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
-* implied.\r
-* See the License for the specific language governing permissions\r
-* and\r
-* limitations under the License.\r
-*/\r
-\r
-package api\r
-\r
-import (\r
- "encoding/json"\r
- "net/http"\r
- "io"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation"\r
- "github.com/gorilla/mux"\r
-)\r
-\r
-\r
-// ControllerHandler is used to store backend implementations objects\r
-type ControllerHandler struct {\r
- client manager.ControllerObjectManager\r
-}\r
-\r
-// CreateHandler handles creation of the Controller Object entry in the database\r
-func (h ControllerHandler) createHandler(w http.ResponseWriter, r *http.Request) {\r
- var ret interface{}\r
- var err error\r
- var v module.ControllerObject\r
-\r
- vars := mux.Vars(r)\r
-\r
- v, err = h.client.ParseObject(r.Body)\r
- switch {\r
- case err == io.EOF:\r
- http.Error(w, "Empty body", http.StatusBadRequest)\r
- return\r
- case err != nil:\r
- http.Error(w, err.Error(), http.StatusUnprocessableEntity)\r
- return\r
- }\r
-\r
- validate := validation.GetValidator(h.client.GetStoreMeta())\r
- isValid, msg := validate.Validate(v)\r
- if isValid == false {\r
- http.Error(w, msg, http.StatusUnprocessableEntity)\r
- return\r
- }\r
-\r
- // Check resource depedency\r
- err = manager.GetDBUtils().CheckDep(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- // Check whether the resource is available\r
- if h.client.IsOperationSupported("GET") {\r
- vars[h.client.GetResourceName()] = v.GetMetadata().Name\r
- ret, err = h.client.GetObject(vars)\r
- if err == nil {\r
- http.Error(w, "Resource " + v.GetMetadata().Name + " is available already", http.StatusConflict)\r
- return\r
- }\r
- }\r
-\r
- ret, err = h.client.CreateObject(vars, v)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- w.Header().Set("Content-Type", "application/json")\r
- w.WriteHeader(http.StatusCreated)\r
- err = json.NewEncoder(w).Encode(ret)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-}\r
-\r
-// getsHandler handle GET All operations\r
-func (h ControllerHandler) getsHandler(w http.ResponseWriter, r *http.Request) {\r
- var err error\r
- vars := mux.Vars(r)\r
-\r
- // Check resource depedency\r
- err = manager.GetDBUtils().CheckDep(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- ret, err := h.client.GetObjects(vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- w.Header().Set("Content-Type", "application/json")\r
- w.WriteHeader(http.StatusOK)\r
- err = json.NewEncoder(w).Encode(ret)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-}\r
-\r
-// getHandler handle GET operations on a particular name\r
-func (h ControllerHandler) getHandler(w http.ResponseWriter, r *http.Request) {\r
- var err error\r
- vars := mux.Vars(r)\r
-\r
- // Check resource depedency\r
- err = manager.GetDBUtils().CheckDep(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- ret, err := h.client.GetObject(vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- w.Header().Set("Content-Type", "application/json")\r
- w.WriteHeader(http.StatusOK)\r
- err = json.NewEncoder(w).Encode(ret)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-}\r
-\r
-// UpdateHandler handles Update operations\r
-func (h ControllerHandler) updateHandler(w http.ResponseWriter, r *http.Request) {\r
- var ret interface{}\r
- var err error\r
- var v module.ControllerObject\r
-\r
- vars := mux.Vars(r)\r
-\r
- v, err = h.client.ParseObject(r.Body)\r
- switch {\r
- case err == io.EOF:\r
- http.Error(w, "Empty body", http.StatusBadRequest)\r
- return\r
- case err != nil:\r
- http.Error(w, err.Error(), http.StatusUnprocessableEntity)\r
- return\r
- }\r
-\r
- validate := validation.GetValidator(h.client.GetStoreName())\r
- isValid, msg := validate.Validate(v)\r
- if isValid == false {\r
- http.Error(w, msg, http.StatusUnprocessableEntity)\r
- return\r
- }\r
-\r
- // Check resource depedency\r
- err = manager.GetDBUtils().CheckDep(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- ret, err = h.client.UpdateObject(vars, v)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- w.Header().Set("Content-Type", "application/json")\r
- w.WriteHeader(http.StatusOK)\r
- err = json.NewEncoder(w).Encode(ret)\r
- if err != nil {\r
- http.Error(w, err.Error(),\r
- http.StatusInternalServerError)\r
- return\r
- }\r
-}\r
-\r
-//deleteHandler handles DELETE operations on a particular record\r
-func (h ControllerHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {\r
- var err error\r
- vars := mux.Vars(r)\r
-\r
- // Check resource depedency\r
- err = manager.GetDBUtils().CheckDep(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- // Check whether sub-resource available\r
- err = manager.GetDBUtils().CheckOwn(h.client, vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
-\r
- err = h.client.DeleteObject(vars)\r
- if err != nil {\r
- http.Error(w, err.Error(), http.StatusInternalServerError)\r
- return\r
- }\r
-\r
- w.WriteHeader(http.StatusNoContent)\r
-}\r
+/*
+* Copyright 2020 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* 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 api
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/gorilla/mux"
+ "io"
+ "net/http"
+)
+
+// ControllerHandler is used to store backend implementations objects
+type ControllerHandler struct {
+ client manager.ControllerObjectManager
+}
+
+// CreateHandler handles creation of the Controller Object entry in the database
+func (h ControllerHandler) createHandler(w http.ResponseWriter, r *http.Request) {
+ var ret interface{}
+ var err error
+ var v module.ControllerObject
+
+ vars := mux.Vars(r)
+
+ v, err = h.client.ParseObject(r.Body)
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ validate := validation.GetValidator(h.client.GetStoreMeta())
+ isValid, msg := validate.Validate(v)
+ if isValid == false {
+ http.Error(w, msg, http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Check resource depedency
+ err = manager.GetDBUtils().CheckDep(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // Check whether the resource is available
+ if h.client.IsOperationSupported("GET") {
+ vars[h.client.GetResourceName()] = v.GetMetadata().Name
+ ret, err = h.client.GetObject(vars)
+ if err == nil {
+ http.Error(w, "Resource "+v.GetMetadata().Name+" is available already", http.StatusConflict)
+ return
+ }
+ }
+
+ ret, err = h.client.CreateObject(vars, v)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// getsHandler handle GET All operations
+func (h ControllerHandler) getsHandler(w http.ResponseWriter, r *http.Request) {
+ var err error
+ vars := mux.Vars(r)
+
+ // Check resource depedency
+ err = manager.GetDBUtils().CheckDep(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ ret, err := h.client.GetObjects(vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// getHandler handle GET operations on a particular name
+func (h ControllerHandler) getHandler(w http.ResponseWriter, r *http.Request) {
+ var err error
+ vars := mux.Vars(r)
+
+ // Check resource depedency
+ err = manager.GetDBUtils().CheckDep(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ ret, err := h.client.GetObject(vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// UpdateHandler handles Update operations
+func (h ControllerHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
+ var ret interface{}
+ var err error
+ var v module.ControllerObject
+
+ vars := mux.Vars(r)
+
+ v, err = h.client.ParseObject(r.Body)
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ validate := validation.GetValidator(h.client.GetStoreName())
+ isValid, msg := validate.Validate(v)
+ if isValid == false {
+ http.Error(w, msg, http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Check resource depedency
+ err = manager.GetDBUtils().CheckDep(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ ret, err = h.client.UpdateObject(vars, v)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(),
+ http.StatusInternalServerError)
+ return
+ }
+}
+
+//deleteHandler handles DELETE operations on a particular record
+func (h ControllerHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
+ var err error
+ vars := mux.Vars(r)
+
+ // Check resource depedency
+ err = manager.GetDBUtils().CheckDep(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // Check whether sub-resource available
+ err = manager.GetDBUtils().CheckOwn(h.client, vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ err = h.client.DeleteObject(vars)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusNoContent)
+}
-/*\r
-Copyright 2020 Intel Corporation.\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
-limitations under the License.\r
-*/\r
-\r
-package main\r
-\r
-import (\r
- "context"\r
- "log"\r
- "math/rand"\r
- "net/http"\r
- "os"\r
- "os/signal"\r
- "time"\r
- "strconv"\r
-\r
- logs "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/api"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/auth"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
- contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"\r
- controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller"\r
- "github.com/gorilla/handlers"\r
- mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"\r
-\r
- rconfig "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/config"\r
-)\r
-\r
-const default_rsync_name = "rsync"\r
-const ENV_RSYNC_NAME = "RSYNC_NAME"\r
-\r
-func main() {\r
-\r
- rand.Seed(time.Now().UnixNano())\r
-\r
- // create database and context database\r
- err := db.InitializeDatabaseConnection("scc")\r
- if err != nil {\r
- log.Println("Unable to initialize database connection...")\r
- log.Println(err)\r
- log.Fatalln("Exiting...")\r
- }\r
-\r
- err = contextDb.InitializeContextDatabase()\r
- if err != nil {\r
- log.Println("Unable to initialize database connection...")\r
- log.Println(err)\r
- log.Fatalln("Exiting...")\r
- }\r
-\r
- // create sdewan namespace and root certificate\r
- cu, err := manager.GetCertUtil()\r
- if err == nil {\r
- _, err = cu.CreateNamespace(manager.NameSpaceName)\r
- if err == nil {\r
- log.Println("Namespace is available : " + manager.NameSpaceName)\r
- _, err = cu.CreateSelfSignedIssuer(manager.RootIssuerName, manager.NameSpaceName)\r
- if err == nil {\r
- log.Println("SDEWAN root issuer is available : " + manager.RootIssuerName)\r
- _, err = cu.CreateCertificate(manager.RootCertName, manager.NameSpaceName, manager.RootIssuerName, true)\r
- if err == nil {\r
- log.Println("SDEWAN root certificate is available : " + manager.RootCertName)\r
- _, err = cu.CreateCAIssuer(manager.RootCAIssuerName, manager.NameSpaceName, manager.RootCertName)\r
- if err == nil {\r
- log.Println("SDEWAN root ca issuer is available : " + manager.RootCAIssuerName)\r
- }\r
- _, err = cu.CreateCertificate(manager.SCCCertName, manager.NameSpaceName, manager.RootCAIssuerName, false)\r
- if err == nil {\r
- log.Println("SDEWAN central controller base certificates is available : " + manager.SCCCertName)\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- if err != nil {\r
- log.Println(err)\r
- }\r
-\r
- //Register rsync client\r
- serviceName := os.Getenv(ENV_RSYNC_NAME)\r
- if serviceName == "" {\r
- serviceName = default_rsync_name\r
- logs.Info("Using default name for rsync service name", logs.Fields{\r
- "Name": serviceName,\r
- })\r
- }\r
-\r
- client := controller.NewControllerClient()\r
-\r
- // Create or update the controller entry\r
- rsync_port, _ := strconv.Atoi(rconfig.GetConfiguration().RsyncPort)\r
- controller := controller.Controller{\r
- Metadata: mtypes.Metadata{\r
- Name: serviceName,\r
- },\r
- Spec: controller.ControllerSpec{\r
- Host: rconfig.GetConfiguration().RsyncIP,\r
- Port: rsync_port,\r
- Type: controller.CONTROLLER_TYPE_ACTION,\r
- Priority: controller.MinControllerPriority,\r
- },\r
- }\r
- _, err = client.CreateController(controller, true)\r
- if err != nil {\r
- logs.Error("Failed to create/update a gRPC controller", logs.Fields{\r
- "Error": err,\r
- "Controller": serviceName,\r
- })\r
- }\r
-\r
- // create http server\r
- httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil)\r
- loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter)\r
- log.Println("Starting SDEWAN Central Controller API")\r
-\r
- httpServer := &http.Server{\r
- Handler: loggedRouter,\r
- Addr: ":" + config.GetConfiguration().ServicePort,\r
- }\r
-\r
- connectionsClose := make(chan struct{})\r
- go func() {\r
- c := make(chan os.Signal, 1)\r
- signal.Notify(c, os.Interrupt)\r
- <-c\r
- httpServer.Shutdown(context.Background())\r
- close(connectionsClose)\r
- }()\r
-\r
- tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key")\r
- if err != nil {\r
- log.Println("Error Getting TLS Configuration. Starting without TLS...")\r
- log.Fatal(httpServer.ListenAndServe())\r
- } else {\r
- httpServer.TLSConfig = tlsConfig\r
-\r
- err = httpServer.ListenAndServeTLS("", "")\r
- }\r
-\r
-}\r
+/*
+Copyright 2020 Intel Corporation.
+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 (
+ "context"
+ "log"
+ "math/rand"
+ "net/http"
+ "os"
+ "os/signal"
+ "strconv"
+ "time"
+
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/api"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/gorilla/handlers"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/auth"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ logs "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller"
+ mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"
+
+ rconfig "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/config"
+)
+
+const default_rsync_name = "rsync"
+const ENV_RSYNC_NAME = "RSYNC_NAME"
+
+func main() {
+
+ rand.Seed(time.Now().UnixNano())
+
+ // create database and context database
+ err := db.InitializeDatabaseConnection("scc")
+ if err != nil {
+ log.Println("Unable to initialize database connection...")
+ log.Println(err)
+ log.Fatalln("Exiting...")
+ }
+
+ err = contextDb.InitializeContextDatabase()
+ if err != nil {
+ log.Println("Unable to initialize database connection...")
+ log.Println(err)
+ log.Fatalln("Exiting...")
+ }
+
+ // create sdewan namespace and root certificate
+ cu, err := manager.GetCertUtil()
+ if err == nil {
+ _, err = cu.CreateNamespace(manager.NameSpaceName)
+ if err == nil {
+ log.Println("Namespace is available : " + manager.NameSpaceName)
+ _, err = cu.CreateSelfSignedIssuer(manager.RootIssuerName, manager.NameSpaceName)
+ if err == nil {
+ log.Println("SDEWAN root issuer is available : " + manager.RootIssuerName)
+ _, err = cu.CreateCertificate(manager.RootCertName, manager.NameSpaceName, manager.RootIssuerName, true)
+ if err == nil {
+ log.Println("SDEWAN root certificate is available : " + manager.RootCertName)
+ _, err = cu.CreateCAIssuer(manager.RootCAIssuerName, manager.NameSpaceName, manager.RootCertName)
+ if err == nil {
+ log.Println("SDEWAN root ca issuer is available : " + manager.RootCAIssuerName)
+ }
+ _, err = cu.CreateCertificate(manager.SCCCertName, manager.NameSpaceName, manager.RootCAIssuerName, false)
+ if err == nil {
+ log.Println("SDEWAN central controller base certificates is available : " + manager.SCCCertName)
+ }
+ }
+ }
+ }
+ }
+
+ if err != nil {
+ log.Println(err)
+ }
+
+ //Register rsync client
+ serviceName := os.Getenv(ENV_RSYNC_NAME)
+ if serviceName == "" {
+ serviceName = default_rsync_name
+ logs.Info("Using default name for rsync service name", logs.Fields{
+ "Name": serviceName,
+ })
+ }
+
+ client := controller.NewControllerClient()
+
+ // Create or update the controller entry
+ rsync_port, _ := strconv.Atoi(rconfig.GetConfiguration().RsyncPort)
+ controller := controller.Controller{
+ Metadata: mtypes.Metadata{
+ Name: serviceName,
+ },
+ Spec: controller.ControllerSpec{
+ Host: rconfig.GetConfiguration().RsyncIP,
+ Port: rsync_port,
+ Type: controller.CONTROLLER_TYPE_ACTION,
+ Priority: controller.MinControllerPriority,
+ },
+ }
+ _, err = client.CreateController(controller, true)
+ if err != nil {
+ logs.Error("Failed to create/update a gRPC controller", logs.Fields{
+ "Error": err,
+ "Controller": serviceName,
+ })
+ }
+
+ // create http server
+ httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
+ loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter)
+ log.Println("Starting SDEWAN Central Controller API")
+
+ httpServer := &http.Server{
+ Handler: loggedRouter,
+ Addr: ":" + config.GetConfiguration().ServicePort,
+ }
+
+ connectionsClose := make(chan struct{})
+ go func() {
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt)
+ <-c
+ httpServer.Shutdown(context.Background())
+ close(connectionsClose)
+ }()
+
+ tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key")
+ if err != nil {
+ log.Println("Error Getting TLS Configuration. Starting without TLS...")
+ log.Fatal(httpServer.ListenAndServe())
+ } else {
+ httpServer.TLSConfig = tlsConfig
+
+ err = httpServer.ListenAndServeTLS("", "")
+ }
+
+}
require (
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect
- github.com/go-playground/validator/v10 v10.4.1 // indirect
- github.com/gorilla/mux v1.7.2 // indirect
- github.com/jetstack/cert-manager v1.2.0 // indirect
- github.com/matryer/runner v0.0.0-20190427160343-b472a46105b1 // indirect
+ github.com/go-playground/validator/v10 v10.4.1
+ github.com/gorilla/mux v1.7.2
+ github.com/jetstack/cert-manager v1.2.0
+ github.com/matryer/runner v0.0.0-20190427160343-b472a46105b1
github.com/open-ness/EMCO/src/orchestrator v0.0.0-00010101000000-000000000000
- github.com/open-ness/EMCO/src/rsync v0.0.0-00010101000000-000000000000 // indirect
- github.com/pkg/errors v0.9.1 // indirect
+ github.com/open-ness/EMCO/src/rsync v0.0.0-00010101000000-000000000000
+ github.com/pkg/errors v0.9.1
go.etcd.io/etcd v3.3.12+incompatible
google.golang.org/grpc v1.28.0
- k8s.io/api v0.19.4 // indirect
- k8s.io/apimachinery v0.19.4 // indirect
+ k8s.io/api v0.20.2
+ k8s.io/apimachinery v0.20.2
k8s.io/client-go v12.0.0+incompatible
- sigs.k8s.io/yaml v1.2.0 // indirect
+ sigs.k8s.io/yaml v1.2.0
)
replace (
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
+k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E=
k8s.io/kubectl v0.19.0/go.mod h1:gPCjjsmE6unJzgaUNXIFGZGafiUp5jh0If3F/x7/rRg=
k8s.io/kubernetes v1.14.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-// Based on Code: https://github.com/johandry/klient\r
-\r
-package client\r
-\r
-import (\r
- "log"\r
- "k8s.io/client-go/rest"\r
- "k8s.io/client-go/tools/clientcmd"\r
- "k8s.io/apimachinery/pkg/runtime/schema"\r
- "k8s.io/client-go/kubernetes/scheme"\r
- "k8s.io/client-go/kubernetes"\r
- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"\r
- certmanagerversioned "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"\r
- certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1"\r
-)\r
-\r
-type KubernetesClient struct {\r
- Context string\r
- ConfigPath string\r
- KubeConfig []byte\r
-}\r
-\r
-func NewClient(context string, configPath string, kubeConfig []byte) *KubernetesClient {\r
- return &KubernetesClient{\r
- Context: context,\r
- ConfigPath: configPath,\r
- KubeConfig: kubeConfig,\r
- }\r
-}\r
-\r
-func (c *KubernetesClient) ToRESTConfig() (*rest.Config, error) {\r
- var config *rest.Config\r
- var err error\r
- if len(c.KubeConfig) == 0 {\r
- // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults()\r
- config, err = c.toRawKubeConfigLoader().ClientConfig()\r
- } else {\r
- config, err = clientcmd.RESTConfigFromKubeConfig(c.KubeConfig)\r
- }\r
-\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- if config.GroupVersion == nil {\r
- config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}\r
- }\r
- if config.APIPath == "" {\r
- config.APIPath = "/api"\r
- }\r
- if config.NegotiatedSerializer == nil {\r
- // This codec config ensures the resources are not converted. Therefore, resources\r
- // will not be round-tripped through internal versions. Defaulting does not happen\r
- // on the client.\r
- config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()\r
- }\r
-\r
- rest.SetKubernetesDefaults(config)\r
- return config, nil\r
-}\r
-\r
-// toRawKubeConfigLoader creates a client using the following rules:\r
-// 1. builds from the given kubeconfig path, if not empty\r
-// 2. use the in cluster factory if running in-cluster\r
-// 3. gets the factory from KUBECONFIG env var\r
-// 4. Uses $HOME/.kube/factory\r
-// It's required to implement the interface genericclioptions.RESTClientGetter\r
-func (c *KubernetesClient) toRawKubeConfigLoader() clientcmd.ClientConfig {\r
- loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()\r
- loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig\r
- if len(c.ConfigPath) != 0 {\r
- loadingRules.ExplicitPath = c.ConfigPath\r
- }\r
- configOverrides := &clientcmd.ConfigOverrides{\r
- ClusterDefaults: clientcmd.ClusterDefaults,\r
- }\r
- if len(c.Context) != 0 {\r
- configOverrides.CurrentContext = c.Context\r
- }\r
-\r
- return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)\r
-}\r
-\r
-func (c *KubernetesClient) GetCMClients() (certmanagerv1beta1.CertmanagerV1beta1Interface, corev1.CoreV1Interface, error) {\r
- config, err := c.ToRESTConfig()\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- cmclientset, err := certmanagerversioned.NewForConfig(config)\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- k8sclientset, err := kubernetes.NewForConfig(config)\r
- if err != nil {\r
- return nil, nil, err\r
- }\r
-\r
- return cmclientset.CertmanagerV1beta1(), k8sclientset.CoreV1(), nil\r
-}\r
-\r
-func (c *KubernetesClient) KubernetesClientSet() (*kubernetes.Clientset, error) {\r
- config, err := c.ToRESTConfig()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- return kubernetes.NewForConfig(config)\r
-}\r
-\r
-func (c *KubernetesClient) IsReachable() bool {\r
- clientset, err := c.KubernetesClientSet()\r
- if err != nil {\r
- log.Println(err)\r
- return false\r
- }\r
-\r
- _, err = clientset.ServerVersion()\r
- if err != nil {\r
- log.Println(err)\r
- return false\r
- }\r
-\r
- return true\r
-}\r
-\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+// Based on Code: https://github.com/johandry/klient
+
+package client
+
+import (
+ certmanagerversioned "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
+ certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/kubernetes/scheme"
+ corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/tools/clientcmd"
+ "log"
+)
+
+type KubernetesClient struct {
+ Context string
+ ConfigPath string
+ KubeConfig []byte
+}
+
+func NewClient(context string, configPath string, kubeConfig []byte) *KubernetesClient {
+ return &KubernetesClient{
+ Context: context,
+ ConfigPath: configPath,
+ KubeConfig: kubeConfig,
+ }
+}
+
+func (c *KubernetesClient) ToRESTConfig() (*rest.Config, error) {
+ var config *rest.Config
+ var err error
+ if len(c.KubeConfig) == 0 {
+ // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults()
+ config, err = c.toRawKubeConfigLoader().ClientConfig()
+ } else {
+ config, err = clientcmd.RESTConfigFromKubeConfig(c.KubeConfig)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if config.GroupVersion == nil {
+ config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}
+ }
+ if config.APIPath == "" {
+ config.APIPath = "/api"
+ }
+ if config.NegotiatedSerializer == nil {
+ // This codec config ensures the resources are not converted. Therefore, resources
+ // will not be round-tripped through internal versions. Defaulting does not happen
+ // on the client.
+ config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
+ }
+
+ rest.SetKubernetesDefaults(config)
+ return config, nil
+}
+
+// toRawKubeConfigLoader creates a client using the following rules:
+// 1. builds from the given kubeconfig path, if not empty
+// 2. use the in cluster factory if running in-cluster
+// 3. gets the factory from KUBECONFIG env var
+// 4. Uses $HOME/.kube/factory
+// It's required to implement the interface genericclioptions.RESTClientGetter
+func (c *KubernetesClient) toRawKubeConfigLoader() clientcmd.ClientConfig {
+ loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
+ loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig
+ if len(c.ConfigPath) != 0 {
+ loadingRules.ExplicitPath = c.ConfigPath
+ }
+ configOverrides := &clientcmd.ConfigOverrides{
+ ClusterDefaults: clientcmd.ClusterDefaults,
+ }
+ if len(c.Context) != 0 {
+ configOverrides.CurrentContext = c.Context
+ }
+
+ return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
+}
+
+func (c *KubernetesClient) GetCMClients() (certmanagerv1beta1.CertmanagerV1beta1Interface, corev1.CoreV1Interface, error) {
+ config, err := c.ToRESTConfig()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ cmclientset, err := certmanagerversioned.NewForConfig(config)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ k8sclientset, err := kubernetes.NewForConfig(config)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return cmclientset.CertmanagerV1beta1(), k8sclientset.CoreV1(), nil
+}
+
+func (c *KubernetesClient) KubernetesClientSet() (*kubernetes.Clientset, error) {
+ config, err := c.ToRESTConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ return kubernetes.NewForConfig(config)
+}
+
+func (c *KubernetesClient) IsReachable() bool {
+ clientset, err := c.KubernetesClientSet()
+ if err != nil {
+ log.Println(err)
+ return false
+ }
+
+ _, err = clientset.ServerVersion()
+ if err != nil {
+ log.Println(err)
+ return false
+ }
+
+ return true
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2021 Intel Corporation
+
+package client
+
+import (
+ "context"
+ "sync"
+ "time"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
+ installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const rsyncName = "rsync"
+
+/*
+RsyncInfo consists of rsyncName, hostName and portNumber.
+*/
+type RsyncInfo struct {
+ RsyncName string
+ hostName string
+ portNumber int
+}
+
+var rsyncInfo RsyncInfo
+var mutex = &sync.Mutex{}
+
+type _testvars struct {
+ UseGrpcMock bool
+ InstallClient installpb.InstallappClient
+}
+
+var Testvars _testvars
+
+// InitRsyncClient initializes connctions to the Resource Synchronizer service
+func initRsyncClient() bool {
+ if (RsyncInfo{}) == rsyncInfo {
+ mutex.Lock()
+ defer mutex.Unlock()
+ log.Error("RsyncInfo not set. InitRsyncClient failed", log.Fields{
+ "Rsyncname": rsyncInfo.RsyncName,
+ "Hostname": rsyncInfo.hostName,
+ "PortNumber": rsyncInfo.portNumber,
+ })
+ return false
+ }
+ rpc.UpdateRpcConn(rsyncInfo.RsyncName, rsyncInfo.hostName, rsyncInfo.portNumber)
+ return true
+}
+
+// NewRsyncInfo shall return a newly created RsyncInfo object
+func NewRsyncInfo(rName, h string, pN int) RsyncInfo {
+ mutex.Lock()
+ defer mutex.Unlock()
+ rsyncInfo = RsyncInfo{RsyncName: rName, hostName: h, portNumber: pN}
+ return rsyncInfo
+
+}
+
+// InvokeInstallApp will make the grpc call to the resource synchronizer
+// or rsync controller.
+// rsync will deploy the resources in the app context to the clusters as
+// prepared in the app context.
+func InvokeInstallApp(appContextId string) error {
+ var err error
+ var rpcClient installpb.InstallappClient
+ var installRes *installpb.InstallAppResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second)
+ defer cancel()
+
+ // Unit test helper code
+ if Testvars.UseGrpcMock {
+ rpcClient = Testvars.InstallClient
+ installReq := new(installpb.InstallAppRequest)
+ installReq.AppContext = appContextId
+ installRes, err = rpcClient.InstallApp(ctx, installReq)
+ if err == nil {
+ log.Info("Response from InstappApp GRPC call", log.Fields{
+ "Succeeded": installRes.AppContextInstalled,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ }
+ return nil
+ }
+
+ conn := rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ initRsyncClient()
+ conn = rpc.GetRpcConn(rsyncName)
+ }
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ installReq := new(installpb.InstallAppRequest)
+ installReq.AppContext = appContextId
+ installRes, err = rpcClient.InstallApp(ctx, installReq)
+ if err == nil {
+ log.Info("Response from InstappApp GRPC call", log.Fields{
+ "Succeeded": installRes.AppContextInstalled,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", "rsync")
+ }
+
+ if err == nil {
+ if installRes.AppContextInstalled {
+ log.Info("InstallApp Success", log.Fields{
+ "AppContext": appContextId,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ return nil
+ } else {
+ return pkgerrors.Errorf("InstallApp Failed: %v", installRes.AppContextInstallMessage)
+ }
+ }
+ return err
+}
+
+func InvokeUninstallApp(appContextId string) error {
+ var err error
+ var rpcClient installpb.InstallappClient
+ var uninstallRes *installpb.UninstallAppResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ conn := rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ initRsyncClient()
+ conn = rpc.GetRpcConn(rsyncName)
+ }
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ uninstallReq := new(installpb.UninstallAppRequest)
+ uninstallReq.AppContext = appContextId
+ uninstallRes, err = rpcClient.UninstallApp(ctx, uninstallReq)
+ if err == nil {
+ log.Info("Response from UninstappApp GRPC call", log.Fields{
+ "Succeeded": uninstallRes.AppContextUninstalled,
+ "Message": uninstallRes.AppContextUninstallMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("UninstallApp Failed - Could not get InstallAppClient: %v", "rsync")
+ }
+
+ if err == nil {
+ if uninstallRes.AppContextUninstalled {
+ log.Info("UninstallApp Success", log.Fields{
+ "AppContext": appContextId,
+ "Message": uninstallRes.AppContextUninstallMessage,
+ })
+ return nil
+ } else {
+ return pkgerrors.Errorf("UninstallApp Failed: %v", uninstallRes.AppContextUninstallMessage)
+ }
+ }
+ return err
+}
+
+func InvokeGetResource(appContextId string) error {
+ var err error
+ var rpcClient installpb.InstallappClient
+ var readAppContextRes *installpb.ReadAppContextResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ conn := rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ initRsyncClient()
+ conn = rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ log.Error("[InvokeReadRq gRPC] connection error", log.Fields{"grpc-server": rsyncName})
+ return pkgerrors.Errorf("[InvokeReadRq gRPC] connection error. grpc-server[%v]", rsyncName)
+ }
+ }
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ readReq := new(installpb.ReadAppContextRequest)
+ readReq.AppContext = appContextId
+ readAppContextRes, err = rpcClient.ReadAppContext(ctx, readReq)
+ if err == nil {
+ log.Info("Response from ReadAppContext GRPC call", log.Fields{
+ "Succeeded": readAppContextRes.AppContextReadSuccessful,
+ "Message": readAppContextRes.AppContextReadMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("ReadAppContext Failed - Could not get ReadAppContext: %v", "rsync")
+ }
+
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package config\r
-\r
-import (\r
- "encoding/json"\r
- "log"\r
- "os"\r
- "reflect"\r
-)\r
-\r
-// Configuration loads up all the values that are used to configure\r
-// backend implementations\r
-type Configuration struct {\r
- RsyncIP string `json:"rsync-ip"`\r
- RsyncPort string `json:"rsync-port"`\r
-}\r
-\r
-// Config is the structure that stores the configuration\r
-var gConfig *Configuration\r
-\r
-// readConfigFile reads the specified smsConfig file to setup some env variables\r
-func readConfigFile(file string) (*Configuration, error) {\r
- f, err := os.Open(file)\r
- if err != nil {\r
- return defaultConfiguration(), err\r
- }\r
- defer f.Close()\r
-\r
- // Setup some defaults here\r
- // If the json file has values in it, the defaults will be overwritten\r
- conf := defaultConfiguration()\r
-\r
- // Read the configuration from json file\r
- decoder := json.NewDecoder(f)\r
- decoder.DisallowUnknownFields()\r
- err = decoder.Decode(conf)\r
- if err != nil {\r
- return conf, err\r
- }\r
-\r
- return conf, nil\r
-}\r
-\r
-func defaultConfiguration() *Configuration {\r
- return &Configuration{\r
- RsyncIP: "localhost",\r
- RsyncPort: "9031",\r
- }\r
-}\r
-\r
-// GetConfiguration returns the configuration for the app.\r
-// It will try to load it if it is not already loaded.\r
-func GetConfiguration() *Configuration {\r
- if gConfig == nil {\r
- conf, err := readConfigFile("rsync_config.json")\r
- if err != nil {\r
- log.Println("Error loading config file: ", err)\r
- log.Println("Using defaults...")\r
- }\r
- gConfig = conf\r
- }\r
-\r
- return gConfig\r
-}\r
-\r
-// SetConfigValue sets a value in the configuration\r
-// This is mostly used to customize the application and\r
-// should be used carefully.\r
-func SetConfigValue(key string, value string) *Configuration {\r
- c := GetConfiguration()\r
- if value == "" || key == "" {\r
- return c\r
- }\r
-\r
- v := reflect.ValueOf(c).Elem()\r
- if v.Kind() == reflect.Struct {\r
- f := v.FieldByName(key)\r
- if f.IsValid() {\r
- if f.CanSet() {\r
- if f.Kind() == reflect.String {\r
- f.SetString(value)\r
- }\r
- }\r
- }\r
- }\r
- return c\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 config
+
+import (
+ "encoding/json"
+ "log"
+ "os"
+ "reflect"
+)
+
+// Configuration loads up all the values that are used to configure
+// backend implementations
+type Configuration struct {
+ RsyncIP string `json:"rsync-ip"`
+ RsyncPort string `json:"rsync-port"`
+}
+
+// Config is the structure that stores the configuration
+var gConfig *Configuration
+
+// readConfigFile reads the specified smsConfig file to setup some env variables
+func readConfigFile(file string) (*Configuration, error) {
+ f, err := os.Open(file)
+ if err != nil {
+ return defaultConfiguration(), err
+ }
+ defer f.Close()
+
+ // Setup some defaults here
+ // If the json file has values in it, the defaults will be overwritten
+ conf := defaultConfiguration()
+
+ // Read the configuration from json file
+ decoder := json.NewDecoder(f)
+ decoder.DisallowUnknownFields()
+ err = decoder.Decode(conf)
+ if err != nil {
+ return conf, err
+ }
+
+ return conf, nil
+}
+
+func defaultConfiguration() *Configuration {
+ return &Configuration{
+ RsyncIP: "localhost",
+ RsyncPort: "9031",
+ }
+}
+
+// GetConfiguration returns the configuration for the app.
+// It will try to load it if it is not already loaded.
+func GetConfiguration() *Configuration {
+ if gConfig == nil {
+ conf, err := readConfigFile("rsync_config.json")
+ if err != nil {
+ log.Println("Error loading config file: ", err)
+ log.Println("Using defaults...")
+ }
+ gConfig = conf
+ }
+
+ return gConfig
+}
+
+// SetConfigValue sets a value in the configuration
+// This is mostly used to customize the application and
+// should be used carefully.
+func SetConfigValue(key string, value string) *Configuration {
+ c := GetConfiguration()
+ if value == "" || key == "" {
+ return c
+ }
+
+ v := reflect.ValueOf(c).Elem()
+ if v.Kind() == reflect.Struct {
+ f := v.FieldByName(key)
+ if f.IsValid() {
+ if f.CanSet() {
+ if f.Kind() == reflect.String {
+ f.SetString(value)
+ }
+ }
+ }
+ }
+ return c
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package validation\r
-\r
-import (\r
- "reflect"\r
- "fmt"\r
- "sync"\r
- "github.com/go-playground/validator/v10"\r
-)\r
-\r
-type SdewanValidator struct {\r
- validate *validator.Validate\r
-}\r
-\r
-type safeSdewanValidators struct {\r
- validates map[string]*SdewanValidator\r
- mux sync.Mutex\r
-}\r
-\r
-var gvalidates = safeSdewanValidators{validates: make(map[string]*SdewanValidator)}\r
-\r
-func GetValidator(name string) *SdewanValidator {\r
- return gvalidates.getValidate(name)\r
-}\r
-\r
-// safeSdewanValidators\r
-func (s *safeSdewanValidators) getValidate(name string) *SdewanValidator {\r
- s.mux.Lock()\r
- defer s.mux.Unlock()\r
-\r
- if s.validates[name] == nil {\r
- s.validates[name] = &SdewanValidator{\r
- validate: validator.New(),\r
- }\r
- }\r
-\r
- return s.validates[name]\r
-}\r
-\r
-// SdewanValidator\r
-func(v *SdewanValidator) Validate(data interface{}) (bool, string) {\r
- err := v.validate.Struct(data)\r
- if err != nil {\r
- if _, ok := err.(*validator.InvalidValidationError); ok {\r
- return false, reflect.TypeOf(err).String()\r
- }\r
-\r
- msg := "Input fields check error: ["\r
- index := 1\r
- for _, err := range err.(validator.ValidationErrors) {\r
- fieldMsg := fmt.Sprintf("%s(%s:%s)", err.Field(), err.Tag(), err.Param())\r
- if index == 1 {\r
- msg = msg + fieldMsg\r
- } else {\r
- msg = msg + ", " + fieldMsg\r
- }\r
-\r
- index = index + 1\r
- }\r
-\r
- msg = msg +"]"\r
-\r
- // from here you can create your own error messages in whatever language you wish\r
- return false, msg\r
- }\r
-\r
- return true, ""\r
-}\r
-\r
-func(v *SdewanValidator) RegisterValidation(tag string, fn validator.Func) error {\r
- return v.validate.RegisterValidation(tag, fn)\r
-}\r
-\r
-func(v *SdewanValidator) RegisterStructValidation(fn validator.StructLevelFunc, types interface{}) {\r
- v.validate.RegisterStructValidation(fn, types)\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 validation
+
+import (
+ "fmt"
+ "github.com/go-playground/validator/v10"
+ "reflect"
+ "sync"
+)
+
+type SdewanValidator struct {
+ validate *validator.Validate
+}
+
+type safeSdewanValidators struct {
+ validates map[string]*SdewanValidator
+ mux sync.Mutex
+}
+
+var gvalidates = safeSdewanValidators{validates: make(map[string]*SdewanValidator)}
+
+func GetValidator(name string) *SdewanValidator {
+ return gvalidates.getValidate(name)
+}
+
+// safeSdewanValidators
+func (s *safeSdewanValidators) getValidate(name string) *SdewanValidator {
+ s.mux.Lock()
+ defer s.mux.Unlock()
+
+ if s.validates[name] == nil {
+ s.validates[name] = &SdewanValidator{
+ validate: validator.New(),
+ }
+ }
+
+ return s.validates[name]
+}
+
+// SdewanValidator
+func (v *SdewanValidator) Validate(data interface{}) (bool, string) {
+ err := v.validate.Struct(data)
+ if err != nil {
+ if _, ok := err.(*validator.InvalidValidationError); ok {
+ return false, reflect.TypeOf(err).String()
+ }
+
+ msg := "Input fields check error: ["
+ index := 1
+ for _, err := range err.(validator.ValidationErrors) {
+ fieldMsg := fmt.Sprintf("%s(%s:%s)", err.Field(), err.Tag(), err.Param())
+ if index == 1 {
+ msg = msg + fieldMsg
+ } else {
+ msg = msg + ", " + fieldMsg
+ }
+
+ index = index + 1
+ }
+
+ msg = msg + "]"
+
+ // from here you can create your own error messages in whatever language you wish
+ return false, msg
+ }
+
+ return true, ""
+}
+
+func (v *SdewanValidator) RegisterValidation(tag string, fn validator.Func) error {
+ return v.validate.RegisterValidation(tag, fn)
+}
+
+func (v *SdewanValidator) RegisterStructValidation(fn validator.StructLevelFunc, types interface{}) {
+ v.validate.RegisterStructValidation(fn, types)
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "log"\r
- "encoding/base64"\r
- "encoding/json"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type CertificateObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- CertificateName string `json:"certificate-name"`\r
-}\r
-\r
-// IPRangeObjectManager implements the ControllerObjectManager\r
-type CertificateObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewCertificateObjectManager() *CertificateObjectManager {\r
- return &CertificateObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "certificate",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *CertificateObjectManager) GetResourceName() string {\r
- return CertResource\r
-}\r
-\r
-func (c *CertificateObjectManager) IsOperationSupported(oper string) bool {\r
- if oper == "PUT" {\r
- // Not allowed for gets\r
- return false\r
- }\r
- return true\r
-}\r
-\r
-func (c *CertificateObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.CertificateObject{}\r
-}\r
-\r
-func (c *CertificateObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- key := CertificateObjectKey{\r
- OverlayName: overlay_name,\r
- CertificateName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.CertificateObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[CertResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- }\r
-\r
- key.CertificateName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name")\r
- }\r
-\r
- key.CertificateName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *CertificateObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.CertificateObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- v.Data = module.CertificateObjectData{\r
- RootCA: "",\r
- Ca: "",\r
- Key: "",\r
- }\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *CertificateObjectManager) GetDeviceCertName(name string) string {\r
- device := module.DeviceObject{\r
- Metadata: module.ObjectMetaData{name, "", "", ""}}\r
- return device.GetCertName()\r
-}\r
-\r
-func GetRootCA(overlay_name string) string {\r
- overlay := GetManagerset().Overlay\r
- cu, _ := GetCertUtil()\r
-\r
- root_ca := cu.GetSelfSignedCA()\r
- interim_ca, _, _ := overlay.GetCertificate(overlay_name)\r
-\r
- root_ca += interim_ca\r
-\r
- return root_ca\r
-}\r
-\r
-func GetRootBaseCA() string {\r
- cu, _ := GetCertUtil()\r
-\r
- root_ca := cu.GetSelfSignedCA()\r
-\r
- return root_ca\r
-}\r
-\r
-\r
-func (c *CertificateObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // Create Certificate\r
- overlay := GetManagerset().Overlay\r
- overlay_name := m[OverlayResource]\r
- cert_name := c.GetDeviceCertName(t.GetMetadata().Name)\r
-\r
- ca, key, err := overlay.CreateCertificate(overlay_name, cert_name)\r
- if err != nil {\r
- log.Println(err)\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
- // DB Operation\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
-\r
- // Fill Certificate data\r
- if err == nil {\r
- to := t.(*module.CertificateObject)\r
- to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name)))\r
- to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca))\r
- to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key))\r
-\r
- return t, nil\r
- } else {\r
- log.Println(err)\r
- return c.CreateEmptyObject(), err\r
- }\r
-}\r
-\r
-func (c *CertificateObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- if err == nil {\r
- overlay := GetManagerset().Overlay\r
- overlay_name := m[OverlayResource]\r
- cert_name := c.GetDeviceCertName(t.GetMetadata().Name)\r
-\r
- ca, key, err := overlay.CreateCertificate(overlay_name, cert_name)\r
- if err != nil {\r
- log.Println(err)\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
- to := t.(*module.CertificateObject)\r
- to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name)))\r
- to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca))\r
- to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key))\r
-\r
- return t, nil\r
- } else {\r
- log.Println(err)\r
- return c.CreateEmptyObject(), err\r
- }\r
-}\r
-\r
-func (c *CertificateObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *CertificateObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *CertificateObjectManager) DeleteObject(m map[string]string) error {\r
- t, err := c.GetObject(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Certificate is not available")\r
- }\r
-\r
- // Delete certificate\r
- overlay := GetManagerset().Overlay\r
- cert_name := c.GetDeviceCertName(t.GetMetadata().Name)\r
-\r
- log.Println("Delete Certificate: " + cert_name)\r
- overlay.DeleteCertificate(cert_name)\r
-\r
- // DB Operation\r
- err = GetDBUtils().DeleteObject(c, m)\r
-\r
- return err\r
-}\r
-\r
-// Create or Get certificate for a device\r
-func (c *CertificateObjectManager) GetOrCreateDC(overlay_name string, dev_name string) (string, string, string, error) {\r
- m := make(map[string]string)\r
- m[OverlayResource] = overlay_name\r
- t := &module.CertificateObject{Metadata: module.ObjectMetaData{dev_name, "", "", ""}}\r
-\r
- _, err := c.CreateObject(m, t)\r
- if err != nil {\r
- return "", "", "", err\r
- }\r
-\r
- return t.Data.RootCA, t.Data.Ca, t.Data.Key, nil\r
-}\r
-\r
-// Delete certificate for a device\r
-func (c *CertificateObjectManager) DeleteDC(overlay_name string, dev_name string) error {\r
- m := make(map[string]string)\r
- m[OverlayResource] = overlay_name\r
- m[CertResource] = dev_name\r
-\r
- return c.DeleteObject(m)\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+ "log"
+)
+
+type CertificateObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ CertificateName string `json:"certificate-name"`
+}
+
+// IPRangeObjectManager implements the ControllerObjectManager
+type CertificateObjectManager struct {
+ BaseObjectManager
+}
+
+func NewCertificateObjectManager() *CertificateObjectManager {
+ return &CertificateObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "certificate",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *CertificateObjectManager) GetResourceName() string {
+ return CertResource
+}
+
+func (c *CertificateObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "PUT" {
+ // Not allowed for gets
+ return false
+ }
+ return true
+}
+
+func (c *CertificateObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.CertificateObject{}
+}
+
+func (c *CertificateObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ key := CertificateObjectKey{
+ OverlayName: overlay_name,
+ CertificateName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.CertificateObject)
+ meta_name := to.Metadata.Name
+ res_name := m[CertResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.CertificateName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.CertificateName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *CertificateObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.CertificateObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ v.Data = module.CertificateObjectData{
+ RootCA: "",
+ Ca: "",
+ Key: "",
+ }
+
+ return &v, err
+}
+
+func (c *CertificateObjectManager) GetDeviceCertName(name string) string {
+ device := module.DeviceObject{
+ Metadata: module.ObjectMetaData{name, "", "", ""}}
+ return device.GetCertName()
+}
+
+func GetRootCA(overlay_name string) string {
+ overlay := GetManagerset().Overlay
+ cu, _ := GetCertUtil()
+
+ root_ca := cu.GetSelfSignedCA()
+ interim_ca, _, _ := overlay.GetCertificate(overlay_name)
+
+ root_ca += interim_ca
+
+ return root_ca
+}
+
+func GetRootBaseCA() string {
+ cu, _ := GetCertUtil()
+
+ root_ca := cu.GetSelfSignedCA()
+
+ return root_ca
+}
+
+func (c *CertificateObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // Create Certificate
+ overlay := GetManagerset().Overlay
+ overlay_name := m[OverlayResource]
+ cert_name := c.GetDeviceCertName(t.GetMetadata().Name)
+
+ ca, key, err := overlay.CreateCertificate(overlay_name, cert_name)
+ if err != nil {
+ log.Println(err)
+ return c.CreateEmptyObject(), err
+ }
+
+ // DB Operation
+ t, err = GetDBUtils().CreateObject(c, m, t)
+
+ // Fill Certificate data
+ if err == nil {
+ to := t.(*module.CertificateObject)
+ to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name)))
+ to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca))
+ to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key))
+
+ return t, nil
+ } else {
+ log.Println(err)
+ return c.CreateEmptyObject(), err
+ }
+}
+
+func (c *CertificateObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ if err == nil {
+ overlay := GetManagerset().Overlay
+ overlay_name := m[OverlayResource]
+ cert_name := c.GetDeviceCertName(t.GetMetadata().Name)
+
+ ca, key, err := overlay.CreateCertificate(overlay_name, cert_name)
+ if err != nil {
+ log.Println(err)
+ return c.CreateEmptyObject(), err
+ }
+
+ to := t.(*module.CertificateObject)
+ to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name)))
+ to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca))
+ to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key))
+
+ return t, nil
+ } else {
+ log.Println(err)
+ return c.CreateEmptyObject(), err
+ }
+}
+
+func (c *CertificateObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *CertificateObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *CertificateObjectManager) DeleteObject(m map[string]string) error {
+ t, err := c.GetObject(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Certificate is not available")
+ }
+
+ // Delete certificate
+ overlay := GetManagerset().Overlay
+ cert_name := c.GetDeviceCertName(t.GetMetadata().Name)
+
+ log.Println("Delete Certificate: " + cert_name)
+ overlay.DeleteCertificate(cert_name)
+
+ // DB Operation
+ err = GetDBUtils().DeleteObject(c, m)
+
+ return err
+}
+
+// Create or Get certificate for a device
+func (c *CertificateObjectManager) GetOrCreateDC(overlay_name string, dev_name string) (string, string, string, error) {
+ m := make(map[string]string)
+ m[OverlayResource] = overlay_name
+ t := &module.CertificateObject{Metadata: module.ObjectMetaData{dev_name, "", "", ""}}
+
+ _, err := c.CreateObject(m, t)
+ if err != nil {
+ return "", "", "", err
+ }
+
+ return t.Data.RootCA, t.Data.Ca, t.Data.Key, nil
+}
+
+// Delete certificate for a device
+func (c *CertificateObjectManager) DeleteDC(overlay_name string, dev_name string) error {
+ m := make(map[string]string)
+ m[OverlayResource] = overlay_name
+ m[CertResource] = dev_name
+
+ return c.DeleteObject(m)
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "log"\r
- "context"\r
- "time"\r
- pkgerrors "github.com/pkg/errors"\r
- kclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"\r
- cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"\r
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\r
- "k8s.io/apimachinery/pkg/util/wait"\r
- v1 "k8s.io/api/core/v1"\r
- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"\r
- certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1"\r
- v1beta1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1beta1"\r
-)\r
-\r
-const SELFSIGNEDCA = "sdewan-controller"\r
-\r
-type CertUtil struct {\r
- client certmanagerv1beta1.CertmanagerV1beta1Interface\r
- k8sclient corev1.CoreV1Interface\r
-}\r
-\r
-var certutil = CertUtil{}\r
-\r
-func GetCertUtil() (*CertUtil, error) {\r
- var err error\r
- if certutil.client == nil || certutil.k8sclient == nil {\r
- certutil.client, certutil.k8sclient, err = kclient.NewClient("", "", []byte{}).GetCMClients()\r
- }\r
-\r
- return &certutil, err\r
-}\r
-\r
-func (c *CertUtil) CreateNamespace(name string) (*v1.Namespace, error) {\r
- ns, err := c.k8sclient.Namespaces().Get(context.TODO(), name, metav1.GetOptions{})\r
- if err == nil {\r
- return ns, nil\r
- }\r
-\r
- log.Println("Create Namespace: " + name)\r
- return c.k8sclient.Namespaces().Create(context.TODO(), &v1.Namespace{\r
- ObjectMeta: metav1.ObjectMeta{\r
- Name: name,\r
- },\r
- }, metav1.CreateOptions{})\r
-}\r
-\r
-func (c *CertUtil) DeleteNamespace(name string) error {\r
- return c.k8sclient.Namespaces().Delete(context.TODO(), name, metav1.DeleteOptions{})\r
-}\r
-\r
-func (c *CertUtil) GetIssuer(name string, namespace string) (*v1beta1.Issuer, error) {\r
- return c.client.Issuers(namespace).Get(context.TODO(), name, metav1.GetOptions{})\r
-}\r
-\r
-func (c *CertUtil) DeleteIssuer(name string, namespace string) error {\r
- return c.client.Issuers(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})\r
-}\r
-\r
-func (c *CertUtil) CreateSelfSignedIssuer(name string, namespace string) (*v1beta1.Issuer, error) {\r
- issuer, err := c.GetIssuer(name, namespace)\r
- if err == nil {\r
- return issuer, nil\r
- }\r
-\r
- // Not existing issuer, create a new one\r
- return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{\r
- ObjectMeta: metav1.ObjectMeta{\r
- Name: name,\r
- },\r
- Spec: v1beta1.IssuerSpec{\r
- IssuerConfig: v1beta1.IssuerConfig{\r
- SelfSigned: &v1beta1.SelfSignedIssuer{\r
- },\r
- },\r
- },\r
- }, metav1.CreateOptions{})\r
-}\r
-\r
-func (c *CertUtil) CreateCAIssuer(name string, namespace string, caname string) (*v1beta1.Issuer, error) {\r
- issuer, err := c.GetIssuer(name, namespace)\r
- if err == nil {\r
- return issuer, nil\r
- }\r
-\r
- // Not existing issuer, create a new one\r
- return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{\r
- ObjectMeta: metav1.ObjectMeta{\r
- Name: name,\r
- },\r
- Spec: v1beta1.IssuerSpec{\r
- IssuerConfig: v1beta1.IssuerConfig{\r
- CA: &v1beta1.CAIssuer{\r
- SecretName: c.GetCertSecretName(caname),\r
- },\r
- },\r
- },\r
- }, metav1.CreateOptions{})\r
-}\r
-\r
-func (c *CertUtil) GetCertSecretName(name string) string {\r
- return name + "-cert-secret"\r
-}\r
-\r
-func (c *CertUtil) GetCertificate(name string, namespace string) (*v1beta1.Certificate, error) {\r
- return c.client.Certificates(namespace).Get(context.TODO(), name, metav1.GetOptions{})\r
-}\r
-\r
-func (c *CertUtil) DeleteCertificate(name string, namespace string) error {\r
- return c.client.Certificates(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})\r
-}\r
-\r
-func (c *CertUtil) CreateCertificate(name string, namespace string, issuer string, isCA bool) (*v1beta1.Certificate, error) {\r
- cert, err := c.GetCertificate(name, namespace)\r
- if err == nil {\r
- return cert, nil\r
- }\r
-\r
- // Not existing cert, create a new one\r
- // Todo: add Duration, RenewBefore, DNSNames\r
- cert, err = c.client.Certificates(namespace).Create(context.TODO(), &v1beta1.Certificate{\r
- ObjectMeta: metav1.ObjectMeta{\r
- Name: name,\r
- },\r
- Spec: v1beta1.CertificateSpec{\r
- CommonName: name,\r
- // Duration: duration,\r
- // RenewBefore: renewBefore,\r
- // DNSNames: dnsNames,\r
- SecretName: c.GetCertSecretName(name),\r
- IssuerRef: cmmeta.ObjectReference {\r
- Name: issuer,\r
- Kind: "Issuer",\r
- },\r
- IsCA: isCA,\r
- },\r
- }, metav1.CreateOptions{})\r
-\r
- if err == nil {\r
- if c.IsCertReady(name, namespace) {\r
- return cert, nil\r
- } else {\r
- return cert, pkgerrors.New("Failed to get certificate " + name)\r
- }\r
- }\r
-\r
- return cert, err\r
-}\r
-\r
-func (c *CertUtil) IsCertReady(name string, namespace string) bool {\r
- err := wait.PollImmediate(time.Second, time.Second*20,\r
- func() (bool, error) {\r
- var err error\r
- var crt *v1beta1.Certificate\r
- crt, err = c.GetCertificate(name, namespace)\r
- if err != nil {\r
- log.Println("Failed to find certificate " + name + ": " + err.Error())\r
- return false, err\r
- }\r
- curConditions := crt.Status.Conditions\r
- for _, cond := range curConditions {\r
- if v1beta1.CertificateConditionReady == cond.Type && cmmeta.ConditionTrue == cond.Status {\r
- return true, nil\r
- }\r
- }\r
- log.Println("Waiting for Certificate " + name + " to be ready.")\r
- return false, nil\r
- },\r
- )\r
-\r
- if err != nil {\r
- log.Println(err)\r
- return false\r
- }\r
-\r
- return true\r
-}\r
-\r
-func (c *CertUtil) GetKeypair(certname string, namespace string) (string, string, error) {\r
- secret, err := c.k8sclient.Secrets(namespace).Get(\r
- context.TODO(),\r
- c.GetCertSecretName(certname),\r
- metav1.GetOptions{})\r
- if err != nil {\r
- log.Println("Failed to get certificate's key pair: " + err.Error())\r
- return "", "", err\r
- }\r
-\r
- return string(secret.Data["tls.crt"]), string(secret.Data["tls.key"]), nil\r
-}\r
-\r
-func (c *CertUtil) GetSelfSignedCA() (string) {\r
- ca, _, _ := c.GetKeypair(RootCertName, NameSpaceName)\r
- return ca\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "context"
+ kclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"
+ v1beta1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1beta1"
+ cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
+ certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1"
+ pkgerrors "github.com/pkg/errors"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/util/wait"
+ corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+ "log"
+ "time"
+)
+
+const SELFSIGNEDCA = "sdewan-controller"
+
+type CertUtil struct {
+ client certmanagerv1beta1.CertmanagerV1beta1Interface
+ k8sclient corev1.CoreV1Interface
+}
+
+var certutil = CertUtil{}
+
+func GetCertUtil() (*CertUtil, error) {
+ var err error
+ if certutil.client == nil || certutil.k8sclient == nil {
+ certutil.client, certutil.k8sclient, err = kclient.NewClient("", "", []byte{}).GetCMClients()
+ }
+
+ return &certutil, err
+}
+
+func (c *CertUtil) CreateNamespace(name string) (*v1.Namespace, error) {
+ ns, err := c.k8sclient.Namespaces().Get(context.TODO(), name, metav1.GetOptions{})
+ if err == nil {
+ return ns, nil
+ }
+
+ log.Println("Create Namespace: " + name)
+ return c.k8sclient.Namespaces().Create(context.TODO(), &v1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ },
+ }, metav1.CreateOptions{})
+}
+
+func (c *CertUtil) DeleteNamespace(name string) error {
+ return c.k8sclient.Namespaces().Delete(context.TODO(), name, metav1.DeleteOptions{})
+}
+
+func (c *CertUtil) GetIssuer(name string, namespace string) (*v1beta1.Issuer, error) {
+ return c.client.Issuers(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+}
+
+func (c *CertUtil) DeleteIssuer(name string, namespace string) error {
+ return c.client.Issuers(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
+}
+
+func (c *CertUtil) CreateSelfSignedIssuer(name string, namespace string) (*v1beta1.Issuer, error) {
+ issuer, err := c.GetIssuer(name, namespace)
+ if err == nil {
+ return issuer, nil
+ }
+
+ // Not existing issuer, create a new one
+ return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ },
+ Spec: v1beta1.IssuerSpec{
+ IssuerConfig: v1beta1.IssuerConfig{
+ SelfSigned: &v1beta1.SelfSignedIssuer{},
+ },
+ },
+ }, metav1.CreateOptions{})
+}
+
+func (c *CertUtil) CreateCAIssuer(name string, namespace string, caname string) (*v1beta1.Issuer, error) {
+ issuer, err := c.GetIssuer(name, namespace)
+ if err == nil {
+ return issuer, nil
+ }
+
+ // Not existing issuer, create a new one
+ return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ },
+ Spec: v1beta1.IssuerSpec{
+ IssuerConfig: v1beta1.IssuerConfig{
+ CA: &v1beta1.CAIssuer{
+ SecretName: c.GetCertSecretName(caname),
+ },
+ },
+ },
+ }, metav1.CreateOptions{})
+}
+
+func (c *CertUtil) GetCertSecretName(name string) string {
+ return name + "-cert-secret"
+}
+
+func (c *CertUtil) GetCertificate(name string, namespace string) (*v1beta1.Certificate, error) {
+ return c.client.Certificates(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+}
+
+func (c *CertUtil) DeleteCertificate(name string, namespace string) error {
+ return c.client.Certificates(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
+}
+
+func (c *CertUtil) CreateCertificate(name string, namespace string, issuer string, isCA bool) (*v1beta1.Certificate, error) {
+ cert, err := c.GetCertificate(name, namespace)
+ if err == nil {
+ return cert, nil
+ }
+
+ // Not existing cert, create a new one
+ // Todo: add Duration, RenewBefore, DNSNames
+ cert, err = c.client.Certificates(namespace).Create(context.TODO(), &v1beta1.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ },
+ Spec: v1beta1.CertificateSpec{
+ CommonName: name,
+ // Duration: duration,
+ // RenewBefore: renewBefore,
+ // DNSNames: dnsNames,
+ SecretName: c.GetCertSecretName(name),
+ IssuerRef: cmmeta.ObjectReference{
+ Name: issuer,
+ Kind: "Issuer",
+ },
+ IsCA: isCA,
+ },
+ }, metav1.CreateOptions{})
+
+ if err == nil {
+ if c.IsCertReady(name, namespace) {
+ return cert, nil
+ } else {
+ return cert, pkgerrors.New("Failed to get certificate " + name)
+ }
+ }
+
+ return cert, err
+}
+
+func (c *CertUtil) IsCertReady(name string, namespace string) bool {
+ err := wait.PollImmediate(time.Second, time.Second*20,
+ func() (bool, error) {
+ var err error
+ var crt *v1beta1.Certificate
+ crt, err = c.GetCertificate(name, namespace)
+ if err != nil {
+ log.Println("Failed to find certificate " + name + ": " + err.Error())
+ return false, err
+ }
+ curConditions := crt.Status.Conditions
+ for _, cond := range curConditions {
+ if v1beta1.CertificateConditionReady == cond.Type && cmmeta.ConditionTrue == cond.Status {
+ return true, nil
+ }
+ }
+ log.Println("Waiting for Certificate " + name + " to be ready.")
+ return false, nil
+ },
+ )
+
+ if err != nil {
+ log.Println(err)
+ return false
+ }
+
+ return true
+}
+
+func (c *CertUtil) GetKeypair(certname string, namespace string) (string, string, error) {
+ secret, err := c.k8sclient.Secrets(namespace).Get(
+ context.TODO(),
+ c.GetCertSecretName(certname),
+ metav1.GetOptions{})
+ if err != nil {
+ log.Println("Failed to get certificate's key pair: " + err.Error())
+ return "", "", err
+ }
+
+ return string(secret.Data["tls.crt"]), string(secret.Data["tls.key"]), nil
+}
+
+func (c *CertUtil) GetSelfSignedCA() string {
+ ca, _, _ := c.GetKeypair(RootCertName, NameSpaceName)
+ return ca
+}
--- /dev/null
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "log"
+)
+
+type CNFObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ ClusterName string `json:"cluster-name"`
+ CNFName string `json:"cnf-name"`
+}
+
+// CNFObjectManager implements the ControllerObjectManager
+type CNFObjectManager struct {
+ BaseObjectManager
+ isHub bool
+}
+
+func NewCNFObjectManager(isHub bool) *CNFObjectManager {
+ object_meta := "cnf"
+ if isHub {
+ object_meta = "hub-" + object_meta
+ } else {
+ object_meta = "device-" + object_meta
+ }
+
+ return &CNFObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: object_meta,
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ isHub,
+ }
+}
+
+func (c *CNFObjectManager) GetResourceName() string {
+ return CNFResource
+}
+
+func (c *CNFObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "GETS" {
+ return true
+ }
+ return false
+}
+
+func (c *CNFObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.CNFObject{}
+}
+
+func (c *CNFObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ cluster_name := ""
+ if c.isHub {
+ cluster_name = m[HubResource]
+ } else {
+ cluster_name = m[DeviceResource]
+ }
+
+ key := CNFObjectKey{
+ OverlayName: overlay_name,
+ ClusterName: cluster_name,
+ CNFName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.CNFObject)
+ meta_name := to.Metadata.Name
+ res_name := m[CNFResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.CNFName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.CNFName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *CNFObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.CNFObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *CNFObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *CNFObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *CNFObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ overlay_name := m[OverlayResource]
+ var cobj module.ControllerObject
+ var cluster_name string
+ var err error
+
+ if c.isHub {
+ cluster_name = m[HubResource]
+ hub_name := m[HubResource]
+ hub_manager := GetManagerset().Hub
+ cobj, err = hub_manager.GetObject(m)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined")
+ }
+ } else {
+ cluster_name = m[DeviceResource]
+ device_name := m[DeviceResource]
+ dev_manager := GetManagerset().Device
+ cobj, err = dev_manager.GetObject(m)
+ if err != nil {
+ //return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " is not defined")
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Device "+device_name+" is not defined")
+ }
+ }
+
+ // Query CNFStatus
+ resutil := NewResUtil()
+
+ res := QueryResource{
+ Resource: ReadResource{
+ Gvk: schema.GroupVersionKind{Group: "batch.sdewan.akraino.org", Version: "v1alpha1", Kind: "CNFStatus"},
+ Name: "cnf-status",
+ Namespace: "sdewan-system",
+ }}
+ resutil.AddQueryResource(cobj, res)
+ ctx_id, err := resutil.Query("ewo-query-app")
+
+ if err != nil {
+ log.Println(err)
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to Query CNFs")
+ }
+
+ // Todo: save ctx_id in DB
+ log.Println(ctx_id)
+ // val, err := resutil.GetResourceData(&deviceObject, "default", "mycm")
+ val, err := resutil.GetResourceData(cobj, "sdewan-system", "cnf-status")
+ if err != nil {
+ log.Println(err)
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available")
+ }
+
+ status, err := c.ParseStatus(val)
+ if err != nil {
+ log.Println(err)
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available")
+ }
+
+ return []module.ControllerObject{&module.CNFObject{
+ Metadata: module.ObjectMetaData{overlay_name + "." + cluster_name, "cnf informaiton", "", ""},
+ Status: status,
+ }}, nil
+}
+
+func (c *CNFObjectManager) ParseStatus(val string) (string, error) {
+ var vi interface{}
+ err := json.Unmarshal([]byte(val), &vi)
+ if err != nil {
+ return "", err
+ }
+
+ status := vi.(map[string]interface{})["status"]
+ status_val, err := json.Marshal(status)
+
+ if err != nil {
+ return "", err
+ }
+
+ return string(status_val), nil
+}
+
+func (c *CNFObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *CNFObjectManager) DeleteObject(m map[string]string) error {
+ return pkgerrors.New("Not implemented")
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "log"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" \r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type ConnectionManager struct {\r
- storeName string\r
- tagMeta string\r
-}\r
-\r
-type ConnectionKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- End1 string `json:"end1-name"`\r
- End2 string `json:"end2-name"`\r
-}\r
-\r
-var connutil = ConnectionManager{\r
- storeName: StoreName,\r
- tagMeta: "connection",\r
- }\r
-\r
-func GetConnectionManager() *ConnectionManager {\r
- return &connutil\r
-}\r
-\r
-func (c *ConnectionManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.ConnectionObject{}\r
-}\r
-\r
-func (c *ConnectionManager) GetStoreName() string {\r
- return c.storeName\r
-}\r
-\r
-func (c *ConnectionManager) GetStoreMeta() string {\r
- return c.tagMeta\r
-}\r
-\r
-\r
-func (c *ConnectionManager) Deploy(overlay string, cm module.ConnectionObject) error {\r
- resutil := NewResUtil()\r
-\r
- // add resource for End1\r
- co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject)\r
- for _, r_str := range cm.Info.End1.Resources {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co1, "create", r)\r
- }\r
- for _, r_str := range cm.Info.End1.ReservedRes {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co1, "create", r)\r
- }\r
-\r
- // add resource for End2\r
- co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject)\r
- for _, r_str := range cm.Info.End2.Resources {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co2, "create", r)\r
- }\r
- for _, r_str := range cm.Info.End2.ReservedRes {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co2, "create", r)\r
- }\r
-\r
- // Deploy resources\r
- cid, err := resutil.Deploy(cm.Metadata.Name, "YAML")\r
- if cm.Info.ContextId == "" {\r
- cm.Info.ContextId = cid\r
- } else {\r
- cm.Info.ContextId = cm.Info.ContextId + "," + cid\r
- }\r
-\r
- if err != nil {\r
- log.Println(err)\r
- cm.Info.State = module.StateEnum.Error\r
- cm.Info.ErrorMessage = err.Error()\r
- } else {\r
- cm.Info.State = module.StateEnum.Deployed\r
- }\r
-\r
- // Save to DB\r
- _, err = c.UpdateObject(overlay, cm)\r
-\r
- return err\r
-}\r
-\r
-func (c *ConnectionManager) Undeploy(overlay string, cm module.ConnectionObject) error {\r
- resutil := NewResUtil()\r
-\r
- // add resource for End1 (reservedRes will be kept)\r
- co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject)\r
- for _, r_str := range cm.Info.End1.Resources {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co1, "create", r)\r
- }\r
-\r
- // add resource for End2 (reservedRes will be kept)\r
- co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject)\r
- for _, r_str := range cm.Info.End2.Resources {\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutil.AddResource(co2, "create", r)\r
- }\r
-\r
- // Undeploy resources\r
- cid, err := resutil.Undeploy(cm.Metadata.Name, "YAML")\r
- if cm.Info.ContextId == "" {\r
- cm.Info.ContextId = cid\r
- } else {\r
- cm.Info.ContextId = cm.Info.ContextId + "," + cid\r
- }\r
-\r
- if err != nil {\r
- log.Println(err)\r
- cm.Info.State = module.StateEnum.Error\r
- cm.Info.ErrorMessage = err.Error()\r
- } else {\r
- cm.Info.State = module.StateEnum.Undeployed\r
- }\r
-\r
- // Delete connection object\r
- err = c.DeleteObject(overlay, cm.Info.End1.Name, cm.Info.End2.Name)\r
-\r
- return err\r
-}\r
-\r
-func (c *ConnectionManager) UpdateObject(overlay string, cm module.ConnectionObject) (module.ControllerObject, error) {\r
- key := ConnectionKey{\r
- OverlayName: overlay,\r
- End1: cm.Info.End1.Name,\r
- End2: cm.Info.End2.Name,\r
- }\r
-\r
- err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), cm)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unable to create the object")\r
- }\r
- return &cm, err\r
-}\r
-\r
-func (c *ConnectionManager) GetObject(overlay string, key1 string, key2 string) (module.ControllerObject, error) {\r
- key := ConnectionKey{\r
- OverlayName: overlay,\r
- End1: key1,\r
- End2: key2,\r
- }\r
- value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())\r
- if err != nil {\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
- if value == nil {\r
- key = ConnectionKey{\r
- OverlayName: overlay,\r
- End1: key2,\r
- End2: key1,\r
- }\r
- value, err = db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())\r
- if err != nil {\r
- return c.CreateEmptyObject(), err\r
- }\r
- }\r
-\r
- if value != nil {\r
- r := c.CreateEmptyObject()\r
- err = db.DBconn.Unmarshal(value[0], r)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value")\r
- }\r
- return r, nil\r
- }\r
-\r
- return c.CreateEmptyObject(), pkgerrors.New("No Object")\r
-}\r
-\r
-func (c *ConnectionManager) GetObjects(overlay string, key string) ([]module.ControllerObject, error) {\r
- key1 := ConnectionKey{\r
- OverlayName: overlay,\r
- End1: key,\r
- End2: "",\r
- }\r
- key2 := ConnectionKey{\r
- OverlayName: overlay,\r
- End1: "",\r
- End2: key,\r
- }\r
- \r
- var resp []module.ControllerObject\r
-\r
- // find objects with end1=key\r
- values, err := db.DBconn.Find(c.GetStoreName(), key1, c.GetStoreMeta())\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")\r
- }\r
-\r
- for _, value := range values {\r
- t := c.CreateEmptyObject()\r
- err = db.DBconn.Unmarshal(value, t)\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")\r
- }\r
- resp = append(resp, t)\r
- }\r
-\r
- // find objects with end2=key\r
- values, err = db.DBconn.Find(c.GetStoreName(), key2, c.GetStoreMeta())\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")\r
- }\r
-\r
- for _, value := range values {\r
- t := c.CreateEmptyObject()\r
- err = db.DBconn.Unmarshal(value, t)\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")\r
- }\r
- resp = append(resp, t)\r
- }\r
-\r
- return resp, nil\r
-}\r
-\r
-func (c *ConnectionManager) DeleteObject(overlay string, key1 string, key2 string) error {\r
- key := ConnectionKey{\r
- OverlayName: overlay,\r
- End1: key1,\r
- End2: key2,\r
- }\r
-\r
- err := db.DBconn.Remove(c.GetStoreName(), key)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Delete Object")\r
- }\r
-\r
- return err\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "log"
+)
+
+type ConnectionManager struct {
+ storeName string
+ tagMeta string
+}
+
+type ConnectionKey struct {
+ OverlayName string `json:"overlay-name"`
+ End1 string `json:"end1-name"`
+ End2 string `json:"end2-name"`
+}
+
+var connutil = ConnectionManager{
+ storeName: StoreName,
+ tagMeta: "connection",
+}
+
+func GetConnectionManager() *ConnectionManager {
+ return &connutil
+}
+
+func (c *ConnectionManager) CreateEmptyObject() module.ControllerObject {
+ return &module.ConnectionObject{}
+}
+
+func (c *ConnectionManager) GetStoreName() string {
+ return c.storeName
+}
+
+func (c *ConnectionManager) GetStoreMeta() string {
+ return c.tagMeta
+}
+
+func (c *ConnectionManager) Deploy(overlay string, cm module.ConnectionObject) error {
+ resutil := NewResUtil()
+
+ // add resource for End1
+ co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject)
+ for _, r_str := range cm.Info.End1.Resources {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co1, "create", r)
+ }
+ for _, r_str := range cm.Info.End1.ReservedRes {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co1, "create", r)
+ }
+
+ // add resource for End2
+ co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject)
+ for _, r_str := range cm.Info.End2.Resources {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co2, "create", r)
+ }
+ for _, r_str := range cm.Info.End2.ReservedRes {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co2, "create", r)
+ }
+
+ // Deploy resources
+ cid, err := resutil.Deploy(cm.Metadata.Name, "YAML")
+ if cm.Info.ContextId == "" {
+ cm.Info.ContextId = cid
+ } else {
+ cm.Info.ContextId = cm.Info.ContextId + "," + cid
+ }
+
+ if err != nil {
+ log.Println(err)
+ cm.Info.State = module.StateEnum.Error
+ cm.Info.ErrorMessage = err.Error()
+ } else {
+ cm.Info.State = module.StateEnum.Deployed
+ }
+
+ // Save to DB
+ _, err = c.UpdateObject(overlay, cm)
+
+ return err
+}
+
+func (c *ConnectionManager) Undeploy(overlay string, cm module.ConnectionObject) error {
+ resutil := NewResUtil()
+
+ // add resource for End1 (reservedRes will be kept)
+ co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject)
+ for _, r_str := range cm.Info.End1.Resources {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co1, "create", r)
+ }
+
+ // add resource for End2 (reservedRes will be kept)
+ co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject)
+ for _, r_str := range cm.Info.End2.Resources {
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutil.AddResource(co2, "create", r)
+ }
+
+ // Undeploy resources
+ cid, err := resutil.Undeploy(cm.Metadata.Name, "YAML")
+ if cm.Info.ContextId == "" {
+ cm.Info.ContextId = cid
+ } else {
+ cm.Info.ContextId = cm.Info.ContextId + "," + cid
+ }
+
+ if err != nil {
+ log.Println(err)
+ cm.Info.State = module.StateEnum.Error
+ cm.Info.ErrorMessage = err.Error()
+ } else {
+ cm.Info.State = module.StateEnum.Undeployed
+ }
+
+ // Delete connection object
+ err = c.DeleteObject(overlay, cm.Info.End1.Name, cm.Info.End2.Name)
+
+ return err
+}
+
+func (c *ConnectionManager) UpdateObject(overlay string, cm module.ConnectionObject) (module.ControllerObject, error) {
+ key := ConnectionKey{
+ OverlayName: overlay,
+ End1: cm.Info.End1.Name,
+ End2: cm.Info.End2.Name,
+ }
+
+ err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), cm)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unable to create the object")
+ }
+ return &cm, err
+}
+
+func (c *ConnectionManager) GetObject(overlay string, key1 string, key2 string) (module.ControllerObject, error) {
+ key := ConnectionKey{
+ OverlayName: overlay,
+ End1: key1,
+ End2: key2,
+ }
+ value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())
+ if err != nil {
+ return c.CreateEmptyObject(), err
+ }
+
+ if value == nil {
+ key = ConnectionKey{
+ OverlayName: overlay,
+ End1: key2,
+ End2: key1,
+ }
+ value, err = db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())
+ if err != nil {
+ return c.CreateEmptyObject(), err
+ }
+ }
+
+ if value != nil {
+ r := c.CreateEmptyObject()
+ err = db.DBconn.Unmarshal(value[0], r)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value")
+ }
+ return r, nil
+ }
+
+ return c.CreateEmptyObject(), pkgerrors.New("No Object")
+}
+
+func (c *ConnectionManager) GetObjects(overlay string, key string) ([]module.ControllerObject, error) {
+ key1 := ConnectionKey{
+ OverlayName: overlay,
+ End1: key,
+ End2: "",
+ }
+ key2 := ConnectionKey{
+ OverlayName: overlay,
+ End1: "",
+ End2: key,
+ }
+
+ var resp []module.ControllerObject
+
+ // find objects with end1=key
+ values, err := db.DBconn.Find(c.GetStoreName(), key1, c.GetStoreMeta())
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")
+ }
+
+ for _, value := range values {
+ t := c.CreateEmptyObject()
+ err = db.DBconn.Unmarshal(value, t)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")
+ }
+ resp = append(resp, t)
+ }
+
+ // find objects with end2=key
+ values, err = db.DBconn.Find(c.GetStoreName(), key2, c.GetStoreMeta())
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")
+ }
+
+ for _, value := range values {
+ t := c.CreateEmptyObject()
+ err = db.DBconn.Unmarshal(value, t)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")
+ }
+ resp = append(resp, t)
+ }
+
+ return resp, nil
+}
+
+func (c *ConnectionManager) DeleteObject(overlay string, key1 string, key2 string) error {
+ key := ConnectionKey{
+ OverlayName: overlay,
+ End1: key1,
+ End2: key2,
+ }
+
+ err := db.DBconn.Remove(c.GetStoreName(), key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Delete Object")
+ }
+
+ return err
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-const (\r
- NameSpaceName = "sdewan-system"\r
- RootIssuerName = "sdewan-controller"\r
- RootCAIssuerName = "sdewan-controller-ca"\r
- RootCertName = "sdewan-controller"\r
- SCCCertName = "sdewan-controller-base"\r
- StoreName = "centralcontroller"\r
- OverlayCollection = "overlays"\r
- OverlayResource = "overlay-name"\r
- ProposalCollection = "proposals"\r
- ProposalResource = "proposal-name"\r
- HubCollection = "hubs"\r
- HubResource = "hub-name"\r
- ConnectionCollection = "connections"\r
- ConnectionResource = "connection-name"\r
- DeviceCollection = "devices"\r
- DeviceResource = "device-name"\r
- IPRangeCollection = "ipranges"\r
- IPRangeResource = "iprange-name"\r
- CertCollection = "certificates"\r
- CertResource = "certificate-name"\r
-)
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+const (
+ NameSpaceName = "sdewan-system"
+ RootIssuerName = "sdewan-controller"
+ RootCAIssuerName = "sdewan-controller-ca"
+ RootCertName = "sdewan-controller"
+ SCCCertName = "sdewan-controller-base"
+ StoreName = "centralcontroller"
+ OverlayCollection = "overlays"
+ OverlayResource = "overlay-name"
+ ProposalCollection = "proposals"
+ ProposalResource = "proposal-name"
+ HubCollection = "hubs"
+ HubResource = "hub-name"
+ ConnectionCollection = "connections"
+ ConnectionResource = "connection-name"
+ CNFCollection = "cnfs"
+ CNFResource = "cnf-name"
+ DeviceCollection = "devices"
+ DeviceResource = "device-name"
+ IPRangeCollection = "ipranges"
+ IPRangeResource = "iprange-name"
+ CertCollection = "certificates"
+ CertResource = "certificate-name"
+)
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
-)\r
-\r
-// ControllerManager is an interface exposes the ControllerObject functionality\r
-type ControllerObjectManager interface {\r
- GetStoreName() string\r
- GetStoreMeta() string\r
- GetDepResManagers() []ControllerObjectManager\r
- AddDepResManager(mgr ControllerObjectManager)\r
- GetOwnResManagers() []ControllerObjectManager\r
- AddOwnResManager(mgr ControllerObjectManager) \r
- \r
- GetResourceName() string\r
- IsOperationSupported(oper string) bool\r
- GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error)\r
- CreateEmptyObject() module.ControllerObject\r
- ParseObject(r io.Reader) (module.ControllerObject, error)\r
- CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error)\r
- GetObject(m map[string]string) (module.ControllerObject, error)\r
- GetObjects(m map[string]string) ([]module.ControllerObject, error)\r
- UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error)\r
- DeleteObject(m map[string]string) error\r
-}\r
-\r
-type BaseObjectManager struct {\r
- storeName string\r
- tagMeta string\r
- depResManagers []ControllerObjectManager\r
- ownResManagers []ControllerObjectManager\r
-}\r
-\r
-func (c *BaseObjectManager) GetStoreName() string {\r
- return c.storeName\r
-}\r
-\r
-func (c *BaseObjectManager) GetStoreMeta() string {\r
- return c.tagMeta\r
-}\r
-\r
-func (c *BaseObjectManager) GetDepResManagers() []ControllerObjectManager {\r
- return c.depResManagers\r
-}\r
-\r
-func (c *BaseObjectManager) AddDepResManager(mgr ControllerObjectManager) {\r
- c.depResManagers = append(c.depResManagers, mgr)\r
-}\r
-\r
-func (c *BaseObjectManager) GetOwnResManagers() []ControllerObjectManager {\r
- return c.ownResManagers\r
-}\r
-\r
-func (c *BaseObjectManager) AddOwnResManager(mgr ControllerObjectManager) {\r
- c.ownResManagers = append(c.ownResManagers, mgr)\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ "io"
+)
+
+// ControllerManager is an interface exposes the ControllerObject functionality
+type ControllerObjectManager interface {
+ GetStoreName() string
+ GetStoreMeta() string
+ GetDepResManagers() []ControllerObjectManager
+ AddDepResManager(mgr ControllerObjectManager)
+ GetOwnResManagers() []ControllerObjectManager
+ AddOwnResManager(mgr ControllerObjectManager)
+
+ GetResourceName() string
+ IsOperationSupported(oper string) bool
+ GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error)
+ CreateEmptyObject() module.ControllerObject
+ ParseObject(r io.Reader) (module.ControllerObject, error)
+ CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error)
+ GetObject(m map[string]string) (module.ControllerObject, error)
+ GetObjects(m map[string]string) ([]module.ControllerObject, error)
+ UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error)
+ DeleteObject(m map[string]string) error
+}
+
+type BaseObjectManager struct {
+ storeName string
+ tagMeta string
+ depResManagers []ControllerObjectManager
+ ownResManagers []ControllerObjectManager
+}
+
+func (c *BaseObjectManager) GetStoreName() string {
+ return c.storeName
+}
+
+func (c *BaseObjectManager) GetStoreMeta() string {
+ return c.tagMeta
+}
+
+func (c *BaseObjectManager) GetDepResManagers() []ControllerObjectManager {
+ return c.depResManagers
+}
+
+func (c *BaseObjectManager) AddDepResManager(mgr ControllerObjectManager) {
+ c.depResManagers = append(c.depResManagers, mgr)
+}
+
+func (c *BaseObjectManager) GetOwnResManagers() []ControllerObjectManager {
+ return c.ownResManagers
+}
+
+func (c *BaseObjectManager) AddOwnResManager(mgr ControllerObjectManager) {
+ c.ownResManagers = append(c.ownResManagers, mgr)
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- rsync "github.com/open-ness/EMCO/src/rsync/pkg/db"\r
- pkgerrors "github.com/pkg/errors"\r
- mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"\r
-)\r
-\r
-const PROVIDERNAME = "akraino_scc"\r
-\r
-type Cluster struct {\r
- Metadata mtypes.Metadata `json:"metadata"`\r
-}\r
-\r
-type ClusterContent struct {\r
- Kubeconfig string `json:"kubeconfig"`\r
-}\r
-\r
-type ClusterKey struct {\r
- ClusterProviderName string `json:"provider"`\r
- ClusterName string `json:"cluster"`\r
-}\r
-\r
-type DBUtils struct {\r
-}\r
-\r
-var dbutils = DBUtils{}\r
-\r
-func GetDBUtils() *DBUtils {\r
- return &dbutils\r
-}\r
-\r
-func (d *DBUtils) CheckDep(c ControllerObjectManager, m map[string]string) error {\r
- depsResManagers := c.GetDepResManagers()\r
- for _, mgr := range depsResManagers {\r
- _, err := d.GetObject(mgr, m)\r
- if err != nil {\r
- return pkgerrors.New("Fail to find " + mgr.GetStoreMeta())\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (d *DBUtils) CheckOwn(c ControllerObjectManager, m map[string]string) error {\r
- depsOwnManagers := c.GetOwnResManagers()\r
- for _, mgr := range depsOwnManagers {\r
- objs, err := d.GetObjects(mgr, m)\r
- if err == nil && len(objs) > 0 {\r
- return pkgerrors.New("Sub-resource found : " + mgr.GetStoreMeta())\r
- }\r
- }\r
- return nil\r
-}\r
-\r
-\r
-func (d *DBUtils) CreateObject(c ControllerObjectManager, m map[string]string,\r
- t module.ControllerObject) (module.ControllerObject, error) {\r
-\r
- key, _ := c.GetStoreKey(m, t, false)\r
- err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.New("Unable to create the object")\r
- }\r
-\r
- return t, nil\r
-}\r
-\r
-func (d *DBUtils) GetObject(c ControllerObjectManager,\r
- m map[string]string) (module.ControllerObject, error) {\r
-\r
- key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false)\r
- if err != nil {\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
-\r
- value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Get Resource")\r
- }\r
-\r
-\r
- if value != nil {\r
- r := c.CreateEmptyObject()\r
- err = db.DBconn.Unmarshal(value[0], r)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value")\r
- }\r
- return r, nil\r
- }\r
-\r
- return c.CreateEmptyObject(), pkgerrors.New("No Object")\r
-}\r
-\r
-func (d *DBUtils) GetObjects(c ControllerObjectManager,\r
- m map[string]string) ([]module.ControllerObject, error) {\r
-\r
-\r
- key, err := c.GetStoreKey(m, c.CreateEmptyObject(), true)\r
- if err != nil {\r
- return []module.ControllerObject{}, err\r
- }\r
-\r
-\r
- values, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")\r
- }\r
-\r
-\r
- var resp []module.ControllerObject\r
- for _, value := range values {\r
- t := c.CreateEmptyObject()\r
- err = db.DBconn.Unmarshal(value, t)\r
- if err != nil {\r
- return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")\r
- }\r
- resp = append(resp, t)\r
- }\r
-\r
- return resp, nil\r
-}\r
-\r
-func (d *DBUtils) UpdateObject(c ControllerObjectManager,\r
- m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
-\r
- key, err := c.GetStoreKey(m, t, false)\r
- if err != nil {\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
- err = db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Updating DB Entry")\r
- }\r
- return t, nil\r
-}\r
-\r
-func (d *DBUtils) DeleteObject(c ControllerObjectManager, m map[string]string) error {\r
- key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- err = db.DBconn.Remove(c.GetStoreName(), key)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Delete Object")\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (d *DBUtils) RegisterDevice(cluster_name string, kubeconfig string) error {\r
- ccc := rsync.NewCloudConfigClient()\r
-\r
- config, _ := ccc.GetCloudConfig(PROVIDERNAME, cluster_name, "0", "sdewan-system")\r
- if config.Config != "" {\r
- ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "sdewan-system")\r
- }\r
-\r
- _, err := ccc.CreateCloudConfig(PROVIDERNAME, cluster_name, "0", "sdewan-system", kubeconfig)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Error creating cloud config")\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func (d *DBUtils) UnregisterDevice(cluster_name string) error {\r
- ccc := rsync.NewCloudConfigClient()\r
-\r
- err := ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "sdewan-system")\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Error deleting cloud config")\r
- }\r
-\r
- return nil\r
-}\r
-\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"
+ rsync "github.com/open-ness/EMCO/src/rsync/pkg/db"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const PROVIDERNAME = "akraino_scc"
+
+type Cluster struct {
+ Metadata mtypes.Metadata `json:"metadata"`
+}
+
+type ClusterContent struct {
+ Kubeconfig string `json:"kubeconfig"`
+}
+
+type ClusterKey struct {
+ ClusterProviderName string `json:"provider"`
+ ClusterName string `json:"cluster"`
+}
+
+type DBUtils struct {
+}
+
+var dbutils = DBUtils{}
+
+func GetDBUtils() *DBUtils {
+ return &dbutils
+}
+
+func (d *DBUtils) CheckDep(c ControllerObjectManager, m map[string]string) error {
+ depsResManagers := c.GetDepResManagers()
+ for _, mgr := range depsResManagers {
+ _, err := d.GetObject(mgr, m)
+ if err != nil {
+ return pkgerrors.New("Fail to find " + mgr.GetStoreMeta())
+ }
+ }
+
+ return nil
+}
+
+func (d *DBUtils) CheckOwn(c ControllerObjectManager, m map[string]string) error {
+ depsOwnManagers := c.GetOwnResManagers()
+ for _, mgr := range depsOwnManagers {
+ objs, err := d.GetObjects(mgr, m)
+ if err == nil && len(objs) > 0 {
+ return pkgerrors.New("Sub-resource found : " + mgr.GetStoreMeta())
+ }
+ }
+ return nil
+}
+
+func (d *DBUtils) CreateObject(c ControllerObjectManager, m map[string]string,
+ t module.ControllerObject) (module.ControllerObject, error) {
+
+ key, _ := c.GetStoreKey(m, t, false)
+ err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.New("Unable to create the object")
+ }
+
+ return t, nil
+}
+
+func (d *DBUtils) GetObject(c ControllerObjectManager,
+ m map[string]string) (module.ControllerObject, error) {
+
+ key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false)
+ if err != nil {
+ return c.CreateEmptyObject(), err
+ }
+
+ value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Get Resource")
+ }
+
+ if value != nil {
+ r := c.CreateEmptyObject()
+ err = db.DBconn.Unmarshal(value[0], r)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value")
+ }
+ return r, nil
+ }
+
+ return c.CreateEmptyObject(), pkgerrors.New("No Object")
+}
+
+func (d *DBUtils) GetObjects(c ControllerObjectManager,
+ m map[string]string) ([]module.ControllerObject, error) {
+
+ key, err := c.GetStoreKey(m, c.CreateEmptyObject(), true)
+ if err != nil {
+ return []module.ControllerObject{}, err
+ }
+
+ values, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta())
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects")
+ }
+
+ var resp []module.ControllerObject
+ for _, value := range values {
+ t := c.CreateEmptyObject()
+ err = db.DBconn.Unmarshal(value, t)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values")
+ }
+ resp = append(resp, t)
+ }
+
+ return resp, nil
+}
+
+func (d *DBUtils) UpdateObject(c ControllerObjectManager,
+ m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+
+ key, err := c.GetStoreKey(m, t, false)
+ if err != nil {
+ return c.CreateEmptyObject(), err
+ }
+
+ err = db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Updating DB Entry")
+ }
+ return t, nil
+}
+
+func (d *DBUtils) DeleteObject(c ControllerObjectManager, m map[string]string) error {
+ key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false)
+ if err != nil {
+ return err
+ }
+
+ err = db.DBconn.Remove(c.GetStoreName(), key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Delete Object")
+ }
+
+ return nil
+}
+
+func (d *DBUtils) RegisterDevice(cluster_name string, kubeconfig string) error {
+ ccc := rsync.NewCloudConfigClient()
+
+ config, _ := ccc.GetCloudConfig(PROVIDERNAME, cluster_name, "0", "default")
+ if config.Config != "" {
+ ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default")
+ }
+
+ _, err := ccc.CreateCloudConfig(PROVIDERNAME, cluster_name, "0", "default", kubeconfig)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error creating cloud config")
+ }
+
+ return nil
+}
+
+func (d *DBUtils) UnregisterDevice(cluster_name string) error {
+ ccc := rsync.NewCloudConfigClient()
+
+ err := ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default")
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error deleting cloud config")
+ }
+
+ return nil
+}
-/*\r
-* Copyright 2020 Intel Corporation, Inc\r
-*\r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
-* you may not use this file except in compliance with the License.\r
-* You may obtain a copy of the License at\r
-*\r
-* http://www.apache.org/licenses/LICENSE-2.0\r
-*\r
-* Unless required by applicable law or agreed to in writing, software\r
-* distributed under the License is distributed on an "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-* See the License for the specific language governing permissions and\r
-* limitations under the License.\r
-*/\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "log"\r
- //"strconv"\r
- "encoding/json"\r
- "encoding/base64"\r
- "strings"\r
- "time"\r
- "github.com/matryer/runner"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- //"github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const SCC_RESOURCE = "scc_ipsec_resource"\r
-const RegStatus = "RegStatus"\r
-\r
-var ips []string\r
-var task *runner.Task\r
-\r
-type DeviceObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- DeviceName string `json:"device-name"`\r
-}\r
-\r
-// DeviceObjectManager implements the ControllerObjectManager\r
-type DeviceObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewDeviceObjectManager() *DeviceObjectManager {\r
- return &DeviceObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "device",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *DeviceObjectManager) GetResourceName() string {\r
- return DeviceResource\r
-}\r
-\r
-func (c *DeviceObjectManager) IsOperationSupported(oper string) bool {\r
- return true\r
-}\r
-\r
-func (c *DeviceObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.DeviceObject{}\r
-}\r
-\r
-func (c *DeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- key := DeviceObjectKey{\r
- OverlayName: overlay_name,\r
- DeviceName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.DeviceObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[DeviceResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- }\r
-\r
- key.DeviceName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name")\r
- }\r
-\r
- key.DeviceName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *DeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.DeviceObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- // initial Status\r
- v.Status.Data = make(map[string]string)\r
- return &v, err\r
-}\r
-\r
-func (c *DeviceObjectManager) PreProcessing(m map[string]string, t module.ControllerObject) error {\r
- to := t.(*module.DeviceObject)\r
-\r
- ipr_manager := GetManagerset().IPRange\r
- kubeutil := GetKubeConfigUtil()\r
-\r
- local_public_ips := to.Specification.PublicIps\r
- kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Fail to decode kubeconfig")\r
- }\r
-\r
- // Set the Register status to pending\r
- to.Status.Data[RegStatus] = "pending"\r
-\r
- if len(local_public_ips) > 0{\r
- // Use public IP as external connection\r
- to.Status.Mode = 1\r
-\r
- kube_config, local_public_ip, err := kubeutil.checkKubeConfigAvail(kube_config, local_public_ips, "6443")\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Fail to verify public ip")\r
- }\r
-\r
- // Set IP in device\r
- log.Println("Use public ip " + local_public_ip)\r
- to.Status.Ip = local_public_ip\r
-\r
- // Set new kubeconfig in device\r
- to.Specification.KubeConfig = base64.StdEncoding.EncodeToString([]byte(kube_config))\r
- } else {\r
- // Use scc as external connection\r
- to.Status.Mode = 2\r
-\r
- // allocate OIP for device\r
- overlay_name := m[OverlayResource]\r
- oip, err := ipr_manager.Allocate(overlay_name, to.Metadata.Name)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Fail to allocate overlay ip for " + to.Metadata.Name)\r
- }\r
-\r
- // Set OIP in Device\r
- log.Println("Using overlay ip " + oip)\r
- to.Status.Ip = oip\r
-\r
- // Get all proposal resources\r
- proposal := GetManagerset().Proposal\r
- proposals, err := proposal.GetObjects(m)\r
- if len(proposals) == 0 || err != nil {\r
- log.Println("Missing Proposal in the overlay\n")\r
- return pkgerrors.New("Error in getting proposals")\r
- }\r
-\r
- var all_proposal []string\r
- var proposalresource []*resource.ProposalResource\r
- for i:= 0 ; i < len(proposals); i++ {\r
- proposal_obj := proposals[i].(*module.ProposalObject)\r
- all_proposal = append(all_proposal, proposal_obj.Metadata.Name)\r
- pr := proposal_obj.ToResource()\r
- proposalresource = append(proposalresource, pr)\r
- }\r
-\r
- //Extract SCC cert/key\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println("Getting certutil error")\r
- }\r
- crts, key, err := cu.GetKeypair(SCCCertName, NameSpaceName)\r
- crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]\r
-\r
- root_ca := GetRootCA(overlay_name)\r
-\r
- // Build up ipsec resource\r
- scc_conn := resource.Connection{\r
- Name: DEFAULT_CONN,\r
- ConnectionType: CONN_TYPE,\r
- Mode: MODE,\r
- Mark: DEFAULT_MARK,\r
- RemoteSourceIp: oip,\r
- LocalUpDown: DEFAULT_UPDOWN,\r
- CryptoProposal: all_proposal,\r
- }\r
-\r
- scc_ipsec_resource := resource.IpsecResource{\r
- Name: "localto" + format_resource_name(to.Metadata.Name, ""),\r
- Type: VTI_MODE,\r
- Remote: ANY,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+ SCCCertName,\r
- RemoteIdentifier: "CN=" + to.GetCertName(),\r
- CryptoProposal: all_proposal,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: scc_conn,\r
- }\r
-\r
- scc := module.EmptyObject{\r
- Metadata: module.ObjectMetaData{"local", "", "", ""}}\r
-\r
- // Add and deploy resource\r
- resutil := NewResUtil()\r
- resutil.AddResource(&scc, "create", &scc_ipsec_resource)\r
- for i :=0; i < len(proposalresource); i++ {\r
- resutil.AddResource(&scc, "create", proposalresource[i])\r
- }\r
-\r
- resutil.Deploy("localto" + to.Metadata.Name, "YAML")\r
-\r
- //Reserve ipsec resource to device object\r
- res_str, err := resource.GetResourceBuilder().ToString(&scc_ipsec_resource)\r
- to.Status.Data[SCC_RESOURCE] = res_str\r
-\r
- ips = append(ips, oip)\r
-\r
- }\r
- return nil\r
-\r
-}\r
-\r
-func (c *DeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- err := c.PreProcessing(m, t)\r
- if err != nil {\r
- return c.CreateEmptyObject(), err\r
- }\r
-\r
- to := t.(*module.DeviceObject)\r
- task = runner.Go(func(ShouldStop runner.S) error {\r
- for to.Status.Data[RegStatus] != "success" {\r
- err = c.PostRegister(m, t)\r
- if err != nil {\r
- log.Println(err)\r
- }\r
- time.Sleep(5 * time.Second)\r
- if ShouldStop() {\r
- break\r
- }\r
- }\r
- return nil\r
- })\r
-\r
- // DB Operation\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
- return t, err\r
-}\r
-\r
-func (c *DeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *DeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *DeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().UpdateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *DeviceObjectManager) DeleteObject(m map[string]string) error {\r
- t, err := c.GetObject(m)\r
- if err != nil {\r
- return nil\r
- }\r
-\r
- if ( task != nil && task.Running() ) {\r
- task.Stop()\r
- select {\r
- case <-task.StopChan():\r
- case <-time.After(2 * time.Second):\r
- log.Println("Goroutine register device stopped")\r
- }\r
- }\r
-\r
- //overlay_manager := GetManagerset().Overlay\r
- ipr_manager := GetManagerset().IPRange\r
-\r
- overlay_name := m[OverlayResource]\r
- device_name := m[DeviceResource]\r
-\r
- to := t.(*module.DeviceObject)\r
-\r
- //If the device is in mode 2:\r
- // * Free OIP assigned\r
- // * Remove ipsec configuration on SCC\r
- if to.Status.Mode == 2 {\r
- // Free OIP\r
- ipr_manager.Free(overlay_name, to.Status.Ip)\r
-\r
- scc := module.EmptyObject{\r
- Metadata: module.ObjectMetaData{"local", "", "", ""}}\r
-\r
- resutils := NewResUtil()\r
- r_str := to.Status.Data["scc_ipsec_resource"]\r
- r, _ := resource.GetResourceBuilder().ToObject(r_str)\r
- resutils.AddResource(&scc, "create", r)\r
- resutils.Undeploy("localto" + device_name, "YAML")\r
- }\r
-\r
-\r
- // DB Operation\r
- err = GetDBUtils().DeleteObject(c, m)\r
-\r
- return err\r
-}\r
-\r
-func GetDeviceCertificate(overlay_name string, device_name string)(string, string, error){\r
- cert := GetManagerset().Cert\r
- _, crts, key, err := cert.GetOrCreateDC(overlay_name, device_name)\r
- if err != nil {\r
- log.Println("Error in getting cert for device ...")\r
- return "", "", err\r
- }\r
-\r
- crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]\r
- return crt, key, nil\r
-}\r
-\r
-func (c *DeviceObjectManager) PostRegister(m map[string]string, t module.ControllerObject) error {\r
-\r
- overlay_manager := GetManagerset().Overlay\r
-\r
- to := t.(*module.DeviceObject)\r
- log.Println("Registering device " + to.Metadata.Name + " ... ")\r
-\r
-\r
- if to.Status.Mode == 2 {\r
- kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)\r
- if err != nil {\r
- to.Status.Data[RegStatus] = "failed"\r
- }\r
-\r
- kube_config, _, err = kubeutil.checkKubeConfigAvail(kube_config, ips, DEFAULT_K8S_API_SERVER_PORT)\r
- if err != nil {\r
- //TODO: check the error type, and if is unauthorized then switch the status to failed.\r
- return err\r
- }\r
-\r
- to.Status.Data[RegStatus] = "success"\r
- to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(kube_config)\r
- err = GetDBUtils().RegisterDevice(to.Metadata.Name, to.Specification.KubeConfig)\r
- if err != nil {\r
- log.Println(err)\r
- return err\r
- }\r
- log.Println("scc connection is verified.")\r
-\r
- } else {\r
- to.Status.Data[RegStatus] = "success"\r
- }\r
-\r
- if to.Status.Data[RegStatus] == "success" {\r
- devices, err := c.GetObjects(m)\r
- if err != nil {\r
- log.Println(err)\r
- return err\r
- }\r
-\r
- //TODO: Need to add funcs to re-create connections if some of the connections are not ready\r
- //Maybe because of cert not ready or other reasons.\r
- for i := 0; i < len(devices); i++ {\r
- dev := devices[i].(*module.DeviceObject)\r
- if to.Status.Mode == 1 || dev.Status.Mode == 1 {\r
- err = overlay_manager.SetupConnection(m, to, dev, DEVICETODEVICE, NameSpaceName)\r
- if err != nil {\r
- return err\r
- }\r
- }\r
- }\r
- }\r
-\r
- c.UpdateObject(m, t)\r
- return nil\r
-}\r
+/*
+* Copyright 2020 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* 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 manager
+
+import (
+ "io"
+ "log"
+ //"strconv"
+ "encoding/base64"
+ "encoding/json"
+ "github.com/matryer/runner"
+ "strings"
+ "time"
+
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ //"github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const SCC_RESOURCE = "scc_ipsec_resource"
+const RegStatus = "RegStatus"
+
+var ips []string
+var task *runner.Task
+
+type DeviceObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ DeviceName string `json:"device-name"`
+}
+
+// DeviceObjectManager implements the ControllerObjectManager
+type DeviceObjectManager struct {
+ BaseObjectManager
+}
+
+func NewDeviceObjectManager() *DeviceObjectManager {
+ return &DeviceObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "device",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *DeviceObjectManager) GetResourceName() string {
+ return DeviceResource
+}
+
+func (c *DeviceObjectManager) IsOperationSupported(oper string) bool {
+ return true
+}
+
+func (c *DeviceObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.DeviceObject{}
+}
+
+func (c *DeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ key := DeviceObjectKey{
+ OverlayName: overlay_name,
+ DeviceName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.DeviceObject)
+ meta_name := to.Metadata.Name
+ res_name := m[DeviceResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.DeviceName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.DeviceName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *DeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.DeviceObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ // initial Status
+ v.Status.Data = make(map[string]string)
+ return &v, err
+}
+
+func (c *DeviceObjectManager) PreProcessing(m map[string]string, t module.ControllerObject) error {
+ to := t.(*module.DeviceObject)
+
+ ipr_manager := GetManagerset().IPRange
+ kubeutil := GetKubeConfigUtil()
+
+ local_public_ips := to.Specification.PublicIps
+ kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Fail to decode kubeconfig")
+ }
+
+ // Set the Register status to pending
+ to.Status.Data[RegStatus] = "pending"
+
+ if len(local_public_ips) > 0 {
+ // Use public IP as external connection
+ to.Status.Mode = 1
+
+ kube_config, local_public_ip, err := kubeutil.checkKubeConfigAvail(kube_config, local_public_ips, "6443")
+ if err != nil {
+ return pkgerrors.Wrap(err, "Fail to verify public ip")
+ }
+
+ // Set IP in device
+ log.Println("Use public ip " + local_public_ip)
+ to.Status.Ip = local_public_ip
+
+ // Set new kubeconfig in device
+ to.Specification.KubeConfig = base64.StdEncoding.EncodeToString([]byte(kube_config))
+ } else {
+ // Use scc as external connection
+ to.Status.Mode = 2
+
+ // allocate OIP for device
+ overlay_name := m[OverlayResource]
+ oip, err := ipr_manager.Allocate(overlay_name, to.Metadata.Name)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Fail to allocate overlay ip for "+to.Metadata.Name)
+ }
+
+ // Set OIP in Device
+ log.Println("Using overlay ip " + oip)
+ to.Status.Ip = oip
+
+ // Get all proposal resources
+ proposal := GetManagerset().Proposal
+ proposals, err := proposal.GetObjects(m)
+ if len(proposals) == 0 || err != nil {
+ log.Println("Missing Proposal in the overlay\n")
+ return pkgerrors.New("Error in getting proposals")
+ }
+
+ var all_proposal []string
+ var proposalresource []*resource.ProposalResource
+ for i := 0; i < len(proposals); i++ {
+ proposal_obj := proposals[i].(*module.ProposalObject)
+ all_proposal = append(all_proposal, proposal_obj.Metadata.Name)
+ pr := proposal_obj.ToResource()
+ proposalresource = append(proposalresource, pr)
+ }
+
+ //Extract SCC cert/key
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println("Getting certutil error")
+ }
+ crts, key, err := cu.GetKeypair(SCCCertName, NameSpaceName)
+ crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]
+
+ root_ca := GetRootCA(overlay_name)
+
+ // Build up ipsec resource
+ scc_conn := resource.Connection{
+ Name: DEFAULT_CONN,
+ ConnectionType: CONN_TYPE,
+ Mode: MODE,
+ Mark: DEFAULT_MARK,
+ RemoteSourceIp: oip,
+ LocalUpDown: DEFAULT_UPDOWN,
+ CryptoProposal: all_proposal,
+ }
+
+ scc_ipsec_resource := resource.IpsecResource{
+ Name: "localto" + format_resource_name(to.Metadata.Name, ""),
+ Type: VTI_MODE,
+ Remote: ANY,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + SCCCertName,
+ RemoteIdentifier: "CN=" + to.GetCertName(),
+ CryptoProposal: all_proposal,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: scc_conn,
+ }
+
+ scc := module.EmptyObject{
+ Metadata: module.ObjectMetaData{"local", "", "", ""}}
+
+ // Add and deploy resource
+ resutil := NewResUtil()
+ resutil.AddResource(&scc, "create", &scc_ipsec_resource)
+ for i := 0; i < len(proposalresource); i++ {
+ resutil.AddResource(&scc, "create", proposalresource[i])
+ }
+
+ resutil.Deploy("localto"+to.Metadata.Name, "YAML")
+
+ //Reserve ipsec resource to device object
+ res_str, err := resource.GetResourceBuilder().ToString(&scc_ipsec_resource)
+ to.Status.Data[SCC_RESOURCE] = res_str
+
+ ips = append(ips, oip)
+
+ }
+ return nil
+
+}
+
+func (c *DeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ err := c.PreProcessing(m, t)
+ if err != nil {
+ return c.CreateEmptyObject(), err
+ }
+
+ to := t.(*module.DeviceObject)
+ task = runner.Go(func(ShouldStop runner.S) error {
+ for to.Status.Data[RegStatus] != "success" {
+ err = c.PostRegister(m, t)
+ if err != nil {
+ log.Println(err)
+ }
+ time.Sleep(5 * time.Second)
+ if ShouldStop() {
+ break
+ }
+ }
+ return nil
+ })
+
+ // DB Operation
+ t, err = GetDBUtils().CreateObject(c, m, t)
+ return t, err
+}
+
+func (c *DeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ return t, err
+}
+
+func (c *DeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *DeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().UpdateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *DeviceObjectManager) DeleteObject(m map[string]string) error {
+ t, err := c.GetObject(m)
+ if err != nil {
+ return nil
+ }
+
+ if task != nil && task.Running() {
+ task.Stop()
+ select {
+ case <-task.StopChan():
+ case <-time.After(2 * time.Second):
+ log.Println("Goroutine register device stopped")
+ }
+ }
+
+ //overlay_manager := GetManagerset().Overlay
+ ipr_manager := GetManagerset().IPRange
+
+ overlay_name := m[OverlayResource]
+ device_name := m[DeviceResource]
+
+ to := t.(*module.DeviceObject)
+
+ //If the device is in mode 2:
+ // * Free OIP assigned
+ // * Remove ipsec configuration on SCC
+ if to.Status.Mode == 2 {
+ // Free OIP
+ ipr_manager.Free(overlay_name, to.Status.Ip)
+
+ scc := module.EmptyObject{
+ Metadata: module.ObjectMetaData{"local", "", "", ""}}
+
+ resutils := NewResUtil()
+ r_str := to.Status.Data["scc_ipsec_resource"]
+ r, _ := resource.GetResourceBuilder().ToObject(r_str)
+ resutils.AddResource(&scc, "create", r)
+ resutils.Undeploy("localto"+device_name, "YAML")
+ }
+
+ // DB Operation
+ err = GetDBUtils().DeleteObject(c, m)
+
+ return err
+}
+
+func GetDeviceCertificate(overlay_name string, device_name string) (string, string, error) {
+ cert := GetManagerset().Cert
+ _, crts, key, err := cert.GetOrCreateDC(overlay_name, device_name)
+ if err != nil {
+ log.Println("Error in getting cert for device ...")
+ return "", "", err
+ }
+
+ crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]
+ return crt, key, nil
+}
+
+func (c *DeviceObjectManager) PostRegister(m map[string]string, t module.ControllerObject) error {
+
+ overlay_manager := GetManagerset().Overlay
+
+ to := t.(*module.DeviceObject)
+ log.Println("Registering device " + to.Metadata.Name + " ... ")
+
+ if to.Status.Mode == 2 {
+ kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)
+ if err != nil {
+ to.Status.Data[RegStatus] = "failed"
+ }
+
+ kube_config, _, err = kubeutil.checkKubeConfigAvail(kube_config, ips, DEFAULT_K8S_API_SERVER_PORT)
+ if err != nil {
+ //TODO: check the error type, and if is unauthorized then switch the status to failed.
+ return err
+ }
+
+ to.Status.Data[RegStatus] = "success"
+ to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(kube_config)
+ err = GetDBUtils().RegisterDevice(to.Metadata.Name, to.Specification.KubeConfig)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+ log.Println("scc connection is verified.")
+
+ } else {
+ to.Status.Data[RegStatus] = "success"
+ }
+
+ if to.Status.Data[RegStatus] == "success" {
+ devices, err := c.GetObjects(m)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+
+ //TODO: Need to add funcs to re-create connections if some of the connections are not ready
+ //Maybe because of cert not ready or other reasons.
+ for i := 0; i < len(devices); i++ {
+ dev := devices[i].(*module.DeviceObject)
+ if to.Status.Mode == 1 || dev.Status.Mode == 1 {
+ err = overlay_manager.SetupConnection(m, to, dev, DEVICETODEVICE, NameSpaceName)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ c.UpdateObject(m, t)
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "encoding/json"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type DeviceConnObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- DeviceName string `json:"device-name"`\r
- ConnName string `json:"connection-name"`\r
-}\r
-\r
-// DeviceConnObjectManager implements the ControllerObjectManager\r
-type DeviceConnObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewDeviceConnObjectManager() *DeviceConnObjectManager {\r
- return &DeviceConnObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "deviceconn",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *DeviceConnObjectManager) GetResourceName() string {\r
- return ConnectionResource\r
-}\r
-\r
-func (c *DeviceConnObjectManager) IsOperationSupported(oper string) bool {\r
- if oper == "GETS" {\r
- return true\r
- }\r
- return false\r
-}\r
-\r
-func (c *DeviceConnObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.ConnectionObject{}\r
-}\r
-\r
-func (c *DeviceConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- device_name := m[DeviceResource]\r
- key := DeviceConnObjectKey{\r
- OverlayName: overlay_name,\r
- DeviceName: device_name,\r
- ConnName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.ConnectionObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[ConnectionResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- } \r
-\r
- key.ConnName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name") \r
- }\r
-\r
- key.ConnName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *DeviceConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.ConnectionObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *DeviceConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *DeviceConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *DeviceConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- overlay_name := m[OverlayResource]\r
- device_name := m[DeviceResource]\r
-\r
- return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Device", device_name))\r
-}\r
-\r
-func (c *DeviceConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *DeviceConnObjectManager) DeleteObject(m map[string]string) error {\r
- return pkgerrors.New("Not implemented")\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+)
+
+type DeviceConnObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ DeviceName string `json:"device-name"`
+ ConnName string `json:"connection-name"`
+}
+
+// DeviceConnObjectManager implements the ControllerObjectManager
+type DeviceConnObjectManager struct {
+ BaseObjectManager
+}
+
+func NewDeviceConnObjectManager() *DeviceConnObjectManager {
+ return &DeviceConnObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "deviceconn",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *DeviceConnObjectManager) GetResourceName() string {
+ return ConnectionResource
+}
+
+func (c *DeviceConnObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "GETS" {
+ return true
+ }
+ return false
+}
+
+func (c *DeviceConnObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.ConnectionObject{}
+}
+
+func (c *DeviceConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ device_name := m[DeviceResource]
+ key := DeviceConnObjectKey{
+ OverlayName: overlay_name,
+ DeviceName: device_name,
+ ConnName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.ConnectionObject)
+ meta_name := to.Metadata.Name
+ res_name := m[ConnectionResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.ConnName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.ConnName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *DeviceConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.ConnectionObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *DeviceConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *DeviceConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *DeviceConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ overlay_name := m[OverlayResource]
+ device_name := m[DeviceResource]
+
+ return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Device", device_name))
+}
+
+func (c *DeviceConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *DeviceConnObjectManager) DeleteObject(m map[string]string) error {
+ return pkgerrors.New("Not implemented")
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "log"\r
- "strings"\r
- "encoding/json"\r
- "encoding/base64"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const DEFAULTPORT = "6443"\r
-\r
-type HubObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- HubName string `json:"hub-name"`\r
-}\r
-\r
-// HubObjectManager implements the ControllerObjectManager\r
-type HubObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewHubObjectManager() *HubObjectManager {\r
- return &HubObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "hub",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *HubObjectManager) GetResourceName() string {\r
- return HubResource\r
-}\r
-\r
-func (c *HubObjectManager) IsOperationSupported(oper string) bool {\r
- return true\r
-}\r
-\r
-func (c *HubObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.HubObject{}\r
-}\r
-\r
-func (c *HubObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- key := HubObjectKey{\r
- OverlayName: overlay_name,\r
- HubName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.HubObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[HubResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- }\r
-\r
- key.HubName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name")\r
- }\r
-\r
- key.HubName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *HubObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.HubObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- // initial Status\r
- v.Status.Data = make(map[string]string)\r
- v.Status.ProxyPort = make(map[string]string)\r
- return &v, err\r
-}\r
-\r
-func (c *HubObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- overlay := GetManagerset().Overlay\r
- overlay_name := m[OverlayResource]\r
- to := t.(*module.HubObject)\r
- hub_name := to.Metadata.Name\r
-\r
- //Todo: Check if public ip can be used.\r
- var local_public_ip string\r
- var config []byte\r
- config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)\r
- if err != nil {\r
- log.Println(err)\r
- return t, err\r
- }\r
-\r
- local_public_ips := to.Specification.PublicIps\r
-\r
- kubeutil := GetKubeConfigUtil()\r
- config, local_public_ip, err = kubeutil.checkKubeConfigAvail(config, local_public_ips, DEFAULTPORT)\r
- if err == nil {\r
- log.Println("Public IP address verified: " + local_public_ip)\r
- to.Status.Ip = local_public_ip\r
- to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(config)\r
- err := GetDBUtils().RegisterDevice(hub_name, to.Specification.KubeConfig)\r
- if err != nil {\r
- log.Println(err)\r
- }\r
- } else {\r
- return t, err\r
- }\r
-\r
- //Create cert for ipsec connection\r
- log.Println("Create Certificate: " + to.GetCertName())\r
- _, _, err = overlay.CreateCertificate(overlay_name, to.GetCertName())\r
- if err != nil {\r
- return t, err\r
- }\r
-\r
- //Get all available hub objects\r
- hubs, err := c.GetObjects(m)\r
- if err != nil {\r
- log.Println(err)\r
- }\r
-\r
- //TODO: Need to add funcs to re-create connections if some of the connections are not ready\r
- //Maybe because of cert not ready or other reasons.\r
- if len(hubs) > 0 && err == nil {\r
- for i := 0; i < len(hubs); i++ {\r
- err := overlay.SetupConnection(m, t, hubs[i], HUBTOHUB, NameSpaceName)\r
- if err != nil {\r
- log.Println("Setup connection with " + hubs[i].(*module.HubObject).Metadata.Name + " failed.")\r
- }\r
- }\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
- } else {\r
-\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
- }\r
-\r
- return t, err\r
-}\r
-\r
-func (c *HubObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *HubObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *HubObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().UpdateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *HubObjectManager) DeleteObject(m map[string]string) error {\r
- //Check resource exists\r
-\r
- t, err := c.GetObject(m)\r
- if err != nil {\r
- return nil\r
- }\r
-\r
- overlay_manager := GetManagerset().Overlay\r
- conn_manager := GetConnectionManager()\r
-\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
-\r
-// Reset all IpSec connection setup by this device\r
- conns, err := conn_manager.GetObjects(overlay_name, module.CreateEndName(t.GetType(), hub_name))\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- for i := 0; i < len(conns); i++ {\r
- conn := conns[i].(*module.ConnectionObject)\r
- err = conn_manager.Undeploy(overlay_name, *conn)\r
- if err != nil {\r
- log.Println(err)\r
- }\r
- }\r
- }\r
-\r
- to := t.(*module.HubObject)\r
- log.Println("Delete Certificate: " + to.GetCertName())\r
- overlay_manager.DeleteCertificate(to.GetCertName())\r
-\r
-\r
- // DB Operation\r
- err = GetDBUtils().DeleteObject(c, m)\r
-\r
- return err\r
-}\r
-\r
-func GetHubCertificate(cert_name string, namespace string)(string, string, error){\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- return "", "", err\r
- } else {\r
- ready := cu.IsCertReady(cert_name, namespace)\r
- if ready != true {\r
- return "", "", pkgerrors.New("Cert for hub is not ready")\r
- } else {\r
- crts, key, err := cu.GetKeypair(cert_name, namespace)\r
- crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]\r
- if err != nil {\r
- log.Println(err)\r
- return "", "", err\r
- }\r
- return crt, key, nil\r
- }\r
- }\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "io"
+ "log"
+ "strings"
+
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const DEFAULTPORT = "6443"
+
+type HubObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ HubName string `json:"hub-name"`
+}
+
+// HubObjectManager implements the ControllerObjectManager
+type HubObjectManager struct {
+ BaseObjectManager
+}
+
+func NewHubObjectManager() *HubObjectManager {
+ return &HubObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "hub",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *HubObjectManager) GetResourceName() string {
+ return HubResource
+}
+
+func (c *HubObjectManager) IsOperationSupported(oper string) bool {
+ return true
+}
+
+func (c *HubObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.HubObject{}
+}
+
+func (c *HubObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ key := HubObjectKey{
+ OverlayName: overlay_name,
+ HubName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.HubObject)
+ meta_name := to.Metadata.Name
+ res_name := m[HubResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.HubName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.HubName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *HubObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.HubObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ // initial Status
+ v.Status.Data = make(map[string]string)
+ v.Status.ProxyPort = make(map[string]string)
+ return &v, err
+}
+
+func (c *HubObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ overlay := GetManagerset().Overlay
+ overlay_name := m[OverlayResource]
+ to := t.(*module.HubObject)
+ hub_name := to.Metadata.Name
+
+ //Todo: Check if public ip can be used.
+ var local_public_ip string
+ var config []byte
+ config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig)
+ if err != nil {
+ log.Println(err)
+ return t, err
+ }
+
+ local_public_ips := to.Specification.PublicIps
+
+ kubeutil := GetKubeConfigUtil()
+ config, local_public_ip, err = kubeutil.checkKubeConfigAvail(config, local_public_ips, DEFAULTPORT)
+ if err == nil {
+ log.Println("Public IP address verified: " + local_public_ip)
+ to.Status.Ip = local_public_ip
+ to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(config)
+ err := GetDBUtils().RegisterDevice(hub_name, to.Specification.KubeConfig)
+ if err != nil {
+ log.Println(err)
+ }
+ } else {
+ return t, err
+ }
+
+ //Create cert for ipsec connection
+ log.Println("Create Certificate: " + to.GetCertName())
+ _, _, err = overlay.CreateCertificate(overlay_name, to.GetCertName())
+ if err != nil {
+ return t, err
+ }
+
+ //Get all available hub objects
+ hubs, err := c.GetObjects(m)
+ if err != nil {
+ log.Println(err)
+ }
+
+ //TODO: Need to add funcs to re-create connections if some of the connections are not ready
+ //Maybe because of cert not ready or other reasons.
+ if len(hubs) > 0 && err == nil {
+ for i := 0; i < len(hubs); i++ {
+ err := overlay.SetupConnection(m, t, hubs[i], HUBTOHUB, NameSpaceName)
+ if err != nil {
+ log.Println("Setup connection with " + hubs[i].(*module.HubObject).Metadata.Name + " failed.")
+ }
+ }
+ t, err = GetDBUtils().CreateObject(c, m, t)
+ } else {
+
+ t, err = GetDBUtils().CreateObject(c, m, t)
+ }
+
+ return t, err
+}
+
+func (c *HubObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ return t, err
+}
+
+func (c *HubObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *HubObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().UpdateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *HubObjectManager) DeleteObject(m map[string]string) error {
+ //Check resource exists
+
+ t, err := c.GetObject(m)
+ if err != nil {
+ return nil
+ }
+
+ overlay_manager := GetManagerset().Overlay
+ conn_manager := GetConnectionManager()
+
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+
+ // Reset all IpSec connection setup by this device
+ conns, err := conn_manager.GetObjects(overlay_name, module.CreateEndName(t.GetType(), hub_name))
+ if err != nil {
+ log.Println(err)
+ } else {
+ for i := 0; i < len(conns); i++ {
+ conn := conns[i].(*module.ConnectionObject)
+ err = conn_manager.Undeploy(overlay_name, *conn)
+ if err != nil {
+ log.Println(err)
+ }
+ }
+ }
+
+ to := t.(*module.HubObject)
+ log.Println("Delete Certificate: " + to.GetCertName())
+ overlay_manager.DeleteCertificate(to.GetCertName())
+
+ // DB Operation
+ err = GetDBUtils().DeleteObject(c, m)
+
+ return err
+}
+
+func GetHubCertificate(cert_name string, namespace string) (string, string, error) {
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ return "", "", err
+ } else {
+ ready := cu.IsCertReady(cert_name, namespace)
+ if ready != true {
+ return "", "", pkgerrors.New("Cert for hub is not ready")
+ } else {
+ crts, key, err := cu.GetKeypair(cert_name, namespace)
+ crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]
+ if err != nil {
+ log.Println(err)
+ return "", "", err
+ }
+ return crt, key, nil
+ }
+ }
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "encoding/json"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type HubConnObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- HubName string `json:"hub-name"`\r
- ConnName string `json:"connection-name"`\r
-}\r
-\r
-// HubConnObjectManager implements the ControllerObjectManager\r
-type HubConnObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewHubConnObjectManager() *HubConnObjectManager {\r
- return &HubConnObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "hubconn",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *HubConnObjectManager) GetResourceName() string {\r
- return ConnectionResource\r
-}\r
-\r
-func (c *HubConnObjectManager) IsOperationSupported(oper string) bool {\r
- if oper == "GETS" {\r
- return true\r
- }\r
- return false\r
-}\r
-\r
-func (c *HubConnObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.ConnectionObject{}\r
-}\r
-\r
-func (c *HubConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
- key := HubConnObjectKey{\r
- OverlayName: overlay_name,\r
- HubName: hub_name,\r
- ConnName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.ConnectionObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[ConnectionResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- } \r
-\r
- key.ConnName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name") \r
- }\r
-\r
- key.ConnName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *HubConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.ConnectionObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *HubConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
-\r
- return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Hub", hub_name))\r
-}\r
-\r
-func (c *HubConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubConnObjectManager) DeleteObject(m map[string]string) error {\r
- return pkgerrors.New("Not implemented")\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+)
+
+type HubConnObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ HubName string `json:"hub-name"`
+ ConnName string `json:"connection-name"`
+}
+
+// HubConnObjectManager implements the ControllerObjectManager
+type HubConnObjectManager struct {
+ BaseObjectManager
+}
+
+func NewHubConnObjectManager() *HubConnObjectManager {
+ return &HubConnObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "hubconn",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *HubConnObjectManager) GetResourceName() string {
+ return ConnectionResource
+}
+
+func (c *HubConnObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "GETS" {
+ return true
+ }
+ return false
+}
+
+func (c *HubConnObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.ConnectionObject{}
+}
+
+func (c *HubConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+ key := HubConnObjectKey{
+ OverlayName: overlay_name,
+ HubName: hub_name,
+ ConnName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.ConnectionObject)
+ meta_name := to.Metadata.Name
+ res_name := m[ConnectionResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.ConnName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.ConnName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *HubConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.ConnectionObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *HubConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *HubConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *HubConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+
+ return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Hub", hub_name))
+}
+
+func (c *HubConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *HubConnObjectManager) DeleteObject(m map[string]string) error {
+ return pkgerrors.New("Not implemented")
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "log"\r
- "encoding/json"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type HubDeviceObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- HubName string `json:"hub-name"`\r
- DeviceName string `json:"device-name"`\r
-}\r
-\r
-// HubDeviceObjectManager implements the ControllerObjectManager\r
-type HubDeviceObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewHubDeviceObjectManager() *HubDeviceObjectManager {\r
- return &HubDeviceObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "hubdevice",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *HubDeviceObjectManager) GetResourceName() string {\r
- return DeviceResource\r
-}\r
-\r
-func (c *HubDeviceObjectManager) IsOperationSupported(oper string) bool {\r
- if oper == "POST" || oper == "DELETE" {\r
- return true\r
- }\r
- return false\r
-}\r
-\r
-func (c *HubDeviceObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.HubDeviceObject{}\r
-}\r
-\r
-func (c *HubDeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
- device_name := m[DeviceResource]\r
- key := HubDeviceObjectKey{\r
- OverlayName: overlay_name,\r
- HubName: hub_name,\r
- DeviceName: device_name,\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *HubDeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.HubDeviceObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *HubDeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // Setup hub-device connection\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
- //device_name :=m[DeviceResource]\r
- to := t.(*module.HubDeviceObject)\r
- device_name := to.Specification.Device\r
- m[DeviceResource] = device_name\r
-\r
- hub_manager := GetManagerset().Hub\r
- dev_manager := GetManagerset().Device\r
- overlay_namager := GetManagerset().Overlay\r
- conn_manager := GetConnectionManager()\r
-\r
- hub, err := hub_manager.GetObject(m)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Hub " + hub_name + " is not defined")\r
- }\r
-\r
- dev, err := dev_manager.GetObject(m)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " is not defined")\r
- }\r
-\r
- device := dev.(*module.DeviceObject)\r
- if device.Status.Data[RegStatus] != "success" {\r
- log.Println("Device registration not ready")\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " registration is not ready")\r
- }\r
-\r
- _, err = conn_manager.GetObject(overlay_name,\r
- module.CreateEndName(hub.GetType(), hub.GetMetadata().Name),\r
- module.CreateEndName(dev.GetType(), dev.GetMetadata().Name))\r
- if err == nil {\r
- return c.CreateEmptyObject(), pkgerrors.New("The connection between Hub " + hub_name + " and Device " + device_name + " is already created")\r
- }\r
-\r
- err = overlay_namager.SetupConnection(m, hub, dev, HUBTODEVICE, NameSpaceName)\r
- if err != nil {\r
- return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Fail to setup connection between " + hub_name + " and " + device_name)\r
- }\r
-\r
- return c.CreateEmptyObject(), nil\r
-}\r
-\r
-func (c *HubDeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubDeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- return []module.ControllerObject{}, pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubDeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Not implemented")\r
-}\r
-\r
-func (c *HubDeviceObjectManager) DeleteObject(m map[string]string) error {\r
- // Delete hub-device connection\r
- overlay_name := m[OverlayResource]\r
- hub_name := m[HubResource]\r
- device_name := m[DeviceResource]\r
-\r
- hub_manager := GetManagerset().Hub\r
- dev_manager := GetManagerset().Device\r
- conn_manager := GetConnectionManager()\r
-\r
- hub, err := hub_manager.GetObject(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Hub " + hub_name + " is not defined")\r
- }\r
-\r
- dev, err := dev_manager.GetObject(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Device " + device_name + " is not defined")\r
- }\r
-\r
- conn, err := conn_manager.GetObject(overlay_name,\r
- module.CreateEndName(hub.GetType(), hub.GetMetadata().Name),\r
- module.CreateEndName(dev.GetType(), dev.GetMetadata().Name))\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- conn_obj := conn.(*module.ConnectionObject)\r
- err = conn_manager.Undeploy(overlay_name, *conn_obj)\r
- if err != nil {\r
- log.Println(err)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "io"
+ "log"
+
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+)
+
+type HubDeviceObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ HubName string `json:"hub-name"`
+ DeviceName string `json:"device-name"`
+}
+
+// HubDeviceObjectManager implements the ControllerObjectManager
+type HubDeviceObjectManager struct {
+ BaseObjectManager
+}
+
+func NewHubDeviceObjectManager() *HubDeviceObjectManager {
+ return &HubDeviceObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "hubdevice",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *HubDeviceObjectManager) GetResourceName() string {
+ return DeviceResource
+}
+
+func (c *HubDeviceObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "POST" || oper == "DELETE" {
+ return true
+ }
+ return false
+}
+
+func (c *HubDeviceObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.HubDeviceObject{}
+}
+
+func (c *HubDeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+ device_name := m[DeviceResource]
+ key := HubDeviceObjectKey{
+ OverlayName: overlay_name,
+ HubName: hub_name,
+ DeviceName: device_name,
+ }
+
+ return key, nil
+}
+
+func (c *HubDeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.HubDeviceObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *HubDeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // Setup hub-device connection
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+ //device_name :=m[DeviceResource]
+ to := t.(*module.HubDeviceObject)
+ device_name := to.Specification.Device
+ m[DeviceResource] = device_name
+
+ hub_manager := GetManagerset().Hub
+ dev_manager := GetManagerset().Device
+ overlay_namager := GetManagerset().Overlay
+ conn_manager := GetConnectionManager()
+
+ hub, err := hub_manager.GetObject(m)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined")
+ }
+
+ dev, err := dev_manager.GetObject(m)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device "+device_name+" is not defined")
+ }
+
+ device := dev.(*module.DeviceObject)
+ if device.Status.Data[RegStatus] != "success" {
+ log.Println("Device registration not ready")
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device "+device_name+" registration is not ready")
+ }
+
+ _, err = conn_manager.GetObject(overlay_name,
+ module.CreateEndName(hub.GetType(), hub.GetMetadata().Name),
+ module.CreateEndName(dev.GetType(), dev.GetMetadata().Name))
+ if err == nil {
+ return c.CreateEmptyObject(), pkgerrors.New("The connection between Hub " + hub_name + " and Device " + device_name + " is already created")
+ }
+
+ err = overlay_namager.SetupConnection(m, hub, dev, HUBTODEVICE, NameSpaceName)
+ if err != nil {
+ return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Fail to setup connection between "+hub_name+" and "+device_name)
+ }
+
+ return c.CreateEmptyObject(), nil
+}
+
+func (c *HubDeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *HubDeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ return []module.ControllerObject{}, pkgerrors.New("Not implemented")
+}
+
+func (c *HubDeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ return c.CreateEmptyObject(), pkgerrors.New("Not implemented")
+}
+
+func (c *HubDeviceObjectManager) DeleteObject(m map[string]string) error {
+ // Delete hub-device connection
+ overlay_name := m[OverlayResource]
+ hub_name := m[HubResource]
+ device_name := m[DeviceResource]
+
+ hub_manager := GetManagerset().Hub
+ dev_manager := GetManagerset().Device
+ conn_manager := GetConnectionManager()
+
+ hub, err := hub_manager.GetObject(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined")
+ }
+
+ dev, err := dev_manager.GetObject(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Device "+device_name+" is not defined")
+ }
+
+ conn, err := conn_manager.GetObject(overlay_name,
+ module.CreateEndName(hub.GetType(), hub.GetMetadata().Name),
+ module.CreateEndName(dev.GetType(), dev.GetMetadata().Name))
+ if err != nil {
+ log.Println(err)
+ } else {
+ conn_obj := conn.(*module.ConnectionObject)
+ err = conn_manager.Undeploy(overlay_name, *conn_obj)
+ if err != nil {
+ log.Println(err)
+ }
+ }
+
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "encoding/json"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation"\r
- "github.com/go-playground/validator/v10"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type IPRangeObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- IPRangeName string `json:"iprange-name"`\r
-}\r
-\r
-// IPRangeObjectManager implements the ControllerObjectManager\r
-type IPRangeObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewIPRangeObjectManager() *IPRangeObjectManager {\r
- object_meta := "iprange"\r
- validate := validation.GetValidator(object_meta)\r
- validate.RegisterStructValidation(ValidateIPRangeObject, module.IPRangeObject{})\r
-\r
- return &IPRangeObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: object_meta,\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func ValidateIPRangeObject(sl validator.StructLevel) {\r
- obj := sl.Current().Interface().(module.IPRangeObject)\r
-\r
- if obj.Specification.MinIp != 0 && obj.Specification.MaxIp != 0 {\r
- if obj.Specification.MinIp > obj.Specification.MaxIp {\r
- sl.ReportError(obj.Specification.MinIp, "Range", "Range", "InValidateIPRange", "")\r
- }\r
- }\r
-}\r
-\r
-func (c *IPRangeObjectManager) GetResourceName() string {\r
- return IPRangeResource\r
-}\r
-\r
-func (c *IPRangeObjectManager) IsOperationSupported(oper string) bool {\r
- if oper == "PUT" {\r
- // Not allowed for update\r
- return false\r
- }\r
- return true\r
-}\r
-\r
-func (c *IPRangeObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.IPRangeObject{}\r
-}\r
-\r
-func (c *IPRangeObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- key := IPRangeObjectKey{\r
- OverlayName: overlay_name,\r
- IPRangeName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.IPRangeObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[IPRangeResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- }\r
-\r
- key.IPRangeName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name")\r
- }\r
-\r
- key.IPRangeName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *IPRangeObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.IPRangeObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- // initial Status\r
- for i:=0; i<32; i++ {\r
- v.Status.Masks[i] = 0\r
- }\r
- v.Status.Data = make(map[string]string)\r
- return &v, err\r
-}\r
-\r
-func (c *IPRangeObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // Check whether conflict with other IPRange object\r
- objs, err := c.GetObjects(m)\r
- if err != nil {\r
- return t, pkgerrors.Wrap(err, "Failed to get available IPRange objects")\r
- }\r
-\r
- ot := t.(*module.IPRangeObject)\r
- for _, obj := range objs {\r
- if ot.IsConflict(obj.(*module.IPRangeObject)) {\r
- return c.CreateEmptyObject(), pkgerrors.New("Conflicted with IPRange object: " + obj.(*module.IPRangeObject).Metadata.Name)\r
- }\r
- }\r
-\r
- // DB Operation\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *IPRangeObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *IPRangeObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *IPRangeObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().UpdateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *IPRangeObjectManager) DeleteObject(m map[string]string) error {\r
- // Check whether in used\r
- obj, err := c.GetObject(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Failed to get IPRange object")\r
- }\r
-\r
- if obj.(*module.IPRangeObject).InUsed() {\r
- return pkgerrors.New("The IPRange object is in used")\r
- }\r
-\r
- // DB Operation\r
- err = GetDBUtils().DeleteObject(c, m)\r
-\r
- return err\r
-}\r
-\r
-func (c *IPRangeObjectManager) Allocate(oname string, name string) (string, error) {\r
- m := make(map[string]string)\r
- m[OverlayResource] = oname\r
-\r
- objs, err := c.GetObjects(m)\r
- if err != nil {\r
- return "", pkgerrors.Wrap(err, "Failed to get available IPRange objects")\r
- }\r
-\r
- for _, obj := range objs {\r
- tobj := obj.(*module.IPRangeObject)\r
- aip, err := tobj.Allocate(name)\r
- if err == nil {\r
- // save update object in DB\r
- c.UpdateObject(m, tobj)\r
- return aip, nil\r
- }\r
- }\r
-\r
- return "", pkgerrors.New("No available ip")\r
-}\r
-\r
-func (c *IPRangeObjectManager) Free(oname string, ip string) error {\r
- m := make(map[string]string)\r
- m[OverlayResource] = oname\r
-\r
- objs, err := c.GetObjects(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Failed to get available IPRange objects")\r
- }\r
-\r
- for _, obj := range objs {\r
- tobj := obj.(*module.IPRangeObject)\r
- err := tobj.Free(ip)\r
- if err == nil {\r
- // save update object in DB\r
- c.UpdateObject(m, tobj)\r
- return nil\r
- }\r
- }\r
-\r
- return pkgerrors.New("ip " + ip + " is not allocated")\r
-}\r
-\r
-func (c *IPRangeObjectManager) FreeAll(oname string) error {\r
- m := make(map[string]string)\r
- m[OverlayResource] = oname\r
-\r
- objs, err := c.GetObjects(m)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Failed to get available IPRange objects")\r
- }\r
-\r
- for _, obj := range objs {\r
- tobj := obj.(*module.IPRangeObject)\r
- err := tobj.FreeAll()\r
- if err == nil {\r
- // save update object in DB\r
- c.UpdateObject(m, tobj)\r
- }\r
- }\r
-\r
- return nil\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/go-playground/validator/v10"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+)
+
+type IPRangeObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ IPRangeName string `json:"iprange-name"`
+}
+
+type ProviderIPRangeObjectKey struct {
+ IPRangeName string `json:"iprange-name"`
+}
+
+// IPRangeObjectManager implements the ControllerObjectManager
+type IPRangeObjectManager struct {
+ BaseObjectManager
+ provider bool
+}
+
+func NewIPRangeObjectManager(provider bool) *IPRangeObjectManager {
+ object_meta := "iprange"
+ if provider {
+ object_meta = "provider-" + object_meta
+ }
+
+ validate := validation.GetValidator(object_meta)
+ validate.RegisterStructValidation(ValidateIPRangeObject, module.IPRangeObject{})
+
+ return &IPRangeObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: object_meta,
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ provider,
+ }
+}
+
+func ValidateIPRangeObject(sl validator.StructLevel) {
+ obj := sl.Current().Interface().(module.IPRangeObject)
+
+ if obj.Specification.MinIp != 0 && obj.Specification.MaxIp != 0 {
+ if obj.Specification.MinIp > obj.Specification.MaxIp {
+ sl.ReportError(obj.Specification.MinIp, "Range", "Range", "InValidateIPRange", "")
+ }
+ }
+}
+
+func (c *IPRangeObjectManager) GetResourceName() string {
+ return IPRangeResource
+}
+
+func (c *IPRangeObjectManager) IsOperationSupported(oper string) bool {
+ if oper == "PUT" {
+ // Not allowed for update
+ return false
+ }
+ return true
+}
+
+func (c *IPRangeObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.IPRangeObject{}
+}
+
+func (c *IPRangeObjectManager) SetIPRangeName(k db.Key, name string) {
+ if c.provider {
+ ko := k.(*ProviderIPRangeObjectKey)
+ ko.IPRangeName = name
+ } else {
+ ko := k.(*IPRangeObjectKey)
+ ko.IPRangeName = name
+ }
+}
+
+func (c *IPRangeObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ var key db.Key
+
+ if c.provider {
+ key = ProviderIPRangeObjectKey{
+ IPRangeName: "",
+ }
+ } else {
+ overlay_name := m[OverlayResource]
+ key = IPRangeObjectKey{
+ OverlayName: overlay_name,
+ IPRangeName: "",
+ }
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.IPRangeObject)
+ meta_name := to.Metadata.Name
+ res_name := m[IPRangeResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ c.SetIPRangeName(key, res_name)
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ c.SetIPRangeName(key, meta_name)
+ }
+
+ return key, nil
+}
+
+func (c *IPRangeObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.IPRangeObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ // initial Status
+ for i := 0; i < 32; i++ {
+ v.Status.Masks[i] = 0
+ }
+ v.Status.Data = make(map[string]string)
+ return &v, err
+}
+
+func (c *IPRangeObjectManager) GetDefinedObjects(m map[string]string) ([]module.ControllerObject, error) {
+ objs, err := c.GetObjects(m)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get available IPRange objects")
+ }
+
+ if c.provider {
+ ipr_manager := GetManagerset().IPRange
+ overlay_manager := GetManagerset().Overlay
+
+ // concact ip ranges defined in all overlays
+ ol_objs, err := overlay_manager.GetObjects(m)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get overlays")
+ }
+
+ for _, ol_obj := range ol_objs {
+ o_m := make(map[string]string)
+ o_m[OverlayResource] = ol_obj.GetMetadata().Name
+ // get ip range for the overlay
+ ip_objs, err := ipr_manager.GetObjects(o_m)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get ip ranges for overlay")
+ }
+ objs = append(objs, ip_objs...)
+ }
+ } else {
+ // concact ip ranges defined in provider
+ providerIP_manager := GetManagerset().ProviderIPRange
+ p_objs, err := providerIP_manager.GetObjects(m)
+ if err != nil {
+ return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get provider IPRange objects")
+ }
+
+ objs = append(objs, p_objs...)
+ }
+
+ return objs, nil
+}
+
+func (c *IPRangeObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // Check whether conflict with other IPRange object
+ objs, err := c.GetDefinedObjects(m)
+ if err != nil {
+ return t, pkgerrors.Wrap(err, "Failed to get available IPRange objects")
+ }
+
+ ot := t.(*module.IPRangeObject)
+ for _, obj := range objs {
+ if ot.IsConflict(obj.(*module.IPRangeObject)) {
+ return c.CreateEmptyObject(), pkgerrors.New("Conflicted with IPRange object: " + obj.(*module.IPRangeObject).Metadata.Name)
+ }
+ }
+
+ // DB Operation
+ t, err = GetDBUtils().CreateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *IPRangeObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ return t, err
+}
+
+func (c *IPRangeObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *IPRangeObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().UpdateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *IPRangeObjectManager) DeleteObject(m map[string]string) error {
+ // Check whether in used
+ obj, err := c.GetObject(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Failed to get IPRange object")
+ }
+
+ if obj.(*module.IPRangeObject).InUsed() {
+ return pkgerrors.New("The IPRange object is in used")
+ }
+
+ // DB Operation
+ err = GetDBUtils().DeleteObject(c, m)
+
+ return err
+}
+
+func (c *IPRangeObjectManager) Allocate(oname string, name string) (string, error) {
+ m := make(map[string]string)
+
+ if !c.provider {
+ m[OverlayResource] = oname
+ }
+
+ objs, err := c.GetObjects(m)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed to get available IPRange objects")
+ }
+
+ for _, obj := range objs {
+ tobj := obj.(*module.IPRangeObject)
+ aip, err := tobj.Allocate(name)
+ if err == nil {
+ // save update object in DB
+ c.UpdateObject(m, tobj)
+ return aip, nil
+ }
+ }
+
+ return "", pkgerrors.New("No available ip")
+}
+
+func (c *IPRangeObjectManager) Free(oname string, ip string) error {
+ m := make(map[string]string)
+
+ if !c.provider {
+ m[OverlayResource] = oname
+ }
+
+ objs, err := c.GetObjects(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Failed to get available IPRange objects")
+ }
+
+ for _, obj := range objs {
+ tobj := obj.(*module.IPRangeObject)
+ err := tobj.Free(ip)
+ if err == nil {
+ // save update object in DB
+ c.UpdateObject(m, tobj)
+ return nil
+ }
+ }
+
+ return pkgerrors.New("ip " + ip + " is not allocated")
+}
+
+func (c *IPRangeObjectManager) FreeAll(oname string) error {
+ m := make(map[string]string)
+
+ if !c.provider {
+ m[OverlayResource] = oname
+ }
+
+ objs, err := c.GetObjects(m)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Failed to get available IPRange objects")
+ }
+
+ for _, obj := range objs {
+ tobj := obj.(*module.IPRangeObject)
+ err := tobj.FreeAll()
+ if err == nil {
+ // save update object in DB
+ c.UpdateObject(m, tobj)
+ }
+ }
+
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "os"\r
- "log"\r
- "io/ioutil"\r
- "sigs.k8s.io/yaml"\r
- "k8s.io/apimachinery/pkg/runtime"\r
- "k8s.io/client-go/kubernetes/scheme"\r
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-func DecodeYAMLFromFile(path string, into runtime.Object) (runtime.Object, error) {\r
- if _, err := os.Stat(path); err != nil {\r
- if os.IsNotExist(err) {\r
- return nil, pkgerrors.New("File " + path + " not found")\r
- } else {\r
- return nil, pkgerrors.Wrap(err, "Stat file error")\r
- }\r
- }\r
-\r
- rawBytes, err := ioutil.ReadFile(path)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read YAML file error")\r
- }\r
-\r
- decode := scheme.Codecs.UniversalDeserializer().Decode\r
- obj, _, err := decode(rawBytes, nil, into)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Deserialize YAML error")\r
- }\r
-\r
- return obj, nil\r
-}\r
-\r
-func DecodeYAMLFromData(data []byte, into runtime.Object) (runtime.Object, error) {\r
- decode := scheme.Codecs.UniversalDeserializer().Decode\r
- obj, _, err := decode(data, nil, into)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Deserialize YAML error")\r
- }\r
-\r
- return obj, nil\r
-}\r
-\r
-type KubeConfigUtil struct {\r
-}\r
-\r
-var kubeutil = KubeConfigUtil{}\r
-\r
-func GetKubeConfigUtil() *KubeConfigUtil {\r
- return &kubeutil\r
-}\r
-\r
-func (c *KubeConfigUtil) toYaml(data *unstructured.Unstructured) ([]byte, error) {\r
- byte_json, err := data.MarshalJSON()\r
- if err != nil {\r
- return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml")\r
- }\r
-\r
- byte_yaml, err := yaml.JSONToYAML(byte_json)\r
- if err != nil {\r
- return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml")\r
- }\r
-\r
- return byte_yaml, nil\r
-}\r
-\r
-func (c *KubeConfigUtil) UpdateK8sConfig(conf []byte, server string, insecure bool) ([]byte, error) {\r
- conf_us_obj := &unstructured.Unstructured{}\r
- _, err := DecodeYAMLFromData(conf, conf_us_obj)\r
- if err == nil {\r
- conf_obj := conf_us_obj.UnstructuredContent()\r
- cluster_objs, _, err := unstructured.NestedSlice(conf_obj, "clusters")\r
- if err == nil {\r
- if len(cluster_objs) > 0 {\r
- cluster_obj := cluster_objs[0].(map[string]interface{})\r
- if insecure {\r
- // remove certificate-authority-data\r
- unstructured.RemoveNestedField(cluster_obj, "cluster", "certificate-authority-data")\r
- // add insecure-skip-tls-verify\r
- err = unstructured.SetNestedField(cluster_obj, true, "cluster", "insecure-skip-tls-verify")\r
- }\r
-\r
- if err == nil {\r
- // set server\r
- err = unstructured.SetNestedField(cluster_obj, server, "cluster", "server")\r
- if err == nil {\r
- err = unstructured.SetNestedSlice(conf_obj, cluster_objs, "clusters")\r
- if err == nil {\r
- return c.toYaml(conf_us_obj)\r
- }\r
- }\r
- }\r
- } else {\r
- return []byte(""), pkgerrors.New("UpdateK8sConfig: No cluster")\r
- }\r
- }\r
- }\r
-\r
- return []byte(""), pkgerrors.Wrap(err, "UpdateK8sConfig")\r
-}\r
-\r
-func (c *KubeConfigUtil)checkKubeConfigAvail(conf []byte, ips []string, port string) ([]byte, string, error){\r
- kubeclient := client.NewClient("", "", conf)\r
- for i := 0 ; i < len(ips); i++ {\r
- ip := ips[i]\r
- //UpdateConfig\r
- new_url := "https://" + ips[i] + ":" + port\r
- conf, err := kubeutil.UpdateK8sConfig(conf, new_url, true)\r
- if err != nil {\r
- log.Println(err)\r
- return []byte(""), "", pkgerrors.New("Error in updating kubeconfig")\r
- }\r
- kubeclient = client.NewClient("", "", []byte(conf))\r
- is_reachable := kubeclient.IsReachable()\r
- if is_reachable == true {\r
- return conf, ip, nil\r
- }\r
- }\r
- return []byte(""), "", pkgerrors.New("No public ip found workable for the cluster")\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"
+ pkgerrors "github.com/pkg/errors"
+ "io/ioutil"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes/scheme"
+ "log"
+ "os"
+ "sigs.k8s.io/yaml"
+)
+
+func DecodeYAMLFromFile(path string, into runtime.Object) (runtime.Object, error) {
+ if _, err := os.Stat(path); err != nil {
+ if os.IsNotExist(err) {
+ return nil, pkgerrors.New("File " + path + " not found")
+ } else {
+ return nil, pkgerrors.Wrap(err, "Stat file error")
+ }
+ }
+
+ rawBytes, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read YAML file error")
+ }
+
+ decode := scheme.Codecs.UniversalDeserializer().Decode
+ obj, _, err := decode(rawBytes, nil, into)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Deserialize YAML error")
+ }
+
+ return obj, nil
+}
+
+func DecodeYAMLFromData(data []byte, into runtime.Object) (runtime.Object, error) {
+ decode := scheme.Codecs.UniversalDeserializer().Decode
+ obj, _, err := decode(data, nil, into)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Deserialize YAML error")
+ }
+
+ return obj, nil
+}
+
+type KubeConfigUtil struct {
+}
+
+var kubeutil = KubeConfigUtil{}
+
+func GetKubeConfigUtil() *KubeConfigUtil {
+ return &kubeutil
+}
+
+func (c *KubeConfigUtil) toYaml(data *unstructured.Unstructured) ([]byte, error) {
+ byte_json, err := data.MarshalJSON()
+ if err != nil {
+ return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml")
+ }
+
+ byte_yaml, err := yaml.JSONToYAML(byte_json)
+ if err != nil {
+ return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml")
+ }
+
+ return byte_yaml, nil
+}
+
+func (c *KubeConfigUtil) UpdateK8sConfig(conf []byte, server string, insecure bool) ([]byte, error) {
+ conf_us_obj := &unstructured.Unstructured{}
+ _, err := DecodeYAMLFromData(conf, conf_us_obj)
+ if err == nil {
+ conf_obj := conf_us_obj.UnstructuredContent()
+ cluster_objs, _, err := unstructured.NestedSlice(conf_obj, "clusters")
+ if err == nil {
+ if len(cluster_objs) > 0 {
+ cluster_obj := cluster_objs[0].(map[string]interface{})
+ if insecure {
+ // remove certificate-authority-data
+ unstructured.RemoveNestedField(cluster_obj, "cluster", "certificate-authority-data")
+ // add insecure-skip-tls-verify
+ err = unstructured.SetNestedField(cluster_obj, true, "cluster", "insecure-skip-tls-verify")
+ }
+
+ if err == nil {
+ // set server
+ err = unstructured.SetNestedField(cluster_obj, server, "cluster", "server")
+ if err == nil {
+ err = unstructured.SetNestedSlice(conf_obj, cluster_objs, "clusters")
+ if err == nil {
+ return c.toYaml(conf_us_obj)
+ }
+ }
+ }
+ } else {
+ return []byte(""), pkgerrors.New("UpdateK8sConfig: No cluster")
+ }
+ }
+ }
+
+ return []byte(""), pkgerrors.Wrap(err, "UpdateK8sConfig")
+}
+
+func (c *KubeConfigUtil) checkKubeConfigAvail(conf []byte, ips []string, port string) ([]byte, string, error) {
+ kubeclient := client.NewClient("", "", conf)
+ for i := 0; i < len(ips); i++ {
+ ip := ips[i]
+ //UpdateConfig
+ new_url := "https://" + ips[i] + ":" + port
+ conf, err := kubeutil.UpdateK8sConfig(conf, new_url, true)
+ if err != nil {
+ log.Println(err)
+ return []byte(""), "", pkgerrors.New("Error in updating kubeconfig")
+ }
+ kubeclient = client.NewClient("", "", []byte(conf))
+ is_reachable := kubeclient.IsReachable()
+ if is_reachable == true {
+ return conf, ip, nil
+ }
+ }
+ return []byte(""), "", pkgerrors.New("No public ip found workable for the cluster")
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-type Managerset struct {\r
- Overlay *OverlayObjectManager\r
- Proposal *ProposalObjectManager\r
- Hub *HubObjectManager\r
- HubConn *HubConnObjectManager\r
- HubDevice *HubDeviceObjectManager\r
- Device *DeviceObjectManager\r
- DeviceConn *DeviceConnObjectManager\r
- IPRange *IPRangeObjectManager\r
- Cert *CertificateObjectManager\r
-}\r
-\r
-var mgrset = Managerset{}\r
-\r
-func GetManagerset() *Managerset {\r
- return &mgrset\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+type Managerset struct {
+ Overlay *OverlayObjectManager
+ Proposal *ProposalObjectManager
+ Hub *HubObjectManager
+ HubConn *HubConnObjectManager
+ HubDevice *HubDeviceObjectManager
+ HubCNF *CNFObjectManager
+ Device *DeviceObjectManager
+ DeviceConn *DeviceConnObjectManager
+ DeviceCNF *CNFObjectManager
+ ProviderIPRange *IPRangeObjectManager
+ IPRange *IPRangeObjectManager
+ Cert *CertificateObjectManager
+}
+
+var mgrset = Managerset{}
+
+func GetManagerset() *Managerset {
+ return &mgrset
+}
-/*\r
-* Copyright 2020 Intel Corporation, Inc\r
-*\r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
-* you may not use this file except in compliance with the License.\r
-* You may obtain a copy of the License at\r
-*\r
-* http://www.apache.org/licenses/LICENSE-2.0\r
-*\r
-* Unless required by applicable law or agreed to in writing, software\r
-* distributed under the License is distributed on an "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-* See the License for the specific language governing permissions and\r
-* limitations under the License.\r
-*/\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "log"\r
- "strings"\r
- //"strconv"\r
- "encoding/json"\r
- "encoding/base64"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const DEFAULT_MARK = "30"\r
-const VTI_MODE = "VTI-based"\r
-const POLICY_MODE = "policy-based"\r
-const PUBKEY_AUTH = "pubkey"\r
-const FORCECRYPTOPROPOSAL = "0"\r
-const DEFAULT_CONN = "Conn"\r
-const DEFAULT_UPDOWN = "/etc/updown"\r
-const IPTABLES_UPDOWN = "/usr/lib/ipsec/_updown iptables"\r
-const OIP_UPDOWN = "/etc/updown_oip"\r
-const CONN_TYPE = "tunnel"\r
-const MODE = "start"\r
-const OVERLAYIP = "overlayip"\r
-const HUBTOHUB = "hub-to-hub"\r
-const HUBTODEVICE = "hub-to-device"\r
-const DEVICETODEVICE = "device-to-device"\r
-const BYCONFIG = "%config"\r
-const ANY = "%any"\r
-const BASE_PROTOCOL = "TCP"\r
-const DEFAULT_K8S_API_SERVER_PORT = "6443"\r
-const ACCEPT="ACCEPT"\r
-\r
-type OverlayObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
-}\r
-\r
-// OverlayObjectManager implements the ControllerObjectManager\r
-type OverlayObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewOverlayObjectManager() *OverlayObjectManager {\r
- return &OverlayObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "overlay",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *OverlayObjectManager) GetResourceName() string {\r
- return OverlayResource\r
-}\r
-\r
-func (c *OverlayObjectManager) IsOperationSupported(oper string) bool {\r
- return true\r
-}\r
-\r
-func (c *OverlayObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.OverlayObject{}\r
-}\r
-\r
-func (c *OverlayObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- key := OverlayObjectKey{""}\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.OverlayObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[OverlayResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- }\r
-\r
- key.OverlayName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name")\r
- }\r
-\r
- key.OverlayName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *OverlayObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.OverlayObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *OverlayObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // Create a issuer each overlay\r
- to := t.(*module.OverlayObject)\r
- overlay_name := to.Metadata.Name\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- // create overlay ca\r
- _, err := cu.CreateCertificate(c.CertName(overlay_name), NameSpaceName, RootCAIssuerName, true)\r
- if err == nil {\r
- // create overlay issuer\r
- _, err := cu.CreateCAIssuer(c.IssuerName(overlay_name), NameSpaceName, c.CertName(overlay_name))\r
- if err != nil {\r
- log.Println("Failed to create overlay[" + overlay_name +"] issuer: " + err.Error())\r
- }\r
- } else {\r
- log.Println("Failed to create overlay[" + overlay_name +"] certificate: " + err.Error())\r
- }\r
- }\r
-\r
- // DB Operation\r
- t, err = GetDBUtils().CreateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *OverlayObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *OverlayObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *OverlayObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().UpdateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *OverlayObjectManager) DeleteObject(m map[string]string) error {\r
- overlay_name := m[OverlayResource]\r
-\r
- // DB Operation\r
- err := GetDBUtils().DeleteObject(c, m)\r
- if err == nil {\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- err = cu.DeleteIssuer(c.IssuerName(overlay_name), NameSpaceName)\r
- if err != nil {\r
- log.Println("Failed to delete overlay[" + overlay_name +"] issuer: " + err.Error())\r
- }\r
- err = cu.DeleteCertificate(c.CertName(overlay_name), NameSpaceName)\r
- if err != nil {\r
- log.Println("Failed to delete overlay[" + overlay_name +"] certificate: " + err.Error())\r
- }\r
- }\r
- }\r
-\r
- return err\r
-}\r
-\r
-func (c *OverlayObjectManager) IssuerName(name string) string {\r
- return name + "-issuer"\r
-}\r
-\r
-func (c *OverlayObjectManager) CertName(name string) string {\r
- return name + "-cert"\r
-}\r
-\r
-func (c *OverlayObjectManager) CreateCertificate(oname string, cname string) (string, string, error) {\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- _, err := cu.CreateCertificate(cname, NameSpaceName, c.IssuerName(oname), false)\r
- if err != nil {\r
- log.Println("Failed to create overlay[" + oname +"] certificate: " + err.Error())\r
- } else {\r
- crts, key, err := cu.GetKeypair(cname, NameSpaceName)\r
- if err != nil {\r
- log.Println(err)\r
- return "", "", err\r
- } else {\r
- crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]\r
- return crt, key, nil\r
- }\r
- }\r
- }\r
-\r
- return "", "", nil\r
-}\r
-\r
-func (c *OverlayObjectManager) DeleteCertificate(cname string) (string, string, error) {\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- err = cu.DeleteCertificate(cname, NameSpaceName)\r
- if err != nil {\r
- log.Println("Failed to delete " + cname +" certificate: " + err.Error())\r
- }\r
- }\r
-\r
- return "", "", nil\r
-}\r
-\r
-func (c *OverlayObjectManager) GetCertificate(oname string) (string, string, error) {\r
- cu, err := GetCertUtil()\r
- if err != nil {\r
- log.Println(err)\r
- } else {\r
- cname := c.CertName(oname)\r
- return cu.GetKeypair(cname, NameSpaceName)\r
- }\r
- return "", "", nil\r
-}\r
-\r
-//Set up Connection between objects\r
-//Passing the original map resource, the two objects, connection type("hub-to-hub", "hub-to-device", "device-to-device") and namespace name.\r
-func (c *OverlayObjectManager) SetupConnection(m map[string]string, m1 module.ControllerObject, m2 module.ControllerObject, conntype string, namespace string) error {\r
- //Get all proposals available in the overlay\r
- proposal := GetManagerset().Proposal\r
- proposals, err := proposal.GetObjects(m)\r
- if len(proposals) == 0 || err != nil {\r
- log.Println("Missing Proposal in the overlay\n")\r
- return pkgerrors.New("Error in getting proposals")\r
- }\r
- var all_proposals []string\r
- var proposalresources []*resource.ProposalResource\r
- for i:= 0 ; i < len(proposals); i++ {\r
- proposal_obj := proposals[i].(*module.ProposalObject)\r
- all_proposals = append(all_proposals, proposal_obj.Metadata.Name)\r
- pr := proposal_obj.ToResource()\r
- proposalresources = append(proposalresources, pr)\r
- }\r
-\r
- //Get the overlay cert\r
- var root_ca string\r
- root_ca = GetRootCA(m[OverlayResource])\r
-\r
- var obj1_ipsec_resource resource.IpsecResource\r
- var obj2_ipsec_resource resource.IpsecResource\r
- var obj1_ip string\r
- var obj2_ip string\r
-\r
- switch conntype {\r
- case HUBTOHUB:\r
- obj1 := m1.(*module.HubObject)\r
- obj2 := m2.(*module.HubObject)\r
-\r
- obj1_ip = obj1.Status.Ip\r
- obj2_ip = obj2.Status.Ip\r
-\r
- //Keypair\r
- obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(),namespace)\r
- if err != nil {\r
- return err\r
- }\r
- obj2_crt, obj2_key, err := GetHubCertificate(obj2.GetCertName(),namespace)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- //IpsecResources\r
- conn := resource.Connection{\r
- Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),\r
- ConnectionType: CONN_TYPE,\r
- Mode: MODE,\r
- Mark: DEFAULT_MARK,\r
- LocalUpDown: DEFAULT_UPDOWN,\r
- CryptoProposal: all_proposals,\r
- }\r
- obj1_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),\r
- Type: VTI_MODE,\r
- Remote: obj2_ip,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj1.GetCertName(),\r
- RemoteIdentifier: "CN="+obj2.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: conn,\r
- }\r
- obj2_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),\r
- Type: VTI_MODE,\r
- Remote: obj1_ip,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj2.GetCertName(),\r
- RemoteIdentifier: "CN="+obj1.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: conn,\r
- }\r
- // Todo: Hub-to-device connection\r
- case HUBTODEVICE:\r
- obj1 := m1.(*module.HubObject)\r
- obj2 := m2.(*module.DeviceObject)\r
-\r
- obj1_ip := obj1.Status.Ip\r
- obj2_ip := obj2.Status.Ip\r
-\r
- //Keypair\r
- obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(),namespace)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- obj1_conn := resource.Connection{\r
- Name: DEFAULT_CONN + format_resource_name(obj2.Metadata.Name, ""),\r
- ConnectionType: CONN_TYPE,\r
- Mode: MODE,\r
- Mark: DEFAULT_MARK,\r
- RemoteSourceIp: obj2_ip,\r
- LocalUpDown: DEFAULT_UPDOWN,\r
- CryptoProposal: all_proposals,\r
- }\r
-\r
- obj1_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),\r
- Type: VTI_MODE,\r
- Remote: ANY,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj1.GetCertName(),\r
- RemoteIdentifier: "CN="+obj2.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: obj1_conn,\r
- }\r
-\r
- obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- //IpsecResources\r
- obj2_conn := resource.Connection{\r
- Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, ""),\r
- Mode: MODE,\r
- LocalUpDown: IPTABLES_UPDOWN,\r
- ConnectionType: CONN_TYPE,\r
- LocalSourceIp: BYCONFIG,\r
- CryptoProposal: all_proposals,\r
- }\r
- obj2_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),\r
- Type: POLICY_MODE,\r
- Remote: obj1_ip,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: obj2_crt,\r
- PrivateCert: obj2_key,\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj2.GetCertName(),\r
- RemoteIdentifier: "CN="+obj1.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: obj2_conn,\r
- }\r
-\r
- //Todo: Device-to-device connection\r
- case DEVICETODEVICE:\r
- obj1 := m1.(*module.DeviceObject)\r
- obj2 := m2.(*module.DeviceObject)\r
-\r
- obj1_ip := obj1.Status.Ip\r
- obj2_ip := obj2.Status.Ip\r
-\r
- //Keypair\r
- obj1_crt, obj1_key, err := GetDeviceCertificate(m[OverlayResource], obj1.Metadata.Name)\r
- if err != nil {\r
- return err\r
- }\r
- obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- conn := resource.Connection{\r
- Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),\r
- ConnectionType: CONN_TYPE,\r
- Mode: MODE,\r
- Mark: DEFAULT_MARK,\r
- LocalUpDown: DEFAULT_UPDOWN,\r
- CryptoProposal: all_proposals,\r
- }\r
- obj1_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),\r
- Type: POLICY_MODE,\r
- Remote: obj2_ip,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj1.GetCertName(),\r
- RemoteIdentifier: "CN="+obj2.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: conn,\r
- }\r
- obj2_ipsec_resource = resource.IpsecResource{\r
- Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),\r
- Type: POLICY_MODE,\r
- Remote: obj1_ip,\r
- AuthenticationMethod: PUBKEY_AUTH,\r
- PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)),\r
- PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)),\r
- SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),\r
- LocalIdentifier: "CN="+obj2.GetCertName(),\r
- RemoteIdentifier: "CN="+obj1.GetCertName(),\r
- CryptoProposal: all_proposals,\r
- ForceCryptoProposal: FORCECRYPTOPROPOSAL,\r
- Connections: conn,\r
- }\r
- default:\r
- return pkgerrors.New("Unknown connection type")\r
- }\r
-\r
- cend1 := module.NewConnectionEnd(m1, obj1_ip)\r
- cend2 := module.NewConnectionEnd(m2, obj2_ip)\r
-\r
- cend1.AddResource(&obj1_ipsec_resource, false)\r
- cend2.AddResource(&obj2_ipsec_resource, false)\r
-\r
- for i :=0; i < len(proposalresources); i++ {\r
- cend1.AddResource(proposalresources[i], true)\r
- cend2.AddResource(proposalresources[i], true)\r
- }\r
-\r
- co := module.NewConnectionObject(cend1, cend2)\r
-\r
- cm := GetConnectionManager()\r
- err = cm.Deploy(m[OverlayResource], co)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Unable to create the object: fail to deploy resource")\r
- }\r
-\r
- return nil\r
-}\r
+/*
+* Copyright 2020 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* 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 manager
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+ "log"
+ "strings"
+)
+
+const DEFAULT_MARK = "30"
+const VTI_MODE = "VTI-based"
+const POLICY_MODE = "policy-based"
+const PUBKEY_AUTH = "pubkey"
+const FORCECRYPTOPROPOSAL = "0"
+const DEFAULT_CONN = "Conn"
+const DEFAULT_UPDOWN = "/etc/updown"
+const IPTABLES_UPDOWN = "/usr/lib/ipsec/_updown iptables"
+const OIP_UPDOWN = "/etc/updown_oip"
+const CONN_TYPE = "tunnel"
+const MODE = "start"
+const OVERLAYIP = "overlayip"
+const HUBTOHUB = "hub-to-hub"
+const HUBTODEVICE = "hub-to-device"
+const DEVICETODEVICE = "device-to-device"
+const BYCONFIG = "%config"
+const ANY = "%any"
+const BASE_PROTOCOL = "TCP"
+const DEFAULT_K8S_API_SERVER_PORT = "6443"
+const ACCEPT = "ACCEPT"
+
+type OverlayObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+}
+
+// OverlayObjectManager implements the ControllerObjectManager
+type OverlayObjectManager struct {
+ BaseObjectManager
+}
+
+func NewOverlayObjectManager() *OverlayObjectManager {
+ return &OverlayObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "overlay",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *OverlayObjectManager) GetResourceName() string {
+ return OverlayResource
+}
+
+func (c *OverlayObjectManager) IsOperationSupported(oper string) bool {
+ return true
+}
+
+func (c *OverlayObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.OverlayObject{}
+}
+
+func (c *OverlayObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ key := OverlayObjectKey{""}
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.OverlayObject)
+ meta_name := to.Metadata.Name
+ res_name := m[OverlayResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.OverlayName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.OverlayName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *OverlayObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.OverlayObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *OverlayObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // Create a issuer each overlay
+ to := t.(*module.OverlayObject)
+ overlay_name := to.Metadata.Name
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ } else {
+ // create overlay ca
+ _, err := cu.CreateCertificate(c.CertName(overlay_name), NameSpaceName, RootCAIssuerName, true)
+ if err == nil {
+ // create overlay issuer
+ _, err := cu.CreateCAIssuer(c.IssuerName(overlay_name), NameSpaceName, c.CertName(overlay_name))
+ if err != nil {
+ log.Println("Failed to create overlay[" + overlay_name + "] issuer: " + err.Error())
+ }
+ } else {
+ log.Println("Failed to create overlay[" + overlay_name + "] certificate: " + err.Error())
+ }
+ }
+
+ // DB Operation
+ t, err = GetDBUtils().CreateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *OverlayObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ return t, err
+}
+
+func (c *OverlayObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *OverlayObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().UpdateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *OverlayObjectManager) DeleteObject(m map[string]string) error {
+ overlay_name := m[OverlayResource]
+
+ // DB Operation
+ err := GetDBUtils().DeleteObject(c, m)
+ if err == nil {
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ } else {
+ err = cu.DeleteIssuer(c.IssuerName(overlay_name), NameSpaceName)
+ if err != nil {
+ log.Println("Failed to delete overlay[" + overlay_name + "] issuer: " + err.Error())
+ }
+ err = cu.DeleteCertificate(c.CertName(overlay_name), NameSpaceName)
+ if err != nil {
+ log.Println("Failed to delete overlay[" + overlay_name + "] certificate: " + err.Error())
+ }
+ }
+ }
+
+ return err
+}
+
+func (c *OverlayObjectManager) IssuerName(name string) string {
+ return name + "-issuer"
+}
+
+func (c *OverlayObjectManager) CertName(name string) string {
+ return name + "-cert"
+}
+
+func (c *OverlayObjectManager) CreateCertificate(oname string, cname string) (string, string, error) {
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ } else {
+ _, err := cu.CreateCertificate(cname, NameSpaceName, c.IssuerName(oname), false)
+ if err != nil {
+ log.Println("Failed to create overlay[" + oname + "] certificate: " + err.Error())
+ } else {
+ crts, key, err := cu.GetKeypair(cname, NameSpaceName)
+ if err != nil {
+ log.Println(err)
+ return "", "", err
+ } else {
+ crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0]
+ return crt, key, nil
+ }
+ }
+ }
+
+ return "", "", nil
+}
+
+func (c *OverlayObjectManager) DeleteCertificate(cname string) (string, string, error) {
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ } else {
+ err = cu.DeleteCertificate(cname, NameSpaceName)
+ if err != nil {
+ log.Println("Failed to delete " + cname + " certificate: " + err.Error())
+ }
+ }
+
+ return "", "", nil
+}
+
+func (c *OverlayObjectManager) GetCertificate(oname string) (string, string, error) {
+ cu, err := GetCertUtil()
+ if err != nil {
+ log.Println(err)
+ } else {
+ cname := c.CertName(oname)
+ return cu.GetKeypair(cname, NameSpaceName)
+ }
+ return "", "", nil
+}
+
+//Set up Connection between objects
+//Passing the original map resource, the two objects, connection type("hub-to-hub", "hub-to-device", "device-to-device") and namespace name.
+func (c *OverlayObjectManager) SetupConnection(m map[string]string, m1 module.ControllerObject, m2 module.ControllerObject, conntype string, namespace string) error {
+ //Get all proposals available in the overlay
+ proposal := GetManagerset().Proposal
+ proposals, err := proposal.GetObjects(m)
+ if len(proposals) == 0 || err != nil {
+ log.Println("Missing Proposal in the overlay\n")
+ return pkgerrors.New("Error in getting proposals")
+ }
+ var all_proposals []string
+ var proposalresources []*resource.ProposalResource
+ for i := 0; i < len(proposals); i++ {
+ proposal_obj := proposals[i].(*module.ProposalObject)
+ all_proposals = append(all_proposals, proposal_obj.Metadata.Name)
+ pr := proposal_obj.ToResource()
+ proposalresources = append(proposalresources, pr)
+ }
+
+ //Get the overlay cert
+ var root_ca string
+ root_ca = GetRootCA(m[OverlayResource])
+
+ var obj1_ipsec_resource resource.IpsecResource
+ var obj2_ipsec_resource resource.IpsecResource
+ var obj1_ip string
+ var obj2_ip string
+
+ switch conntype {
+ case HUBTOHUB:
+ obj1 := m1.(*module.HubObject)
+ obj2 := m2.(*module.HubObject)
+
+ obj1_ip = obj1.Status.Ip
+ obj2_ip = obj2.Status.Ip
+
+ //Keypair
+ obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(), namespace)
+ if err != nil {
+ return err
+ }
+ obj2_crt, obj2_key, err := GetHubCertificate(obj2.GetCertName(), namespace)
+ if err != nil {
+ return err
+ }
+
+ //IpsecResources
+ conn := resource.Connection{
+ Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),
+ ConnectionType: CONN_TYPE,
+ Mode: MODE,
+ Mark: DEFAULT_MARK,
+ LocalUpDown: DEFAULT_UPDOWN,
+ CryptoProposal: all_proposals,
+ }
+ obj1_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),
+ Type: VTI_MODE,
+ Remote: obj2_ip,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj1.GetCertName(),
+ RemoteIdentifier: "CN=" + obj2.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: conn,
+ }
+ obj2_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),
+ Type: VTI_MODE,
+ Remote: obj1_ip,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj2.GetCertName(),
+ RemoteIdentifier: "CN=" + obj1.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: conn,
+ }
+ // Todo: Hub-to-device connection
+ case HUBTODEVICE:
+ obj1 := m1.(*module.HubObject)
+ obj2 := m2.(*module.DeviceObject)
+
+ obj1_ip := obj1.Status.Ip
+ obj2_ip := obj2.Status.Ip
+
+ //Keypair
+ obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(), namespace)
+ if err != nil {
+ return err
+ }
+
+ obj1_conn := resource.Connection{
+ Name: DEFAULT_CONN + format_resource_name(obj2.Metadata.Name, ""),
+ ConnectionType: CONN_TYPE,
+ Mode: MODE,
+ Mark: DEFAULT_MARK,
+ RemoteSourceIp: obj2_ip,
+ LocalUpDown: DEFAULT_UPDOWN,
+ CryptoProposal: all_proposals,
+ }
+
+ obj1_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),
+ Type: VTI_MODE,
+ Remote: ANY,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj1.GetCertName(),
+ RemoteIdentifier: "CN=" + obj2.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: obj1_conn,
+ }
+
+ obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name)
+ if err != nil {
+ return err
+ }
+
+ //IpsecResources
+ obj2_conn := resource.Connection{
+ Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, ""),
+ Mode: MODE,
+ LocalUpDown: IPTABLES_UPDOWN,
+ ConnectionType: CONN_TYPE,
+ LocalSourceIp: BYCONFIG,
+ CryptoProposal: all_proposals,
+ }
+ obj2_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),
+ Type: POLICY_MODE,
+ Remote: obj1_ip,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: obj2_crt,
+ PrivateCert: obj2_key,
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj2.GetCertName(),
+ RemoteIdentifier: "CN=" + obj1.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: obj2_conn,
+ }
+
+ //Todo: Device-to-device connection
+ case DEVICETODEVICE:
+ obj1 := m1.(*module.DeviceObject)
+ obj2 := m2.(*module.DeviceObject)
+
+ obj1_ip := obj1.Status.Ip
+ obj2_ip := obj2.Status.Ip
+
+ //Keypair
+ obj1_crt, obj1_key, err := GetDeviceCertificate(m[OverlayResource], obj1.Metadata.Name)
+ if err != nil {
+ return err
+ }
+ obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name)
+ if err != nil {
+ return err
+ }
+
+ conn := resource.Connection{
+ Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),
+ ConnectionType: CONN_TYPE,
+ Mode: MODE,
+ Mark: DEFAULT_MARK,
+ LocalUpDown: DEFAULT_UPDOWN,
+ CryptoProposal: all_proposals,
+ }
+ obj1_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name),
+ Type: POLICY_MODE,
+ Remote: obj2_ip,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj1.GetCertName(),
+ RemoteIdentifier: "CN=" + obj2.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: conn,
+ }
+ obj2_ipsec_resource = resource.IpsecResource{
+ Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name),
+ Type: POLICY_MODE,
+ Remote: obj1_ip,
+ AuthenticationMethod: PUBKEY_AUTH,
+ PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)),
+ PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)),
+ SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)),
+ LocalIdentifier: "CN=" + obj2.GetCertName(),
+ RemoteIdentifier: "CN=" + obj1.GetCertName(),
+ CryptoProposal: all_proposals,
+ ForceCryptoProposal: FORCECRYPTOPROPOSAL,
+ Connections: conn,
+ }
+ default:
+ return pkgerrors.New("Unknown connection type")
+ }
+
+ cend1 := module.NewConnectionEnd(m1, obj1_ip)
+ cend2 := module.NewConnectionEnd(m2, obj2_ip)
+
+ cend1.AddResource(&obj1_ipsec_resource, false)
+ cend2.AddResource(&obj2_ipsec_resource, false)
+
+ for i := 0; i < len(proposalresources); i++ {
+ cend1.AddResource(proposalresources[i], true)
+ cend2.AddResource(proposalresources[i], true)
+ }
+
+ co := module.NewConnectionObject(cend1, cend2)
+
+ cm := GetConnectionManager()
+ err = cm.Deploy(m[OverlayResource], co)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Unable to create the object: fail to deploy resource")
+ }
+
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "io"\r
- "encoding/json"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type ProposalObjectKey struct {\r
- OverlayName string `json:"overlay-name"`\r
- ProposalName string `json:"proposal-name"`\r
-}\r
-\r
-// ProposalObjectManager implements the ControllerObjectManager\r
-type ProposalObjectManager struct {\r
- BaseObjectManager\r
-}\r
-\r
-func NewProposalObjectManager() *ProposalObjectManager {\r
- return &ProposalObjectManager{\r
- BaseObjectManager {\r
- storeName: StoreName,\r
- tagMeta: "proposal",\r
- depResManagers: []ControllerObjectManager {},\r
- ownResManagers: []ControllerObjectManager {},\r
- },\r
- }\r
-}\r
-\r
-func (c *ProposalObjectManager) GetResourceName() string {\r
- return ProposalResource\r
-}\r
-\r
-func (c *ProposalObjectManager) IsOperationSupported(oper string) bool {\r
- return true\r
-}\r
-\r
-func (c *ProposalObjectManager) CreateEmptyObject() module.ControllerObject {\r
- return &module.ProposalObject{}\r
-}\r
-\r
-func (c *ProposalObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {\r
- overlay_name := m[OverlayResource]\r
- key := ProposalObjectKey{\r
- OverlayName: overlay_name,\r
- ProposalName: "",\r
- }\r
-\r
- if isCollection == true {\r
- return key, nil\r
- }\r
-\r
- to := t.(*module.ProposalObject)\r
- meta_name := to.Metadata.Name\r
- res_name := m[ProposalResource]\r
-\r
- if res_name != "" {\r
- if meta_name != "" && res_name != meta_name {\r
- return key, pkgerrors.New("Resource name unmatched metadata name")\r
- } \r
-\r
- key.ProposalName = res_name\r
- } else {\r
- if meta_name == "" {\r
- return key, pkgerrors.New("Unable to find resource name") \r
- }\r
-\r
- key.ProposalName = meta_name\r
- }\r
-\r
- return key, nil;\r
-}\r
-\r
-func (c *ProposalObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {\r
- var v module.ProposalObject\r
- err := json.NewDecoder(r).Decode(&v)\r
-\r
- return &v, err\r
-}\r
-\r
-func (c *ProposalObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().CreateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *ProposalObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObject(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *ProposalObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().GetObjects(c, m)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *ProposalObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {\r
- // DB Operation\r
- t, err := GetDBUtils().UpdateObject(c, m, t)\r
-\r
- return t, err\r
-}\r
-\r
-func (c *ProposalObjectManager) DeleteObject(m map[string]string) error {\r
- // DB Operation\r
- err := GetDBUtils().DeleteObject(c, m)\r
-\r
- return err\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ pkgerrors "github.com/pkg/errors"
+ "io"
+)
+
+type ProposalObjectKey struct {
+ OverlayName string `json:"overlay-name"`
+ ProposalName string `json:"proposal-name"`
+}
+
+// ProposalObjectManager implements the ControllerObjectManager
+type ProposalObjectManager struct {
+ BaseObjectManager
+}
+
+func NewProposalObjectManager() *ProposalObjectManager {
+ return &ProposalObjectManager{
+ BaseObjectManager{
+ storeName: StoreName,
+ tagMeta: "proposal",
+ depResManagers: []ControllerObjectManager{},
+ ownResManagers: []ControllerObjectManager{},
+ },
+ }
+}
+
+func (c *ProposalObjectManager) GetResourceName() string {
+ return ProposalResource
+}
+
+func (c *ProposalObjectManager) IsOperationSupported(oper string) bool {
+ return true
+}
+
+func (c *ProposalObjectManager) CreateEmptyObject() module.ControllerObject {
+ return &module.ProposalObject{}
+}
+
+func (c *ProposalObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) {
+ overlay_name := m[OverlayResource]
+ key := ProposalObjectKey{
+ OverlayName: overlay_name,
+ ProposalName: "",
+ }
+
+ if isCollection == true {
+ return key, nil
+ }
+
+ to := t.(*module.ProposalObject)
+ meta_name := to.Metadata.Name
+ res_name := m[ProposalResource]
+
+ if res_name != "" {
+ if meta_name != "" && res_name != meta_name {
+ return key, pkgerrors.New("Resource name unmatched metadata name")
+ }
+
+ key.ProposalName = res_name
+ } else {
+ if meta_name == "" {
+ return key, pkgerrors.New("Unable to find resource name")
+ }
+
+ key.ProposalName = meta_name
+ }
+
+ return key, nil
+}
+
+func (c *ProposalObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) {
+ var v module.ProposalObject
+ err := json.NewDecoder(r).Decode(&v)
+
+ return &v, err
+}
+
+func (c *ProposalObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().CreateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *ProposalObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObject(c, m)
+
+ return t, err
+}
+
+func (c *ProposalObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().GetObjects(c, m)
+
+ return t, err
+}
+
+func (c *ProposalObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) {
+ // DB Operation
+ t, err := GetDBUtils().UpdateObject(c, m, t)
+
+ return t, err
+}
+
+func (c *ProposalObjectManager) DeleteObject(m map[string]string) error {
+ // DB Operation
+ err := GetDBUtils().DeleteObject(c, m)
+
+ return err
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"\r
- rsyncclient "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/installappclient"\r
- controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"\r
- "log"\r
- "fmt"\r
- "encoding/json"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-var rsync_initialized = false\r
-var provider_name = "akraino_scc"\r
-var project_name = "akraino_scc"\r
-\r
-// sdewan definition\r
-type DeployResource struct {\r
- Action string\r
- Resource resource.ISdewanResource\r
-}\r
-\r
-type DeployResources struct {\r
- Resources []DeployResource\r
-}\r
-\r
-type ResUtil struct {\r
- resmap map[module.ControllerObject]*DeployResources\r
-}\r
-\r
-func NewResUtil() *ResUtil {\r
- if rsync_initialized == false {\r
- rsync_initialized = InitRsyncClient()\r
- }\r
-\r
- return &ResUtil{\r
- resmap: make(map[module.ControllerObject]*DeployResources),\r
- }\r
-}\r
-\r
-// --------------------------------------------------------------------------------------------------------------\r
-// temp definition for rsync\r
-type contextForCompositeApp struct {\r
- context appcontext.AppContext\r
- ctxval interface{}\r
- compositeAppHandle interface{}\r
-}\r
-\r
-func makeAppContextForCompositeApp(p, ca, v, rName, dig string, namespace string, level string) (contextForCompositeApp, error) {\r
- // ctxval: context.rtcObj.id\r
- context := appcontext.AppContext{}\r
- ctxval, err := context.InitAppContext()\r
- if err != nil {\r
- return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")\r
- }\r
- compositeHandle, err := context.CreateCompositeApp()\r
- if err != nil {\r
- return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle")\r
- }\r
- err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName, DeploymentIntentGroup: dig, Namespace: namespace, Level: level})\r
- if err != nil {\r
- return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta")\r
- }\r
-\r
- //_, err = context.GetCompositeAppMeta()\r
-\r
- log.Println(":: The meta data stored in the runtime context :: ")\r
-\r
- cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle}\r
-\r
- return cca, nil\r
-}\r
-\r
-func addResourcesToCluster(ct appcontext.AppContext, ch interface{}, resources []DeployResource, isDeploy bool) error {\r
-\r
- var resOrderInstr struct {\r
- Resorder []string `json:"resorder"`\r
- }\r
-\r
- var resDepInstr struct {\r
- Resdep map[string]string `json:"resdependency"`\r
- }\r
- resdep := make(map[string]string)\r
-\r
- for _, resource := range resources {\r
- resource_name := resource.Resource.GetName() + "+" + resource.Resource.GetType()\r
- resource_data := resource.Resource.ToYaml()\r
- resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name)\r
- resdep[resource_name] = "go"\r
- // rtc.RtcAddResource("<cid>/app/app_name/cluster/clusername/", res.name, res.content)\r
- // -> save ("<cid>/app/app_name/cluster/clusername/resource/res.name/", res.content) in etcd\r
- // return ("<cid>/app/app_name/cluster/clusername/resource/res.name/"\r
- rh, err := ct.AddResource(ch, resource_name, resource_data)\r
- if isDeploy == false {\r
- //Delete resource\r
- ct.AddLevelValue(rh, "status", resourcestatus.ResourceStatus{Status:resourcestatus.RsyncStatusEnum.Applied})\r
- }\r
- if err != nil {\r
- cleanuperr := ct.DeleteCompositeApp()\r
- if cleanuperr != nil {\r
- log.Printf(":: Error Cleaning up AppContext after add resource failure ::")\r
- }\r
- return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name)\r
- }\r
- jresOrderInstr, _ := json.Marshal(resOrderInstr)\r
- resDepInstr.Resdep = resdep\r
- jresDepInstr, _ := json.Marshal(resDepInstr)\r
- // rtc.RtcAddInstruction("<cid>app/app_name/cluster/clusername/", "resource", "order", "{[res.name]}")\r
- // ->save ("<cid>/app/app_name/cluster/clusername/resource/instruction/order/", "{[res.name]}") in etcd\r
- // return "<cid>/app/app_name/cluster/clusername/resource/instruction/order/"\r
- _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr))\r
- _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr))\r
- if err != nil {\r
- cleanuperr := ct.DeleteCompositeApp()\r
- if cleanuperr != nil {\r
- log.Printf(":: Error Cleaning up AppContext after add instruction failure ::")\r
- }\r
- return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name)\r
- }\r
- }\r
- return nil\r
-}\r
-\r
-func InitRsyncClient() bool {\r
- client := controller.NewControllerClient()\r
-\r
- vals, _ := client.GetControllers()\r
- found := false\r
- for _, v := range vals {\r
- if v.Metadata.Name == "rsync" {\r
- log.Println("Initializing RPC connection to resource synchronizer")\r
- rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)\r
- found = true\r
- break\r
- }\r
- }\r
- return found\r
-}\r
-\r
-func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {\r
- h, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- return err\r
- }\r
- sh, err := ac.GetLevelHandle(h, "status")\r
- if sh == nil {\r
- _, err = ac.AddLevelValue(h, "status", acStatus)\r
- } else {\r
- err = ac.UpdateValue(sh, acStatus)\r
- }\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-// --------------------------------------------------------------------------------------------------------------\r
-func (d *ResUtil) contains(reses []DeployResource, res DeployResource) bool {\r
- for _, r := range reses {\r
- if r.Action == res.Action &&\r
- r.Resource.GetName() == res.Resource.GetName() &&\r
- r.Resource.GetType() == res.Resource.GetType() {\r
- return true\r
- }\r
- }\r
-\r
- return false\r
-}\r
-\r
-func (d *ResUtil) AddResource(device module.ControllerObject, action string, resource resource.ISdewanResource) error {\r
- if d.resmap[device] == nil {\r
- d.resmap[device] = &DeployResources{Resources: []DeployResource{}}\r
- }\r
-\r
- ds := DeployResource{Action: action, Resource: resource,}\r
- if !d.contains(d.resmap[device].Resources, ds) {\r
- d.resmap[device].Resources = append(d.resmap[device].Resources, ds)\r
- }\r
- return nil\r
-}\r
-\r
-func (d *ResUtil) Deploy(app_name string, format string) (string, error) {\r
- // Generate Application context\r
- cca, err := makeAppContextForCompositeApp(project_name, app_name + "-d", "1.0", "1.0", "di", "sdewan-system", "0")\r
- context := cca.context // appcontext.AppContext\r
- ctxval := cca.ctxval // id\r
- compositeHandle := cca.compositeAppHandle // cid\r
-\r
- var appOrderInstr struct {\r
- Apporder []string `json:"apporder"`\r
- }\r
- var appDepInstr struct {\r
- Appdep map[string]string `json:"appdependency"`\r
- }\r
- appdep := make(map[string]string)\r
- // create a com_app for each device\r
- for device, res := range d.resmap {\r
- // Add application\r
- app_name := device.GetMetadata().Name + "-app"\r
- appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name)\r
- appdep[app_name] = "go"\r
-\r
- // rtc.RtcAddLevel(cid, "app", app_name) -> save ("<cid>app/app_name/", app_name) in etcd\r
- // apphandle = "<cid>app/app_name/"\r
- apphandle, _ := context.AddApp(compositeHandle, app_name)\r
-\r
- // Add cluster\r
- // err = addClustersToAppContext(listOfClusters, context, apphandle, resources)\r
- // rtc.RtcAddLevel("<cid>app/app_name/", "cluster", clustername) \r
- // -> save ("<cid>app/app_name/cluster/clusername/", clustername) in etcd\r
- // return "<cid>app/app_name/cluster/clusername/"\r
- clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name)\r
- err = addResourcesToCluster(context, clusterhandle, res.Resources, true)\r
- }\r
-\r
- jappOrderInstr, _ := json.Marshal(appOrderInstr)\r
- appDepInstr.Appdep = appdep\r
- jappDepInstr, _ := json.Marshal(appDepInstr)\r
- context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))\r
- context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))\r
-\r
- // invoke deployment prrocess\r
- appContextID := fmt.Sprintf("%v", ctxval)\r
- err = rsyncclient.InvokeInstallApp(appContextID)\r
- if err != nil {\r
- log.Println(err)\r
- return appContextID, err\r
- }\r
-\r
- return appContextID, nil\r
-}\r
-\r
-func (d *ResUtil) Undeploy(app_name string, format string) (string, error) {\r
- // Generate Application context\r
- cca, err := makeAppContextForCompositeApp(project_name, app_name + "-u", "1.0", "1.0", "di", "sdewan-system", "0")\r
- context := cca.context // appcontext.AppContext\r
- ctxval := cca.ctxval // id\r
- compositeHandle := cca.compositeAppHandle // cid\r
-\r
- var appOrderInstr struct {\r
- Apporder []string `json:"apporder"`\r
- }\r
- var appDepInstr struct {\r
- Appdep map[string]string `json:"appdependency"`\r
- }\r
- appdep := make(map[string]string)\r
- // create a com_app for each device\r
- for device, res := range d.resmap {\r
- // Add application\r
- app_name := device.GetMetadata().Name + "-app"\r
- appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name)\r
- appdep[app_name] = "go"\r
- apphandle, _ := context.AddApp(compositeHandle, app_name)\r
-\r
- // Add cluster\r
- clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name)\r
- err = addResourcesToCluster(context, clusterhandle, res.Resources, false)\r
- }\r
-\r
- jappOrderInstr, _ := json.Marshal(appOrderInstr)\r
- appDepInstr.Appdep = appdep\r
- jappDepInstr, _ := json.Marshal(appDepInstr)\r
- context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))\r
- context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))\r
-\r
- initializeAppContextStatus(context, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiated})\r
- // invoke deployment prrocess\r
- appContextID := fmt.Sprintf("%v", ctxval)\r
- err = rsyncclient.InvokeUninstallApp(appContextID)\r
- if err != nil {\r
- log.Println(err)\r
- return appContextID, err\r
- }\r
-\r
- return appContextID, nil\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ rsyncclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext"
+ // rsyncclient "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/installappclient"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
+ controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller"
+
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/wait"
+
+ "encoding/json"
+ "fmt"
+ pkgerrors "github.com/pkg/errors"
+ "log"
+ "time"
+)
+
+var rsync_initialized = false
+var provider_name = "akraino_scc"
+var project_name = "akraino_scc"
+
+// sdewan definition
+type DeployResource struct {
+ Action string
+ Resource resource.ISdewanResource
+}
+
+type DeployResources struct {
+ Resources []DeployResource
+}
+
+type ReadResource struct {
+ Gvk schema.GroupVersionKind `json:"GVK,omitempty"`
+ Name string `json:"name,omitempty"`
+ Namespace string `json:"namespace,omitempty"`
+}
+
+type QueryResource struct {
+ Handle interface{}
+ Resource ReadResource
+}
+
+type QueryResources struct {
+ Resources []*QueryResource
+}
+
+type ResUtil struct {
+ resmap map[module.ControllerObject]*DeployResources
+ qryResmap map[module.ControllerObject]*QueryResources
+ qryCtxId string
+}
+
+func NewResUtil() *ResUtil {
+ if rsync_initialized == false {
+ rsync_initialized = InitRsyncClient()
+ }
+
+ return &ResUtil{
+ resmap: make(map[module.ControllerObject]*DeployResources),
+ qryResmap: make(map[module.ControllerObject]*QueryResources),
+ qryCtxId: "",
+ }
+}
+
+type contextForCompositeApp struct {
+ context appcontext.AppContext
+ ctxval interface{}
+ compositeAppHandle interface{}
+}
+
+func makeAppContextForCompositeApp(p, ca, v, rName, dig string, namespace string, level string) (contextForCompositeApp, error) {
+ // ctxval: context.rtcObj.id
+ context := appcontext.AppContext{}
+ ctxval, err := context.InitAppContext()
+ if err != nil {
+ return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")
+ }
+ compositeHandle, err := context.CreateCompositeApp()
+ if err != nil {
+ return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle")
+ }
+ err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName, DeploymentIntentGroup: dig, Namespace: namespace, Level: level})
+ if err != nil {
+ return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta")
+ }
+
+ //_, err = context.GetCompositeAppMeta()
+
+ log.Println(":: The meta data stored in the runtime context :: ")
+
+ cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle}
+
+ return cca, nil
+}
+
+func addResourcesToCluster(ct appcontext.AppContext, ch interface{}, target string, resources []DeployResource, isDeploy bool) error {
+
+ var resOrderInstr struct {
+ Resorder []string `json:"resorder"`
+ }
+
+ var resDepInstr struct {
+ Resdep map[string]string `json:"resdependency"`
+ }
+ resdep := make(map[string]string)
+
+ for _, resource := range resources {
+ resource_name := resource.Resource.GetName() + "+" + resource.Resource.GetType()
+ resource_data := resource.Resource.ToYaml(target)
+ resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name)
+ resdep[resource_name] = "go"
+ // rtc.RtcAddResource("<cid>/app/app_name/cluster/clusername/", res.name, res.content)
+ // -> save ("<cid>/app/app_name/cluster/clusername/resource/res.name/", res.content) in etcd
+ // return ("<cid>/app/app_name/cluster/clusername/resource/res.name/"
+ rh, err := ct.AddResource(ch, resource_name, resource_data)
+ if isDeploy == false {
+ //Delete resource
+ ct.AddLevelValue(rh, "status", resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Applied})
+ }
+ if err != nil {
+ cleanuperr := ct.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Printf(":: Error Cleaning up AppContext after add resource failure ::")
+ }
+ return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name)
+ }
+ jresOrderInstr, _ := json.Marshal(resOrderInstr)
+ resDepInstr.Resdep = resdep
+ jresDepInstr, _ := json.Marshal(resDepInstr)
+ // rtc.RtcAddInstruction("<cid>app/app_name/cluster/clusername/", "resource", "order", "{[res.name]}")
+ // ->save ("<cid>/app/app_name/cluster/clusername/resource/instruction/order/", "{[res.name]}") in etcd
+ // return "<cid>/app/app_name/cluster/clusername/resource/instruction/order/"
+ _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr))
+ _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr))
+ if err != nil {
+ cleanuperr := ct.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Printf(":: Error Cleaning up AppContext after add instruction failure ::")
+ }
+ return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name)
+ }
+ }
+ return nil
+}
+
+func InitRsyncClient() bool {
+ client := controller.NewControllerClient()
+
+ vals, _ := client.GetControllers()
+ found := false
+ for _, v := range vals {
+ if v.Metadata.Name == "rsync" {
+ log.Println("Initializing RPC connection to resource synchronizer")
+ rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)
+ found = true
+ break
+ }
+ }
+ return found
+}
+
+func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error {
+ h, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return err
+ }
+ sh, err := ac.GetLevelHandle(h, "status")
+ if sh == nil {
+ _, err = ac.AddLevelValue(h, "status", acStatus)
+ } else {
+ err = ac.UpdateValue(sh, acStatus)
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (d *ResUtil) contains(reses []DeployResource, res DeployResource) bool {
+ for _, r := range reses {
+ if r.Action == res.Action &&
+ r.Resource.GetName() == res.Resource.GetName() &&
+ r.Resource.GetType() == res.Resource.GetType() {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (d *ResUtil) AddResource(device module.ControllerObject, action string, resource resource.ISdewanResource) error {
+ if d.resmap[device] == nil {
+ d.resmap[device] = &DeployResources{Resources: []DeployResource{}}
+ }
+
+ ds := DeployResource{Action: action, Resource: resource}
+ if !d.contains(d.resmap[device].Resources, ds) {
+ d.resmap[device].Resources = append(d.resmap[device].Resources, ds)
+ }
+ return nil
+}
+
+func (d *ResUtil) TargetName(o module.ControllerObject) string {
+ return o.GetType() + "." + o.GetMetadata().Name
+}
+
+func (d *ResUtil) Deploy(app_name string, format string) (string, error) {
+ // Generate Application context
+ cca, err := makeAppContextForCompositeApp(project_name, app_name+"-d", "1.0", "1.0", "di", "default", "0")
+ context := cca.context // appcontext.AppContext
+ ctxval := cca.ctxval // id
+ compositeHandle := cca.compositeAppHandle // cid
+
+ var appOrderInstr struct {
+ Apporder []string `json:"apporder"`
+ }
+ var appDepInstr struct {
+ Appdep map[string]string `json:"appdependency"`
+ }
+ appdep := make(map[string]string)
+ // create a com_app for each device
+ for device, res := range d.resmap {
+ // Add application
+ app_name := device.GetMetadata().Name + "-app"
+ appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name)
+ appdep[app_name] = "go"
+
+ // rtc.RtcAddLevel(cid, "app", app_name) -> save ("<cid>app/app_name/", app_name) in etcd
+ // apphandle = "<cid>app/app_name/"
+ apphandle, _ := context.AddApp(compositeHandle, app_name)
+
+ // Add cluster
+ // err = addClustersToAppContext(listOfClusters, context, apphandle, resources)
+ // rtc.RtcAddLevel("<cid>app/app_name/", "cluster", clustername)
+ // -> save ("<cid>app/app_name/cluster/clusername/", clustername) in etcd
+ // return "<cid>app/app_name/cluster/clusername/"
+ clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name)
+ err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, true)
+ }
+
+ jappOrderInstr, _ := json.Marshal(appOrderInstr)
+ appDepInstr.Appdep = appdep
+ jappDepInstr, _ := json.Marshal(appDepInstr)
+ context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))
+ context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))
+
+ // invoke deployment process
+ appContextID := fmt.Sprintf("%v", ctxval)
+ err = rsyncclient.InvokeInstallApp(appContextID)
+ if err != nil {
+ log.Println(err)
+ return appContextID, err
+ }
+
+ return appContextID, nil
+}
+
+func (d *ResUtil) Undeploy(app_name string, format string) (string, error) {
+ // Generate Application context
+ cca, err := makeAppContextForCompositeApp(project_name, app_name+"-u", "1.0", "1.0", "di", "default", "0")
+ context := cca.context // appcontext.AppContext
+ ctxval := cca.ctxval // id
+ compositeHandle := cca.compositeAppHandle // cid
+
+ var appOrderInstr struct {
+ Apporder []string `json:"apporder"`
+ }
+ var appDepInstr struct {
+ Appdep map[string]string `json:"appdependency"`
+ }
+ appdep := make(map[string]string)
+ // create a com_app for each device
+ for device, res := range d.resmap {
+ // Add application
+ app_name := device.GetMetadata().Name + "-app"
+ appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name)
+ appdep[app_name] = "go"
+ apphandle, _ := context.AddApp(compositeHandle, app_name)
+
+ // Add cluster
+ clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name)
+ err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, false)
+ }
+
+ jappOrderInstr, _ := json.Marshal(appOrderInstr)
+ appDepInstr.Appdep = appdep
+ jappDepInstr, _ := json.Marshal(appDepInstr)
+ context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))
+ context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))
+
+ initializeAppContextStatus(context, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiated})
+ // invoke deployment process
+ appContextID := fmt.Sprintf("%v", ctxval)
+ err = rsyncclient.InvokeUninstallApp(appContextID)
+ if err != nil {
+ log.Println(err)
+ return appContextID, err
+ }
+
+ return appContextID, nil
+}
+
+func (d *ResUtil) AddQueryResource(device module.ControllerObject, resource QueryResource) error {
+ if d.qryResmap[device] == nil {
+ d.qryResmap[device] = &QueryResources{Resources: []*QueryResource{}}
+ }
+
+ d.qryResmap[device].Resources = append(d.qryResmap[device].Resources, &resource)
+ d.qryCtxId = ""
+
+ return nil
+}
+
+func addQueryResourcesToCluster(ct appcontext.AppContext, ch interface{}, resources *[]*QueryResource) error {
+
+ var resOrderInstr struct {
+ Resorder []string `json:"resorder"`
+ }
+
+ var resDepInstr struct {
+ Resdep map[string]string `json:"resdependency"`
+ }
+ resdep := make(map[string]string)
+
+ for _, resource := range *resources {
+ resource_name := resource.Resource.Namespace + "+" + resource.Resource.Name
+ v, _ := json.Marshal(resource.Resource)
+ resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name)
+ resdep[resource_name] = "go"
+
+ rh, err := ct.AddResource(ch, resource_name, string(v))
+
+ if err != nil {
+ return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name)
+ }
+
+ // save the resource handler for query result
+ resource.Handle = rh
+
+ jresOrderInstr, _ := json.Marshal(resOrderInstr)
+ resDepInstr.Resdep = resdep
+ jresDepInstr, _ := json.Marshal(resDepInstr)
+
+ _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr))
+ _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr))
+ if err != nil {
+ return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name)
+ }
+ }
+ return nil
+}
+
+func (d *ResUtil) Query(app_name string) (string, error) {
+ if d.qryCtxId == "" {
+ // Generate Application context
+ cca, err := makeAppContextForCompositeApp(project_name, app_name+"-d", "1.0", "1.0", "di", "default", "0")
+ if err != nil {
+ log.Println(err)
+ return "", err
+ }
+
+ context := cca.context // appcontext.AppContext
+ ctxval := cca.ctxval // id
+ compositeHandle := cca.compositeAppHandle // cid
+
+ var appOrderInstr struct {
+ Apporder []string `json:"apporder"`
+ }
+ var appDepInstr struct {
+ Appdep map[string]string `json:"appdependency"`
+ }
+ appdep := make(map[string]string)
+ // create a com_app for each device
+ for device, res := range d.qryResmap {
+ // Add application
+ app_name := device.GetMetadata().Name + "-query-app"
+ appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name)
+ appdep[app_name] = "go"
+
+ apphandle, _ := context.AddApp(compositeHandle, app_name)
+
+ // Add cluster
+ clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name)
+ err = addQueryResourcesToCluster(context, clusterhandle, &res.Resources)
+ }
+
+ jappOrderInstr, _ := json.Marshal(appOrderInstr)
+ appDepInstr.Appdep = appdep
+ jappDepInstr, _ := json.Marshal(appDepInstr)
+ context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))
+ context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))
+
+ // invoke query process
+ appContextID := fmt.Sprintf("%v", ctxval)
+ d.qryCtxId = appContextID
+ }
+
+ err := rsyncclient.InvokeGetResource(d.qryCtxId)
+ if err != nil {
+ log.Println(err)
+ d.qryCtxId = ""
+ return "", err
+ }
+
+ return d.qryCtxId, nil
+}
+
+func (d *ResUtil) GetResourceData(device module.ControllerObject, ns string, name string) (string, error) {
+ if d.qryCtxId == "" {
+ return "", pkgerrors.New("Query failed to be executed.")
+ }
+
+ var ac appcontext.AppContext
+ ah, err := ac.LoadAppContext(d.qryCtxId)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "AppContext is not found.")
+ }
+
+ // wait for resource ready
+ err = wait.PollImmediate(time.Second, time.Second*20,
+ func() (bool, error) {
+ sh, err := ac.GetLevelHandle(ah, "status")
+ if err != nil {
+ log.Println("Waiting for Resource status to be ready.")
+ return false, nil
+ }
+
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ log.Println("Waiting for Resource status to be ready..")
+ return false, nil
+ }
+
+ acStatus := appcontext.AppContextStatus{}
+ js, _ := json.Marshal(s)
+ json.Unmarshal(js, &acStatus)
+ log.Println(acStatus.Status)
+ if acStatus.Status == appcontext.AppContextStatusEnum.Instantiated {
+ return true, nil
+ }
+
+ log.Println("Waiting for Resource status to be ready...")
+ return false, nil
+ },
+ )
+
+ if err != nil {
+ log.Println(err)
+ return "", pkgerrors.Wrap(err, "Resource is not available")
+ }
+
+ // found resource handle
+ if d.qryResmap[device] == nil {
+ return "", pkgerrors.Wrap(err, "No query resource found.")
+ }
+
+ for _, resource := range d.qryResmap[device].Resources {
+ if ns == resource.Resource.Namespace && name == resource.Resource.Name {
+ rdh, _ := ac.GetLevelHandle(resource.Handle, "definition")
+ if rdh != nil {
+ ret, err := ac.GetValue(rdh)
+ if err == nil {
+ return ret.(string), nil
+ }
+ }
+ return "", pkgerrors.Wrap(err, "Failed to query the resource value.")
+ }
+ }
+
+ return "", pkgerrors.New("No query resource found.")
+}
-/*\r
- * Copyright 2021 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package manager\r
-\r
-import (\r
- "strings"\r
-)\r
-\r
-func format_resource_name(name1 string, name2 string) string {\r
- name1 = strings.Replace(name1, "-", "", -1)\r
- name2 = strings.Replace(name2, "-", "", -1)\r
-\r
- return strings.ToLower(name1+name2)\r
-}\r
+/*
+ * Copyright 2021 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 manager
+
+import (
+ "strings"
+)
+
+func format_resource_name(name1 string, name2 string) string {
+ name1 = strings.Replace(name1, "-", "", -1)
+ name2 = strings.Replace(name2, "-", "", -1)
+
+ return strings.ToLower(name1 + name2)
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// App contains metadata for Apps\r
-type CertificateObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification CertificateObjectSpec `json:"spec"`\r
- Data CertificateObjectData `json:"data"`\r
-}\r
-\r
-// CertificateObjectSpec contains the parameters\r
-type CertificateObjectSpec struct {\r
-}\r
-\r
-type CertificateObjectData struct {\r
- RootCA string `json:"rootca"`\r
- Ca string `json:"ca"`\r
- Key string `json:"key"`\r
-}\r
-\r
-func (c *CertificateObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *CertificateObject) GetType() string {\r
- return "Certificate"\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type CertificateObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification CertificateObjectSpec `json:"spec"`
+ Data CertificateObjectData `json:"data"`
+}
+
+// CertificateObjectSpec contains the parameters
+type CertificateObjectSpec struct {
+}
+
+type CertificateObjectData struct {
+ RootCA string `json:"rootca"`
+ Ca string `json:"ca"`
+ Key string `json:"key"`
+}
+
+func (c *CertificateObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *CertificateObject) GetType() string {
+ return "Certificate"
+}
--- /dev/null
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type CNFObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Status string `json:"status"`
+}
+
+func (c *CNFObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *CNFObject) GetType() string {
+ return "CNF"
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-import (\r
- "log"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"\r
-)\r
-\r
-\r
-type states struct {\r
- Created string\r
- Deployed string\r
- Undeployed string\r
- Error string\r
-}\r
-\r
-var StateEnum = &states{\r
- Created: "Created",\r
- Deployed: "Deployed",\r
- Undeployed: "Undeployed",\r
- Error: "Error",\r
-}\r
-\r
-type ConnectionObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Info ConnectionInfo `json:"information"`\r
-}\r
-\r
-//ConnectionInfo contains the connection information\r
-type ConnectionInfo struct {\r
- End1 ConnectionEnd `json:"end1"`\r
- End2 ConnectionEnd `json:"end2"`\r
- ContextId string `json:"-"`\r
- State string `json:"state"`\r
- ErrorMessage string `json:"message"`\r
-}\r
-\r
-type ConnectionEnd struct {\r
- Name string `json:"name"`\r
- Type string `json:"type"`\r
- IP string `json:"ip"`\r
- ConnObject string `json:"-"`\r
- Resources []string `json:"-"`\r
- ReservedRes []string `json:"-"`\r
-}\r
-\r
-func (c *ConnectionObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *ConnectionObject) GetType() string {\r
- return "Connection"\r
-}\r
-\r
-func CreateEndName(t string, n string) string {\r
- return t + "." + n\r
-}\r
-\r
-func CreateConnectionName(e1 string, e2 string) string {\r
- return e1 + "-" + e2\r
-}\r
-\r
-func NewConnectionEnd(conn_obj ControllerObject, ip string) ConnectionEnd {\r
- obj_str, err := GetObjectBuilder().ToString(conn_obj)\r
- if err == nil {\r
- return ConnectionEnd{\r
- Name: CreateEndName(conn_obj.GetType(), conn_obj.GetMetadata().Name),\r
- Type: conn_obj.GetType(),\r
- IP: ip,\r
- ConnObject: obj_str,\r
- Resources: []string{},\r
- ReservedRes: []string{},\r
- }\r
- } else {\r
- log.Println(err)\r
- return ConnectionEnd{}\r
- }\r
-}\r
-\r
-func NewConnectionObject(end1 ConnectionEnd, end2 ConnectionEnd) ConnectionObject {\r
- return ConnectionObject{\r
- Metadata: ObjectMetaData{CreateConnectionName(end1.Name, end2.Name), "", "", ""}, \r
- Info: ConnectionInfo{\r
- End1: end1,\r
- End2: end2,\r
- ContextId: "",\r
- State: StateEnum.Created,\r
- ErrorMessage: "",\r
- },\r
- }\r
-}\r
-\r
-func (c *ConnectionEnd) contains(res resource.ISdewanResource, isReserved bool) bool {\r
- if isReserved {\r
- for _, r_str := range c.ReservedRes {\r
- r, err := resource.GetResourceBuilder().ToObject(r_str)\r
- if err == nil {\r
- if r.GetName() == res.GetName() &&\r
- r.GetType() == res.GetType() {\r
- return true\r
- }\r
- }\r
- }\r
- } else {\r
- for _, r_str := range c.Resources {\r
- r, err := resource.GetResourceBuilder().ToObject(r_str)\r
- if err == nil {\r
- if r.GetName() == res.GetName() &&\r
- r.GetType() == res.GetType() {\r
- return true\r
- }\r
- }\r
- }\r
- }\r
-\r
- return false\r
-}\r
-\r
-func (c *ConnectionEnd) AddResource(res resource.ISdewanResource, isReserved bool) error {\r
- if !c.contains(res, isReserved) {\r
- res_str, err := resource.GetResourceBuilder().ToString(res)\r
- if err == nil {\r
- if isReserved {\r
- c.ReservedRes = append(c.ReservedRes, res_str)\r
- } else {\r
- c.Resources = append(c.Resources, res_str)\r
- }\r
- }\r
- }\r
-\r
- return nil\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+ "log"
+)
+
+type states struct {
+ Created string
+ Deployed string
+ Undeployed string
+ Error string
+}
+
+var StateEnum = &states{
+ Created: "Created",
+ Deployed: "Deployed",
+ Undeployed: "Undeployed",
+ Error: "Error",
+}
+
+type ConnectionObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Info ConnectionInfo `json:"information"`
+}
+
+//ConnectionInfo contains the connection information
+type ConnectionInfo struct {
+ End1 ConnectionEnd `json:"end1"`
+ End2 ConnectionEnd `json:"end2"`
+ ContextId string `json:"-"`
+ State string `json:"state"`
+ ErrorMessage string `json:"message"`
+}
+
+type ConnectionEnd struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+ IP string `json:"ip"`
+ ConnObject string `json:"-"`
+ Resources []string `json:"-"`
+ ReservedRes []string `json:"-"`
+}
+
+func (c *ConnectionObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *ConnectionObject) GetType() string {
+ return "Connection"
+}
+
+func CreateEndName(t string, n string) string {
+ return t + "." + n
+}
+
+func CreateConnectionName(e1 string, e2 string) string {
+ return e1 + "-" + e2
+}
+
+func NewConnectionEnd(conn_obj ControllerObject, ip string) ConnectionEnd {
+ obj_str, err := GetObjectBuilder().ToString(conn_obj)
+ if err == nil {
+ return ConnectionEnd{
+ Name: CreateEndName(conn_obj.GetType(), conn_obj.GetMetadata().Name),
+ Type: conn_obj.GetType(),
+ IP: ip,
+ ConnObject: obj_str,
+ Resources: []string{},
+ ReservedRes: []string{},
+ }
+ } else {
+ log.Println(err)
+ return ConnectionEnd{}
+ }
+}
+
+func NewConnectionObject(end1 ConnectionEnd, end2 ConnectionEnd) ConnectionObject {
+ return ConnectionObject{
+ Metadata: ObjectMetaData{CreateConnectionName(end1.Name, end2.Name), "", "", ""},
+ Info: ConnectionInfo{
+ End1: end1,
+ End2: end2,
+ ContextId: "",
+ State: StateEnum.Created,
+ ErrorMessage: "",
+ },
+ }
+}
+
+func (c *ConnectionEnd) contains(res resource.ISdewanResource, isReserved bool) bool {
+ if isReserved {
+ for _, r_str := range c.ReservedRes {
+ r, err := resource.GetResourceBuilder().ToObject(r_str)
+ if err == nil {
+ if r.GetName() == res.GetName() &&
+ r.GetType() == res.GetType() {
+ return true
+ }
+ }
+ }
+ } else {
+ for _, r_str := range c.Resources {
+ r, err := resource.GetResourceBuilder().ToObject(r_str)
+ if err == nil {
+ if r.GetName() == res.GetName() &&
+ r.GetType() == res.GetType() {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+func (c *ConnectionEnd) AddResource(res resource.ISdewanResource, isReserved bool) error {
+ if !c.contains(res, isReserved) {
+ res_str, err := resource.GetResourceBuilder().ToString(res)
+ if err == nil {
+ if isReserved {
+ c.ReservedRes = append(c.ReservedRes, res_str)
+ } else {
+ c.Resources = append(c.Resources, res_str)
+ }
+ }
+ }
+
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// ControllerObject define the basic functionality of ControllerObject\r
-type ControllerObject interface {\r
- GetMetadata() ObjectMetaData\r
- GetType() string\r
-}\r
-\r
-// ObjectMetaData contains the parameters \r
-type ObjectMetaData struct {\r
- Name string `json:"name" validate:"required,hostname_rfc1123"`\r
- Description string `json:"description"`\r
- UserData1 string `json:"userData1"`\r
- UserData2 string `json:"userData2"`\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// ControllerObject define the basic functionality of ControllerObject
+type ControllerObject interface {
+ GetMetadata() ObjectMetaData
+ GetType() string
+}
+
+// ObjectMetaData contains the parameters
+type ObjectMetaData struct {
+ Name string `json:"name" validate:"required,hostname_rfc1123"`
+ Description string `json:"description"`
+ UserData1 string `json:"userData1"`
+ UserData2 string `json:"userData2"`
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// App contains metadata for Apps\r
-type DeviceObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification DeviceObjectSpec `json:"spec"`\r
- Status DeviceObjectStatus `json:"-"`\r
-}\r
-\r
-// DeviceObjectSpec contains the parameters\r
-type DeviceObjectSpec struct {\r
- PublicIps []string `json:"publicIps"`\r
- ForceHubConnectivity bool `json:"forceHubConnectivity"`\r
- ProxyHub string `json:"proxyHub"`\r
- ProxyHubPort int `json:"proxyHubPort"`\r
- UseHub4Internet bool `json:"useHub4Internet"`\r
- DedicatedSFC bool `json:"dedicatedSFC"` \r
- CertificateId string `json:"certificateId"`\r
- KubeConfig string `json:"kubeConfig"`\r
-}\r
-\r
-// DeviceObjectStatus\r
-type DeviceObjectStatus struct {\r
- // 1: use public ip 2: use hub as proxy\r
- Mode int\r
- // ip used for external connection\r
- // if Mode=1, ip is one of public ip\r
- // if Mode=2, ip is the OIP allocated by SCC\r
- Ip string\r
- // Status Data\r
- Data map[string]string\r
-}\r
-\r
-func (c *DeviceObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *DeviceObject) GetType() string {\r
- return "Device"\r
-}\r
-\r
-func (c *DeviceObject) IsProxyHub(hub_name string) bool {\r
- if c.Status.Mode == 2 {\r
- return c.Specification.ProxyHub == hub_name\r
- }\r
-\r
- return false\r
-}\r
-\r
-func init() {\r
- GetObjectBuilder().Register("Device", &DeviceObject{})\r
-}\r
-\r
-func (c *DeviceObject) GetCertName() string {\r
- return "device-" + c.Metadata.Name + "-cert"\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type DeviceObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification DeviceObjectSpec `json:"spec"`
+ Status DeviceObjectStatus `json:"-"`
+}
+
+// DeviceObjectSpec contains the parameters
+type DeviceObjectSpec struct {
+ PublicIps []string `json:"publicIps"`
+ ForceHubConnectivity bool `json:"forceHubConnectivity"`
+ ProxyHub string `json:"proxyHub"`
+ ProxyHubPort int `json:"proxyHubPort"`
+ UseHub4Internet bool `json:"useHub4Internet"`
+ DedicatedSFC bool `json:"dedicatedSFC"`
+ CertificateId string `json:"certificateId"`
+ KubeConfig string `json:"kubeConfig"`
+}
+
+// DeviceObjectStatus
+type DeviceObjectStatus struct {
+ // 1: use public ip 2: use hub as proxy
+ Mode int
+ // ip used for external connection
+ // if Mode=1, ip is one of public ip
+ // if Mode=2, ip is the OIP allocated by SCC
+ Ip string
+ // Status Data
+ Data map[string]string
+}
+
+func (c *DeviceObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *DeviceObject) GetType() string {
+ return "Device"
+}
+
+func (c *DeviceObject) IsProxyHub(hub_name string) bool {
+ if c.Status.Mode == 2 {
+ return c.Specification.ProxyHub == hub_name
+ }
+
+ return false
+}
+
+func init() {
+ GetObjectBuilder().Register("Device", &DeviceObject{})
+}
+
+func (c *DeviceObject) GetCertName() string {
+ return "device-" + c.Metadata.Name + "-cert"
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// App contains metadata for Apps\r
-type EmptyObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
-}\r
-\r
-func (c *EmptyObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *EmptyObject) GetType() string {\r
- return "Empty"\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type EmptyObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+}
+
+func (c *EmptyObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *EmptyObject) GetType() string {
+ return "Empty"
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// App contains metadata for Apps\r
-type HubDeviceObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification HubDeviceObjectSpec `json:"spec"`\r
-}\r
-\r
-//HubDeviceObjectSpec contains the parameters\r
-type HubDeviceObjectSpec struct {\r
- Device string `json:"device"`\r
-}\r
-\r
-func (c *HubDeviceObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *HubDeviceObject) GetType() string {\r
- return "HubDevice"\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type HubDeviceObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification HubDeviceObjectSpec `json:"spec"`
+}
+
+//HubDeviceObjectSpec contains the parameters
+type HubDeviceObjectSpec struct {
+ Device string `json:"device"`
+}
+
+func (c *HubDeviceObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *HubDeviceObject) GetType() string {
+ return "HubDevice"
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-import (\r
- "strconv"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const (\r
- MinProxyPort = 10000\r
- MaxProxyPort = 16000\r
-)\r
-\r
-// App contains metadata for Apps\r
-type HubObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification HubObjectSpec `json:"spec"`\r
- Status HubObjectStatus `json:"-"`\r
-}\r
-\r
-//HubObjectSpec contains the parameters\r
-type HubObjectSpec struct {\r
- PublicIps []string `json:"publicIps"`\r
- CertificateId string `json:"certificateId"`\r
- KubeConfig string `json:"kubeConfig"`\r
-}\r
-\r
-//HubObjectStatus\r
-type HubObjectStatus struct {\r
- Ip string\r
- Data map[string]string\r
- // Allocated proxy port for device\r
- ProxyPort map[string]string\r
-}\r
-\r
-func (c *HubObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-\r
-func (c *HubObject) GetCertName() string {\r
- return "hub-" + c.Metadata.Name + "-cert"\r
-}\r
-\r
-func (c *HubObject) GetType() string {\r
- return "Hub"\r
-}\r
-\r
-func (c *HubObject) IsProxyPortUsed(port int) bool {\r
- _, ok := c.Status.ProxyPort[strconv.Itoa(port)]\r
- return ok\r
-}\r
-\r
-func (c *HubObject) SetProxyPort(port int, device string) {\r
- c.Status.ProxyPort[strconv.Itoa(port)] = device\r
-}\r
-\r
-func (c *HubObject) UnsetProxyPort(port int) {\r
- delete(c.Status.ProxyPort, strconv.Itoa(port))\r
-}\r
-\r
-func (c *HubObject) GetProxyPort(port int) string {\r
- return c.Status.ProxyPort[strconv.Itoa(port)]\r
-}\r
-\r
-func (c *HubObject) AllocateProxyPort() (int, error) {\r
- for i:=MinProxyPort; i<MaxProxyPort; i++ {\r
- if !c.IsProxyPortUsed(i) {\r
- return i, nil\r
- }\r
- }\r
-\r
- return 0, pkgerrors.New("Fail to allocate proxy port")\r
-}\r
-\r
-func init() {\r
- GetObjectBuilder().Register("Hub", &HubObject{})\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+import (
+ pkgerrors "github.com/pkg/errors"
+ "strconv"
+)
+
+const (
+ MinProxyPort = 10000
+ MaxProxyPort = 16000
+)
+
+// App contains metadata for Apps
+type HubObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification HubObjectSpec `json:"spec"`
+ Status HubObjectStatus `json:"-"`
+}
+
+//HubObjectSpec contains the parameters
+type HubObjectSpec struct {
+ PublicIps []string `json:"publicIps"`
+ CertificateId string `json:"certificateId"`
+ KubeConfig string `json:"kubeConfig"`
+}
+
+//HubObjectStatus
+type HubObjectStatus struct {
+ Ip string
+ Data map[string]string
+ // Allocated proxy port for device
+ ProxyPort map[string]string
+}
+
+func (c *HubObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *HubObject) GetCertName() string {
+ return "hub-" + c.Metadata.Name + "-cert"
+}
+
+func (c *HubObject) GetType() string {
+ return "Hub"
+}
+
+func (c *HubObject) IsProxyPortUsed(port int) bool {
+ _, ok := c.Status.ProxyPort[strconv.Itoa(port)]
+ return ok
+}
+
+func (c *HubObject) SetProxyPort(port int, device string) {
+ c.Status.ProxyPort[strconv.Itoa(port)] = device
+}
+
+func (c *HubObject) UnsetProxyPort(port int) {
+ delete(c.Status.ProxyPort, strconv.Itoa(port))
+}
+
+func (c *HubObject) GetProxyPort(port int) string {
+ return c.Status.ProxyPort[strconv.Itoa(port)]
+}
+
+func (c *HubObject) AllocateProxyPort() (int, error) {
+ for i := MinProxyPort; i < MaxProxyPort; i++ {
+ if !c.IsProxyPortUsed(i) {
+ return i, nil
+ }
+ }
+
+ return 0, pkgerrors.New("Fail to allocate proxy port")
+}
+
+func init() {
+ GetObjectBuilder().Register("Hub", &HubObject{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-import (\r
- "math"\r
- "strconv"\r
- "strings"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// App contains metadata for Apps\r
-type IPRangeObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification IPRangeObjectSpec `json:"spec"`\r
- Status IPRangeObjectStatus `json:"-"`\r
-}\r
-\r
-//IPRangeObjectSpec contains the parameters\r
-type IPRangeObjectSpec struct {\r
- Subnet string `json:"subnet" validate:"required,ipv4"`\r
- MinIp int `json:"minIp" validate:"gte=1,lte=255"`\r
- MaxIp int `json:"maxIp" validate:"gte=1,lte=255"`\r
-}\r
-\r
-type IPRangeObjectStatus struct {\r
- Masks [32]byte\r
- Data map[string]string\r
-}\r
-\r
-func (c *IPRangeObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *IPRangeObject) GetType() string {\r
- return "IPRange"\r
-}\r
-\r
-func (c *IPRangeObject) base() string {\r
- index := strings.LastIndex(c.Specification.Subnet, ".")\r
- if index == -1 {\r
- return c.Specification.Subnet\r
- } else {\r
- return c.Specification.Subnet[0:index+1]\r
- }\r
-}\r
-\r
-func (c *IPRangeObject) IsConflict(o *IPRangeObject) bool {\r
- if strings.Compare(c.base(), o.base()) != 0 {\r
- return false\r
- }\r
-\r
- if c.Specification.MinIp > o.Specification.MaxIp || c.Specification.MaxIp < o.Specification.MinIp {\r
- return false\r
- }\r
-\r
- return true\r
-}\r
-\r
-func (c *IPRangeObject) InUsed() bool {\r
- return (len(c.Status.Data) != 0)\r
-}\r
-\r
-func (c *IPRangeObject) Allocate(name string) (string, error) {\r
- i := c.Specification.MinIp\r
- index := (c.Specification.MinIp-1)/8\r
- b := byte(math.Exp2(float64(7-(c.Specification.MinIp-1)%8)))\r
- for i <= c.Specification.MaxIp {\r
- if c.Status.Masks[index] & b == 0 {\r
- c.Status.Masks[index] |= b\r
- c.Status.Data[strconv.Itoa(i)] = name\r
- return c.base() + strconv.Itoa(i), nil\r
- }\r
- if (i % 8 == 0) {\r
- b = 0x80\r
- index += 1\r
- for c.Status.Masks[index] == 0xff {\r
- // log.Println("by pass", index)\r
- i += 8\r
- index += 1\r
- }\r
- } else {\r
- b = b / 2\r
- }\r
- i = i + 1\r
- }\r
-\r
- return "", pkgerrors.New("No available IP")\r
-}\r
-\r
-func (c *IPRangeObject) Free(sip string) error {\r
- ip := 0\r
- i := strings.LastIndex(sip, ".")\r
- if i == -1 {\r
- return pkgerrors.New("invalid ip")\r
- } else {\r
- base_ip := sip[0:i+1]\r
- if c.base() != base_ip {\r
- return pkgerrors.New("ip is not in range")\r
- }\r
-\r
- ip, _ = strconv.Atoi(sip[i+1:len(sip)])\r
- }\r
- \r
- if ip < c.Specification.MinIp || ip > c.Specification.MaxIp {\r
- return pkgerrors.New("ip is not in range")\r
- }\r
-\r
- index := (ip-1)/8\r
- b := byte(math.Exp2(float64(7-(ip-1)%8)))\r
- if c.Status.Masks[index] & b == 0 {\r
- return pkgerrors.New("ip is not allocated")\r
- }\r
-\r
- delete(c.Status.Data, strconv.Itoa(ip))\r
- c.Status.Masks[index] &= (^b)\r
- return nil\r
-}\r
-\r
-func (c *IPRangeObject) FreeAll() error {\r
- for sip, _ := range c.Status.Data {\r
- ip, _ := strconv.Atoi(sip)\r
- index := (ip-1)/8\r
- b := byte(math.Exp2(float64(7-(ip-1)%8)))\r
- delete(c.Status.Data, sip)\r
- c.Status.Masks[index] &= (^b)\r
- }\r
- return nil\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+import (
+ pkgerrors "github.com/pkg/errors"
+ "math"
+ "strconv"
+ "strings"
+)
+
+// App contains metadata for Apps
+type IPRangeObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification IPRangeObjectSpec `json:"spec"`
+ Status IPRangeObjectStatus `json:"-"`
+}
+
+//IPRangeObjectSpec contains the parameters
+type IPRangeObjectSpec struct {
+ Subnet string `json:"subnet" validate:"required,ipv4"`
+ MinIp int `json:"minIp" validate:"gte=1,lte=255"`
+ MaxIp int `json:"maxIp" validate:"gte=1,lte=255"`
+}
+
+type IPRangeObjectStatus struct {
+ Masks [32]byte
+ Data map[string]string
+}
+
+func (c *IPRangeObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *IPRangeObject) GetType() string {
+ return "IPRange"
+}
+
+func (c *IPRangeObject) base() string {
+ index := strings.LastIndex(c.Specification.Subnet, ".")
+ if index == -1 {
+ return c.Specification.Subnet
+ } else {
+ return c.Specification.Subnet[0 : index+1]
+ }
+}
+
+func (c *IPRangeObject) IsConflict(o *IPRangeObject) bool {
+ if strings.Compare(c.base(), o.base()) != 0 {
+ return false
+ }
+
+ if c.Specification.MinIp > o.Specification.MaxIp || c.Specification.MaxIp < o.Specification.MinIp {
+ return false
+ }
+
+ return true
+}
+
+func (c *IPRangeObject) InUsed() bool {
+ return (len(c.Status.Data) != 0)
+}
+
+func (c *IPRangeObject) Allocate(name string) (string, error) {
+ i := c.Specification.MinIp
+ index := (c.Specification.MinIp - 1) / 8
+ b := byte(math.Exp2(float64(7 - (c.Specification.MinIp-1)%8)))
+ for i <= c.Specification.MaxIp {
+ if c.Status.Masks[index]&b == 0 {
+ c.Status.Masks[index] |= b
+ c.Status.Data[strconv.Itoa(i)] = name
+ return c.base() + strconv.Itoa(i), nil
+ }
+ if i%8 == 0 {
+ b = 0x80
+ index += 1
+ for c.Status.Masks[index] == 0xff {
+ // log.Println("by pass", index)
+ i += 8
+ index += 1
+ }
+ } else {
+ b = b / 2
+ }
+ i = i + 1
+ }
+
+ return "", pkgerrors.New("No available IP")
+}
+
+func (c *IPRangeObject) Free(sip string) error {
+ ip := 0
+ i := strings.LastIndex(sip, ".")
+ if i == -1 {
+ return pkgerrors.New("invalid ip")
+ } else {
+ base_ip := sip[0 : i+1]
+ if c.base() != base_ip {
+ return pkgerrors.New("ip is not in range")
+ }
+
+ ip, _ = strconv.Atoi(sip[i+1 : len(sip)])
+ }
+
+ if ip < c.Specification.MinIp || ip > c.Specification.MaxIp {
+ return pkgerrors.New("ip is not in range")
+ }
+
+ index := (ip - 1) / 8
+ b := byte(math.Exp2(float64(7 - (ip-1)%8)))
+ if c.Status.Masks[index]&b == 0 {
+ return pkgerrors.New("ip is not allocated")
+ }
+
+ delete(c.Status.Data, strconv.Itoa(ip))
+ c.Status.Masks[index] &= (^b)
+ return nil
+}
+
+func (c *IPRangeObject) FreeAll() error {
+ for sip, _ := range c.Status.Data {
+ ip, _ := strconv.Atoi(sip)
+ index := (ip - 1) / 8
+ b := byte(math.Exp2(float64(7 - (ip-1)%8)))
+ delete(c.Status.Data, sip)
+ c.Status.Masks[index] &= (^b)
+ }
+ return nil
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-import (\r
- "strings"\r
- "reflect"\r
- "encoding/json"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type ObjectBuilder struct {\r
- omap map[string]reflect.Type\r
-}\r
-\r
-var obj_builder = ObjectBuilder{\r
- omap: make(map[string]reflect.Type),\r
-}\r
-\r
-func GetObjectBuilder() *ObjectBuilder {\r
- return &obj_builder\r
-}\r
-\r
-func (c *ObjectBuilder) Register(name string, r interface{}) {\r
- c.omap[name] = reflect.TypeOf(r).Elem()\r
-}\r
-\r
-func (c *ObjectBuilder) ToString(obj ControllerObject) (string, error) {\r
- obj_str, err := json.Marshal(obj)\r
- if err != nil {\r
- return "", err\r
- }\r
-\r
- return obj.GetType() + "-" + string(obj_str), nil\r
-}\r
-\r
-func (c *ObjectBuilder) ToObject(obj_str string) (ControllerObject, error) {\r
- if !strings.Contains(obj_str, "-") {\r
- return &EmptyObject{}, pkgerrors.New("Not a valid object")\r
- }\r
- strs := strings.SplitN(obj_str, "-", 2)\r
-\r
- if v, ok := c.omap[strs[0]]; ok {\r
- retObj := reflect.New(v).Interface()\r
- err := json.Unmarshal([]byte(strs[1]), retObj)\r
- return retObj.(ControllerObject), err\r
- } else {\r
- return &EmptyObject{}, pkgerrors.New("Not a valid object")\r
- }\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+import (
+ "encoding/json"
+ pkgerrors "github.com/pkg/errors"
+ "reflect"
+ "strings"
+)
+
+type ObjectBuilder struct {
+ omap map[string]reflect.Type
+}
+
+var obj_builder = ObjectBuilder{
+ omap: make(map[string]reflect.Type),
+}
+
+func GetObjectBuilder() *ObjectBuilder {
+ return &obj_builder
+}
+
+func (c *ObjectBuilder) Register(name string, r interface{}) {
+ c.omap[name] = reflect.TypeOf(r).Elem()
+}
+
+func (c *ObjectBuilder) ToString(obj ControllerObject) (string, error) {
+ obj_str, err := json.Marshal(obj)
+ if err != nil {
+ return "", err
+ }
+
+ return obj.GetType() + "-" + string(obj_str), nil
+}
+
+func (c *ObjectBuilder) ToObject(obj_str string) (ControllerObject, error) {
+ if !strings.Contains(obj_str, "-") {
+ return &EmptyObject{}, pkgerrors.New("Not a valid object")
+ }
+ strs := strings.SplitN(obj_str, "-", 2)
+
+ if v, ok := c.omap[strs[0]]; ok {
+ retObj := reflect.New(v).Interface()
+ err := json.Unmarshal([]byte(strs[1]), retObj)
+ return retObj.(ControllerObject), err
+ } else {
+ return &EmptyObject{}, pkgerrors.New("Not a valid object")
+ }
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-// App contains metadata for Apps\r
-type OverlayObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification OverlayObjectSpec `json:"spec"`\r
-}\r
-\r
-//OverlayObjectSpec contains the parameters\r
-type OverlayObjectSpec struct {\r
-}\r
-\r
-func (c *OverlayObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *OverlayObject) GetType() string {\r
- return "Overlay"\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+// App contains metadata for Apps
+type OverlayObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification OverlayObjectSpec `json:"spec"`
+}
+
+//OverlayObjectSpec contains the parameters
+type OverlayObjectSpec struct {
+}
+
+func (c *OverlayObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *OverlayObject) GetType() string {
+ return "Overlay"
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package module\r
-\r
-import (\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"\r
-)\r
-\r
-// App contains metadata for Apps\r
-type ProposalObject struct {\r
- Metadata ObjectMetaData `json:"metadata"`\r
- Specification ProposalObjectSpec `json:"spec"`\r
-}\r
-\r
-//ProposalObjectSpec contains the parameters\r
-type ProposalObjectSpec struct {\r
- Encryption string `json:"encryption"`\r
- Hash string `json:"hash"`\r
- DhGroup string `json:"dhGroup"`\r
-}\r
-\r
-func (c *ProposalObject) GetMetadata() ObjectMetaData {\r
- return c.Metadata\r
-}\r
-\r
-func (c *ProposalObject) GetType() string {\r
- return "Proposal"\r
-}\r
-\r
-func (c *ProposalObject) ToResource() *resource.ProposalResource {\r
- return &resource.ProposalResource{\r
- Name: c.Metadata.Name,\r
- Encryption: c.Specification.Encryption,\r
- Hash: c.Specification.Hash,\r
- DhGroup: c.Specification.DhGroup,\r
- }\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 module
+
+import (
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource"
+)
+
+// App contains metadata for Apps
+type ProposalObject struct {
+ Metadata ObjectMetaData `json:"metadata"`
+ Specification ProposalObjectSpec `json:"spec"`
+}
+
+//ProposalObjectSpec contains the parameters
+type ProposalObjectSpec struct {
+ Encryption string `json:"encryption"`
+ Hash string `json:"hash"`
+ DhGroup string `json:"dhGroup"`
+}
+
+func (c *ProposalObject) GetMetadata() ObjectMetaData {
+ return c.Metadata
+}
+
+func (c *ProposalObject) GetType() string {
+ return "Proposal"
+}
+
+func (c *ProposalObject) ToResource() *resource.ProposalResource {
+ return &resource.ProposalResource{
+ Name: c.Metadata.Name,
+ Encryption: c.Specification.Encryption,
+ Hash: c.Specification.Hash,
+ DhGroup: c.Specification.DhGroup,
+ }
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
-)\r
-\r
-type EmptyResource struct {\r
-}\r
-\r
-func (c *EmptyResource) GetName() string {\r
- return ""\r
-}\r
-\r
-func (c *EmptyResource) GetType() string {\r
- return "Empty"\r
-}\r
-\r
-func (c *EmptyResource) ToYaml() string {\r
- return ""\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import ()
+
+type EmptyResource struct {
+}
+
+func (c *EmptyResource) GetName() string {
+ return ""
+}
+
+func (c *EmptyResource) GetType() string {
+ return "Empty"
+}
+
+func (c *EmptyResource) ToYaml(target string) string {
+ return ""
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
- "io/ioutil"\r
-)\r
-\r
-type FileResource struct {\r
- Name string\r
- Type string\r
- FileName string\r
-}\r
-\r
-func (c *FileResource) GetName() string {\r
- return c.Name\r
-}\r
-\r
-func (c *FileResource) GetType() string {\r
- return "File"\r
-}\r
-\r
-func (c *FileResource) ToYaml() string {\r
- yamlFile, _ := ioutil.ReadFile(c.FileName)\r
- return string(yamlFile)\r
-}\r
-\r
-func init() {\r
- GetResourceBuilder().Register("File", &FileResource{})\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import (
+ "io/ioutil"
+)
+
+type FileResource struct {
+ Name string
+ Type string
+ FileName string
+}
+
+func (c *FileResource) GetName() string {
+ return c.Name
+}
+
+func (c *FileResource) GetType() string {
+ return "File"
+}
+
+func (c *FileResource) ToYaml(target string) string {
+ yamlFile, _ := ioutil.ReadFile(c.FileName)
+ return string(yamlFile)
+}
+
+func init() {
+ GetResourceBuilder().Register("File", &FileResource{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
-)\r
-\r
-type FirewallDnatResource struct {\r
- Name string\r
- Source string\r
- SourceIP string\r
- SourceDestIP string\r
- SourceDestPort string\r
- DestinationIP string\r
- DestinationPort string\r
- Protocol string\r
-}\r
-\r
-func (c *FirewallDnatResource) GetName() string {\r
- return c.Name\r
-}\r
-\r
-func (c *FirewallDnatResource) GetType() string {\r
- return "FirewallDNAT"\r
-}\r
-\r
-func (c *FirewallDnatResource) ToYaml() string {\r
- basic := `apiVersion: ` + SdewanApiVersion + `\r
-kind: FirewallDNAT\r
-metadata:\r
- name: ` + c.Name + `\r
- namespace: default\r
- labels:\r
- sdewanPurpose: ` + SdewanPurpose + `\r
-spec:\r
- src: ` + c.Source + `\r
- src_dip: ` + c.SourceDestIP + `\r
- src_dport: ` + c.SourceDestPort + `\r
- dest_ip: ` + c.DestinationIP + `\r
- dest_port: ` + c.DestinationPort + `\r
- proto: ` + c.Protocol + `\r
- target: DNAT `\r
-\r
- if c.SourceIP != "" {\r
- basic += `\r
- src_ip: ` + c.SourceIP\r
- }\r
-\r
- return basic\r
-}\r
-\r
-func init() {\r
- GetResourceBuilder().Register("FirewallDnat", &FirewallDnatResource{})\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import ()
+
+type FirewallDnatResource struct {
+ Name string
+ Source string
+ SourceIP string
+ SourceDestIP string
+ SourceDestPort string
+ DestinationIP string
+ DestinationPort string
+ Protocol string
+}
+
+func (c *FirewallDnatResource) GetName() string {
+ return c.Name
+}
+
+func (c *FirewallDnatResource) GetType() string {
+ return "FirewallDNAT"
+}
+
+func (c *FirewallDnatResource) ToYaml(target string) string {
+ basic := `apiVersion: ` + SdewanApiVersion + `
+kind: FirewallDNAT
+metadata:
+ name: ` + c.Name + `
+ namespace: default
+ labels:
+ sdewanPurpose: ` + SdewanPurpose + `
+ targetCluster: ` + target + `
+spec:
+ src: ` + c.Source + `
+ src_dip: ` + c.SourceDestIP + `
+ src_dport: ` + c.SourceDestPort + `
+ dest_ip: ` + c.DestinationIP + `
+ dest_port: ` + c.DestinationPort + `
+ proto: ` + c.Protocol + `
+ target: DNAT `
+
+ if c.SourceIP != "" {
+ basic += `
+ src_ip: ` + c.SourceIP
+ }
+
+ return basic
+}
+
+func init() {
+ GetResourceBuilder().Register("FirewallDnat", &FirewallDnatResource{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
- "strings"\r
-)\r
-\r
-type FirewallZoneResource struct {\r
- Name string\r
- Network []string\r
- Input string\r
- Output string\r
- Forward string\r
- MASQ string\r
- MTU_FIX string\r
-}\r
-\r
-func (c *FirewallZoneResource) GetName() string {\r
- return c.Name\r
-}\r
-\r
-func (c *FirewallZoneResource) GetType() string {\r
- return "FirewallZone"\r
-}\r
-\r
-func (c *FirewallZoneResource) ToYaml() string {\r
- basic := `apiVersion: ` + SdewanApiVersion + `\r
-kind: FirewallZone\r
-metadata:\r
- name: ` + c.Name + `\r
- namespace: default\r
- labels:\r
- sdewanPurpose: ` + SdewanPurpose + `\r
-spec:\r
- network: [` + strings.Join(c.Network, ",") + `]\r
- input: ` + c.Input + `\r
- output: ` + c.Output + `\r
- forward: ` + c.Forward\r
-\r
- if (c.MASQ != "" && c.MTU_FIX != "") {\r
- optional := `\r
- masq: ` + c.MASQ + `\r
- mtu_fix: ` + c.MTU_FIX\r
- basic += optional\r
- }\r
-\r
- return basic\r
-}\r
-\r
-func init() {\r
- GetResourceBuilder().Register("FirewallZone", &FirewallZoneResource{})\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import (
+ "strings"
+)
+
+type FirewallZoneResource struct {
+ Name string
+ Network []string
+ Input string
+ Output string
+ Forward string
+ MASQ string
+ MTU_FIX string
+}
+
+func (c *FirewallZoneResource) GetName() string {
+ return c.Name
+}
+
+func (c *FirewallZoneResource) GetType() string {
+ return "FirewallZone"
+}
+
+func (c *FirewallZoneResource) ToYaml(target string) string {
+ basic := `apiVersion: ` + SdewanApiVersion + `
+kind: FirewallZone
+metadata:
+ name: ` + c.Name + `
+ namespace: default
+ labels:
+ sdewanPurpose: ` + SdewanPurpose + `
+ targetCluster: ` + target + `
+spec:
+ network: [` + strings.Join(c.Network, ",") + `]
+ input: ` + c.Input + `
+ output: ` + c.Output + `
+ forward: ` + c.Forward
+
+ if c.MASQ != "" && c.MTU_FIX != "" {
+ optional := `
+ masq: ` + c.MASQ + `
+ mtu_fix: ` + c.MTU_FIX
+ basic += optional
+ }
+
+ return basic
+}
+
+func init() {
+ GetResourceBuilder().Register("FirewallZone", &FirewallZoneResource{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governinog permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
- "strings"\r
-)\r
-\r
-const (\r
- AuthTypePSK = "psk"\r
- AuthTypePUBKEY = "pubkey"\r
-)\r
-\r
-type Connection struct {\r
- Name string\r
- ConnectionType string\r
- Mode string\r
- LocalSubnet string\r
- LocalSourceIp string\r
- LocalUpDown string\r
- LocalFirewall string\r
- RemoteSubnet string\r
- RemoteSourceIp string\r
- RemoteUpDown string\r
- RemoteFirewall string\r
- CryptoProposal []string\r
- Mark string\r
- IfId string\r
-}\r
-\r
-type IpsecResource struct {\r
- Name string\r
- Type string\r
- Remote string\r
- AuthenticationMethod string\r
- CryptoProposal []string\r
- LocalIdentifier string\r
- RemoteIdentifier string\r
- ForceCryptoProposal string\r
- PresharedKey string\r
- PublicCert string\r
- PrivateCert string\r
- SharedCA string\r
- Connections Connection\r
-}\r
-\r
-func (c *IpsecResource) GetName() string {\r
- return c.Name\r
-}\r
-\r
-func (c *IpsecResource) GetType() string {\r
- return "Ipsec"\r
-}\r
-\r
-func (c *IpsecResource) ToYaml() string {\r
- p := strings.Join(c.CryptoProposal, ",")\r
- pr := strings.Join(c.Connections.CryptoProposal, ",")\r
- var connection = ""\r
-\r
- if c.Connections.LocalSubnet != "" {\r
- base := `apiVersion: ` + SdewanApiVersion + ` \r
-kind: IpsecSite\r
-metadata:\r
- name: ` + c.Name + `\r
- namespace: default\r
- labels:\r
- sdewanPurpose: ` + SdewanPurpose + `\r
-spec:\r
- type: ` + c.Type + `\r
- remote: '` + c.Remote + `'\r
- authentication_method: `+ c.AuthenticationMethod + `\r
- force_crypto_proposal: "` + c.ForceCryptoProposal + `\r
- crypto_proposal: [` + p + `]`\r
-\r
- connection = `\r
- connections: \r
- - name: ` + c.Connections.Name + `\r
- conn_type: ` + c.Connections.ConnectionType + `\r
- mode: ` + c.Connections.Mode + `\r
- mark: "` + c.Connections.Mark + `"\r
- local_updown: ` + c.Connections.LocalUpDown + `\r
- local_subnet: ` + c.Connections.LocalSubnet + `\r
- crypto_proposal: [` + pr +`]`\r
-\r
- if c.Connections.RemoteSourceIp != "" {\r
- remote_source_ip := `\r
- remote_source_ip: '` + c.Connections.RemoteSourceIp + `'`\r
- connection += remote_source_ip\r
- }\r
-\r
- if c.AuthenticationMethod == AuthTypePUBKEY {\r
- auth := `\r
- local_public_cert: ` + c.PublicCert + `\r
- local_private_cert: ` + c.PrivateCert + `\r
- shared_ca: ` + c.SharedCA + `\r
- local_identifier: ` + c.LocalIdentifier + `\r
- remote_identifier: ` + c.RemoteIdentifier\r
- return base + auth + connection\r
- } else if c.AuthenticationMethod == AuthTypePSK {\r
- auth := `\r
- pre_shared_key: ` + c.PresharedKey + `\r
- local_identifier: ` + c.LocalIdentifier + `\r
- remote_identifier: ` + c.RemoteIdentifier\r
- return base + auth + connection\r
- } else {\r
- return "Error in authentication method"\r
- }\r
-\r
- }\r
-\r
- base := `apiVersion: ` + SdewanApiVersion + ` \r
-kind: IpsecHost\r
-metadata:\r
- name: ` + c.Name + `\r
- namespace: default\r
- labels:\r
- sdewanPurpose: ` + SdewanPurpose + `\r
-spec:\r
- type: ` + c.Type + `\r
- remote: '` + c.Remote + `'\r
- authentication_method: `+ c.AuthenticationMethod +`\r
- force_crypto_proposal: "` + c.ForceCryptoProposal + `"\r
- crypto_proposal: [` + p + `]`\r
-\r
- if c.Connections.LocalSourceIp != "" {\r
- connection = `\r
- connections: \r
- - name: ` + c.Connections.Name + `\r
- conn_type: ` + c.Connections.ConnectionType + `\r
- mode: ` + c.Connections.Mode + `\r
- mark: "` + c.Connections.Mark + `"\r
- local_updown: ` + c.Connections.LocalUpDown + `\r
- local_sourceip: '` + c.Connections.LocalSourceIp + `'\r
- crypto_proposal: [` + pr +`]`\r
- } else {\r
- connection = `\r
- connections: \r
- - name: ` + c.Connections.Name + `\r
- conn_type: ` + c.Connections.ConnectionType + `\r
- mode: ` + c.Connections.Mode + `\r
- mark: "` + c.Connections.Mark + `"\r
- local_updown: ` + c.Connections.LocalUpDown + `\r
- crypto_proposal: [` + pr +`]`\r
- }\r
-\r
- if c.Connections.RemoteSourceIp != "" {\r
- remote_source_ip := `\r
- remote_sourceip: '` + c.Connections.RemoteSourceIp + `'`\r
- connection += remote_source_ip\r
- }\r
-\r
- if c.AuthenticationMethod == AuthTypePUBKEY {\r
- auth := `\r
- local_public_cert: ` + c.PublicCert + `\r
- local_private_cert: ` + c.PrivateCert + `\r
- shared_ca: ` + c.SharedCA + `\r
- local_identifier: ` + c.LocalIdentifier + `\r
- remote_identifier: ` + c.RemoteIdentifier\r
- return base + auth + connection\r
- } else if c.AuthenticationMethod == AuthTypePSK {\r
- auth := `\r
- pre_shared_key: ` + c.PresharedKey + `\r
- local_identifier: ` + c.LocalIdentifier + `\r
- remote_identifier: ` + c.RemoteIdentifier\r
- return base + auth + connection\r
- } else {\r
- return "Error in authentication method"\r
- }\r
-\r
-}\r
-\r
-func init() {\r
- GetResourceBuilder().Register("Ipsec", &IpsecResource{})\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 governinog permissions and
+ * limitations under the License.
+ */
+
+package resource
+
+import (
+ "strings"
+)
+
+const (
+ AuthTypePSK = "psk"
+ AuthTypePUBKEY = "pubkey"
+)
+
+type Connection struct {
+ Name string
+ ConnectionType string
+ Mode string
+ LocalSubnet string
+ LocalSourceIp string
+ LocalUpDown string
+ LocalFirewall string
+ RemoteSubnet string
+ RemoteSourceIp string
+ RemoteUpDown string
+ RemoteFirewall string
+ CryptoProposal []string
+ Mark string
+ IfId string
+}
+
+type IpsecResource struct {
+ Name string
+ Type string
+ Remote string
+ AuthenticationMethod string
+ CryptoProposal []string
+ LocalIdentifier string
+ RemoteIdentifier string
+ ForceCryptoProposal string
+ PresharedKey string
+ PublicCert string
+ PrivateCert string
+ SharedCA string
+ Connections Connection
+}
+
+func (c *IpsecResource) GetName() string {
+ return c.Name
+}
+
+func (c *IpsecResource) GetType() string {
+ return "Ipsec"
+}
+
+func (c *IpsecResource) ToYaml(target string) string {
+ p := strings.Join(c.CryptoProposal, ",")
+ pr := strings.Join(c.Connections.CryptoProposal, ",")
+ var connection = ""
+
+ if c.Connections.LocalSubnet != "" {
+ base := `apiVersion: ` + SdewanApiVersion + `
+kind: IpsecSite
+metadata:
+ name: ` + c.Name + `
+ namespace: default
+ labels:
+ sdewanPurpose: ` + SdewanPurpose + `
+ targetCluster: ` + target + `
+spec:
+ type: ` + c.Type + `
+ remote: '` + c.Remote + `'
+ authentication_method: ` + c.AuthenticationMethod + `
+ force_crypto_proposal: "` + c.ForceCryptoProposal + `
+ crypto_proposal: [` + p + `]`
+
+ connection = `
+ connections:
+ - name: ` + c.Connections.Name + `
+ conn_type: ` + c.Connections.ConnectionType + `
+ mode: ` + c.Connections.Mode + `
+ mark: "` + c.Connections.Mark + `"
+ local_updown: ` + c.Connections.LocalUpDown + `
+ local_subnet: ` + c.Connections.LocalSubnet + `
+ crypto_proposal: [` + pr + `]`
+
+ if c.Connections.RemoteSourceIp != "" {
+ remote_source_ip := `
+ remote_source_ip: '` + c.Connections.RemoteSourceIp + `'`
+ connection += remote_source_ip
+ }
+
+ if c.AuthenticationMethod == AuthTypePUBKEY {
+ auth := `
+ local_public_cert: ` + c.PublicCert + `
+ local_private_cert: ` + c.PrivateCert + `
+ shared_ca: ` + c.SharedCA + `
+ local_identifier: ` + c.LocalIdentifier + `
+ remote_identifier: ` + c.RemoteIdentifier
+ return base + auth + connection
+ } else if c.AuthenticationMethod == AuthTypePSK {
+ auth := `
+ pre_shared_key: ` + c.PresharedKey + `
+ local_identifier: ` + c.LocalIdentifier + `
+ remote_identifier: ` + c.RemoteIdentifier
+ return base + auth + connection
+ } else {
+ return "Error in authentication method"
+ }
+
+ }
+
+ base := `apiVersion: ` + SdewanApiVersion + `
+kind: IpsecHost
+metadata:
+ name: ` + c.Name + `
+ namespace: default
+ labels:
+ sdewanPurpose: ` + SdewanPurpose + `
+spec:
+ type: ` + c.Type + `
+ remote: '` + c.Remote + `'
+ authentication_method: ` + c.AuthenticationMethod + `
+ force_crypto_proposal: "` + c.ForceCryptoProposal + `"
+ crypto_proposal: [` + p + `]`
+
+ if c.Connections.LocalSourceIp != "" {
+ connection = `
+ connections:
+ - name: ` + c.Connections.Name + `
+ conn_type: ` + c.Connections.ConnectionType + `
+ mode: ` + c.Connections.Mode + `
+ mark: "` + c.Connections.Mark + `"
+ local_updown: ` + c.Connections.LocalUpDown + `
+ local_sourceip: '` + c.Connections.LocalSourceIp + `'
+ crypto_proposal: [` + pr + `]`
+ } else {
+ connection = `
+ connections:
+ - name: ` + c.Connections.Name + `
+ conn_type: ` + c.Connections.ConnectionType + `
+ mode: ` + c.Connections.Mode + `
+ mark: "` + c.Connections.Mark + `"
+ local_updown: ` + c.Connections.LocalUpDown + `
+ crypto_proposal: [` + pr + `]`
+ }
+
+ if c.Connections.RemoteSourceIp != "" {
+ remote_source_ip := `
+ remote_sourceip: '` + c.Connections.RemoteSourceIp + `'`
+ connection += remote_source_ip
+ }
+
+ if c.AuthenticationMethod == AuthTypePUBKEY {
+ auth := `
+ local_public_cert: ` + c.PublicCert + `
+ local_private_cert: ` + c.PrivateCert + `
+ shared_ca: ` + c.SharedCA + `
+ local_identifier: ` + c.LocalIdentifier + `
+ remote_identifier: ` + c.RemoteIdentifier
+ return base + auth + connection
+ } else if c.AuthenticationMethod == AuthTypePSK {
+ auth := `
+ pre_shared_key: ` + c.PresharedKey + `
+ local_identifier: ` + c.LocalIdentifier + `
+ remote_identifier: ` + c.RemoteIdentifier
+ return base + auth + connection
+ } else {
+ return "Error in authentication method"
+ }
+
+}
+
+func init() {
+ GetResourceBuilder().Register("Ipsec", &IpsecResource{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
-)\r
-\r
-type ProposalResource struct {\r
- Name string\r
- Encryption string\r
- Hash string\r
- DhGroup string\r
-}\r
-\r
-func (c *ProposalResource) GetName() string {\r
- return c.Name\r
-}\r
-\r
-func (c *ProposalResource) GetType() string {\r
- return "Proposal"\r
-}\r
-\r
-func (c *ProposalResource) ToYaml() string {\r
- return `apiVersion: ` + SdewanApiVersion + `\r
-kind: IpsecProposal\r
-metadata:\r
- name: ` + c.Name + `\r
- namespace: default\r
- labels:\r
- sdewanPurpose: ` + SdewanPurpose + `\r
-spec:\r
- encryption_algorithm: ` + c.Encryption + `\r
- hash_algorithm: ` + c.Hash + `\r
- dh_group: ` + c.DhGroup\r
-}\r
-\r
-func init() {\r
- GetResourceBuilder().Register("Proposal", &ProposalResource{})\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import ()
+
+type ProposalResource struct {
+ Name string
+ Encryption string
+ Hash string
+ DhGroup string
+}
+
+func (c *ProposalResource) GetName() string {
+ return c.Name
+}
+
+func (c *ProposalResource) GetType() string {
+ return "Proposal"
+}
+
+func (c *ProposalResource) ToYaml(target string) string {
+ return `apiVersion: ` + SdewanApiVersion + `
+kind: IpsecProposal
+metadata:
+ name: ` + c.Name + `
+ namespace: default
+ labels:
+ sdewanPurpose: ` + SdewanPurpose + `
+ targetCluster: ` + target + `
+spec:
+ encryption_algorithm: ` + c.Encryption + `
+ hash_algorithm: ` + c.Hash + `
+ dh_group: ` + c.DhGroup
+}
+
+func init() {
+ GetResourceBuilder().Register("Proposal", &ProposalResource{})
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
- "strings"\r
- "reflect"\r
- "encoding/json"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type ResourceBuilder struct {\r
- omap map[string]reflect.Type\r
-}\r
-\r
-var res_builder = ResourceBuilder{\r
- omap: make(map[string]reflect.Type),\r
-}\r
-\r
-func GetResourceBuilder() *ResourceBuilder {\r
- return &res_builder\r
-}\r
-\r
-func (c *ResourceBuilder) Register(name string, r interface{}) {\r
- c.omap[name] = reflect.TypeOf(r).Elem()\r
-}\r
-\r
-func (c *ResourceBuilder) ToString(obj ISdewanResource) (string, error) {\r
- obj_str, err := json.Marshal(obj)\r
- if err != nil {\r
- return "", err\r
- }\r
-\r
- return obj.GetType() + "-" + string(obj_str), nil\r
-}\r
-\r
-func (c *ResourceBuilder) ToObject(obj_str string) (ISdewanResource, error) {\r
- if !strings.Contains(obj_str, "-") {\r
- return &EmptyResource{}, pkgerrors.New("Not a valid object")\r
- }\r
- strs := strings.SplitN(obj_str, "-", 2)\r
- if len(strs) != 2 {\r
- return &EmptyResource{}, pkgerrors.New("Not a valid object")\r
- }\r
-\r
- if v, ok := c.omap[strs[0]]; ok {\r
- retObj := reflect.New(v).Interface()\r
- err := json.Unmarshal([]byte(strs[1]), retObj)\r
- return retObj.(ISdewanResource), err\r
- } else {\r
- return &EmptyResource{}, pkgerrors.New("Not a valid object")\r
- }\r
-}\r
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import (
+ "encoding/json"
+ pkgerrors "github.com/pkg/errors"
+ "reflect"
+ "strings"
+)
+
+type ResourceBuilder struct {
+ omap map[string]reflect.Type
+}
+
+var res_builder = ResourceBuilder{
+ omap: make(map[string]reflect.Type),
+}
+
+func GetResourceBuilder() *ResourceBuilder {
+ return &res_builder
+}
+
+func (c *ResourceBuilder) Register(name string, r interface{}) {
+ c.omap[name] = reflect.TypeOf(r).Elem()
+}
+
+func (c *ResourceBuilder) ToString(obj ISdewanResource) (string, error) {
+ obj_str, err := json.Marshal(obj)
+ if err != nil {
+ return "", err
+ }
+
+ return obj.GetType() + "-" + string(obj_str), nil
+}
+
+func (c *ResourceBuilder) ToObject(obj_str string) (ISdewanResource, error) {
+ if !strings.Contains(obj_str, "-") {
+ return &EmptyResource{}, pkgerrors.New("Not a valid object")
+ }
+ strs := strings.SplitN(obj_str, "-", 2)
+ if len(strs) != 2 {
+ return &EmptyResource{}, pkgerrors.New("Not a valid object")
+ }
+
+ if v, ok := c.omap[strs[0]]; ok {
+ retObj := reflect.New(v).Interface()
+ err := json.Unmarshal([]byte(strs[1]), retObj)
+ return retObj.(ISdewanResource), err
+ } else {
+ return &EmptyResource{}, pkgerrors.New("Not a valid object")
+ }
+}
-/*\r
- * Copyright 2020 Intel Corporation, Inc\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package resource\r
-\r
-import (\r
-)\r
-\r
-const (\r
- SdewanApiVersion = "batch.sdewan.akraino.org/v1alpha1"\r
- SdewanPurpose = "base"\r
-)\r
-\r
-type ISdewanResource interface {\r
- GetName() string\r
- GetType() string\r
- ToYaml() string\r
-}
\ No newline at end of file
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 resource
+
+import ()
+
+const (
+ SdewanApiVersion = "batch.sdewan.akraino.org/v1alpha1"
+ SdewanPurpose = "base"
+)
+
+type ISdewanResource interface {
+ GetName() string
+ GetType() string
+ ToYaml(target string) string
+}
{\r
-"rsync-ip": "localhost",\r
-"rsync-port": "9031"\r
+"rsync-ip": "",\r
+"rsync-port": "9041"\r
}\r
-package test\r
-\r
-import (\r
- "testing"\r
- "flag"\r
- "encoding/json"\r
- "fmt"\r
- "os"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
-)\r
-\r
-var BaseUrl string\r
-var OverlayUrl string\r
-\r
-func TestMain(m *testing.M) {\r
- servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")\r
- flag.Parse()\r
- OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection\r
- BaseUrl = OverlayUrl + "/overlay1/" + manager.CertCollection\r
-\r
- var overlay_object = module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}}\r
- \r
- var cert_object1 = module.CertificateObject{\r
- Metadata: module.ObjectMetaData{"device1", "", "", ""}}\r
- var cert_object2 = module.CertificateObject{\r
- Metadata: module.ObjectMetaData{"device2", "", "", ""}}\r
- \r
- createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})\r
- createControllerObject(BaseUrl, &cert_object1, &module.CertificateObject{})\r
- createControllerObject(BaseUrl, &cert_object2, &module.CertificateObject{})\r
-\r
- var ret = m.Run()\r
-\r
- deleteControllerObject(BaseUrl, "device1")\r
- deleteControllerObject(BaseUrl, "device2")\r
- deleteControllerObject(OverlayUrl, "overlay1")\r
-\r
- os.Exit(ret)\r
-}\r
-\r
-func TestGetObjects(t *testing.T) {\r
- url := BaseUrl\r
- res, err := callRest("GET", url, "")\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test case GetObjects: can not get Objects")\r
- return\r
- }\r
-\r
- var objs []module.CertificateObject\r
- err = json.Unmarshal([]byte(res), &objs)\r
-\r
- if len(objs) == 0 {\r
- fmt.Printf("Test case GetObjects: no object found")\r
- return\r
- }\r
-\r
- p_data, _ := json.Marshal(objs)\r
- fmt.Printf("%s\n", string(p_data))\r
-}\r
-\r
-func TestGetObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "Normal",\r
- object_name: "device1",\r
- },\r
- {\r
- name: "GetFoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- obj, err := getControllerObject(BaseUrl, tcase.object_name, &module.CertificateObject{})\r
- if err == nil {\r
- p_data, _ := json.Marshal(obj)\r
- fmt.Printf("%s\n", string(p_data))\r
- }\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestCreateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- url string\r
- obj module.CertificateObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- obj: module.CertificateObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "WrongOverlayName",\r
- obj: module.CertificateObject{\r
- Metadata: module.ObjectMetaData{"device3", "", "", ""}},\r
- url: OverlayUrl + "/foooverlay/" + manager.CertCollection,\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- {\r
- name: "DumplicateName",\r
- obj: module.CertificateObject{\r
- Metadata: module.ObjectMetaData{"device1", "", "", ""}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 409,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := createControllerObject(tcase.url, &tcase.obj, &module.CertificateObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestDeleteObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "FoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := deleteControllerObject(BaseUrl, tcase.object_name)\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestHappyPath(t *testing.T) {\r
- cert_name := "my-device"\r
-\r
- obj := module.CertificateObject{\r
- Metadata: module.ObjectMetaData{cert_name, "", "", ""}}\r
-\r
- _, err := createControllerObject(BaseUrl, &obj, &module.CertificateObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- _, err = deleteControllerObject(BaseUrl, cert_name)\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: delete object")\r
- return\r
- }\r
-}
\ No newline at end of file
+package test
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "os"
+ "testing"
+)
+
+var BaseUrl string
+var OverlayUrl string
+
+func TestMain(m *testing.M) {
+ servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")
+ flag.Parse()
+ OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection
+ BaseUrl = OverlayUrl + "/overlay1/" + manager.CertCollection
+
+ var overlay_object = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ var cert_object1 = module.CertificateObject{
+ Metadata: module.ObjectMetaData{"device1", "", "", ""}}
+ var cert_object2 = module.CertificateObject{
+ Metadata: module.ObjectMetaData{"device2", "", "", ""}}
+
+ createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})
+ createControllerObject(BaseUrl, &cert_object1, &module.CertificateObject{})
+ createControllerObject(BaseUrl, &cert_object2, &module.CertificateObject{})
+
+ var ret = m.Run()
+
+ deleteControllerObject(BaseUrl, "device1")
+ deleteControllerObject(BaseUrl, "device2")
+ deleteControllerObject(OverlayUrl, "overlay1")
+
+ os.Exit(ret)
+}
+
+func TestGetObjects(t *testing.T) {
+ url := BaseUrl
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ printError(err)
+ t.Errorf("Test case GetObjects: can not get Objects")
+ return
+ }
+
+ var objs []module.CertificateObject
+ err = json.Unmarshal([]byte(res), &objs)
+
+ if len(objs) == 0 {
+ fmt.Printf("Test case GetObjects: no object found")
+ return
+ }
+
+ p_data, _ := json.Marshal(objs)
+ fmt.Printf("%s\n", string(p_data))
+}
+
+func TestGetObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "Normal",
+ object_name: "device1",
+ },
+ {
+ name: "GetFoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ obj, err := getControllerObject(BaseUrl, tcase.object_name, &module.CertificateObject{})
+ if err == nil {
+ p_data, _ := json.Marshal(obj)
+ fmt.Printf("%s\n", string(p_data))
+ }
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestCreateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ url string
+ obj module.CertificateObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ obj: module.CertificateObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "WrongOverlayName",
+ obj: module.CertificateObject{
+ Metadata: module.ObjectMetaData{"device3", "", "", ""}},
+ url: OverlayUrl + "/foooverlay/" + manager.CertCollection,
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ {
+ name: "DumplicateName",
+ obj: module.CertificateObject{
+ Metadata: module.ObjectMetaData{"device1", "", "", ""}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 409,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := createControllerObject(tcase.url, &tcase.obj, &module.CertificateObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestDeleteObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "FoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := deleteControllerObject(BaseUrl, tcase.object_name)
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestHappyPath(t *testing.T) {
+ cert_name := "my-device"
+
+ obj := module.CertificateObject{
+ Metadata: module.ObjectMetaData{cert_name, "", "", ""}}
+
+ _, err := createControllerObject(BaseUrl, &obj, &module.CertificateObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ _, err = deleteControllerObject(BaseUrl, cert_name)
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: delete object")
+ return
+ }
+}
--- /dev/null
+package test
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "os"
+ "testing"
+)
+
+var BaseUrl string
+
+func TestMain(m *testing.M) {
+ servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")
+ flag.Parse()
+ BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection
+
+ var object1 = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ createControllerObject(BaseUrl, &object1, &module.OverlayObject{})
+
+ var ret = m.Run()
+
+ deleteControllerObject(BaseUrl, "overlay1")
+
+ os.Exit(ret)
+}
+
+func TestGetObjects(t *testing.T) {
+ url := BaseUrl + "/overlay1/devices/device1/cnfs"
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ printError(err)
+ t.Errorf("Test case GetObjects: can not get Objects")
+ return
+ }
+
+ var objs []module.CNFObject
+ err = json.Unmarshal([]byte(res), &objs)
+
+ if len(objs) == 0 {
+ fmt.Printf("Test case GetObjects: no object found")
+ return
+ }
+
+ p_data, _ := json.Marshal(objs)
+ fmt.Printf("%s\n", string(p_data))
+}
--- /dev/null
+{\r
+"etcd-ip": "",\r
+"database-ip": ""\r
+}\r
-package test\r
-\r
-import (\r
- "testing"\r
- "flag"\r
- "encoding/json"\r
- "fmt"\r
- "os"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
-)\r
-\r
-var BaseUrl string\r
-var OverlayUrl string\r
-\r
-func TestMain(m *testing.M) {\r
- servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")\r
- flag.Parse()\r
- OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection\r
- BaseUrl = OverlayUrl + "/overlay1/" + manager.IPRangeCollection\r
-\r
- var overlay_object = module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}}\r
- \r
- var iprange_object1 = module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 12}}\r
- var iprange_object2 = module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.1.3", 32, 36}}\r
- \r
- createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})\r
- createControllerObject(BaseUrl, &iprange_object1, &module.IPRangeObject{})\r
- createControllerObject(BaseUrl, &iprange_object2, &module.IPRangeObject{})\r
-\r
- var ret = m.Run()\r
-\r
- deleteControllerObject(BaseUrl, "ipr1")\r
- deleteControllerObject(BaseUrl, "ipr2")\r
- deleteControllerObject(OverlayUrl, "overlay1")\r
-\r
- os.Exit(ret)\r
-}\r
-\r
-func TestGetObjects(t *testing.T) {\r
- url := BaseUrl\r
- res, err := callRest("GET", url, "")\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test case GetObjects: can not get Objects")\r
- return\r
- }\r
-\r
- var objs []module.IPRangeObject\r
- err = json.Unmarshal([]byte(res), &objs)\r
-\r
- if len(objs) == 0 {\r
- fmt.Printf("Test case GetObjects: no object found")\r
- return\r
- }\r
-\r
- p_data, _ := json.Marshal(objs)\r
- fmt.Printf("%s\n", string(p_data))\r
-}\r
-\r
-func TestGetObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "Normal",\r
- object_name: "ipr1",\r
- },\r
- {\r
- name: "GetFoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := getControllerObject(BaseUrl, tcase.object_name, &module.IPRangeObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestCreateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- url string\r
- obj module.IPRangeObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}, \r
- Specification: module.IPRangeObjectSpec{}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "DumplicateName",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 409,\r
- },\r
- {\r
- name: "WrongOverlayName",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}},\r
- url: OverlayUrl + "/foooverlay/" + manager.IPRangeCollection,\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- {\r
- name: "WrongSubnet",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.3.0", 1, 15}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "WrongMinIP",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.3", 0, 15}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "WrongMaxIP",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.1.3", 1, 300}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "WrongMinMaxIP",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.3", 20, 15}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "ConflictRange1",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.0.3", 11, 15}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- {\r
- name: "ConflictRange2",\r
- obj: module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.1.3", 30, 40}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := createControllerObject(tcase.url, &tcase.obj, &module.IPRangeObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestDeleteObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "FoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := deleteControllerObject(BaseUrl, tcase.object_name)\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestHappyPath(t *testing.T) {\r
- ipr_name := "my-ipr"\r
-\r
- obj := module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{ipr_name, "", "", ""},\r
- Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}\r
-\r
- ret_obj, err := createControllerObject(BaseUrl, &obj, &module.IPRangeObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- if ret_obj.(*module.IPRangeObject).Specification.Subnet != "192.168.2.3" {\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- _, err = deleteControllerObject(BaseUrl, ipr_name)\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: delete object")\r
- return\r
- }\r
-}
\ No newline at end of file
+package test
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "os"
+ "testing"
+)
+
+var BaseUrl string
+var OverlayUrl string
+
+func TestMain(m *testing.M) {
+ servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")
+ flag.Parse()
+ OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection
+ BaseUrl = OverlayUrl + "/overlay1/" + manager.IPRangeCollection
+
+ var overlay_object = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ var iprange_object1 = module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"ipr1", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 12}}
+ var iprange_object2 = module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"ipr2", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.1.3", 32, 36}}
+
+ createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})
+ createControllerObject(BaseUrl, &iprange_object1, &module.IPRangeObject{})
+ createControllerObject(BaseUrl, &iprange_object2, &module.IPRangeObject{})
+
+ var ret = m.Run()
+
+ deleteControllerObject(BaseUrl, "ipr1")
+ deleteControllerObject(BaseUrl, "ipr2")
+ deleteControllerObject(OverlayUrl, "overlay1")
+
+ os.Exit(ret)
+}
+
+func TestGetObjects(t *testing.T) {
+ url := BaseUrl
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ printError(err)
+ t.Errorf("Test case GetObjects: can not get Objects")
+ return
+ }
+
+ var objs []module.IPRangeObject
+ err = json.Unmarshal([]byte(res), &objs)
+
+ if len(objs) == 0 {
+ fmt.Printf("Test case GetObjects: no object found")
+ return
+ }
+
+ p_data, _ := json.Marshal(objs)
+ fmt.Printf("%s\n", string(p_data))
+}
+
+func TestGetObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "Normal",
+ object_name: "ipr1",
+ },
+ {
+ name: "GetFoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := getControllerObject(BaseUrl, tcase.object_name, &module.IPRangeObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestCreateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ url string
+ obj module.IPRangeObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""},
+ Specification: module.IPRangeObjectSpec{}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "DumplicateName",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"ipr1", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 409,
+ },
+ {
+ name: "WrongOverlayName",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}},
+ url: OverlayUrl + "/foooverlay/" + manager.IPRangeCollection,
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ {
+ name: "WrongSubnet",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3.0", 1, 15}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "WrongMinIP",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3", 0, 15}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "WrongMaxIP",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.1.3", 1, 300}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "WrongMinMaxIP",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3", 20, 15}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "ConflictRange1",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.0.3", 11, 15}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ {
+ name: "ConflictRange2",
+ obj: module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"my-ipr", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.1.3", 30, 40}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := createControllerObject(tcase.url, &tcase.obj, &module.IPRangeObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestDeleteObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "FoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := deleteControllerObject(BaseUrl, tcase.object_name)
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestHappyPath(t *testing.T) {
+ ipr_name := "my-ipr"
+
+ obj := module.IPRangeObject{
+ Metadata: module.ObjectMetaData{ipr_name, "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}
+
+ ret_obj, err := createControllerObject(BaseUrl, &obj, &module.IPRangeObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ if ret_obj.(*module.IPRangeObject).Specification.Subnet != "192.168.2.3" {
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ _, err = deleteControllerObject(BaseUrl, ipr_name)
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: delete object")
+ return
+ }
+}
-package test\r
-\r
-import (\r
- "testing"\r
- "flag"\r
- "encoding/json"\r
- "fmt"\r
- "os"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
-)\r
-\r
-var BaseUrl string\r
-\r
-func TestMain(m *testing.M) {\r
- servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")\r
- flag.Parse()\r
- BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection\r
-\r
- var object1 = module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}}\r
- var object2 = module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay2", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}}\r
-\r
- createControllerObject(BaseUrl, &object1, &module.OverlayObject{})\r
- createControllerObject(BaseUrl, &object2, &module.OverlayObject{})\r
-\r
- var ret = m.Run()\r
-\r
- deleteControllerObject(BaseUrl, "overlay1")\r
- deleteControllerObject(BaseUrl, "overlay2")\r
-\r
- os.Exit(ret)\r
-}\r
-\r
-func TestGetObjects(t *testing.T) {\r
- url := BaseUrl\r
- res, err := callRest("GET", url, "")\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test case GetObjects: can not get Objects")\r
- return\r
- }\r
-\r
- var objs []module.OverlayObject\r
- err = json.Unmarshal([]byte(res), &objs)\r
-\r
- if len(objs) == 0 {\r
- fmt.Printf("Test case GetObjects: no object found")\r
- return\r
- }\r
-\r
- p_data, _ := json.Marshal(objs)\r
- fmt.Printf("%s\n", string(p_data))\r
-}\r
-\r
-func TestGetObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "Normal",\r
- object_name: "overlay1",\r
- },\r
- {\r
- name: "GetFoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := getControllerObject(BaseUrl, tcase.object_name, &module.OverlayObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestCreateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- obj module.OverlayObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- obj: module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}, \r
- Specification: module.OverlayObjectSpec{}},\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "DumplicateName",\r
- obj: module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}},\r
- expectedErr: true,\r
- expectedErrCode: 409,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := createControllerObject(BaseUrl, &tcase.obj, &module.OverlayObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestUpdateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- obj module.OverlayObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- object_name: "overlay1",\r
- obj: module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}, \r
- Specification: module.OverlayObjectSpec{}},\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "MisMatchName",\r
- object_name: "overlay2",\r
- obj: module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}},\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.OverlayObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestDeleteObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "FoolName",\r
- object_name: "foo_name",\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := deleteControllerObject(BaseUrl, tcase.object_name)\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestHappyPath(t *testing.T) {\r
- overlay_name := "my-overlay"\r
-\r
- obj := module.OverlayObject{\r
- Metadata: module.ObjectMetaData{overlay_name, "object 1", "", ""},\r
- Specification: module.OverlayObjectSpec{}}\r
-\r
- obj_update := module.OverlayObject{\r
- Metadata: module.ObjectMetaData{overlay_name, "object 2", "", ""},\r
- Specification: module.OverlayObjectSpec{}}\r
-\r
- ret_obj, err := createControllerObject(BaseUrl, &obj, &module.OverlayObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- if ret_obj.(*module.OverlayObject).Metadata.Description != "object 1" {\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- ret_obj, err = updateControllerObject(BaseUrl, overlay_name, &obj_update, &module.OverlayObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: update object")\r
- return\r
- }\r
-\r
- if ret_obj.(*module.OverlayObject).Metadata.Description != "object 2" {\r
- t.Errorf("Test Case 'Happy Path' failed: update object")\r
- return\r
- }\r
-\r
- _, err = deleteControllerObject(BaseUrl, overlay_name)\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: delete object")\r
- return\r
- }\r
-}
\ No newline at end of file
+package test
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "os"
+ "testing"
+)
+
+var BaseUrl string
+
+func TestMain(m *testing.M) {
+ servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")
+ flag.Parse()
+ BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection
+
+ var object1 = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+ var object2 = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay2", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ createControllerObject(BaseUrl, &object1, &module.OverlayObject{})
+ createControllerObject(BaseUrl, &object2, &module.OverlayObject{})
+
+ var ret = m.Run()
+
+ deleteControllerObject(BaseUrl, "overlay1")
+ deleteControllerObject(BaseUrl, "overlay2")
+
+ os.Exit(ret)
+}
+
+func TestGetObjects(t *testing.T) {
+ url := BaseUrl
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ printError(err)
+ t.Errorf("Test case GetObjects: can not get Objects")
+ return
+ }
+
+ var objs []module.OverlayObject
+ err = json.Unmarshal([]byte(res), &objs)
+
+ if len(objs) == 0 {
+ fmt.Printf("Test case GetObjects: no object found")
+ return
+ }
+
+ p_data, _ := json.Marshal(objs)
+ fmt.Printf("%s\n", string(p_data))
+}
+
+func TestGetObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "Normal",
+ object_name: "overlay1",
+ },
+ {
+ name: "GetFoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := getControllerObject(BaseUrl, tcase.object_name, &module.OverlayObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestCreateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ obj module.OverlayObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ obj: module.OverlayObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""},
+ Specification: module.OverlayObjectSpec{}},
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "DumplicateName",
+ obj: module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}},
+ expectedErr: true,
+ expectedErrCode: 409,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := createControllerObject(BaseUrl, &tcase.obj, &module.OverlayObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestUpdateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ obj module.OverlayObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ object_name: "overlay1",
+ obj: module.OverlayObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""},
+ Specification: module.OverlayObjectSpec{}},
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "MisMatchName",
+ object_name: "overlay2",
+ obj: module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}},
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.OverlayObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestDeleteObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "FoolName",
+ object_name: "foo_name",
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := deleteControllerObject(BaseUrl, tcase.object_name)
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestHappyPath(t *testing.T) {
+ overlay_name := "my-overlay"
+
+ obj := module.OverlayObject{
+ Metadata: module.ObjectMetaData{overlay_name, "object 1", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ obj_update := module.OverlayObject{
+ Metadata: module.ObjectMetaData{overlay_name, "object 2", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ ret_obj, err := createControllerObject(BaseUrl, &obj, &module.OverlayObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ if ret_obj.(*module.OverlayObject).Metadata.Description != "object 1" {
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ ret_obj, err = updateControllerObject(BaseUrl, overlay_name, &obj_update, &module.OverlayObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: update object")
+ return
+ }
+
+ if ret_obj.(*module.OverlayObject).Metadata.Description != "object 2" {
+ t.Errorf("Test Case 'Happy Path' failed: update object")
+ return
+ }
+
+ _, err = deleteControllerObject(BaseUrl, overlay_name)
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: delete object")
+ return
+ }
+}
-package test\r
-\r
-import (\r
- "testing"\r
- "flag"\r
- "encoding/json"\r
- "fmt"\r
- "os"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"\r
-)\r
-\r
-var BaseUrl string\r
-var OverlayUrl string\r
-\r
-func TestMain(m *testing.M) {\r
- servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")\r
- flag.Parse()\r
- OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection\r
- IPBaseUrl := OverlayUrl + "/overlay1/" + manager.IPRangeCollection\r
- BaseUrl = OverlayUrl + "/overlay1/" + manager.ProposalCollection\r
-\r
- var overlay_object = module.OverlayObject{\r
- Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, \r
- Specification: module.OverlayObjectSpec{}}\r
- \r
- var iprange_object1 = module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 20}}\r
- var iprange_object2 = module.IPRangeObject{\r
- Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, \r
- Specification: module.IPRangeObjectSpec{"192.168.2.2", 18, 20}}\r
-\r
- var proposal_object1 = module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}}\r
- var proposal_object2 = module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"proposal2", "", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}\r
- \r
- createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})\r
- createControllerObject(IPBaseUrl, &iprange_object1, &module.IPRangeObject{})\r
- createControllerObject(IPBaseUrl, &iprange_object2, &module.IPRangeObject{})\r
- createControllerObject(BaseUrl, &proposal_object1, &module.ProposalObject{})\r
- createControllerObject(BaseUrl, &proposal_object2, &module.ProposalObject{})\r
-\r
- var ret = m.Run()\r
-\r
- deleteControllerObject(BaseUrl, "proposal1")\r
- deleteControllerObject(BaseUrl, "proposal2")\r
- deleteControllerObject(IPBaseUrl, "ipr1")\r
- deleteControllerObject(IPBaseUrl, "ipr2")\r
- deleteControllerObject(OverlayUrl, "overlay1")\r
-\r
- os.Exit(ret)\r
-}\r
-\r
-func TestGetObjects(t *testing.T) {\r
- url := BaseUrl\r
- res, err := callRest("GET", url, "")\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test case GetObjects: can not get Objects")\r
- return\r
- }\r
-\r
- var objs []module.ProposalObject\r
- err = json.Unmarshal([]byte(res), &objs)\r
-\r
- if len(objs) == 0 {\r
- fmt.Printf("Test case GetObjects: no object found")\r
- return\r
- }\r
-\r
- p_data, _ := json.Marshal(objs)\r
- fmt.Printf("%s\n", string(p_data))\r
-}\r
-\r
-func TestGetObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "Normal",\r
- object_name: "proposal1",\r
- },\r
- {\r
- name: "GetFoolName",\r
- object_name: "foo_name",\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := getControllerObject(BaseUrl, tcase.object_name, &module.ProposalObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestCreateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- url string\r
- obj module.ProposalObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- obj: module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}, \r
- Specification: module.ProposalObjectSpec{}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "WrongOverlayName",\r
- obj: module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},\r
- url: OverlayUrl + "/foooverlay/" + manager.ProposalCollection,\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- {\r
- name: "DumplicateName",\r
- obj: module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},\r
- url: BaseUrl,\r
- expectedErr: true,\r
- expectedErrCode: 409,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := createControllerObject(tcase.url, &tcase.obj, &module.ProposalObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestUpdateObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- obj module.ProposalObject\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "EmptyName",\r
- object_name: "proposal1",\r
- obj: module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"", "object 1", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},\r
- expectedErr: true,\r
- expectedErrCode: 422,\r
- },\r
- {\r
- name: "MisMatchName",\r
- object_name: "proposal2",\r
- obj: module.ProposalObject{\r
- Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, \r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},\r
- expectedErr: true,\r
- expectedErrCode: 500,\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.ProposalObject{})\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestDeleteObject(t *testing.T) {\r
- tcases := []struct {\r
- name string\r
- object_name string\r
- expectedErr bool\r
- expectedErrCode int\r
- }{\r
- {\r
- name: "FoolName",\r
- object_name: "foo_name",\r
- },\r
- }\r
-\r
- for _, tcase := range tcases {\r
- _, err := deleteControllerObject(BaseUrl, tcase.object_name)\r
- handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)\r
- }\r
-}\r
-\r
-func TestHappyPath(t *testing.T) {\r
- proposal_name := "my-proposal"\r
-\r
- obj := module.ProposalObject{\r
- Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""},\r
- Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}}\r
-\r
- obj_update := module.ProposalObject{\r
- Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""},\r
- Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}\r
-\r
- ret_obj, err := createControllerObject(BaseUrl, &obj, &module.ProposalObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes256" {\r
- t.Errorf("Test Case 'Happy Path' failed: create object")\r
- return\r
- }\r
-\r
- ret_obj, err = updateControllerObject(BaseUrl, proposal_name, &obj_update, &module.ProposalObject{})\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: update object")\r
- return\r
- }\r
-\r
- if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes512" {\r
- t.Errorf("Test Case 'Happy Path' failed: update object")\r
- return\r
- }\r
-\r
- _, err = deleteControllerObject(BaseUrl, proposal_name)\r
- if err != nil {\r
- printError(err)\r
- t.Errorf("Test Case 'Happy Path' failed: delete object")\r
- return\r
- }\r
-}
\ No newline at end of file
+package test
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "os"
+ "testing"
+)
+
+var BaseUrl string
+var OverlayUrl string
+
+func TestMain(m *testing.M) {
+ servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address")
+ flag.Parse()
+ OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection
+ IPBaseUrl := OverlayUrl + "/overlay1/" + manager.IPRangeCollection
+ BaseUrl = OverlayUrl + "/overlay1/" + manager.ProposalCollection
+
+ var overlay_object = module.OverlayObject{
+ Metadata: module.ObjectMetaData{"overlay1", "", "", ""},
+ Specification: module.OverlayObjectSpec{}}
+
+ var iprange_object1 = module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"ipr1", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 20}}
+ var iprange_object2 = module.IPRangeObject{
+ Metadata: module.ObjectMetaData{"ipr2", "", "", ""},
+ Specification: module.IPRangeObjectSpec{"192.168.2.2", 18, 20}}
+
+ var proposal_object1 = module.ProposalObject{
+ Metadata: module.ObjectMetaData{"proposal1", "", "", ""},
+ Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}}
+ var proposal_object2 = module.ProposalObject{
+ Metadata: module.ObjectMetaData{"proposal2", "", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}
+
+ createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{})
+ createControllerObject(IPBaseUrl, &iprange_object1, &module.IPRangeObject{})
+ createControllerObject(IPBaseUrl, &iprange_object2, &module.IPRangeObject{})
+ createControllerObject(BaseUrl, &proposal_object1, &module.ProposalObject{})
+ createControllerObject(BaseUrl, &proposal_object2, &module.ProposalObject{})
+
+ var ret = m.Run()
+
+ deleteControllerObject(BaseUrl, "proposal1")
+ deleteControllerObject(BaseUrl, "proposal2")
+ deleteControllerObject(IPBaseUrl, "ipr1")
+ deleteControllerObject(IPBaseUrl, "ipr2")
+ deleteControllerObject(OverlayUrl, "overlay1")
+
+ os.Exit(ret)
+}
+
+func TestGetObjects(t *testing.T) {
+ url := BaseUrl
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ printError(err)
+ t.Errorf("Test case GetObjects: can not get Objects")
+ return
+ }
+
+ var objs []module.ProposalObject
+ err = json.Unmarshal([]byte(res), &objs)
+
+ if len(objs) == 0 {
+ fmt.Printf("Test case GetObjects: no object found")
+ return
+ }
+
+ p_data, _ := json.Marshal(objs)
+ fmt.Printf("%s\n", string(p_data))
+}
+
+func TestGetObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "Normal",
+ object_name: "proposal1",
+ },
+ {
+ name: "GetFoolName",
+ object_name: "foo_name",
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := getControllerObject(BaseUrl, tcase.object_name, &module.ProposalObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestCreateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ url string
+ obj module.ProposalObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ obj: module.ProposalObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""},
+ Specification: module.ProposalObjectSpec{}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "WrongOverlayName",
+ obj: module.ProposalObject{
+ Metadata: module.ObjectMetaData{"proposal1", "", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},
+ url: OverlayUrl + "/foooverlay/" + manager.ProposalCollection,
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ {
+ name: "DumplicateName",
+ obj: module.ProposalObject{
+ Metadata: module.ObjectMetaData{"proposal1", "", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},
+ url: BaseUrl,
+ expectedErr: true,
+ expectedErrCode: 409,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := createControllerObject(tcase.url, &tcase.obj, &module.ProposalObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestUpdateObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ obj module.ProposalObject
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "EmptyName",
+ object_name: "proposal1",
+ obj: module.ProposalObject{
+ Metadata: module.ObjectMetaData{"", "object 1", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},
+ expectedErr: true,
+ expectedErrCode: 422,
+ },
+ {
+ name: "MisMatchName",
+ object_name: "proposal2",
+ obj: module.ProposalObject{
+ Metadata: module.ObjectMetaData{"proposal1", "", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}},
+ expectedErr: true,
+ expectedErrCode: 500,
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.ProposalObject{})
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestDeleteObject(t *testing.T) {
+ tcases := []struct {
+ name string
+ object_name string
+ expectedErr bool
+ expectedErrCode int
+ }{
+ {
+ name: "FoolName",
+ object_name: "foo_name",
+ },
+ }
+
+ for _, tcase := range tcases {
+ _, err := deleteControllerObject(BaseUrl, tcase.object_name)
+ handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode)
+ }
+}
+
+func TestHappyPath(t *testing.T) {
+ proposal_name := "my-proposal"
+
+ obj := module.ProposalObject{
+ Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""},
+ Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}}
+
+ obj_update := module.ProposalObject{
+ Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""},
+ Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}
+
+ ret_obj, err := createControllerObject(BaseUrl, &obj, &module.ProposalObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes256" {
+ t.Errorf("Test Case 'Happy Path' failed: create object")
+ return
+ }
+
+ ret_obj, err = updateControllerObject(BaseUrl, proposal_name, &obj_update, &module.ProposalObject{})
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: update object")
+ return
+ }
+
+ if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes512" {
+ t.Errorf("Test Case 'Happy Path' failed: update object")
+ return
+ }
+
+ _, err = deleteControllerObject(BaseUrl, proposal_name)
+ if err != nil {
+ printError(err)
+ t.Errorf("Test Case 'Happy Path' failed: delete object")
+ return
+ }
+}
-package test\r
-\r
-import (\r
- "fmt"\r
- "io/ioutil"\r
- \r
- "net/http"\r
- \r
- "bytes"\r
- "reflect"\r
- "testing"\r
- "encoding/json"\r
- "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"\r
-)\r
-\r
-type TestError struct {\r
- Code int\r
- Message string\r
-}\r
-\r
-func (e *TestError) Error() string {\r
- return fmt.Sprintf("Error Code: %d, Error Message: %s", e.Code, e.Message)\r
-}\r
-\r
-// Error handler\r
-func handleError(t *testing.T, err error, name string, expectedErr bool, errorCode int) {\r
- if (err != nil) {\r
- if (expectedErr) {\r
- switch err.(type) {\r
- case *TestError:\r
- if(errorCode != err.(*TestError).Code) {\r
- t.Errorf("Test case '%s': expected '%d', but got '%d'", name, errorCode, err.(*TestError).Code)\r
- } else {\r
- fmt.Printf("%s\n", err.(*TestError).Message)\r
- }\r
- default:\r
- t.Errorf("Test case '%s': expected openwrt.OpenwrtError, but got '%s'", name, reflect.TypeOf(err).String())\r
- }\r
- } else {\r
- t.Errorf("Test case '%s': expected success, but got '%s'", name, reflect.TypeOf(err).String())\r
- }\r
- } else {\r
- if (expectedErr) {\r
- t.Errorf("Test case '%s': expected error code '%d', but success", name, errorCode)\r
- }\r
- }\r
-}\r
-\r
-func printError(err error) {\r
- switch err.(type) {\r
- case *TestError:\r
- fmt.Printf("%s\n", err.(*TestError).Message)\r
- default:\r
- fmt.Printf("%s\n", reflect.TypeOf(err).String())\r
- }\r
-}\r
-\r
-func callRest(method string, url string, request string) (string, error) {\r
- client := &http.Client{}\r
- req_body := bytes.NewBuffer([]byte(request))\r
- req, _ := http.NewRequest(method, url, req_body)\r
-\r
- req.Header.Set("Cache-Control", "no-cache")\r
- \r
- resp, err := client.Do(req)\r
- if err != nil {\r
- return "", err\r
- }\r
- defer resp.Body.Close()\r
-\r
- body, _ := ioutil.ReadAll(resp.Body)\r
- if resp.StatusCode >= 400 {\r
- return "", &TestError{Code: resp.StatusCode, Message: string(body)}\r
- }\r
-\r
- return string(body), nil\r
-}\r
-\r
-func createControllerObject(baseUrl string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) {\r
- url := baseUrl\r
- obj_str, _ := json.Marshal(obj)\r
-\r
- res, err := callRest("POST", url, string(obj_str))\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- err = json.Unmarshal([]byte(res), retObj)\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- return retObj, nil\r
-}\r
-\r
-func getControllerObject(baseUrl string, name string, retObj module.ControllerObject) (module.ControllerObject, error) {\r
- url := baseUrl + "/" + name\r
-\r
- res, err := callRest("GET", url, "")\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- err = json.Unmarshal([]byte(res), retObj)\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- return retObj, nil\r
-}\r
-\r
-func updateControllerObject(baseUrl string, name string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) {\r
- url := baseUrl + "/" + name\r
- obj_str, _ := json.Marshal(obj)\r
-\r
- res, err := callRest("PUT", url, string(obj_str))\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- err = json.Unmarshal([]byte(res), retObj)\r
- if err != nil {\r
- return retObj, err\r
- }\r
-\r
- return retObj, nil\r
-}\r
-\r
-func deleteControllerObject(baseUrl string, name string) (bool, error) {\r
- url := baseUrl + "/" + name\r
-\r
- _, err := callRest("DELETE", url, "")\r
- if err != nil {\r
- printError(err)\r
- return false, err\r
- }\r
-\r
- _, err = callRest("GET", url, "")\r
- if err == nil {\r
- return false, &TestError{Code: 500, Message: "Filed to delete object"}\r
- }\r
-\r
- return true, nil\r
-}
\ No newline at end of file
+package test
+
+import (
+ "fmt"
+ "io/ioutil"
+
+ "net/http"
+
+ "bytes"
+ "encoding/json"
+ "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module"
+ "reflect"
+ "testing"
+)
+
+type TestError struct {
+ Code int
+ Message string
+}
+
+func (e *TestError) Error() string {
+ return fmt.Sprintf("Error Code: %d, Error Message: %s", e.Code, e.Message)
+}
+
+// Error handler
+func handleError(t *testing.T, err error, name string, expectedErr bool, errorCode int) {
+ if err != nil {
+ if expectedErr {
+ switch err.(type) {
+ case *TestError:
+ if errorCode != err.(*TestError).Code {
+ t.Errorf("Test case '%s': expected '%d', but got '%d'", name, errorCode, err.(*TestError).Code)
+ } else {
+ fmt.Printf("%s\n", err.(*TestError).Message)
+ }
+ default:
+ t.Errorf("Test case '%s': expected openwrt.OpenwrtError, but got '%s'", name, reflect.TypeOf(err).String())
+ }
+ } else {
+ t.Errorf("Test case '%s': expected success, but got '%s'", name, reflect.TypeOf(err).String())
+ }
+ } else {
+ if expectedErr {
+ t.Errorf("Test case '%s': expected error code '%d', but success", name, errorCode)
+ }
+ }
+}
+
+func printError(err error) {
+ switch err.(type) {
+ case *TestError:
+ fmt.Printf("%s\n", err.(*TestError).Message)
+ default:
+ fmt.Printf("%s\n", reflect.TypeOf(err).String())
+ }
+}
+
+func callRest(method string, url string, request string) (string, error) {
+ client := &http.Client{}
+ req_body := bytes.NewBuffer([]byte(request))
+ req, _ := http.NewRequest(method, url, req_body)
+
+ req.Header.Set("Cache-Control", "no-cache")
+
+ resp, err := client.Do(req)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ if resp.StatusCode >= 400 {
+ return "", &TestError{Code: resp.StatusCode, Message: string(body)}
+ }
+
+ return string(body), nil
+}
+
+func createControllerObject(baseUrl string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) {
+ url := baseUrl
+ obj_str, _ := json.Marshal(obj)
+
+ res, err := callRest("POST", url, string(obj_str))
+ if err != nil {
+ return retObj, err
+ }
+
+ err = json.Unmarshal([]byte(res), retObj)
+ if err != nil {
+ return retObj, err
+ }
+
+ return retObj, nil
+}
+
+func getControllerObject(baseUrl string, name string, retObj module.ControllerObject) (module.ControllerObject, error) {
+ url := baseUrl + "/" + name
+
+ res, err := callRest("GET", url, "")
+ if err != nil {
+ return retObj, err
+ }
+
+ err = json.Unmarshal([]byte(res), retObj)
+ if err != nil {
+ return retObj, err
+ }
+
+ return retObj, nil
+}
+
+func updateControllerObject(baseUrl string, name string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) {
+ url := baseUrl + "/" + name
+ obj_str, _ := json.Marshal(obj)
+
+ res, err := callRest("PUT", url, string(obj_str))
+ if err != nil {
+ return retObj, err
+ }
+
+ err = json.Unmarshal([]byte(res), retObj)
+ if err != nil {
+ return retObj, err
+ }
+
+ return retObj, nil
+}
+
+func deleteControllerObject(baseUrl string, name string) (bool, error) {
+ url := baseUrl + "/" + name
+
+ _, err := callRest("DELETE", url, "")
+ if err != nil {
+ printError(err)
+ return false, err
+ }
+
+ _, err = callRest("GET", url, "")
+ if err == nil {
+ return false, &TestError{Code: 500, Message: "Filed to delete object"}
+ }
+
+ return true, nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package appcontext\r
-\r
-import (\r
- "fmt"\r
- "strings"\r
-\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/rtcontext"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// metaPrefix used for denoting clusterMeta level\r
-const metaGrpPREFIX = "!@#metaGrp"\r
-\r
-type AppContext struct {\r
- initDone bool\r
- rtcObj rtcontext.RunTimeContext\r
- rtc rtcontext.Rtcontext\r
-}\r
-\r
-// AppContextStatus represents the current status of the appcontext\r
-// Instantiating - instantiate has been invoked and is still in progress\r
-// Instantiated - instantiate has completed\r
-// Terminating - terminate has been invoked and is still in progress\r
-// Terminated - terminate has completed\r
-// InstantiateFailed - the instantiate action has failed\r
-// TerminateFailed - the terminate action has failed\r
-type AppContextStatus struct {\r
- Status StatusValue\r
-}\r
-type StatusValue string\r
-type statuses struct {\r
- Instantiating StatusValue\r
- Instantiated StatusValue\r
- Terminating StatusValue\r
- Terminated StatusValue\r
- InstantiateFailed StatusValue\r
- TerminateFailed StatusValue\r
-}\r
-\r
-var AppContextStatusEnum = &statuses{\r
- Instantiating: "Instantiating",\r
- Instantiated: "Instantiated",\r
- Terminating: "Terminating",\r
- Terminated: "Terminated",\r
- InstantiateFailed: "InstantiateFailed",\r
- TerminateFailed: "TerminateFailed",\r
-}\r
-\r
-// CompositeAppMeta consists of projectName, CompositeAppName,\r
-// CompositeAppVersion, ReleaseName. This shall be used for\r
-// instantiation of a compositeApp\r
-type CompositeAppMeta struct {\r
- Project string `json:"Project"`\r
- CompositeApp string `json:"CompositeApp"`\r
- Version string `json:"Version"`\r
- Release string `json:"Release"`\r
- DeploymentIntentGroup string `json:"DeploymentIntentGroup"`\r
- Namespace string `json:"Namespace"`\r
- Level string `json:"Level"`\r
-}\r
-\r
-// Init app context\r
-func (ac *AppContext) InitAppContext() (interface{}, error) {\r
- ac.rtcObj = rtcontext.RunTimeContext{}\r
- ac.rtc = &ac.rtcObj\r
- return ac.rtc.RtcInit()\r
-}\r
-\r
-// Load app context that was previously created\r
-func (ac *AppContext) LoadAppContext(cid interface{}) (interface{}, error) {\r
- ac.rtcObj = rtcontext.RunTimeContext{}\r
- ac.rtc = &ac.rtcObj\r
- return ac.rtc.RtcLoad(cid)\r
-}\r
-\r
-// CreateCompositeApp method returns composite app handle as interface.\r
-func (ac *AppContext) CreateCompositeApp() (interface{}, error) {\r
- h, err := ac.rtc.RtcCreate()\r
- if err != nil {\r
- return nil, err\r
- }\r
- log.Info(":: CreateCompositeApp ::", log.Fields{"CompositeAppHandle": h})\r
- return h, nil\r
-}\r
-\r
-// AddCompositeAppMeta adds the meta data associated with a composite app\r
-func (ac *AppContext) AddCompositeAppMeta(meta interface{}) error {\r
- err := ac.rtc.RtcAddMeta(meta)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-// Deletes the entire context\r
-func (ac *AppContext) DeleteCompositeApp() error {\r
- h, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return err\r
- }\r
- err = ac.rtc.RtcDeletePrefix(h)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-//Returns the handles for a given composite app context\r
-func (ac *AppContext) GetCompositeAppHandle() (interface{}, error) {\r
- h, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
- return h, nil\r
-}\r
-\r
-// GetLevelHandle returns the handle for the supplied level at the given handle.\r
-// For example, to get the handle of the 'status' level at a given handle.\r
-func (ac *AppContext) GetLevelHandle(handle interface{}, level string) (interface{}, error) {\r
- ach := fmt.Sprintf("%v%v/", handle, level)\r
- hs, err := ac.rtc.RtcGetHandles(ach)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == ach {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for level %v", level)\r
-}\r
-\r
-//Add app to the context under composite app\r
-func (ac *AppContext) AddApp(handle interface{}, appname string) (interface{}, error) {\r
- h, err := ac.rtc.RtcAddLevel(handle, "app", appname)\r
- if err != nil {\r
- return nil, err\r
- }\r
- log.Info(":: Added app handle ::", log.Fields{"AppHandle": h})\r
- return h, nil\r
-}\r
-\r
-//Delete app from the context and everything underneth\r
-func (ac *AppContext) DeleteApp(handle interface{}) error {\r
- err := ac.rtc.RtcDeletePrefix(handle)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-//Returns the handle for a given app\r
-func (ac *AppContext) GetAppHandle(appname string) (interface{}, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- apph := fmt.Sprintf("%v", rh) + "app/" + appname + "/"\r
- hs, err := ac.rtc.RtcGetHandles(apph)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == apph {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for the given app")\r
-}\r
-\r
-// AddCluster helps to add cluster to the context under app. It takes in the app handle and clusterName as value.\r
-func (ac *AppContext) AddCluster(handle interface{}, clustername string) (interface{}, error) {\r
- h, err := ac.rtc.RtcAddLevel(handle, "cluster", clustername)\r
- if err != nil {\r
- return nil, err\r
- }\r
- log.Info(":: Added cluster handle ::", log.Fields{"ClusterHandler": h})\r
- return h, nil\r
-}\r
-\r
-// AddClusterMetaGrp adds the meta info of groupNumber to which a cluster belongs.\r
-// It takes in cluster handle and groupNumber as arguments\r
-func (ac *AppContext) AddClusterMetaGrp(ch interface{}, gn string) error {\r
- mh, err := ac.rtc.RtcAddOneLevel(ch, metaGrpPREFIX, gn)\r
- if err != nil {\r
- return err\r
- }\r
- log.Info(":: Added cluster meta handle ::", log.Fields{"ClusterMetaHandler": mh})\r
- return nil\r
-}\r
-\r
-// DeleteClusterMetaGrpHandle deletes the group number to which the cluster belongs, it takes in the cluster handle.\r
-func (ac *AppContext) DeleteClusterMetaGrpHandle(ch interface{}) error {\r
- err := ac.rtc.RtcDeletePrefix(ch)\r
- if err != nil {\r
- return err\r
- }\r
- log.Info(":: Deleted cluster meta handle ::", log.Fields{"ClusterMetaHandler": ch})\r
- return nil\r
-}\r
-\r
-/*\r
-GetClusterMetaHandle takes in appName and ClusterName as string arguments and return the ClusterMetaHandle as string\r
-*/\r
-func (ac *AppContext) GetClusterMetaHandle(app string, cluster string) (string, error) {\r
- if app == "" {\r
- return "", pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
- if cluster == "" {\r
- return "", pkgerrors.Errorf("Not a valid run time context cluster name")\r
- }\r
-\r
- ch, err := ac.GetClusterHandle(app, cluster)\r
- if err != nil {\r
- return "", err\r
- }\r
- cmh := fmt.Sprintf("%v", ch) + metaGrpPREFIX + "/"\r
- return cmh, nil\r
-\r
-}\r
-\r
-/*\r
-GetClusterGroupMap shall take in appName and return a map showing the grouping among the clusters.\r
-sample output of "GroupMap" :{"1":["cluster_provider1+clusterName3","cluster_provider1+clusterName5"],"2":["cluster_provider2+clusterName4","cluster_provider2+clusterName6"]}\r
-*/\r
-func (ac *AppContext) GetClusterGroupMap(an string) (map[string][]string, error) {\r
- cl, err := ac.GetClusterNames(an)\r
- if err != nil {\r
- log.Info(":: Unable to fetch clusterList for app ::", log.Fields{"AppName ": an})\r
- return nil, err\r
- }\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- var gmap = make(map[string][]string)\r
- for _, cn := range cl {\r
- s := fmt.Sprintf("%v", rh) + "app/" + an + "/cluster/" + cn + "/" + metaGrpPREFIX + "/"\r
- var v string\r
- err = ac.rtc.RtcGetValue(s, &v)\r
- if err != nil {\r
- log.Info(":: No group number for cluster ::", log.Fields{"cluster": cn, "Reason": err})\r
- continue\r
- }\r
- gn := fmt.Sprintf("%v", v)\r
- log.Info(":: GroupNumber retrieved ::", log.Fields{"GroupNumber": gn})\r
-\r
- cl, found := gmap[gn]\r
- if found == false {\r
- cl = make([]string, 0)\r
- }\r
- cl = append(cl, cn)\r
- gmap[gn] = cl\r
- }\r
- return gmap, nil\r
-}\r
-\r
-//Delete cluster from the context and everything underneth\r
-func (ac *AppContext) DeleteCluster(handle interface{}) error {\r
- err := ac.rtc.RtcDeletePrefix(handle)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-//Returns the handle for a given app and cluster\r
-func (ac *AppContext) GetClusterHandle(appname string, clustername string) (interface{}, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
- if clustername == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context cluster name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- ach := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/"\r
- hs, err := ac.rtc.RtcGetHandles(ach)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == ach {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for the given cluster")\r
-}\r
-\r
-//Returns a list of all clusters for a given app\r
-func (ac *AppContext) GetClusterNames(appname string) ([]string, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- prefix := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/"\r
- hs, err := ac.rtc.RtcGetHandles(prefix)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error getting handles for %v", prefix)\r
- }\r
- var cs []string\r
- for _, h := range hs {\r
- hstr := fmt.Sprintf("%v", h)\r
- ks := strings.Split(hstr, prefix)\r
- for _, k := range ks {\r
- ck := strings.Split(k, "/")\r
- if len(ck) == 2 && ck[1] == "" {\r
- cs = append(cs, ck[0])\r
- }\r
- }\r
- }\r
- return cs, nil\r
-}\r
-\r
-//Add resource under app and cluster\r
-func (ac *AppContext) AddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {\r
- h, err := ac.rtc.RtcAddResource(handle, resname, value)\r
- if err != nil {\r
- return nil, err\r
- }\r
- log.Info(":: Added resource handle ::", log.Fields{"ResourceHandler": h})\r
-\r
- return h, nil\r
-}\r
-\r
-//Return the handle for given app, cluster and resource name\r
-func (ac *AppContext) GetResourceHandle(appname string, clustername string, resname string) (interface{}, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
- if clustername == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context cluster name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/" + resname + "/"\r
- hs, err := ac.rtc.RtcGetHandles(acrh)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == acrh {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for the given resource")\r
-}\r
-\r
-//Update the resource value using the given handle\r
-func (ac *AppContext) UpdateResourceValue(handle interface{}, value interface{}) error {\r
- return ac.rtc.RtcUpdateValue(handle, value)\r
-}\r
-\r
-//Return the handle for given app, cluster and resource name\r
-func (ac *AppContext) GetResourceStatusHandle(appname string, clustername string, resname string) (interface{}, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
- if clustername == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context cluster name")\r
- }\r
- if resname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context resource name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/" + resname + "/status/"\r
- hs, err := ac.rtc.RtcGetHandles(acrh)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == acrh {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for the given resource")\r
-}\r
-\r
-//Add instruction under given handle and type\r
-func (ac *AppContext) AddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {\r
- if !(insttype == "order" || insttype == "dependency") {\r
- log.Error("Not a valid app context instruction type", log.Fields{})\r
- return nil, pkgerrors.Errorf("Not a valid app context instruction type")\r
- }\r
- if !(level == "app" || level == "resource" || level == "subresource") {\r
- log.Error("Not a valid app context instruction level", log.Fields{})\r
- return nil, pkgerrors.Errorf("Not a valid app context instruction level")\r
- }\r
- h, err := ac.rtc.RtcAddInstruction(handle, level, insttype, value)\r
- if err != nil {\r
- log.Error("ac.rtc.RtcAddInstruction(handle, level, insttype, value)", log.Fields{"err": err})\r
- return nil, err\r
- }\r
- log.Info(":: Added instruction handle ::", log.Fields{"InstructionHandler": h})\r
- return h, nil\r
-}\r
-\r
-//Delete instruction under given handle\r
-func (ac *AppContext) DeleteInstruction(handle interface{}) error {\r
- err := ac.rtc.RtcDeletePair(handle)\r
- if err != nil {\r
- return err\r
- }\r
- return nil\r
-}\r
-\r
-//Returns the app instruction for a given instruction type\r
-func (ac *AppContext) GetAppInstruction(insttype string) (interface{}, error) {\r
- if !(insttype == "order" || insttype == "dependency") {\r
- log.Error("Not a valid app context instruction type", log.Fields{})\r
- return nil, pkgerrors.Errorf("Not a valid app context instruction type")\r
- }\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- log.Error("ac.rtc.RtcGet()", log.Fields{"err": err})\r
- return nil, err\r
- }\r
- s := fmt.Sprintf("%v", rh) + "app/" + "instruction/" + insttype + "/"\r
- log.Info("Getting app instruction", log.Fields{"s": s})\r
- var v string\r
- err = ac.rtc.RtcGetValue(s, &v)\r
- if err != nil {\r
- log.Error("ac.rtc.RtcGetValue(s, &v)", log.Fields{"err": err})\r
- return nil, err\r
- }\r
- return v, nil\r
-}\r
-\r
-//Update the instruction usign the given handle\r
-func (ac *AppContext) UpdateInstructionValue(handle interface{}, value interface{}) error {\r
- return ac.rtc.RtcUpdateValue(handle, value)\r
-}\r
-\r
-//Returns the resource instruction for a given instruction type\r
-func (ac *AppContext) GetResourceInstruction(appname string, clustername string, insttype string) (interface{}, error) {\r
- if !(insttype == "order" || insttype == "dependency") {\r
- log.Error("Not a valid app context instruction type", log.Fields{})\r
- return nil, pkgerrors.Errorf("Not a valid app context instruction type")\r
- }\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- log.Error("ac.rtc.RtcGet()", log.Fields{"err": err})\r
- return nil, err\r
- }\r
- s := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/instruction/" + insttype + "/"\r
- var v string\r
- err = ac.rtc.RtcGetValue(s, &v)\r
- if err != nil {\r
- log.Error("ac.rtc.RtcGetValue(s, &v)", log.Fields{"err": err})\r
- return nil, err\r
- }\r
- return v, nil\r
-}\r
-\r
-// AddLevelValue for holding a state object at a given level\r
-// will make a handle with an appended "<level>/" to the key\r
-func (ac *AppContext) AddLevelValue(handle interface{}, level string, value interface{}) (interface{}, error) {\r
- h, err := ac.rtc.RtcAddOneLevel(handle, level, value)\r
- if err != nil {\r
- return nil, err\r
- }\r
- log.Info(":: Added handle ::", log.Fields{"Handle": h})\r
-\r
- return h, nil\r
-}\r
-\r
-// GetClusterStatusHandle returns the handle for cluster status for a given app and cluster\r
-func (ac *AppContext) GetClusterStatusHandle(appname string, clustername string) (interface{}, error) {\r
- if appname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context app name")\r
- }\r
- if clustername == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context cluster name")\r
- }\r
-\r
- rh, err := ac.rtc.RtcGet()\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/status/"\r
- hs, err := ac.rtc.RtcGetHandles(acrh)\r
- if err != nil {\r
- return nil, err\r
- }\r
- for _, v := range hs {\r
- if v == acrh {\r
- return v, nil\r
- }\r
- }\r
- return nil, pkgerrors.Errorf("No handle was found for the given resource")\r
-}\r
-\r
-//UpdateStatusValue updates the status value with the given handle\r
-func (ac *AppContext) UpdateStatusValue(handle interface{}, value interface{}) error {\r
- return ac.rtc.RtcUpdateValue(handle, value)\r
-}\r
-\r
-//UpdateValue updates the state value with the given handle\r
-func (ac *AppContext) UpdateValue(handle interface{}, value interface{}) error {\r
- return ac.rtc.RtcUpdateValue(handle, value)\r
-}\r
-\r
-//Return all the handles under the composite app\r
-func (ac *AppContext) GetAllHandles(handle interface{}) ([]interface{}, error) {\r
- hs, err := ac.rtc.RtcGetHandles(handle)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return hs, nil\r
-}\r
-\r
-//Returns the value for a given handle\r
-func (ac *AppContext) GetValue(handle interface{}) (interface{}, error) {\r
- var v interface{}\r
- err := ac.rtc.RtcGetValue(handle, &v)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return v, nil\r
-}\r
-\r
-// GetCompositeAppMeta returns the meta data associated with the compositeApp\r
-// Its return type is CompositeAppMeta\r
-func (ac *AppContext) GetCompositeAppMeta() (CompositeAppMeta, error) {\r
- mi, err := ac.rtcObj.RtcGetMeta()\r
-\r
- if err != nil {\r
- return CompositeAppMeta{}, pkgerrors.Errorf("Failed to get compositeApp meta")\r
- }\r
- datamap, ok := mi.(map[string]interface{})\r
- if ok == false {\r
- return CompositeAppMeta{}, pkgerrors.Errorf("Failed to cast meta interface to compositeApp meta")\r
- }\r
-\r
- p := fmt.Sprintf("%v", datamap["Project"])\r
- ca := fmt.Sprintf("%v", datamap["CompositeApp"])\r
- v := fmt.Sprintf("%v", datamap["Version"])\r
- rn := fmt.Sprintf("%v", datamap["Release"])\r
- dig := fmt.Sprintf("%v", datamap["DeploymentIntentGroup"])\r
- namespace := fmt.Sprintf("%v", datamap["Namespace"])\r
- level := fmt.Sprintf("%v", datamap["Level"])\r
-\r
- return CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rn, DeploymentIntentGroup: dig, Namespace: namespace, Level: level}, nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package appcontext
+
+import (
+ "fmt"
+ "strings"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/rtcontext"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// metaPrefix used for denoting clusterMeta level
+const metaGrpPREFIX = "!@#metaGrp"
+
+type AppContext struct {
+ initDone bool
+ rtcObj rtcontext.RunTimeContext
+ rtc rtcontext.Rtcontext
+}
+
+// AppContextStatus represents the current status of the appcontext
+// Instantiating - instantiate has been invoked and is still in progress
+// Instantiated - instantiate has completed
+// Terminating - terminate has been invoked and is still in progress
+// Terminated - terminate has completed
+// InstantiateFailed - the instantiate action has failed
+// TerminateFailed - the terminate action has failed
+type AppContextStatus struct {
+ Status StatusValue
+}
+type StatusValue string
+type statuses struct {
+ Instantiating StatusValue
+ Instantiated StatusValue
+ Terminating StatusValue
+ Terminated StatusValue
+ InstantiateFailed StatusValue
+ TerminateFailed StatusValue
+}
+
+var AppContextStatusEnum = &statuses{
+ Instantiating: "Instantiating",
+ Instantiated: "Instantiated",
+ Terminating: "Terminating",
+ Terminated: "Terminated",
+ InstantiateFailed: "InstantiateFailed",
+ TerminateFailed: "TerminateFailed",
+}
+
+// CompositeAppMeta consists of projectName, CompositeAppName,
+// CompositeAppVersion, ReleaseName. This shall be used for
+// instantiation of a compositeApp
+type CompositeAppMeta struct {
+ Project string `json:"Project"`
+ CompositeApp string `json:"CompositeApp"`
+ Version string `json:"Version"`
+ Release string `json:"Release"`
+ DeploymentIntentGroup string `json:"DeploymentIntentGroup"`
+ Namespace string `json:"Namespace"`
+ Level string `json:"Level"`
+ ChildContextIDs []string `json:"ChildContextIDs"`
+}
+
+// Init app context
+func (ac *AppContext) InitAppContext() (interface{}, error) {
+ ac.rtcObj = rtcontext.RunTimeContext{}
+ ac.rtc = &ac.rtcObj
+ return ac.rtc.RtcInit()
+}
+
+// Load app context that was previously created
+func (ac *AppContext) LoadAppContext(cid interface{}) (interface{}, error) {
+ ac.rtcObj = rtcontext.RunTimeContext{}
+ ac.rtc = &ac.rtcObj
+ return ac.rtc.RtcLoad(cid)
+}
+
+// CreateCompositeApp method returns composite app handle as interface.
+func (ac *AppContext) CreateCompositeApp() (interface{}, error) {
+ h, err := ac.rtc.RtcCreate()
+ if err != nil {
+ return nil, err
+ }
+ log.Info(":: CreateCompositeApp ::", log.Fields{"CompositeAppHandle": h})
+ return h, nil
+}
+
+// AddCompositeAppMeta adds the meta data associated with a composite app
+func (ac *AppContext) AddCompositeAppMeta(meta interface{}) error {
+ err := ac.rtc.RtcAddMeta(meta)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// Deletes the entire context
+func (ac *AppContext) DeleteCompositeApp() error {
+ h, err := ac.rtc.RtcGet()
+ if err != nil {
+ return err
+ }
+ err = ac.rtc.RtcDeletePrefix(h)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//Returns the handles for a given composite app context
+func (ac *AppContext) GetCompositeAppHandle() (interface{}, error) {
+ h, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+ return h, nil
+}
+
+// GetLevelHandle returns the handle for the supplied level at the given handle.
+// For example, to get the handle of the 'status' level at a given handle.
+func (ac *AppContext) GetLevelHandle(handle interface{}, level string) (interface{}, error) {
+ ach := fmt.Sprintf("%v%v/", handle, level)
+ hs, err := ac.rtc.RtcGetHandles(ach)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == ach {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for level %v", level)
+}
+
+//Add app to the context under composite app
+func (ac *AppContext) AddApp(handle interface{}, appname string) (interface{}, error) {
+ h, err := ac.rtc.RtcAddLevel(handle, "app", appname)
+ if err != nil {
+ return nil, err
+ }
+ log.Info(":: Added app handle ::", log.Fields{"AppHandle": h})
+ return h, nil
+}
+
+//Delete app from the context and everything underneth
+func (ac *AppContext) DeleteApp(handle interface{}) error {
+ err := ac.rtc.RtcDeletePrefix(handle)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//Returns the handle for a given app
+func (ac *AppContext) GetAppHandle(appname string) (interface{}, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ apph := fmt.Sprintf("%v", rh) + "app/" + appname + "/"
+ hs, err := ac.rtc.RtcGetHandles(apph)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == apph {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for the given app")
+}
+
+// AddCluster helps to add cluster to the context under app. It takes in the app handle and clusterName as value.
+func (ac *AppContext) AddCluster(handle interface{}, clustername string) (interface{}, error) {
+ h, err := ac.rtc.RtcAddLevel(handle, "cluster", clustername)
+ if err != nil {
+ return nil, err
+ }
+ log.Info(":: Added cluster handle ::", log.Fields{"ClusterHandler": h})
+ return h, nil
+}
+
+// AddClusterMetaGrp adds the meta info of groupNumber to which a cluster belongs.
+// It takes in cluster handle and groupNumber as arguments
+func (ac *AppContext) AddClusterMetaGrp(ch interface{}, gn string) error {
+ mh, err := ac.rtc.RtcAddOneLevel(ch, metaGrpPREFIX, gn)
+ if err != nil {
+ return err
+ }
+ log.Info(":: Added cluster meta handle ::", log.Fields{"ClusterMetaHandler": mh})
+ return nil
+}
+
+// DeleteClusterMetaGrpHandle deletes the group number to which the cluster belongs, it takes in the cluster handle.
+func (ac *AppContext) DeleteClusterMetaGrpHandle(ch interface{}) error {
+ err := ac.rtc.RtcDeletePrefix(ch)
+ if err != nil {
+ return err
+ }
+ log.Info(":: Deleted cluster meta handle ::", log.Fields{"ClusterMetaHandler": ch})
+ return nil
+}
+
+/*
+GetClusterMetaHandle takes in appName and ClusterName as string arguments and return the ClusterMetaHandle as string
+*/
+func (ac *AppContext) GetClusterMetaHandle(app string, cluster string) (string, error) {
+ if app == "" {
+ return "", pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if cluster == "" {
+ return "", pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+
+ ch, err := ac.GetClusterHandle(app, cluster)
+ if err != nil {
+ return "", err
+ }
+ cmh := fmt.Sprintf("%v", ch) + metaGrpPREFIX + "/"
+ return cmh, nil
+
+}
+
+/*
+GetClusterGroupMap shall take in appName and return a map showing the grouping among the clusters.
+sample output of "GroupMap" :{"1":["cluster_provider1+clusterName3","cluster_provider1+clusterName5"],"2":["cluster_provider2+clusterName4","cluster_provider2+clusterName6"]}
+*/
+func (ac *AppContext) GetClusterGroupMap(an string) (map[string][]string, error) {
+ cl, err := ac.GetClusterNames(an)
+ if err != nil {
+ log.Info(":: Unable to fetch clusterList for app ::", log.Fields{"AppName ": an})
+ return nil, err
+ }
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ var gmap = make(map[string][]string)
+ for _, cn := range cl {
+ s := fmt.Sprintf("%v", rh) + "app/" + an + "/cluster/" + cn + "/" + metaGrpPREFIX + "/"
+ var v string
+ err = ac.rtc.RtcGetValue(s, &v)
+ if err != nil {
+ log.Info(":: No group number for cluster ::", log.Fields{"cluster": cn, "Reason": err})
+ continue
+ }
+ gn := fmt.Sprintf("%v", v)
+ log.Info(":: GroupNumber retrieved ::", log.Fields{"GroupNumber": gn})
+
+ cl, found := gmap[gn]
+ if found == false {
+ cl = make([]string, 0)
+ }
+ cl = append(cl, cn)
+ gmap[gn] = cl
+ }
+ return gmap, nil
+}
+
+//Delete cluster from the context and everything underneth
+func (ac *AppContext) DeleteCluster(handle interface{}) error {
+ err := ac.rtc.RtcDeletePrefix(handle)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//Returns the handle for a given app and cluster
+func (ac *AppContext) GetClusterHandle(appname string, clustername string) (interface{}, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if clustername == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ ach := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/"
+ hs, err := ac.rtc.RtcGetHandles(ach)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == ach {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for the given cluster")
+}
+
+//Returns a list of all clusters for a given app
+func (ac *AppContext) GetClusterNames(appname string) ([]string, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ prefix := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/"
+ hs, err := ac.rtc.RtcGetHandles(prefix)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting handles for %v", prefix)
+ }
+ var cs []string
+ for _, h := range hs {
+ hstr := fmt.Sprintf("%v", h)
+ ks := strings.Split(hstr, prefix)
+ for _, k := range ks {
+ ck := strings.Split(k, "/")
+ if len(ck) == 2 && ck[1] == "" {
+ cs = append(cs, ck[0])
+ }
+ }
+ }
+
+ if len(cs) == 0 {
+ err = pkgerrors.New("Cluster list is empty")
+ log.Error("Cluster list is empty",
+ log.Fields{"clusters": cs})
+ return cs, err
+ }
+ return cs, nil
+}
+
+//Add resource under app and cluster
+func (ac *AppContext) AddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {
+ h, err := ac.rtc.RtcAddResource(handle, resname, value)
+ if err != nil {
+ return nil, err
+ }
+ log.Info(":: Added resource handle ::", log.Fields{"ResourceHandler": h})
+
+ return h, nil
+}
+
+//Return the handle for given app, cluster and resource name
+func (ac *AppContext) GetResourceHandle(appname string, clustername string, resname string) (interface{}, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if clustername == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/" + resname + "/"
+ hs, err := ac.rtc.RtcGetHandles(acrh)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == acrh {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for the given resource")
+}
+
+//Update the resource value using the given handle
+func (ac *AppContext) UpdateResourceValue(handle interface{}, value interface{}) error {
+ return ac.rtc.RtcUpdateValue(handle, value)
+}
+
+//Return the handle for given app, cluster and resource name
+func (ac *AppContext) GetResourceStatusHandle(appname string, clustername string, resname string) (interface{}, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if clustername == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+ if resname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context resource name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/" + resname + "/status/"
+ hs, err := ac.rtc.RtcGetHandles(acrh)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == acrh {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for the given resource")
+}
+
+//GetResourceNames ... Returns a list of all resource names for a given app
+func (ac *AppContext) GetResourceNames(appname string, clustername string) ([]string, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if clustername == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ prefix := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/"
+ hs, err := ac.rtc.RtcGetHandles(prefix)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting handles for %v", prefix)
+ }
+ var cs []string
+ for _, h := range hs {
+ hstr := fmt.Sprintf("%v", h)
+ ks := strings.Split(hstr, prefix)
+ for _, k := range ks {
+ ck := strings.Split(k, "/")
+ if len(ck) == 2 && ck[1] == "" {
+ cs = append(cs, ck[0])
+ }
+ }
+ }
+ return cs, nil
+}
+
+//Add instruction under given handle and type
+func (ac *AppContext) AddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {
+ if !(insttype == "order" || insttype == "dependency") {
+ log.Error("Not a valid app context instruction type", log.Fields{})
+ return nil, pkgerrors.Errorf("Not a valid app context instruction type")
+ }
+ if !(level == "app" || level == "resource" || level == "subresource") {
+ log.Error("Not a valid app context instruction level", log.Fields{})
+ return nil, pkgerrors.Errorf("Not a valid app context instruction level")
+ }
+ h, err := ac.rtc.RtcAddInstruction(handle, level, insttype, value)
+ if err != nil {
+ log.Error("ac.rtc.RtcAddInstruction(handle, level, insttype, value)", log.Fields{"err": err})
+ return nil, err
+ }
+ log.Info(":: Added instruction handle ::", log.Fields{"InstructionHandler": h})
+ return h, nil
+}
+
+//Delete instruction under given handle
+func (ac *AppContext) DeleteInstruction(handle interface{}) error {
+ err := ac.rtc.RtcDeletePair(handle)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//Returns the app instruction for a given instruction type
+func (ac *AppContext) GetAppInstruction(insttype string) (interface{}, error) {
+ if !(insttype == "order" || insttype == "dependency") {
+ log.Error("Not a valid app context instruction type", log.Fields{})
+ return nil, pkgerrors.Errorf("Not a valid app context instruction type")
+ }
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ log.Error("ac.rtc.RtcGet()", log.Fields{"err": err})
+ return nil, err
+ }
+ s := fmt.Sprintf("%v", rh) + "app/" + "instruction/" + insttype + "/"
+ log.Info("Getting app instruction", log.Fields{"s": s})
+ var v string
+ err = ac.rtc.RtcGetValue(s, &v)
+ if err != nil {
+ log.Error("ac.rtc.RtcGetValue(s, &v)", log.Fields{"err": err})
+ return nil, err
+ }
+ return v, nil
+}
+
+//Update the instruction usign the given handle
+func (ac *AppContext) UpdateInstructionValue(handle interface{}, value interface{}) error {
+ return ac.rtc.RtcUpdateValue(handle, value)
+}
+
+//Returns the resource instruction for a given instruction type
+func (ac *AppContext) GetResourceInstruction(appname string, clustername string, insttype string) (interface{}, error) {
+ if !(insttype == "order" || insttype == "dependency") {
+ log.Error("Not a valid app context instruction type", log.Fields{})
+ return nil, pkgerrors.Errorf("Not a valid app context instruction type")
+ }
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ log.Error("ac.rtc.RtcGet()", log.Fields{"err": err})
+ return nil, err
+ }
+ s := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/resource/instruction/" + insttype + "/"
+ var v string
+ err = ac.rtc.RtcGetValue(s, &v)
+ if err != nil {
+ log.Error("ac.rtc.RtcGetValue(s, &v)", log.Fields{"err": err})
+ return nil, err
+ }
+ return v, nil
+}
+
+// AddLevelValue for holding a state object at a given level
+// will make a handle with an appended "<level>/" to the key
+func (ac *AppContext) AddLevelValue(handle interface{}, level string, value interface{}) (interface{}, error) {
+ h, err := ac.rtc.RtcAddOneLevel(handle, level, value)
+ if err != nil {
+ return nil, err
+ }
+ log.Info(":: Added handle ::", log.Fields{"Handle": h})
+
+ return h, nil
+}
+
+// GetClusterStatusHandle returns the handle for cluster status for a given app and cluster
+func (ac *AppContext) GetClusterStatusHandle(appname string, clustername string) (interface{}, error) {
+ if appname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context app name")
+ }
+ if clustername == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context cluster name")
+ }
+
+ rh, err := ac.rtc.RtcGet()
+ if err != nil {
+ return nil, err
+ }
+
+ acrh := fmt.Sprintf("%v", rh) + "app/" + appname + "/cluster/" + clustername + "/status/"
+ hs, err := ac.rtc.RtcGetHandles(acrh)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range hs {
+ if v == acrh {
+ return v, nil
+ }
+ }
+ return nil, pkgerrors.Errorf("No handle was found for the given resource")
+}
+
+//UpdateStatusValue updates the status value with the given handle
+func (ac *AppContext) UpdateStatusValue(handle interface{}, value interface{}) error {
+ return ac.rtc.RtcUpdateValue(handle, value)
+}
+
+//UpdateValue updates the state value with the given handle
+func (ac *AppContext) UpdateValue(handle interface{}, value interface{}) error {
+ return ac.rtc.RtcUpdateValue(handle, value)
+}
+
+//Return all the handles under the composite app
+func (ac *AppContext) GetAllHandles(handle interface{}) ([]interface{}, error) {
+ hs, err := ac.rtc.RtcGetHandles(handle)
+ if err != nil {
+ return nil, err
+ }
+ return hs, nil
+}
+
+//Returns the value for a given handle
+func (ac *AppContext) GetValue(handle interface{}) (interface{}, error) {
+ var v interface{}
+ err := ac.rtc.RtcGetValue(handle, &v)
+ if err != nil {
+ return nil, err
+ }
+ return v, nil
+}
+
+// GetCompositeAppMeta returns the meta data associated with the compositeApp
+// Its return type is CompositeAppMeta
+func (ac *AppContext) GetCompositeAppMeta() (CompositeAppMeta, error) {
+ mi, err := ac.rtcObj.RtcGetMeta()
+
+ if err != nil {
+ return CompositeAppMeta{}, pkgerrors.Errorf("Failed to get compositeApp meta")
+ }
+ datamap, ok := mi.(map[string]interface{})
+ if ok == false {
+ return CompositeAppMeta{}, pkgerrors.Errorf("Failed to cast meta interface to compositeApp meta")
+ }
+
+ p := fmt.Sprintf("%v", datamap["Project"])
+ ca := fmt.Sprintf("%v", datamap["CompositeApp"])
+ v := fmt.Sprintf("%v", datamap["Version"])
+ rn := fmt.Sprintf("%v", datamap["Release"])
+ dig := fmt.Sprintf("%v", datamap["DeploymentIntentGroup"])
+ namespace := fmt.Sprintf("%v", datamap["Namespace"])
+ level := fmt.Sprintf("%v", datamap["Level"])
+ var childInterface []interface{}
+ childCtxs := make([]string, len(childInterface))
+ if datamap["ChildContextIDs"] != nil {
+ childInterface = datamap["ChildContextIDs"].([]interface{})
+ for _, v := range childInterface {
+ childCtxs = append(childCtxs, v.(string))
+ }
+ }
+
+ return CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rn, DeploymentIntentGroup: dig, Namespace: namespace, Level: level, ChildContextIDs: childCtxs}, nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package appcontext\r
-\r
-import (\r
- "fmt"\r
- "strings"\r
- "testing"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// Mock run time context\r
-type MockRunTimeContext struct {\r
- Items map[string]interface{}\r
- Err error\r
-}\r
-\r
-type MockCompositeAppMeta struct {\r
- Project string\r
- CompositeApp string\r
- Version string\r
- Release string\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcCreate() (interface{}, error) {\r
- var key string = "/context/9345674458787728/"\r
-\r
- if c.Items == nil {\r
- c.Items = make(map[string]interface{})\r
- }\r
- c.Items[key] = "9345674458787728"\r
- return interface{}(key), c.Err\r
-\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcAddMeta(meta interface{}) error {\r
- var cid string = "/context/9345674458787728/"\r
- key := cid + "meta" + "/"\r
- if c.Items == nil {\r
- c.Items = make(map[string]interface{})\r
- }\r
- c.Items[key] = meta\r
- return nil\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcInit() (interface{}, error) {\r
- var id string = "9345674458787728"\r
- return id, c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcLoad(id interface{}) (interface{}, error) {\r
- str := "/context/" + fmt.Sprintf("%v", id) + "/"\r
- return interface{}(str), c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcGet() (interface{}, error) {\r
- var key string = "/context/9345674458787728/"\r
- return key, c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcGetMeta() (interface{}, error) {\r
- meta := CompositeAppMeta{Project: "pn", CompositeApp: "ca", Version: "v", Release: "rName"}\r
- return meta, nil\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle) + level + "/" + value + "/"\r
- c.Items[str] = value\r
- return nil, c.Err\r
-\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcAddOneLevel(handle interface{}, level string, value interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle) + level + "/"\r
- c.Items[str] = value\r
- return nil, c.Err\r
-\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle) + "resource" + "/" + resname + "/"\r
- c.Items[str] = value\r
- return nil, c.Err\r
-\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle) + level + "/" + insttype + "/"\r
- c.Items[str] = value\r
- return nil, c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcDeletePair(handle interface{}) error {\r
- str := fmt.Sprintf("%v", handle)\r
- delete(c.Items, str)\r
- return c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcDeletePrefix(handle interface{}) error {\r
- for k := range c.Items {\r
- delete(c.Items, k)\r
- }\r
- return c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {\r
- var keys []interface{}\r
-\r
- for k := range c.Items {\r
- keys = append(keys, string(k))\r
- }\r
- return keys, c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {\r
- key := fmt.Sprintf("%v", handle)\r
- var s *string\r
- s = value.(*string)\r
- for kvKey, kvValue := range c.Items {\r
- if kvKey == key {\r
- *s = kvValue.(string)\r
- return c.Err\r
- }\r
- }\r
- return c.Err\r
-}\r
-\r
-func (c *MockRunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {\r
- key := fmt.Sprintf("%v", handle)\r
- c.Items[key] = value\r
- return c.Err\r
-}\r
-\r
-func TestCreateCompositeApp(t *testing.T) {\r
- var ac = AppContext{}\r
- testCases := []struct {\r
- label string\r
- mockRtcontext *MockRunTimeContext\r
- expectedError string\r
- meta interface{}\r
- }{\r
- {\r
- label: "Success case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),\r
- },\r
- {\r
- label: "Create returns error case",\r
- mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error creating run time context:")},\r
- expectedError: "Error creating run time context:",\r
- meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- ac.rtc = testCase.mockRtcontext\r
- _, err := ac.CreateCompositeApp()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestGetCompositeApp(t *testing.T) {\r
- var ac = AppContext{}\r
- testCases := []struct {\r
- label string\r
- mockRtcontext *MockRunTimeContext\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- },\r
- {\r
- label: "Get returns error case",\r
- mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error getting run time context:")},\r
- expectedError: "Error getting run time context:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- ac.rtc = testCase.mockRtcontext\r
- _, err := ac.GetCompositeAppHandle()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestDeleteCompositeApp(t *testing.T) {\r
- var ac = AppContext{}\r
- testCases := []struct {\r
- label string\r
- mockRtcontext *MockRunTimeContext\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- },\r
- {\r
- label: "Delete returns error case",\r
- mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error deleting run time context:")},\r
- expectedError: "Error deleting run time context:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- ac.rtc = testCase.mockRtcontext\r
- err := ac.DeleteCompositeApp()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestAddApp(t *testing.T) {\r
- var ac = AppContext{}\r
- testCases := []struct {\r
- label string\r
- mockRtcontext *MockRunTimeContext\r
- key interface{}\r
- expectedError string\r
- meta interface{}\r
- }{\r
- {\r
- label: "Success case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- key: "/context/9345674458787728/",\r
- meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),\r
- },\r
- {\r
- label: "Error case for adding app",\r
- mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error adding app to run time context:")},\r
- key: "/context/9345674458787728/",\r
- expectedError: "Error adding app to run time context:",\r
- meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- ac.rtc = testCase.mockRtcontext\r
- _, err := ac.CreateCompositeApp()\r
- _, err = ac.AddApp(testCase.key, "testapp1")\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestGetAppHandle(t *testing.T) {\r
- var ac = AppContext{}\r
- testCases := []struct {\r
- label string\r
- mockRtcontext *MockRunTimeContext\r
- key interface{}\r
- appname string\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- key: "/context/9345674458787728/",\r
- appname: "testapp1",\r
- },\r
- {\r
- label: "Invalid app name case",\r
- mockRtcontext: &MockRunTimeContext{},\r
- key: "/context/9345674458787728/",\r
- appname: "",\r
- },\r
- {\r
- label: "Delete returns error case",\r
- mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error getting app handle from run time context:")},\r
- key: "/context/9345674458787728/",\r
- appname: "testapp1",\r
- expectedError: "Error getting app handle from run time context:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- ac.rtc = testCase.mockRtcontext\r
- _, err := ac.GetAppHandle(testCase.appname)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package appcontext
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// Mock run time context
+type MockRunTimeContext struct {
+ Items map[string]interface{}
+ Err error
+}
+
+type MockCompositeAppMeta struct {
+ Project string
+ CompositeApp string
+ Version string
+ Release string
+}
+
+func (c *MockRunTimeContext) RtcCreate() (interface{}, error) {
+ var key string = "/context/9345674458787728/"
+
+ if c.Items == nil {
+ c.Items = make(map[string]interface{})
+ }
+ c.Items[key] = "9345674458787728"
+ return interface{}(key), c.Err
+
+}
+
+func (c *MockRunTimeContext) RtcAddMeta(meta interface{}) error {
+ var cid string = "/context/9345674458787728/"
+ key := cid + "meta" + "/"
+ if c.Items == nil {
+ c.Items = make(map[string]interface{})
+ }
+ c.Items[key] = meta
+ return nil
+}
+
+func (c *MockRunTimeContext) RtcInit() (interface{}, error) {
+ var id string = "9345674458787728"
+ return id, c.Err
+}
+
+func (c *MockRunTimeContext) RtcLoad(id interface{}) (interface{}, error) {
+ str := "/context/" + fmt.Sprintf("%v", id) + "/"
+ return interface{}(str), c.Err
+}
+
+func (c *MockRunTimeContext) RtcGet() (interface{}, error) {
+ var key string = "/context/9345674458787728/"
+ return key, c.Err
+}
+
+func (c *MockRunTimeContext) RtcGetMeta() (interface{}, error) {
+ meta := CompositeAppMeta{Project: "pn", CompositeApp: "ca", Version: "v", Release: "rName"}
+ return meta, nil
+}
+
+func (c *MockRunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle) + level + "/" + value + "/"
+ c.Items[str] = value
+ return nil, c.Err
+
+}
+
+func (c *MockRunTimeContext) RtcAddOneLevel(handle interface{}, level string, value interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle) + level + "/"
+ c.Items[str] = value
+ return nil, c.Err
+
+}
+
+func (c *MockRunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle) + "resource" + "/" + resname + "/"
+ c.Items[str] = value
+ return nil, c.Err
+
+}
+
+func (c *MockRunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle) + level + "/" + insttype + "/"
+ c.Items[str] = value
+ return nil, c.Err
+}
+
+func (c *MockRunTimeContext) RtcDeletePair(handle interface{}) error {
+ str := fmt.Sprintf("%v", handle)
+ delete(c.Items, str)
+ return c.Err
+}
+
+func (c *MockRunTimeContext) RtcDeletePrefix(handle interface{}) error {
+ for k := range c.Items {
+ delete(c.Items, k)
+ }
+ return c.Err
+}
+
+func (c *MockRunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {
+ var keys []interface{}
+
+ for k := range c.Items {
+ keys = append(keys, string(k))
+ }
+ return keys, c.Err
+}
+
+func (c *MockRunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {
+ key := fmt.Sprintf("%v", handle)
+ var s *string
+ s = value.(*string)
+ for kvKey, kvValue := range c.Items {
+ if kvKey == key {
+ *s = kvValue.(string)
+ return c.Err
+ }
+ }
+ return c.Err
+}
+
+func (c *MockRunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {
+ key := fmt.Sprintf("%v", handle)
+ c.Items[key] = value
+ return c.Err
+}
+
+func TestCreateCompositeApp(t *testing.T) {
+ var ac = AppContext{}
+ testCases := []struct {
+ label string
+ mockRtcontext *MockRunTimeContext
+ expectedError string
+ meta interface{}
+ }{
+ {
+ label: "Success case",
+ mockRtcontext: &MockRunTimeContext{},
+ meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),
+ },
+ {
+ label: "Create returns error case",
+ mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error creating run time context:")},
+ expectedError: "Error creating run time context:",
+ meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ ac.rtc = testCase.mockRtcontext
+ _, err := ac.CreateCompositeApp()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestGetCompositeApp(t *testing.T) {
+ var ac = AppContext{}
+ testCases := []struct {
+ label string
+ mockRtcontext *MockRunTimeContext
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockRtcontext: &MockRunTimeContext{},
+ },
+ {
+ label: "Get returns error case",
+ mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error getting run time context:")},
+ expectedError: "Error getting run time context:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ ac.rtc = testCase.mockRtcontext
+ _, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestDeleteCompositeApp(t *testing.T) {
+ var ac = AppContext{}
+ testCases := []struct {
+ label string
+ mockRtcontext *MockRunTimeContext
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockRtcontext: &MockRunTimeContext{},
+ },
+ {
+ label: "Delete returns error case",
+ mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error deleting run time context:")},
+ expectedError: "Error deleting run time context:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ ac.rtc = testCase.mockRtcontext
+ err := ac.DeleteCompositeApp()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestAddApp(t *testing.T) {
+ var ac = AppContext{}
+ testCases := []struct {
+ label string
+ mockRtcontext *MockRunTimeContext
+ key interface{}
+ expectedError string
+ meta interface{}
+ }{
+ {
+ label: "Success case",
+ mockRtcontext: &MockRunTimeContext{},
+ key: "/context/9345674458787728/",
+ meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),
+ },
+ {
+ label: "Error case for adding app",
+ mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error adding app to run time context:")},
+ key: "/context/9345674458787728/",
+ expectedError: "Error adding app to run time context:",
+ meta: interface{}(MockCompositeAppMeta{Project: "Testproject", CompositeApp: "TestCompApp", Version: "CompAppVersion", Release: "TestRelease"}),
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ ac.rtc = testCase.mockRtcontext
+ _, err := ac.CreateCompositeApp()
+ _, err = ac.AddApp(testCase.key, "testapp1")
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestGetAppHandle(t *testing.T) {
+ var ac = AppContext{}
+ testCases := []struct {
+ label string
+ mockRtcontext *MockRunTimeContext
+ key interface{}
+ appname string
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockRtcontext: &MockRunTimeContext{},
+ key: "/context/9345674458787728/",
+ appname: "testapp1",
+ },
+ {
+ label: "Invalid app name case",
+ mockRtcontext: &MockRunTimeContext{},
+ key: "/context/9345674458787728/",
+ appname: "",
+ },
+ {
+ label: "Delete returns error case",
+ mockRtcontext: &MockRunTimeContext{Err: pkgerrors.Errorf("Error getting app handle from run time context:")},
+ key: "/context/9345674458787728/",
+ appname: "testapp1",
+ expectedError: "Error getting app handle from run time context:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ ac.rtc = testCase.mockRtcontext
+ _, err := ac.GetAppHandle(testCase.appname)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package subresources\r
-\r
-// The ApprovalSubresource type defines the 4 necessary parameters\r
-// that the "approval" subresource of a CertificateSigningRequest in K8s\r
-// requires, in a forma tto be exchanged over AppContext\r
-type ApprovalSubresource struct {\r
- LastUpdateTime string `json:"lastUpdateTime,omitempty"`\r
- Message string `json:"message,omitempty"`\r
- Reason string `json:"reason,omitempty"`\r
- Type string `json:"type,omitempty"`\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package subresources
+
+// The ApprovalSubresource type defines the 4 necessary parameters
+// that the "approval" subresource of a CertificateSigningRequest in K8s
+// requires, in a forma tto be exchanged over AppContext
+type ApprovalSubresource struct {
+ LastUpdateTime string `json:"lastUpdateTime,omitempty"`
+ Message string `json:"message,omitempty"`
+ Reason string `json:"reason,omitempty"`
+ Type string `json:"type,omitempty"`
+}
-//\r
-// Copyright 2020 Intel Corporation, Inc\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-// http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-\r
-// Code generated by protoc-gen-go. DO NOT EDIT.\r
-// versions:\r
-// protoc-gen-go v1.24.0\r
-// protoc v3.11.4\r
-// source: contextupdate.proto\r
-\r
-package contextupdate\r
-\r
-import (\r
- context "context"\r
- proto "github.com/golang/protobuf/proto"\r
- grpc "google.golang.org/grpc"\r
- codes "google.golang.org/grpc/codes"\r
- status "google.golang.org/grpc/status"\r
- protoreflect "google.golang.org/protobuf/reflect/protoreflect"\r
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"\r
- reflect "reflect"\r
- sync "sync"\r
-)\r
-\r
-const (\r
- // Verify that this generated code is sufficiently up-to-date.\r
- _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\r
- // Verify that runtime/protoimpl is sufficiently up-to-date.\r
- _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\r
-)\r
-\r
-// This is a compile-time assertion that a sufficiently up-to-date version\r
-// of the legacy proto package is being used.\r
-const _ = proto.ProtoPackageIsVersion4\r
-\r
-type ContextUpdateRequest struct {\r
- state protoimpl.MessageState\r
- sizeCache protoimpl.SizeCache\r
- unknownFields protoimpl.UnknownFields\r
-\r
- AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`\r
- IntentName string `protobuf:"bytes,2,opt,name=intent_name,json=intentName,proto3" json:"intent_name,omitempty"`\r
-}\r
-\r
-func (x *ContextUpdateRequest) Reset() {\r
- *x = ContextUpdateRequest{}\r
- if protoimpl.UnsafeEnabled {\r
- mi := &file_contextupdate_proto_msgTypes[0]\r
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\r
- ms.StoreMessageInfo(mi)\r
- }\r
-}\r
-\r
-func (x *ContextUpdateRequest) String() string {\r
- return protoimpl.X.MessageStringOf(x)\r
-}\r
-\r
-func (*ContextUpdateRequest) ProtoMessage() {}\r
-\r
-func (x *ContextUpdateRequest) ProtoReflect() protoreflect.Message {\r
- mi := &file_contextupdate_proto_msgTypes[0]\r
- if protoimpl.UnsafeEnabled && x != nil {\r
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\r
- if ms.LoadMessageInfo() == nil {\r
- ms.StoreMessageInfo(mi)\r
- }\r
- return ms\r
- }\r
- return mi.MessageOf(x)\r
-}\r
-\r
-// Deprecated: Use ContextUpdateRequest.ProtoReflect.Descriptor instead.\r
-func (*ContextUpdateRequest) Descriptor() ([]byte, []int) {\r
- return file_contextupdate_proto_rawDescGZIP(), []int{0}\r
-}\r
-\r
-func (x *ContextUpdateRequest) GetAppContext() string {\r
- if x != nil {\r
- return x.AppContext\r
- }\r
- return ""\r
-}\r
-\r
-func (x *ContextUpdateRequest) GetIntentName() string {\r
- if x != nil {\r
- return x.IntentName\r
- }\r
- return ""\r
-}\r
-\r
-type ContextUpdateResponse struct {\r
- state protoimpl.MessageState\r
- sizeCache protoimpl.SizeCache\r
- unknownFields protoimpl.UnknownFields\r
-\r
- AppContextUpdated bool `protobuf:"varint,1,opt,name=app_context_updated,json=appContextUpdated,proto3" json:"app_context_updated,omitempty"`\r
- AppContextUpdateMessage string `protobuf:"bytes,2,opt,name=app_context_update_message,json=appContextUpdateMessage,proto3" json:"app_context_update_message,omitempty"`\r
-}\r
-\r
-func (x *ContextUpdateResponse) Reset() {\r
- *x = ContextUpdateResponse{}\r
- if protoimpl.UnsafeEnabled {\r
- mi := &file_contextupdate_proto_msgTypes[1]\r
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\r
- ms.StoreMessageInfo(mi)\r
- }\r
-}\r
-\r
-func (x *ContextUpdateResponse) String() string {\r
- return protoimpl.X.MessageStringOf(x)\r
-}\r
-\r
-func (*ContextUpdateResponse) ProtoMessage() {}\r
-\r
-func (x *ContextUpdateResponse) ProtoReflect() protoreflect.Message {\r
- mi := &file_contextupdate_proto_msgTypes[1]\r
- if protoimpl.UnsafeEnabled && x != nil {\r
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\r
- if ms.LoadMessageInfo() == nil {\r
- ms.StoreMessageInfo(mi)\r
- }\r
- return ms\r
- }\r
- return mi.MessageOf(x)\r
-}\r
-\r
-// Deprecated: Use ContextUpdateResponse.ProtoReflect.Descriptor instead.\r
-func (*ContextUpdateResponse) Descriptor() ([]byte, []int) {\r
- return file_contextupdate_proto_rawDescGZIP(), []int{1}\r
-}\r
-\r
-func (x *ContextUpdateResponse) GetAppContextUpdated() bool {\r
- if x != nil {\r
- return x.AppContextUpdated\r
- }\r
- return false\r
-}\r
-\r
-func (x *ContextUpdateResponse) GetAppContextUpdateMessage() string {\r
- if x != nil {\r
- return x.AppContextUpdateMessage\r
- }\r
- return ""\r
-}\r
-\r
-var File_contextupdate_proto protoreflect.FileDescriptor\r
-\r
-var file_contextupdate_proto_rawDesc = []byte{\r
- 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e,\r
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,\r
- 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a,\r
- 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01,\r
- 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f,\r
- 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,\r
- 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22,\r
- 0x84, 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74,\r
- 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x70,\r
- 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,\r
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65,\r
- 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x70, 0x70,\r
- 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,\r
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x61,\r
- 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d,\r
- 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x54, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,\r
- 0x74, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74,\r
- 0x65, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x15, 0x2e, 0x43, 0x6f,\r
- 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,\r
- 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61,\r
- 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62, 0x06, 0x70, 0x72,\r
- 0x6f, 0x74, 0x6f, 0x33,\r
-}\r
-\r
-var (\r
- file_contextupdate_proto_rawDescOnce sync.Once\r
- file_contextupdate_proto_rawDescData = file_contextupdate_proto_rawDesc\r
-)\r
-\r
-func file_contextupdate_proto_rawDescGZIP() []byte {\r
- file_contextupdate_proto_rawDescOnce.Do(func() {\r
- file_contextupdate_proto_rawDescData = protoimpl.X.CompressGZIP(file_contextupdate_proto_rawDescData)\r
- })\r
- return file_contextupdate_proto_rawDescData\r
-}\r
-\r
-var file_contextupdate_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\r
-var file_contextupdate_proto_goTypes = []interface{}{\r
- (*ContextUpdateRequest)(nil), // 0: ContextUpdateRequest\r
- (*ContextUpdateResponse)(nil), // 1: ContextUpdateResponse\r
-}\r
-var file_contextupdate_proto_depIdxs = []int32{\r
- 0, // 0: contextupdate.UpdateAppContext:input_type -> ContextUpdateRequest\r
- 1, // 1: contextupdate.UpdateAppContext:output_type -> ContextUpdateResponse\r
- 1, // [1:2] is the sub-list for method output_type\r
- 0, // [0:1] is the sub-list for method input_type\r
- 0, // [0:0] is the sub-list for extension type_name\r
- 0, // [0:0] is the sub-list for extension extendee\r
- 0, // [0:0] is the sub-list for field type_name\r
-}\r
-\r
-func init() { file_contextupdate_proto_init() }\r
-func file_contextupdate_proto_init() {\r
- if File_contextupdate_proto != nil {\r
- return\r
- }\r
- if !protoimpl.UnsafeEnabled {\r
- file_contextupdate_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\r
- switch v := v.(*ContextUpdateRequest); i {\r
- case 0:\r
- return &v.state\r
- case 1:\r
- return &v.sizeCache\r
- case 2:\r
- return &v.unknownFields\r
- default:\r
- return nil\r
- }\r
- }\r
- file_contextupdate_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\r
- switch v := v.(*ContextUpdateResponse); i {\r
- case 0:\r
- return &v.state\r
- case 1:\r
- return &v.sizeCache\r
- case 2:\r
- return &v.unknownFields\r
- default:\r
- return nil\r
- }\r
- }\r
- }\r
- type x struct{}\r
- out := protoimpl.TypeBuilder{\r
- File: protoimpl.DescBuilder{\r
- GoPackagePath: reflect.TypeOf(x{}).PkgPath(),\r
- RawDescriptor: file_contextupdate_proto_rawDesc,\r
- NumEnums: 0,\r
- NumMessages: 2,\r
- NumExtensions: 0,\r
- NumServices: 1,\r
- },\r
- GoTypes: file_contextupdate_proto_goTypes,\r
- DependencyIndexes: file_contextupdate_proto_depIdxs,\r
- MessageInfos: file_contextupdate_proto_msgTypes,\r
- }.Build()\r
- File_contextupdate_proto = out.File\r
- file_contextupdate_proto_rawDesc = nil\r
- file_contextupdate_proto_goTypes = nil\r
- file_contextupdate_proto_depIdxs = nil\r
-}\r
-\r
-// Reference imports to suppress errors if they are not otherwise used.\r
-var _ context.Context\r
-var _ grpc.ClientConnInterface\r
-\r
-// This is a compile-time assertion to ensure that this generated file\r
-// is compatible with the grpc package it is being compiled against.\r
-const _ = grpc.SupportPackageIsVersion6\r
-\r
-// ContextupdateClient is the client API for Contextupdate service.\r
-//\r
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\r
-type ContextupdateClient interface {\r
- // Controllers\r
- UpdateAppContext(ctx context.Context, in *ContextUpdateRequest, opts ...grpc.CallOption) (*ContextUpdateResponse, error)\r
-}\r
-\r
-type contextupdateClient struct {\r
- cc grpc.ClientConnInterface\r
-}\r
-\r
-func NewContextupdateClient(cc grpc.ClientConnInterface) ContextupdateClient {\r
- return &contextupdateClient{cc}\r
-}\r
-\r
-func (c *contextupdateClient) UpdateAppContext(ctx context.Context, in *ContextUpdateRequest, opts ...grpc.CallOption) (*ContextUpdateResponse, error) {\r
- out := new(ContextUpdateResponse)\r
- err := c.cc.Invoke(ctx, "/contextupdate/UpdateAppContext", in, out, opts...)\r
- if err != nil {\r
- return nil, err\r
- }\r
- return out, nil\r
-}\r
-\r
-// ContextupdateServer is the server API for Contextupdate service.\r
-type ContextupdateServer interface {\r
- // Controllers\r
- UpdateAppContext(context.Context, *ContextUpdateRequest) (*ContextUpdateResponse, error)\r
-}\r
-\r
-// UnimplementedContextupdateServer can be embedded to have forward compatible implementations.\r
-type UnimplementedContextupdateServer struct {\r
-}\r
-\r
-func (*UnimplementedContextupdateServer) UpdateAppContext(context.Context, *ContextUpdateRequest) (*ContextUpdateResponse, error) {\r
- return nil, status.Errorf(codes.Unimplemented, "method UpdateAppContext not implemented")\r
-}\r
-\r
-func RegisterContextupdateServer(s *grpc.Server, srv ContextupdateServer) {\r
- s.RegisterService(&_Contextupdate_serviceDesc, srv)\r
-}\r
-\r
-func _Contextupdate_UpdateAppContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\r
- in := new(ContextUpdateRequest)\r
- if err := dec(in); err != nil {\r
- return nil, err\r
- }\r
- if interceptor == nil {\r
- return srv.(ContextupdateServer).UpdateAppContext(ctx, in)\r
- }\r
- info := &grpc.UnaryServerInfo{\r
- Server: srv,\r
- FullMethod: "/contextupdate/UpdateAppContext",\r
- }\r
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {\r
- return srv.(ContextupdateServer).UpdateAppContext(ctx, req.(*ContextUpdateRequest))\r
- }\r
- return interceptor(ctx, in, info, handler)\r
-}\r
-\r
-var _Contextupdate_serviceDesc = grpc.ServiceDesc{\r
- ServiceName: "contextupdate",\r
- HandlerType: (*ContextupdateServer)(nil),\r
- Methods: []grpc.MethodDesc{\r
- {\r
- MethodName: "UpdateAppContext",\r
- Handler: _Contextupdate_UpdateAppContext_Handler,\r
- },\r
- },\r
- Streams: []grpc.StreamDesc{},\r
- Metadata: "contextupdate.proto",\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.24.0
+// protoc v3.11.4
+// source: contextupdate.proto
+
+package contextupdate
+
+import (
+ context "context"
+ proto "github.com/golang/protobuf/proto"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type ContextUpdateRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContext string `protobuf:"bytes,1,opt,name=app_context,json=appContext,proto3" json:"app_context,omitempty"`
+ IntentName string `protobuf:"bytes,2,opt,name=intent_name,json=intentName,proto3" json:"intent_name,omitempty"`
+}
+
+func (x *ContextUpdateRequest) Reset() {
+ *x = ContextUpdateRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_contextupdate_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ContextUpdateRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ContextUpdateRequest) ProtoMessage() {}
+
+func (x *ContextUpdateRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_contextupdate_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ContextUpdateRequest.ProtoReflect.Descriptor instead.
+func (*ContextUpdateRequest) Descriptor() ([]byte, []int) {
+ return file_contextupdate_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *ContextUpdateRequest) GetAppContext() string {
+ if x != nil {
+ return x.AppContext
+ }
+ return ""
+}
+
+func (x *ContextUpdateRequest) GetIntentName() string {
+ if x != nil {
+ return x.IntentName
+ }
+ return ""
+}
+
+type ContextUpdateResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AppContextUpdated bool `protobuf:"varint,1,opt,name=app_context_updated,json=appContextUpdated,proto3" json:"app_context_updated,omitempty"`
+ AppContextUpdateMessage string `protobuf:"bytes,2,opt,name=app_context_update_message,json=appContextUpdateMessage,proto3" json:"app_context_update_message,omitempty"`
+}
+
+func (x *ContextUpdateResponse) Reset() {
+ *x = ContextUpdateResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_contextupdate_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ContextUpdateResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ContextUpdateResponse) ProtoMessage() {}
+
+func (x *ContextUpdateResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_contextupdate_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ContextUpdateResponse.ProtoReflect.Descriptor instead.
+func (*ContextUpdateResponse) Descriptor() ([]byte, []int) {
+ return file_contextupdate_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ContextUpdateResponse) GetAppContextUpdated() bool {
+ if x != nil {
+ return x.AppContextUpdated
+ }
+ return false
+}
+
+func (x *ContextUpdateResponse) GetAppContextUpdateMessage() string {
+ if x != nil {
+ return x.AppContextUpdateMessage
+ }
+ return ""
+}
+
+var File_contextupdate_proto protoreflect.FileDescriptor
+
+var file_contextupdate_proto_rawDesc = []byte{
+ 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f,
+ 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+ 0x84, 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x70,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x70, 0x70,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
+ 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x61,
+ 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x54, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+ 0x74, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x41, 0x70, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x15, 0x2e, 0x43, 0x6f,
+ 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61,
+ 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62, 0x06, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_contextupdate_proto_rawDescOnce sync.Once
+ file_contextupdate_proto_rawDescData = file_contextupdate_proto_rawDesc
+)
+
+func file_contextupdate_proto_rawDescGZIP() []byte {
+ file_contextupdate_proto_rawDescOnce.Do(func() {
+ file_contextupdate_proto_rawDescData = protoimpl.X.CompressGZIP(file_contextupdate_proto_rawDescData)
+ })
+ return file_contextupdate_proto_rawDescData
+}
+
+var file_contextupdate_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_contextupdate_proto_goTypes = []interface{}{
+ (*ContextUpdateRequest)(nil), // 0: ContextUpdateRequest
+ (*ContextUpdateResponse)(nil), // 1: ContextUpdateResponse
+}
+var file_contextupdate_proto_depIdxs = []int32{
+ 0, // 0: contextupdate.UpdateAppContext:input_type -> ContextUpdateRequest
+ 1, // 1: contextupdate.UpdateAppContext:output_type -> ContextUpdateResponse
+ 1, // [1:2] is the sub-list for method output_type
+ 0, // [0:1] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_contextupdate_proto_init() }
+func file_contextupdate_proto_init() {
+ if File_contextupdate_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_contextupdate_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ContextUpdateRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_contextupdate_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ContextUpdateResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_contextupdate_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_contextupdate_proto_goTypes,
+ DependencyIndexes: file_contextupdate_proto_depIdxs,
+ MessageInfos: file_contextupdate_proto_msgTypes,
+ }.Build()
+ File_contextupdate_proto = out.File
+ file_contextupdate_proto_rawDesc = nil
+ file_contextupdate_proto_goTypes = nil
+ file_contextupdate_proto_depIdxs = nil
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConnInterface
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion6
+
+// ContextupdateClient is the client API for Contextupdate service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type ContextupdateClient interface {
+ // Controllers
+ UpdateAppContext(ctx context.Context, in *ContextUpdateRequest, opts ...grpc.CallOption) (*ContextUpdateResponse, error)
+}
+
+type contextupdateClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewContextupdateClient(cc grpc.ClientConnInterface) ContextupdateClient {
+ return &contextupdateClient{cc}
+}
+
+func (c *contextupdateClient) UpdateAppContext(ctx context.Context, in *ContextUpdateRequest, opts ...grpc.CallOption) (*ContextUpdateResponse, error) {
+ out := new(ContextUpdateResponse)
+ err := c.cc.Invoke(ctx, "/contextupdate/UpdateAppContext", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// ContextupdateServer is the server API for Contextupdate service.
+type ContextupdateServer interface {
+ // Controllers
+ UpdateAppContext(context.Context, *ContextUpdateRequest) (*ContextUpdateResponse, error)
+}
+
+// UnimplementedContextupdateServer can be embedded to have forward compatible implementations.
+type UnimplementedContextupdateServer struct {
+}
+
+func (*UnimplementedContextupdateServer) UpdateAppContext(context.Context, *ContextUpdateRequest) (*ContextUpdateResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UpdateAppContext not implemented")
+}
+
+func RegisterContextupdateServer(s *grpc.Server, srv ContextupdateServer) {
+ s.RegisterService(&_Contextupdate_serviceDesc, srv)
+}
+
+func _Contextupdate_UpdateAppContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ContextUpdateRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ContextupdateServer).UpdateAppContext(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/contextupdate/UpdateAppContext",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ContextupdateServer).UpdateAppContext(ctx, req.(*ContextUpdateRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _Contextupdate_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "contextupdate",
+ HandlerType: (*ContextupdateServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "UpdateAppContext",
+ Handler: _Contextupdate_UpdateAppContext_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "contextupdate.proto",
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-syntax = "proto3";\r
-\r
-service contextupdate {\r
- // Controllers\r
- rpc UpdateAppContext(ContextUpdateRequest) returns (ContextUpdateResponse) {\r
- }\r
-}\r
-\r
-message ContextUpdateRequest {\r
- string app_context = 1;\r
- string intent_name = 2;\r
-}\r
-\r
-message ContextUpdateResponse {\r
- bool app_context_updated = 1;\r
- string app_context_update_message = 2;\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+syntax = "proto3";
+
+service contextupdate {
+ // Controllers
+ rpc UpdateAppContext(ContextUpdateRequest) returns (ContextUpdateResponse) {
+ }
+}
+
+message ContextUpdateRequest {
+ string app_context = 1;
+ string intent_name = 2;
+}
+
+message ContextUpdateResponse {
+ bool app_context_updated = 1;
+ string app_context_update_message = 2;
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package contextupdateclient\r
-\r
-import (\r
- "context"\r
- "time"\r
-\r
- contextpb "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/contextupdate"\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// InvokeContextUpdate will make the grpc call to the specified controller\r
-// The controller will take the specified intentName and update the AppContext\r
-// appropriatly based on its operation as a placement or action controller.\r
-func InvokeContextUpdate(controllerName, intentName, appContextId string) error {\r
- var err error\r
- var rpcClient contextpb.ContextupdateClient\r
- var updateRes *contextpb.ContextUpdateResponse\r
- ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second)\r
- defer cancel()\r
-\r
- conn := rpc.GetRpcConn(controllerName)\r
-\r
- if conn != nil {\r
- rpcClient = contextpb.NewContextupdateClient(conn)\r
- updateReq := new(contextpb.ContextUpdateRequest)\r
- updateReq.AppContext = appContextId\r
- updateReq.IntentName = intentName\r
- updateRes, err = rpcClient.UpdateAppContext(ctx, updateReq)\r
- } else {\r
- return pkgerrors.Errorf("ContextUpdate Failed - Could not get ContextupdateClient: %v", controllerName)\r
- }\r
-\r
- if err == nil {\r
- if updateRes.AppContextUpdated {\r
- log.Info("ContextUpdate Passed", log.Fields{\r
- "Controller": controllerName,\r
- "Intent": intentName,\r
- "AppContext": appContextId,\r
- "Message": updateRes.AppContextUpdateMessage,\r
- })\r
- return nil\r
- } else {\r
- return pkgerrors.Errorf("ContextUpdate Failed: %v", updateRes.AppContextUpdateMessage)\r
- }\r
- }\r
- return err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package contextupdateclient
+
+import (
+ "context"
+ "time"
+
+ contextpb "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/contextupdate"
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// InvokeContextUpdate will make the grpc call to the specified controller
+// The controller will take the specified intentName and update the AppContext
+// appropriatly based on its operation as a placement or action controller.
+func InvokeContextUpdate(controllerName, intentName, appContextId string) error {
+ var err error
+ var rpcClient contextpb.ContextupdateClient
+ var updateRes *contextpb.ContextUpdateResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second)
+ defer cancel()
+
+ conn := rpc.GetRpcConn(controllerName)
+ if conn != nil {
+ rpcClient = contextpb.NewContextupdateClient(conn)
+ updateReq := new(contextpb.ContextUpdateRequest)
+ updateReq.AppContext = appContextId
+ updateReq.IntentName = intentName
+ updateRes, err = rpcClient.UpdateAppContext(ctx, updateReq)
+ } else {
+ return pkgerrors.Errorf("ContextUpdate Failed - Could not get ContextupdateClient: %v", controllerName)
+ }
+
+ if err == nil {
+ if updateRes.AppContextUpdated {
+ log.Info("ContextUpdate Passed", log.Fields{
+ "Controller": controllerName,
+ "Intent": intentName,
+ "AppContext": appContextId,
+ "Message": updateRes.AppContextUpdateMessage,
+ })
+ return nil
+ } else {
+ return pkgerrors.Errorf("ContextUpdate Failed: %v", updateRes.AppContextUpdateMessage)
+ }
+ }
+ return err
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package installappclient\r
-\r
-import (\r
- "context"\r
- "sync"\r
- "time"\r
-\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"\r
- installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const rsyncName = "rsync"\r
-\r
-/*\r
-RsyncInfo consists of rsyncName, hostName and portNumber.\r
-*/\r
-type RsyncInfo struct {\r
- RsyncName string\r
- hostName string\r
- portNumber int\r
-}\r
-\r
-var rsyncInfo RsyncInfo\r
-var mutex = &sync.Mutex{}\r
-\r
-// InitRsyncClient initializes connctions to the Resource Synchronizer service\r
-func initRsyncClient() bool {\r
- if (RsyncInfo{}) == rsyncInfo {\r
- mutex.Lock()\r
- defer mutex.Unlock()\r
- log.Error("RsyncInfo not set. InitRsyncClient failed", log.Fields{\r
- "Rsyncname": rsyncInfo.RsyncName,\r
- "Hostname": rsyncInfo.hostName,\r
- "PortNumber": rsyncInfo.portNumber,\r
- })\r
- return false\r
- }\r
- rpc.UpdateRpcConn(rsyncInfo.RsyncName, rsyncInfo.hostName, rsyncInfo.portNumber)\r
- return true\r
-}\r
-\r
-// NewRsyncInfo shall return a newly created RsyncInfo object\r
-func NewRsyncInfo(rName, h string, pN int) RsyncInfo {\r
- mutex.Lock()\r
- defer mutex.Unlock()\r
- rsyncInfo = RsyncInfo{RsyncName: rName, hostName: h, portNumber: pN}\r
- return rsyncInfo\r
-\r
-}\r
-\r
-// InvokeInstallApp will make the grpc call to the resource synchronizer\r
-// or rsync controller.\r
-// rsync will deploy the resources in the app context to the clusters as\r
-// prepared in the app context.\r
-func InvokeInstallApp(appContextId string) error {\r
- var err error\r
- var rpcClient installpb.InstallappClient\r
- var installRes *installpb.InstallAppResponse\r
- ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second)\r
- defer cancel()\r
-\r
- conn := rpc.GetRpcConn(rsyncName)\r
- if conn == nil {\r
- initRsyncClient()\r
- conn = rpc.GetRpcConn(rsyncName)\r
- }\r
-\r
- if conn != nil {\r
- rpcClient = installpb.NewInstallappClient(conn)\r
- installReq := new(installpb.InstallAppRequest)\r
- installReq.AppContext = appContextId\r
- installRes, err = rpcClient.InstallApp(ctx, installReq)\r
- if err == nil {\r
- log.Info("Response from InstappApp GRPC call", log.Fields{\r
- "Succeeded": installRes.AppContextInstalled,\r
- "Message": installRes.AppContextInstallMessage,\r
- })\r
- }\r
- } else {\r
- return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", "rsync")\r
- }\r
-\r
- if err == nil {\r
- if installRes.AppContextInstalled {\r
- log.Info("InstallApp Success", log.Fields{\r
- "AppContext": appContextId,\r
- "Message": installRes.AppContextInstallMessage,\r
- })\r
- return nil\r
- } else {\r
- return pkgerrors.Errorf("InstallApp Failed: %v", installRes.AppContextInstallMessage)\r
- }\r
- }\r
- return err\r
-}\r
-\r
-func InvokeUninstallApp(appContextId string) error {\r
- var err error\r
- var rpcClient installpb.InstallappClient\r
- var uninstallRes *installpb.UninstallAppResponse\r
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\r
- defer cancel()\r
-\r
- conn := rpc.GetRpcConn(rsyncName)\r
- if conn == nil {\r
- initRsyncClient()\r
- conn = rpc.GetRpcConn(rsyncName)\r
- }\r
-\r
- if conn != nil {\r
- rpcClient = installpb.NewInstallappClient(conn)\r
- uninstallReq := new(installpb.UninstallAppRequest)\r
- uninstallReq.AppContext = appContextId\r
- uninstallRes, err = rpcClient.UninstallApp(ctx, uninstallReq)\r
- if err == nil {\r
- log.Info("Response from UninstappApp GRPC call", log.Fields{\r
- "Succeeded": uninstallRes.AppContextUninstalled,\r
- "Message": uninstallRes.AppContextUninstallMessage,\r
- })\r
- }\r
- } else {\r
- return pkgerrors.Errorf("UninstallApp Failed - Could not get InstallAppClient: %v", "rsync")\r
- }\r
-\r
- if err == nil {\r
- if uninstallRes.AppContextUninstalled {\r
- log.Info("UninstallApp Success", log.Fields{\r
- "AppContext": appContextId,\r
- "Message": uninstallRes.AppContextUninstallMessage,\r
- })\r
- return nil\r
- } else {\r
- return pkgerrors.Errorf("UninstallApp Failed: %v", uninstallRes.AppContextUninstallMessage)\r
- }\r
- }\r
- return err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package installappclient
+
+import (
+ "context"
+ "sync"
+ "time"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
+ installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const rsyncName = "rsync"
+
+/*
+RsyncInfo consists of rsyncName, hostName and portNumber.
+*/
+type RsyncInfo struct {
+ RsyncName string
+ hostName string
+ portNumber int
+}
+
+var rsyncInfo RsyncInfo
+var mutex = &sync.Mutex{}
+
+type _testvars struct {
+ UseGrpcMock bool
+ InstallClient installpb.InstallappClient
+}
+
+var Testvars _testvars
+
+// InitRsyncClient initializes connctions to the Resource Synchronizer service
+func initRsyncClient() bool {
+ if (RsyncInfo{}) == rsyncInfo {
+ mutex.Lock()
+ defer mutex.Unlock()
+ log.Error("RsyncInfo not set. InitRsyncClient failed", log.Fields{
+ "Rsyncname": rsyncInfo.RsyncName,
+ "Hostname": rsyncInfo.hostName,
+ "PortNumber": rsyncInfo.portNumber,
+ })
+ return false
+ }
+ rpc.UpdateRpcConn(rsyncInfo.RsyncName, rsyncInfo.hostName, rsyncInfo.portNumber)
+ return true
+}
+
+// NewRsyncInfo shall return a newly created RsyncInfo object
+func NewRsyncInfo(rName, h string, pN int) RsyncInfo {
+ mutex.Lock()
+ defer mutex.Unlock()
+ rsyncInfo = RsyncInfo{RsyncName: rName, hostName: h, portNumber: pN}
+ return rsyncInfo
+
+}
+
+// InvokeInstallApp will make the grpc call to the resource synchronizer
+// or rsync controller.
+// rsync will deploy the resources in the app context to the clusters as
+// prepared in the app context.
+func InvokeInstallApp(appContextId string) error {
+ var err error
+ var rpcClient installpb.InstallappClient
+ var installRes *installpb.InstallAppResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second)
+ defer cancel()
+
+ // Unit test helper code
+ if Testvars.UseGrpcMock {
+ rpcClient = Testvars.InstallClient
+ installReq := new(installpb.InstallAppRequest)
+ installReq.AppContext = appContextId
+ installRes, err = rpcClient.InstallApp(ctx, installReq)
+ if err == nil {
+ log.Info("Response from InstappApp GRPC call", log.Fields{
+ "Succeeded": installRes.AppContextInstalled,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ }
+ return nil
+ }
+
+ conn := rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ initRsyncClient()
+ conn = rpc.GetRpcConn(rsyncName)
+ }
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ installReq := new(installpb.InstallAppRequest)
+ installReq.AppContext = appContextId
+ installRes, err = rpcClient.InstallApp(ctx, installReq)
+ if err == nil {
+ log.Info("Response from InstappApp GRPC call", log.Fields{
+ "Succeeded": installRes.AppContextInstalled,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", "rsync")
+ }
+
+ if err == nil {
+ if installRes.AppContextInstalled {
+ log.Info("InstallApp Success", log.Fields{
+ "AppContext": appContextId,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ return nil
+ } else {
+ return pkgerrors.Errorf("InstallApp Failed: %v", installRes.AppContextInstallMessage)
+ }
+ }
+ return err
+}
+
+func InvokeUninstallApp(appContextId string) error {
+ var err error
+ var rpcClient installpb.InstallappClient
+ var uninstallRes *installpb.UninstallAppResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ conn := rpc.GetRpcConn(rsyncName)
+ if conn == nil {
+ initRsyncClient()
+ conn = rpc.GetRpcConn(rsyncName)
+ }
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ uninstallReq := new(installpb.UninstallAppRequest)
+ uninstallReq.AppContext = appContextId
+ uninstallRes, err = rpcClient.UninstallApp(ctx, uninstallReq)
+ if err == nil {
+ log.Info("Response from UninstappApp GRPC call", log.Fields{
+ "Succeeded": uninstallRes.AppContextUninstalled,
+ "Message": uninstallRes.AppContextUninstallMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("UninstallApp Failed - Could not get InstallAppClient: %v", "rsync")
+ }
+
+ if err == nil {
+ if uninstallRes.AppContextUninstalled {
+ log.Info("UninstallApp Success", log.Fields{
+ "AppContext": appContextId,
+ "Message": uninstallRes.AppContextUninstallMessage,
+ })
+ return nil
+ } else {
+ return pkgerrors.Errorf("UninstallApp Failed: %v", uninstallRes.AppContextUninstallMessage)
+ }
+ }
+ return err
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package auth\r
-\r
-import (\r
- "crypto/tls"\r
- "crypto/x509"\r
- "encoding/base64"\r
- "encoding/pem"\r
- "io/ioutil"\r
- "log"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// GetTLSConfig initializes a tlsConfig using the CA's certificate\r
-// This config is then used to enable the server for mutual TLS\r
-func GetTLSConfig(caCertFile string, certFile string, keyFile string) (*tls.Config, error) {\r
-\r
- // Initialize tlsConfig once\r
- caCert, err := ioutil.ReadFile(caCertFile)\r
-\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read CA Cert file")\r
- }\r
-\r
- caCertPool := x509.NewCertPool()\r
- caCertPool.AppendCertsFromPEM(caCert)\r
-\r
- tlsConfig := &tls.Config{\r
- // Change to RequireAndVerify once we have mandatory certs\r
- ClientAuth: tls.VerifyClientCertIfGiven,\r
- ClientCAs: caCertPool,\r
- MinVersion: tls.VersionTLS12,\r
- }\r
-\r
- certPEMBlk, err := readPEMBlock(certFile)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read Cert File")\r
- }\r
-\r
- keyPEMBlk, err := readPEMBlock(keyFile)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read Key File")\r
- }\r
-\r
- tlsConfig.Certificates = make([]tls.Certificate, 1)\r
- tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlk, keyPEMBlk)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Load x509 cert and key")\r
- }\r
-\r
- tlsConfig.BuildNameToCertificate()\r
- return tlsConfig, nil\r
-}\r
-\r
-func readPEMBlock(filename string) ([]byte, error) {\r
-\r
- pemData, err := ioutil.ReadFile(filename)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read PEM File")\r
- }\r
-\r
- pemBlock, rest := pem.Decode(pemData)\r
- if len(rest) > 0 {\r
- log.Println("Pemfile has extra data")\r
- }\r
-\r
- if x509.IsEncryptedPEMBlock(pemBlock) {\r
- password, err := ioutil.ReadFile(filename + ".pass")\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Read Password File")\r
- }\r
-\r
- pByte, err := base64.StdEncoding.DecodeString(string(password))\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Decode PEM Password")\r
- }\r
-\r
- pemData, err = x509.DecryptPEMBlock(pemBlock, pByte)\r
- if err != nil {\r
- return nil, pkgerrors.Wrap(err, "Decrypt PEM Data")\r
- }\r
- var newPEMBlock pem.Block\r
- newPEMBlock.Type = pemBlock.Type\r
- newPEMBlock.Bytes = pemData\r
- // Converting back to PEM from DER data you get from\r
- // DecryptPEMBlock\r
- pemData = pem.EncodeToMemory(&newPEMBlock)\r
- }\r
-\r
- return pemData, nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package auth
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/base64"
+ "encoding/pem"
+ "io/ioutil"
+ "log"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// GetTLSConfig initializes a tlsConfig using the CA's certificate
+// This config is then used to enable the server for mutual TLS
+func GetTLSConfig(caCertFile string, certFile string, keyFile string) (*tls.Config, error) {
+
+ // Initialize tlsConfig once
+ caCert, err := ioutil.ReadFile(caCertFile)
+
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read CA Cert file")
+ }
+
+ caCertPool := x509.NewCertPool()
+ caCertPool.AppendCertsFromPEM(caCert)
+
+ tlsConfig := &tls.Config{
+ // Change to RequireAndVerify once we have mandatory certs
+ ClientAuth: tls.VerifyClientCertIfGiven,
+ ClientCAs: caCertPool,
+ MinVersion: tls.VersionTLS12,
+ }
+
+ certPEMBlk, err := readPEMBlock(certFile)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read Cert File")
+ }
+
+ keyPEMBlk, err := readPEMBlock(keyFile)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read Key File")
+ }
+
+ tlsConfig.Certificates = make([]tls.Certificate, 1)
+ tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlk, keyPEMBlk)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Load x509 cert and key")
+ }
+
+ tlsConfig.BuildNameToCertificate()
+ return tlsConfig, nil
+}
+
+func readPEMBlock(filename string) ([]byte, error) {
+
+ pemData, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read PEM File")
+ }
+
+ pemBlock, rest := pem.Decode(pemData)
+ if len(rest) > 0 {
+ log.Println("Pemfile has extra data")
+ }
+
+ if x509.IsEncryptedPEMBlock(pemBlock) {
+ password, err := ioutil.ReadFile(filename + ".pass")
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Read Password File")
+ }
+
+ pByte, err := base64.StdEncoding.DecodeString(string(password))
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Decode PEM Password")
+ }
+
+ pemData, err = x509.DecryptPEMBlock(pemBlock, pByte)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Decrypt PEM Data")
+ }
+ var newPEMBlock pem.Block
+ newPEMBlock.Type = pemBlock.Type
+ newPEMBlock.Bytes = pemData
+ // Converting back to PEM from DER data you get from
+ // DecryptPEMBlock
+ pemData = pem.EncodeToMemory(&newPEMBlock)
+ }
+
+ return pemData, nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package config\r
-\r
-import (\r
- "encoding/json"\r
- "log"\r
- "os"\r
- "reflect"\r
-)\r
-\r
-// Configuration loads up all the values that are used to configure\r
-// backend implementations\r
-type Configuration struct {\r
- CAFile string `json:"ca-file"`\r
- ServerCert string `json:"server-cert"`\r
- ServerKey string `json:"server-key"`\r
- Password string `json:"password"`\r
- DatabaseIP string `json:"database-ip"`\r
- DatabaseType string `json:"database-type"`\r
- PluginDir string `json:"plugin-dir"`\r
- EtcdIP string `json:"etcd-ip"`\r
- EtcdCert string `json:"etcd-cert"`\r
- EtcdKey string `json:"etcd-key"`\r
- EtcdCAFile string `json:"etcd-ca-file"`\r
- GrpcServerCert string `json:"grpc-server-cert"`\r
- GrpcServerKey string `json:"grpc-server-key"`\r
- GrpcCAFile string `json:"grpc-ca-file"`\r
- GrpcEnableTLS string `json:"grpc-enable-tls"`\r
- GrpcServerNameOverride string `json:"grpc-server-name-override"`\r
- ServicePort string `json:"service-port"`\r
- KubernetesLabelName string `json:"kubernetes-label-name"`\r
- LogLevel string `json:"log-level"`\r
- MaxRetries string `json:"max-retries"`\r
-}\r
-\r
-// Config is the structure that stores the configuration\r
-var gConfig *Configuration\r
-\r
-// readConfigFile reads the specified smsConfig file to setup some env variables\r
-func readConfigFile(file string) (*Configuration, error) {\r
- f, err := os.Open(file)\r
- if err != nil {\r
- return defaultConfiguration(), err\r
- }\r
- defer f.Close()\r
-\r
- // Setup some defaults here\r
- // If the json file has values in it, the defaults will be overwritten\r
- conf := defaultConfiguration()\r
-\r
- // Read the configuration from json file\r
- decoder := json.NewDecoder(f)\r
- decoder.DisallowUnknownFields()\r
- err = decoder.Decode(conf)\r
- if err != nil {\r
- return conf, err\r
- }\r
-\r
- return conf, nil\r
-}\r
-\r
-func defaultConfiguration() *Configuration {\r
- cwd, err := os.Getwd()\r
- if err != nil {\r
- log.Println("Error getting cwd. Using .")\r
- cwd = "."\r
- }\r
-\r
- return &Configuration{\r
- CAFile: "ca.cert",\r
- ServerCert: "server.cert",\r
- ServerKey: "server.key",\r
- Password: "",\r
- DatabaseIP: "127.0.0.1",\r
- DatabaseType: "mongo",\r
- PluginDir: cwd,\r
- EtcdIP: "127.0.0.1",\r
- EtcdCert: "",\r
- EtcdKey: "",\r
- EtcdCAFile: "",\r
- GrpcServerCert: "",\r
- GrpcServerKey: "",\r
- GrpcCAFile: "",\r
- GrpcEnableTLS: "disable",\r
- GrpcServerNameOverride: "",\r
- ServicePort: "9015",\r
- KubernetesLabelName: "orchestrator.io/rb-instance-id",\r
- LogLevel: "warn",\r
- MaxRetries: "",\r
- }\r
-}\r
-\r
-// GetConfiguration returns the configuration for the app.\r
-// It will try to load it if it is not already loaded.\r
-func GetConfiguration() *Configuration {\r
- if gConfig == nil {\r
- conf, err := readConfigFile("config.json")\r
- if err != nil {\r
- log.Println("Error loading config file: ", err)\r
- log.Println("Using defaults...")\r
- }\r
- gConfig = conf\r
- }\r
-\r
- return gConfig\r
-}\r
-\r
-// SetConfigValue sets a value in the configuration\r
-// This is mostly used to customize the application and\r
-// should be used carefully.\r
-func SetConfigValue(key string, value string) *Configuration {\r
- c := GetConfiguration()\r
- if value == "" || key == "" {\r
- return c\r
- }\r
-\r
- v := reflect.ValueOf(c).Elem()\r
- if v.Kind() == reflect.Struct {\r
- f := v.FieldByName(key)\r
- if f.IsValid() {\r
- if f.CanSet() {\r
- if f.Kind() == reflect.String {\r
- f.SetString(value)\r
- }\r
- }\r
- }\r
- }\r
- return c\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package config
+
+import (
+ "encoding/json"
+ "log"
+ "os"
+ "reflect"
+)
+
+// Configuration loads up all the values that are used to configure
+// backend implementations
+type Configuration struct {
+ CAFile string `json:"ca-file"`
+ ServerCert string `json:"server-cert"`
+ ServerKey string `json:"server-key"`
+ Password string `json:"password"`
+ DatabaseIP string `json:"database-ip"`
+ DatabaseType string `json:"database-type"`
+ PluginDir string `json:"plugin-dir"`
+ EtcdIP string `json:"etcd-ip"`
+ EtcdCert string `json:"etcd-cert"`
+ EtcdKey string `json:"etcd-key"`
+ EtcdCAFile string `json:"etcd-ca-file"`
+ GrpcServerCert string `json:"grpc-server-cert"`
+ GrpcServerKey string `json:"grpc-server-key"`
+ GrpcCAFile string `json:"grpc-ca-file"`
+ GrpcEnableTLS string `json:"grpc-enable-tls"`
+ GrpcServerNameOverride string `json:"grpc-server-name-override"`
+ ServicePort string `json:"service-port"`
+ KubernetesLabelName string `json:"kubernetes-label-name"`
+ LogLevel string `json:"log-level"`
+ MaxRetries string `json:"max-retries"`
+}
+
+// Config is the structure that stores the configuration
+var gConfig *Configuration
+
+// readConfigFile reads the specified smsConfig file to setup some env variables
+func readConfigFile(file string) (*Configuration, error) {
+ f, err := os.Open(file)
+ if err != nil {
+ return defaultConfiguration(), err
+ }
+ defer f.Close()
+
+ // Setup some defaults here
+ // If the json file has values in it, the defaults will be overwritten
+ conf := defaultConfiguration()
+
+ // Read the configuration from json file
+ decoder := json.NewDecoder(f)
+ decoder.DisallowUnknownFields()
+ err = decoder.Decode(conf)
+ if err != nil {
+ return conf, err
+ }
+
+ return conf, nil
+}
+
+func defaultConfiguration() *Configuration {
+ cwd, err := os.Getwd()
+ if err != nil {
+ log.Println("Error getting cwd. Using .")
+ cwd = "."
+ }
+
+ return &Configuration{
+ CAFile: "ca.cert",
+ ServerCert: "server.cert",
+ ServerKey: "server.key",
+ Password: "",
+ DatabaseIP: "127.0.0.1",
+ DatabaseType: "mongo",
+ PluginDir: cwd,
+ EtcdIP: "127.0.0.1",
+ EtcdCert: "",
+ EtcdKey: "",
+ EtcdCAFile: "",
+ GrpcServerCert: "",
+ GrpcServerKey: "",
+ GrpcCAFile: "",
+ GrpcEnableTLS: "disable",
+ GrpcServerNameOverride: "",
+ ServicePort: "9015",
+ KubernetesLabelName: "orchestrator.io/rb-instance-id",
+ LogLevel: "warn", // default log-level of all modules
+ MaxRetries: "",
+ }
+}
+
+// GetConfiguration returns the configuration for the app.
+// It will try to load it if it is not already loaded.
+func GetConfiguration() *Configuration {
+ if gConfig == nil {
+ conf, err := readConfigFile("config.json")
+ if err != nil {
+ log.Println("Error loading config file: ", err)
+ log.Println("Using defaults...")
+ }
+ gConfig = conf
+ }
+
+ return gConfig
+}
+
+// SetConfigValue sets a value in the configuration
+// This is mostly used to customize the application and
+// should be used carefully.
+func SetConfigValue(key string, value string) *Configuration {
+ c := GetConfiguration()
+ if value == "" || key == "" {
+ return c
+ }
+
+ v := reflect.ValueOf(c).Elem()
+ if v.Kind() == reflect.Struct {
+ f := v.FieldByName(key)
+ if f.IsValid() {
+ if f.CanSet() {
+ if f.Kind() == reflect.String {
+ f.SetString(value)
+ }
+ }
+ }
+ }
+ return c
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package config\r
-\r
-import (\r
- "testing"\r
-)\r
-\r
-func TestReadConfigurationFile(t *testing.T) {\r
- t.Run("Non Existent Configuration File", func(t *testing.T) {\r
- _, err := readConfigFile("filedoesnotexist.json")\r
- if err == nil {\r
- t.Fatal("ReadConfiguationFile: Expected Error, got nil")\r
- }\r
- })\r
-\r
- t.Run("Read Configuration File", func(t *testing.T) {\r
- conf, err := readConfigFile("../../../tests/configs/mock_config.json")\r
- if err != nil {\r
- t.Fatal("ReadConfigurationFile: Error reading file: ", err)\r
- }\r
- if conf.DatabaseType != "mock_db_test" {\r
- t.Fatal("ReadConfigurationFile: Incorrect entry read from file")\r
- }\r
- })\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package config
+
+import (
+ "testing"
+)
+
+func TestReadConfigurationFile(t *testing.T) {
+ t.Run("Non Existent Configuration File", func(t *testing.T) {
+ _, err := readConfigFile("filedoesnotexist.json")
+ if err == nil {
+ t.Fatal("ReadConfiguationFile: Expected Error, got nil")
+ }
+ })
+
+ t.Run("Read Configuration File", func(t *testing.T) {
+ conf, err := readConfigFile("../../../tests/configs/mock_config.json")
+ if err != nil {
+ t.Fatal("ReadConfigurationFile: Error reading file: ", err)
+ }
+ if conf.DatabaseType != "mock_db_test" {
+ t.Fatal("ReadConfigurationFile: Incorrect entry read from file")
+ }
+ })
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package contextdb\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// Db interface used to talk a concrete Database connection\r
-var Db ContextDb\r
-\r
-// ContextDb is an interface for accessing the context database\r
-type ContextDb interface {\r
- // Returns nil if db health is good\r
- HealthCheck() error\r
- // Puts Json Struct in db with key\r
- Put(key string, value interface{}) error\r
- // Delete k,v\r
- Delete(key string) error\r
- // Delete all keys in heirarchy\r
- DeleteAll(key string) error\r
- // Gets Json Struct from db\r
- Get(key string, value interface{}) error\r
- // Returns all keys with a prefix\r
- GetAllKeys(path string) ([]string, error)\r
-}\r
-\r
-// createContextDBClient creates the DB client\r
-func createContextDBClient(dbType string) error {\r
- var err error\r
- switch dbType {\r
- case "etcd":\r
- c := EtcdConfig{\r
- Endpoint: config.GetConfiguration().EtcdIP,\r
- CertFile: config.GetConfiguration().EtcdCert,\r
- KeyFile: config.GetConfiguration().EtcdKey,\r
- CAFile: config.GetConfiguration().EtcdCAFile,\r
- }\r
- Db, err = NewEtcdClient(nil, c)\r
- if err != nil {\r
- pkgerrors.Wrap(err, "Etcd Client Initialization failed with error")\r
- }\r
- default:\r
- return pkgerrors.New(dbType + "DB not supported")\r
- }\r
- return err\r
-}\r
-\r
-// InitializeContextDatabase sets up the connection to the\r
-// configured database to allow the application to talk to it.\r
-func InitializeContextDatabase() error {\r
- // Only support Etcd for now\r
- err := createContextDBClient("etcd")\r
- if err != nil {\r
- return pkgerrors.Cause(err)\r
- }\r
- err = Db.HealthCheck()\r
- if err != nil {\r
- return pkgerrors.Cause(err)\r
- }\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package contextdb
+
+import (
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// Db interface used to talk a concrete Database connection
+var Db ContextDb
+
+// ContextDb is an interface for accessing the context database
+type ContextDb interface {
+ // Returns nil if db health is good
+ HealthCheck() error
+ // Puts Json Struct in db with key
+ Put(key string, value interface{}) error
+ // Delete k,v
+ Delete(key string) error
+ // Delete all keys in heirarchy
+ DeleteAll(key string) error
+ // Gets Json Struct from db
+ Get(key string, value interface{}) error
+ // Returns all keys with a prefix
+ GetAllKeys(path string) ([]string, error)
+}
+
+// createContextDBClient creates the DB client
+func createContextDBClient(dbType string) error {
+ var err error
+ switch dbType {
+ case "etcd":
+ c := EtcdConfig{
+ Endpoint: config.GetConfiguration().EtcdIP,
+ CertFile: config.GetConfiguration().EtcdCert,
+ KeyFile: config.GetConfiguration().EtcdKey,
+ CAFile: config.GetConfiguration().EtcdCAFile,
+ }
+ Db, err = NewEtcdClient(nil, c)
+ if err != nil {
+ pkgerrors.Wrap(err, "Etcd Client Initialization failed with error")
+ }
+ default:
+ return pkgerrors.New(dbType + "DB not supported")
+ }
+ return err
+}
+
+// InitializeContextDatabase sets up the connection to the
+// configured database to allow the application to talk to it.
+func InitializeContextDatabase() error {
+ // Only support Etcd for now
+ err := createContextDBClient("etcd")
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+ err = Db.HealthCheck()
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package contextdb\r
-\r
-import (\r
- "context"\r
- "encoding/json"\r
- "os"\r
- "time"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
- "go.etcd.io/etcd/clientv3"\r
-)\r
-\r
-// EtcdConfig Configuration values needed for Etcd Client\r
-type EtcdConfig struct {\r
- Endpoint string\r
- CertFile string\r
- KeyFile string\r
- CAFile string\r
-}\r
-\r
-// EtcdClient for Etcd\r
-type EtcdClient struct {\r
- cli *clientv3.Client\r
- endpoint string\r
-}\r
-\r
-// Etcd For Mocking purposes\r
-type Etcd interface {\r
- Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error)\r
- Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error)\r
- Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error)\r
-}\r
-\r
-var getEtcd = func(e *EtcdClient) Etcd {\r
- return e.cli\r
-}\r
-\r
-// NewEtcdClient function initializes Etcd client\r
-func NewEtcdClient(store *clientv3.Client, c EtcdConfig) (ContextDb, error) {\r
- var endpoint string\r
- if store == nil {\r
- endpoint = "http://" + c.Endpoint + ":2379"\r
-\r
- etcdClient := clientv3.Config{\r
- Endpoints: []string{endpoint},\r
- DialTimeout: 5 * time.Second,\r
- }\r
- if len(os.Getenv("CONTEXTDB_EMCO_USERNAME")) > 0 && len(os.Getenv("CONTEXTDB_EMCO_PASSWORD")) > 0 {\r
- etcdClient.Username = os.Getenv("CONTEXTDB_EMCO_USERNAME")\r
- etcdClient.Password = os.Getenv("CONTEXTDB_EMCO_PASSWORD")\r
- }\r
- var err error\r
- store, err = clientv3.New(etcdClient)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error creating etcd client: %s", err.Error())\r
- }\r
- }\r
-\r
- return &EtcdClient{\r
- cli: store,\r
- endpoint: endpoint,\r
- }, nil\r
-}\r
-\r
-// Put values in Etcd DB\r
-func (e *EtcdClient) Put(key string, value interface{}) error {\r
- cli := getEtcd(e)\r
- if cli == nil {\r
- return pkgerrors.Errorf("Etcd Client not initialized")\r
- }\r
- if key == "" {\r
- return pkgerrors.Errorf("Key is null")\r
- }\r
- if value == nil {\r
- return pkgerrors.Errorf("Value is nil")\r
- }\r
- v, err := json.Marshal(value)\r
- if err != nil {\r
- return pkgerrors.Errorf("Json Marshal error: %s", err.Error())\r
- }\r
- _, err = cli.Put(context.Background(), key, string(v))\r
- if err != nil {\r
- return pkgerrors.Errorf("Error creating etcd entry: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// Get values from Etcd DB and decodes from json\r
-func (e *EtcdClient) Get(key string, value interface{}) error {\r
- cli := getEtcd(e)\r
- if cli == nil {\r
- return pkgerrors.Errorf("Etcd Client not initialized")\r
- }\r
- if key == "" {\r
- return pkgerrors.Errorf("Key is null")\r
- }\r
- if value == nil {\r
- return pkgerrors.Errorf("Value is nil")\r
- }\r
- getResp, err := cli.Get(context.Background(), key)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())\r
- }\r
- if getResp.Count == 0 {\r
- return pkgerrors.Errorf("Key doesn't exist")\r
- }\r
- return json.Unmarshal(getResp.Kvs[0].Value, value)\r
-}\r
-\r
-// GetAllKeys values from Etcd DB\r
-func (e *EtcdClient) GetAllKeys(key string) ([]string, error) {\r
- cli := getEtcd(e)\r
- if cli == nil {\r
- return nil, pkgerrors.Errorf("Etcd Client not initialized")\r
- }\r
- getResp, err := cli.Get(context.Background(), key, clientv3.WithPrefix())\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())\r
- }\r
- if getResp.Count == 0 {\r
- return nil, pkgerrors.Errorf("Key doesn't exist")\r
- }\r
- var keys []string\r
- for _, ev := range getResp.Kvs {\r
- keys = append(keys, string(ev.Key))\r
- }\r
- return keys, nil\r
-}\r
-\r
-// DeleteAll keys from Etcd DB\r
-func (e *EtcdClient) DeleteAll(key string) error {\r
- cli := getEtcd(e)\r
- if cli == nil {\r
- return pkgerrors.Errorf("Etcd Client not initialized")\r
- }\r
- _, err := cli.Delete(context.Background(), key, clientv3.WithPrefix())\r
- if err != nil {\r
- return pkgerrors.Errorf("Delete failed etcd entry: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// Delete values from Etcd DB\r
-func (e *EtcdClient) Delete(key string) error {\r
- cli := getEtcd(e)\r
- if cli == nil {\r
- return pkgerrors.Errorf("Etcd Client not initialized")\r
- }\r
- _, err := cli.Delete(context.Background(), key)\r
- if err != nil {\r
- return pkgerrors.Errorf("Delete failed etcd entry: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// HealthCheck for checking health of the etcd cluster\r
-func (e *EtcdClient) HealthCheck() error {\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package contextdb
+
+import (
+ "context"
+ "encoding/json"
+ "os"
+ "time"
+
+ pkgerrors "github.com/pkg/errors"
+ "go.etcd.io/etcd/clientv3"
+)
+
+// EtcdConfig Configuration values needed for Etcd Client
+type EtcdConfig struct {
+ Endpoint string
+ CertFile string
+ KeyFile string
+ CAFile string
+}
+
+// EtcdClient for Etcd
+type EtcdClient struct {
+ cli *clientv3.Client
+ endpoint string
+}
+
+// Etcd For Mocking purposes
+type Etcd interface {
+ Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error)
+ Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error)
+ Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error)
+}
+
+var getEtcd = func(e *EtcdClient) Etcd {
+ return e.cli
+}
+
+// NewEtcdClient function initializes Etcd client
+func NewEtcdClient(store *clientv3.Client, c EtcdConfig) (ContextDb, error) {
+ var endpoint string
+ if store == nil {
+ endpoint = "http://" + c.Endpoint + ":2379"
+
+ etcdClient := clientv3.Config{
+ Endpoints: []string{endpoint},
+ DialTimeout: 5 * time.Second,
+ }
+ if len(os.Getenv("CONTEXTDB_EMCO_USERNAME")) > 0 && len(os.Getenv("CONTEXTDB_EMCO_PASSWORD")) > 0 {
+ etcdClient.Username = os.Getenv("CONTEXTDB_EMCO_USERNAME")
+ etcdClient.Password = os.Getenv("CONTEXTDB_EMCO_PASSWORD")
+ }
+ var err error
+ store, err = clientv3.New(etcdClient)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error creating etcd client: %s", err.Error())
+ }
+ }
+
+ return &EtcdClient{
+ cli: store,
+ endpoint: endpoint,
+ }, nil
+}
+
+// Put values in Etcd DB
+func (e *EtcdClient) Put(key string, value interface{}) error {
+ cli := getEtcd(e)
+ if cli == nil {
+ return pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ if key == "" {
+ return pkgerrors.Errorf("Key is null")
+ }
+ if value == nil {
+ return pkgerrors.Errorf("Value is nil")
+ }
+ v, err := json.Marshal(value)
+ if err != nil {
+ return pkgerrors.Errorf("Json Marshal error: %s", err.Error())
+ }
+ _, err = cli.Put(context.Background(), key, string(v))
+ if err != nil {
+ return pkgerrors.Errorf("Error creating etcd entry: %s", err.Error())
+ }
+ return nil
+}
+
+// Get values from Etcd DB and decodes from json
+func (e *EtcdClient) Get(key string, value interface{}) error {
+ cli := getEtcd(e)
+ if cli == nil {
+ return pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ if key == "" {
+ return pkgerrors.Errorf("Key is null")
+ }
+ if value == nil {
+ return pkgerrors.Errorf("Value is nil")
+ }
+ getResp, err := cli.Get(context.Background(), key)
+ if err != nil {
+ return pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())
+ }
+ if getResp.Count == 0 {
+ return pkgerrors.Errorf("Key doesn't exist")
+ }
+ return json.Unmarshal(getResp.Kvs[0].Value, value)
+}
+
+// GetAllKeys values from Etcd DB
+func (e *EtcdClient) GetAllKeys(key string) ([]string, error) {
+ cli := getEtcd(e)
+ if cli == nil {
+ return nil, pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ getResp, err := cli.Get(context.Background(), key, clientv3.WithPrefix())
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())
+ }
+ if getResp.Count == 0 {
+ return nil, pkgerrors.Errorf("Key doesn't exist")
+ }
+ var keys []string
+ for _, ev := range getResp.Kvs {
+ keys = append(keys, string(ev.Key))
+ }
+ return keys, nil
+}
+
+// DeleteAll keys from Etcd DB
+func (e *EtcdClient) DeleteAll(key string) error {
+ cli := getEtcd(e)
+ if cli == nil {
+ return pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ _, err := cli.Delete(context.Background(), key, clientv3.WithPrefix())
+ if err != nil {
+ return pkgerrors.Errorf("Delete failed etcd entry: %s", err.Error())
+ }
+ return nil
+}
+
+// Delete values from Etcd DB
+func (e *EtcdClient) Delete(key string) error {
+ cli := getEtcd(e)
+ if cli == nil {
+ return pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ _, err := cli.Delete(context.Background(), key)
+ if err != nil {
+ return pkgerrors.Errorf("Delete failed etcd entry: %s", err.Error())
+ }
+ return nil
+}
+
+// HealthCheck for checking health of the etcd cluster
+func (e *EtcdClient) HealthCheck() error {
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package contextdb\r
-\r
-import (\r
- "context"\r
- mvccpb "github.com/coreos/etcd/mvcc/mvccpb"\r
- pkgerrors "github.com/pkg/errors"\r
- "go.etcd.io/etcd/clientv3"\r
- "strings"\r
- "testing"\r
-)\r
-\r
-type kv struct {\r
- Key []byte\r
- Value []byte\r
-}\r
-\r
-// MockEtcdClient for mocking etcd\r
-type MockEtcdClient struct {\r
- Kvs []*mvccpb.KeyValue\r
- Count int64\r
- Err error\r
-}\r
-\r
-// Mocking only Single Value\r
-// Put function\r
-func (e *MockEtcdClient) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {\r
- var m mvccpb.KeyValue\r
- m.Key = []byte(key)\r
- m.Value = []byte(val)\r
- e.Count = e.Count + 1\r
- e.Kvs = append(e.Kvs, &m)\r
- return &clientv3.PutResponse{}, e.Err\r
-}\r
-\r
-// Get function\r
-func (e *MockEtcdClient) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {\r
- var g clientv3.GetResponse\r
- g.Kvs = e.Kvs\r
- g.Count = e.Count\r
- return &g, e.Err\r
-}\r
-\r
-// Delete function\r
-func (e *MockEtcdClient) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) {\r
- return &clientv3.DeleteResponse{}, e.Err\r
-}\r
-\r
-type testStruct struct {\r
- Name string `json:"name"`\r
- Num int `json:"num"`\r
-}\r
-\r
-// TestPut test Put\r
-func TestPut(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- mockEtcd *MockEtcdClient\r
- expectedError string\r
- key string\r
- value *testStruct\r
- }{\r
- {\r
- label: "Success Case",\r
- mockEtcd: &MockEtcdClient{},\r
- key: "test1",\r
- value: &testStruct{Name: "test", Num: 5},\r
- },\r
- {\r
- label: "Key is null",\r
- mockEtcd: &MockEtcdClient{},\r
- key: "",\r
- expectedError: "Key is null",\r
- },\r
- {\r
- label: "Value is nil",\r
- mockEtcd: &MockEtcdClient{},\r
- key: "test1",\r
- value: nil,\r
- expectedError: "Value is nil",\r
- },\r
- {\r
- label: "Error creating etcd entry",\r
- mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},\r
- key: "test1",\r
- value: &testStruct{Name: "test", Num: 5},\r
- expectedError: "Error creating etcd entry: DB Error",\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})\r
- getEtcd = func(e *EtcdClient) Etcd {\r
- return testCase.mockEtcd\r
- }\r
- err := cli.Put(testCase.key, testCase.value)\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Method returned an un-expected (%s)", err)\r
- }\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestGet(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- mockEtcd *MockEtcdClient\r
- expectedError string\r
- key string\r
- value *testStruct\r
- }{\r
- {\r
- label: "Key is null",\r
- mockEtcd: &MockEtcdClient{},\r
- key: "",\r
- value: nil,\r
- expectedError: "Key is null",\r
- },\r
- {\r
- label: "Key doesn't exist",\r
- mockEtcd: &MockEtcdClient{},\r
- key: "test1",\r
- value: &testStruct{},\r
- expectedError: "Key doesn't exist",\r
- },\r
- {\r
- label: "Error getting etcd entry",\r
- mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},\r
- key: "test1",\r
- value: &testStruct{},\r
- expectedError: "Error getting etcd entry: DB Error",\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})\r
- getEtcd = func(e *EtcdClient) Etcd {\r
- return testCase.mockEtcd\r
- }\r
- err := cli.Get(testCase.key, testCase.value)\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Method returned an un-expected (%s)", err)\r
- }\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestGetString(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- mockEtcd *MockEtcdClient\r
- expectedError string\r
- value string\r
- }{\r
- {\r
- label: "Success Case",\r
- mockEtcd: &MockEtcdClient{},\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})\r
- getEtcd = func(e *EtcdClient) Etcd {\r
- return testCase.mockEtcd\r
- }\r
- err := cli.Put("test", "test1")\r
- if err != nil {\r
- t.Error("Test failed", err)\r
- }\r
- var s string\r
- err = cli.Get("test", &s)\r
- if err != nil {\r
- t.Error("Test failed", err)\r
- }\r
- if "test1" != s {\r
- t.Error("Get Failed")\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestDelete(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- mockEtcd *MockEtcdClient\r
- expectedError string\r
- }{\r
- {\r
- label: "Success Case",\r
- mockEtcd: &MockEtcdClient{},\r
- },\r
- {\r
- label: "Delete failed etcd entry",\r
- mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},\r
- expectedError: "Delete failed etcd entry: DB Error",\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})\r
- getEtcd = func(e *EtcdClient) Etcd {\r
- return testCase.mockEtcd\r
- }\r
- err := cli.Delete("test")\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Method returned an un-expected (%s)", err)\r
- }\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestGetAll(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- mockEtcd *MockEtcdClient\r
- expectedError string\r
- }{\r
- {\r
- label: "Key doesn't exist",\r
- mockEtcd: &MockEtcdClient{},\r
- expectedError: "Key doesn't exist",\r
- },\r
- {\r
- label: "Error getting etcd entry",\r
- mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},\r
- expectedError: "Error getting etcd entry: DB Error",\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})\r
- getEtcd = func(e *EtcdClient) Etcd {\r
- return testCase.mockEtcd\r
- }\r
- _, err := cli.GetAllKeys("test")\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Method returned an un-expected (%s)", err)\r
- }\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package contextdb
+
+import (
+ "context"
+ pkgerrors "github.com/pkg/errors"
+ "go.etcd.io/etcd/clientv3"
+ mvccpb "go.etcd.io/etcd/mvcc/mvccpb"
+ "strings"
+ "testing"
+)
+
+type kv struct {
+ Key []byte
+ Value []byte
+}
+
+// MockEtcdClient for mocking etcd
+type MockEtcdClient struct {
+ Kvs []*mvccpb.KeyValue
+ Count int64
+ Err error
+}
+
+// Mocking only Single Value
+// Put function
+func (e *MockEtcdClient) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {
+ var m mvccpb.KeyValue
+ m.Key = []byte(key)
+ m.Value = []byte(val)
+ e.Count = e.Count + 1
+ e.Kvs = append(e.Kvs, &m)
+ return &clientv3.PutResponse{}, e.Err
+}
+
+// Get function
+func (e *MockEtcdClient) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {
+ var g clientv3.GetResponse
+ g.Kvs = e.Kvs
+ g.Count = e.Count
+ return &g, e.Err
+}
+
+// Delete function
+func (e *MockEtcdClient) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) {
+ return &clientv3.DeleteResponse{}, e.Err
+}
+
+type testStruct struct {
+ Name string `json:"name"`
+ Num int `json:"num"`
+}
+
+// TestPut test Put
+func TestPut(t *testing.T) {
+ testCases := []struct {
+ label string
+ mockEtcd *MockEtcdClient
+ expectedError string
+ key string
+ value *testStruct
+ }{
+ {
+ label: "Success Case",
+ mockEtcd: &MockEtcdClient{},
+ key: "test1",
+ value: &testStruct{Name: "test", Num: 5},
+ },
+ {
+ label: "Key is null",
+ mockEtcd: &MockEtcdClient{},
+ key: "",
+ expectedError: "Key is null",
+ },
+ {
+ label: "Value is nil",
+ mockEtcd: &MockEtcdClient{},
+ key: "test1",
+ value: nil,
+ expectedError: "Value is nil",
+ },
+ {
+ label: "Error creating etcd entry",
+ mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},
+ key: "test1",
+ value: &testStruct{Name: "test", Num: 5},
+ expectedError: "Error creating etcd entry: DB Error",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})
+ getEtcd = func(e *EtcdClient) Etcd {
+ return testCase.mockEtcd
+ }
+ err := cli.Put(testCase.key, testCase.value)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Method returned an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestGet(t *testing.T) {
+ testCases := []struct {
+ label string
+ mockEtcd *MockEtcdClient
+ expectedError string
+ key string
+ value *testStruct
+ }{
+ {
+ label: "Key is null",
+ mockEtcd: &MockEtcdClient{},
+ key: "",
+ value: nil,
+ expectedError: "Key is null",
+ },
+ {
+ label: "Key doesn't exist",
+ mockEtcd: &MockEtcdClient{},
+ key: "test1",
+ value: &testStruct{},
+ expectedError: "Key doesn't exist",
+ },
+ {
+ label: "Error getting etcd entry",
+ mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},
+ key: "test1",
+ value: &testStruct{},
+ expectedError: "Error getting etcd entry: DB Error",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})
+ getEtcd = func(e *EtcdClient) Etcd {
+ return testCase.mockEtcd
+ }
+ err := cli.Get(testCase.key, testCase.value)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Method returned an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestGetString(t *testing.T) {
+ testCases := []struct {
+ label string
+ mockEtcd *MockEtcdClient
+ expectedError string
+ value string
+ }{
+ {
+ label: "Success Case",
+ mockEtcd: &MockEtcdClient{},
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})
+ getEtcd = func(e *EtcdClient) Etcd {
+ return testCase.mockEtcd
+ }
+ err := cli.Put("test", "test1")
+ if err != nil {
+ t.Error("Test failed", err)
+ }
+ var s string
+ err = cli.Get("test", &s)
+ if err != nil {
+ t.Error("Test failed", err)
+ }
+ if "test1" != s {
+ t.Error("Get Failed")
+ }
+ })
+ }
+}
+
+func TestDelete(t *testing.T) {
+ testCases := []struct {
+ label string
+ mockEtcd *MockEtcdClient
+ expectedError string
+ }{
+ {
+ label: "Success Case",
+ mockEtcd: &MockEtcdClient{},
+ },
+ {
+ label: "Delete failed etcd entry",
+ mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},
+ expectedError: "Delete failed etcd entry: DB Error",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})
+ getEtcd = func(e *EtcdClient) Etcd {
+ return testCase.mockEtcd
+ }
+ err := cli.Delete("test")
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Method returned an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestGetAll(t *testing.T) {
+ testCases := []struct {
+ label string
+ mockEtcd *MockEtcdClient
+ expectedError string
+ }{
+ {
+ label: "Key doesn't exist",
+ mockEtcd: &MockEtcdClient{},
+ expectedError: "Key doesn't exist",
+ },
+ {
+ label: "Error getting etcd entry",
+ mockEtcd: &MockEtcdClient{Err: pkgerrors.New("DB Error")},
+ expectedError: "Error getting etcd entry: DB Error",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ cli, _ := NewEtcdClient(&clientv3.Client{}, EtcdConfig{})
+ getEtcd = func(e *EtcdClient) Etcd {
+ return testCase.mockEtcd
+ }
+ _, err := cli.GetAllKeys("test")
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Method returned an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package contextdb\r
-\r
-import (\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type MockEtcd struct {\r
- Items map[string]interface{}\r
- Err error\r
-}\r
-\r
-func (c *MockEtcd) Put(key string, value interface{}) error {\r
- if c.Items == nil {\r
- c.Items = make(map[string]interface{})\r
- }\r
- c.Items[key] = value\r
- return c.Err\r
-}\r
-\r
-func (c *MockEtcd) Get(key string, value interface{}) error {\r
- for kvKey, kvValue := range c.Items {\r
- if kvKey == key {\r
- value = kvValue\r
- return nil\r
- }\r
- }\r
- return pkgerrors.Errorf("Key doesn't exist")\r
-}\r
-\r
-func (c *MockEtcd) Delete(key string) error {\r
- delete(c.Items, key)\r
- return c.Err\r
-}\r
-\r
-func (c *MockEtcd) GetAllKeys(path string) ([]string, error) {\r
- var keys []string\r
- for k := range c.Items {\r
- keys = append(keys, string(k))\r
- }\r
- return keys, nil\r
-}\r
-\r
-func (e *MockEtcd) HealthCheck() error {\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2021 Intel Corporation
+
+package contextdb
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+type MockConDb struct {
+ Items []map[string][]byte
+ Err error
+}
+
+func (c *MockConDb) Put(key string, value interface{}) error {
+
+ var vg interface{}
+ err := c.Get(key, interface{}(&vg))
+ if vg != "" {
+ c.Delete(key)
+ }
+ d := make(map[string][]byte)
+ v, err := json.Marshal(value)
+ if err != nil {
+ fmt.Println("Error during json marshal")
+ }
+ d[key] = v
+ c.Items = append(c.Items, d)
+ return c.Err
+}
+func (c *MockConDb) HealthCheck() error {
+ return c.Err
+}
+func (c *MockConDb) Get(key string, value interface{}) error {
+ for _, item := range c.Items {
+ for k, v := range item {
+ if k == key {
+ err := json.Unmarshal([]byte(v), value)
+ if err != nil {
+ fmt.Println("Error during json unmarshal")
+ }
+ return c.Err
+ }
+ }
+ }
+ value = nil
+ return c.Err
+}
+func (c *MockConDb) GetAllKeys(path string) ([]string, error) {
+ n := 0
+ for _, item := range c.Items {
+ for k, _ := range item {
+ ok := strings.HasPrefix(k, path)
+ if ok {
+ n++
+ }
+ }
+ }
+ if n == 0 {
+ return nil, c.Err
+ }
+
+ retk := make([]string, n)
+
+ i := 0
+ for _, item := range c.Items {
+ for k, _ := range item {
+ ok := strings.HasPrefix(k, path)
+ if ok {
+ retk[i] = k
+ i++
+ }
+ }
+ }
+ return retk, c.Err
+}
+func (c *MockConDb) Delete(key string) error {
+ for i, item := range c.Items {
+ for k, _ := range item {
+ if k == key {
+ c.Items[i] = c.Items[len(c.Items)-1]
+ c.Items = c.Items[:len(c.Items)-1]
+ return c.Err
+ }
+ }
+ }
+ return c.Err
+}
+func (c *MockConDb) DeleteAll(key string) error {
+ for i, item := range c.Items {
+ for k, _ := range item {
+ ok := strings.HasPrefix(k, key)
+ if ok {
+ c.Items[i] = c.Items[len(c.Items)-1]
+ c.Items = c.Items[:len(c.Items)-1]
+ }
+ }
+ }
+ return c.Err
+}
-# Database Abstraction Layer\r
-\r
-This package contains implementations of the Database interface defined in `store.go`\r
-Any database can be used as the backend as long as the following interface is implemented;\r
-\r
-```go\r
-type Store interface {\r
- // Returns nil if db health is good\r
- HealthCheck() error\r
-\r
- // Unmarshal implements any unmarshaling needed for the database\r
- Unmarshal(inp []byte, out interface{}) error\r
-\r
- // Inserts and Updates a tag with key and also adds query fields if provided\r
- Insert(coll string, key Key, query interface{}, tag string, data interface{}) error\r
-\r
- // Find the document(s) with key and get the tag values from the document(s)\r
- Find(coll string, key Key, tag string) ([][]byte, error)\r
-\r
- // Removes the document(s) matching the key\r
- Remove(coll string, key Key) error\r
-}\r
-```\r
-\r
-With this interface multiple database types can be supported by providing backends.\r
-\r
-## Details on Mongo Implementation\r
-\r
-`mongo.go` implements the above interface using the `go.mongodb.org/mongo-driver` package.\r
-The code converts incoming binary data and creates a new document in the database.\r
-\r
-### Insert\r
-\r
-Arguments:\r
-```go\r
-collection string\r
-key interface\r
-query interface\r
-tag string\r
-data []byte\r
-```\r
-\r
-Insert function inserts the provided `data` into the `collection` as a document in MongoDB. `FindOneAndUpdate` mongo API is used to achieve this with the `upsert` option set to `true`. With this if the record doesn't exist it is created and if it exists it is updated with new data for the tag.\r
-\r
-Key and Query parameters are assumed to be json structures with each element as part of the key. Those key-value pairs are used as the key for the document.\r
-Internally this API takes all the fields in the Key structure and adds them as fields in the document. Query parameter works just like key and it is used to add additional fields to the document. \r
-\r
-With this key the document can be quried with Mongo `Find` function for both the key fields and Query fields.\r
-\r
-This API also adds another field called "Key" field to the document. The "Key" field is concatenation of the key part of the Key parameter. Internally this is used to figure out the type of the document.\r
-\r
-Assumption is that all the elememts of the key structure are strings.\r
-\r
-#### Example of Key Structure\r
-```go\r
-type CompositeAppKey struct {\r
- CompositeAppName string `json:"compositeappname"`\r
- Version string `json:"version"`\r
- Project string `json:"project"`\r
-}\r
-```\r
-#### Example of Key Values\r
-```go\r
-key := CompositeAppKey{\r
- CompositeAppName: "ca1",\r
- Version: "v1",\r
- Project: "testProject",\r
- }\r
-```\r
-\r
-#### Example of Query Structure\r
-```go\r
-type Query struct {\r
- Userdata1 string `json:"userdata1"`\r
-}\r
-```\r
-#### Example of Document store in MongoDB\r
-```json\r
-{\r
- "_id":"ObjectId(" "5e54c206f53ca130893c8020" ")",\r
- "compositeappname":"ca1",\r
- "project":"testProject",\r
- "version":"v1",\r
- "compositeAppmetadata":{\r
- "metadata":{\r
- "name":"ca1",\r
- "description":"Test ca",\r
- "userdata1":"Data1",\r
- "userdata2":"Data2"\r
- },\r
- "spec":{\r
- "version":"v1"\r
- }\r
- },\r
- "key":"{compositeappname,project,version,}"\r
-}\r
-```\r
-\r
-### Find\r
-\r
-Arguments:\r
-```go\r
-collection string\r
-key interface\r
-tag string\r
-```\r
-\r
-Find function return one or more tag data based on the Key value. If key has all the fields defined then an exact match is looked for based on the key passed in. \r
-If some of the field value in structure are empty strings then this function returns all the documents which have the same type. (ANY operation)\r
-\r
-#### Example of Exact Match based on fields Key Values\r
-```go\r
-key := CompositeAppKey{\r
- CompositeAppName: "ca1",\r
- Version: "v1",\r
- Project: "testProject",\r
- }\r
-```\r
-\r
-#### Example of Match based on some fields\r
-This example will return all the compositeApp under project testProject.\r
-```go\r
-key := CompositeAppKey{\r
- Project: "testProject",\r
- CompositeAppName: "",\r
- Version: "",\r
- \r
- }\r
-```\r
-\r
-NOTE: Key structure can be different from the original key and can include Query fields also. ANY operation is not supported for Query fields.\r
-\r
-### RemoveAll\r
-\r
-Arguments:\r
-```go\r
-collection string\r
-key interface\r
-```\r
-Similar to find. This will remove one or more documents based on the key structure.\r
-\r
-### Remove\r
-\r
-Arguments:\r
-```go\r
-collection string\r
-key interface\r
-```\r
-This will remove one document based on the key structure. If child refrences exist for the key then the document will not be removed.\r
-\r
-### Unmarshal\r
-\r
-Data in mongo is stored as `bson` which is a compressed form of `json`. We need mongo to convert the stored `bson` data to regular `json`\r
-that we can use in our code when returned.\r
-\r
-`bson.Unmarshal` API is used to achieve this.\r
-\r
-\r
-\r
+# SPDX-License-Identifier: Apache-2.0
+# Copyright (c) 2020 Intel Corporation
+
+# Database Abstraction Layer
+
+This package contains implementations of the Database interface defined in `store.go`
+Any database can be used as the backend as long as the following interface is implemented;
+
+```go
+type Store interface {
+ // Returns nil if db health is good
+ HealthCheck() error
+
+ // Unmarshal implements any unmarshaling needed for the database
+ Unmarshal(inp []byte, out interface{}) error
+
+ // Inserts and Updates a tag with key and also adds query fields if provided
+ Insert(coll string, key Key, query interface{}, tag string, data interface{}) error
+
+ // Find the document(s) with key and get the tag values from the document(s)
+ Find(coll string, key Key, tag string) ([][]byte, error)
+
+ // Removes the document(s) matching the key
+ Remove(coll string, key Key) error
+}
+```
+
+With this interface multiple database types can be supported by providing backends.
+
+## Details on Mongo Implementation
+
+`mongo.go` implements the above interface using the `go.mongodb.org/mongo-driver` package.
+The code converts incoming binary data and creates a new document in the database.
+
+### Insert
+
+Arguments:
+```go
+collection string
+key interface
+query interface
+tag string
+data []byte
+```
+
+Insert function inserts the provided `data` into the `collection` as a document in MongoDB. `FindOneAndUpdate` mongo API is used to achieve this with the `upsert` option set to `true`. With this if the record doesn't exist it is created and if it exists it is updated with new data for the tag.
+
+Key and Query parameters are assumed to be json structures with each element as part of the key. Those key-value pairs are used as the key for the document.
+Internally this API takes all the fields in the Key structure and adds them as fields in the document. Query parameter works just like key and it is used to add additional fields to the document.
+
+With this key the document can be quried with Mongo `Find` function for both the key fields and Query fields.
+
+This API also adds another field called "Key" field to the document. The "Key" field is concatenation of the key part of the Key parameter. Internally this is used to figure out the type of the document.
+
+Assumption is that all the elememts of the key structure are strings.
+
+#### Example of Key Structure
+```go
+type CompositeAppKey struct {
+ CompositeAppName string `json:"compositeappname"`
+ Version string `json:"version"`
+ Project string `json:"project"`
+}
+```
+#### Example of Key Values
+```go
+key := CompositeAppKey{
+ CompositeAppName: "ca1",
+ Version: "v1",
+ Project: "testProject",
+ }
+```
+
+#### Example of Query Structure
+```go
+type Query struct {
+ Userdata1 string `json:"userdata1"`
+}
+```
+#### Example of Document store in MongoDB
+```json
+{
+ "_id":"ObjectId(" "5e54c206f53ca130893c8020" ")",
+ "compositeappname":"ca1",
+ "project":"testProject",
+ "version":"v1",
+ "compositeAppmetadata":{
+ "metadata":{
+ "name":"ca1",
+ "description":"Test ca",
+ "userdata1":"Data1",
+ "userdata2":"Data2"
+ },
+ "spec":{
+ "version":"v1"
+ }
+ },
+ "key":"{compositeappname,project,version,}"
+}
+```
+
+### Find
+
+Arguments:
+```go
+collection string
+key interface
+tag string
+```
+
+Find function return one or more tag data based on the Key value. If key has all the fields defined then an exact match is looked for based on the key passed in.
+If some of the field value in structure are empty strings then this function returns all the documents which have the same type. (ANY operation)
+
+#### Example of Exact Match based on fields Key Values
+```go
+key := CompositeAppKey{
+ CompositeAppName: "ca1",
+ Version: "v1",
+ Project: "testProject",
+ }
+```
+
+#### Example of Match based on some fields
+This example will return all the compositeApp under project testProject.
+```go
+key := CompositeAppKey{
+ Project: "testProject",
+ CompositeAppName: "",
+ Version: "",
+
+ }
+```
+
+NOTE: Key structure can be different from the original key and can include Query fields also. ANY operation is not supported for Query fields.
+
+### RemoveAll
+
+Arguments:
+```go
+collection string
+key interface
+```
+Similar to find. This will remove one or more documents based on the key structure.
+
+### Remove
+
+Arguments:
+```go
+collection string
+key interface
+```
+This will remove one document based on the key structure. If child refrences exist for the key then the document will not be removed.
+
+### Unmarshal
+
+Data in mongo is stored as `bson` which is a compressed form of `json`. We need mongo to convert the stored `bson` data to regular `json`
+that we can use in our code when returned.
+
+`bson.Unmarshal` API is used to achieve this.
+
+
+
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "encoding/json"\r
- "fmt"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-type MockKey struct {\r
- Key string\r
-}\r
-\r
-func (m MockKey) String() string {\r
- return m.Key\r
-}\r
-\r
-//Creating an embedded interface via anonymous variable\r
-//This allows us to make mockDB satisfy the DatabaseConnection\r
-//interface even if we are not implementing all the methods in it\r
-type MockDB struct {\r
- Store\r
- Items map[string]map[string][]byte\r
- Err error\r
-}\r
-\r
-func (m *MockDB) HealthCheck() error {\r
- return m.Err\r
-}\r
-\r
-func (m *MockDB) Insert(table string, key Key, query interface{}, tag string, data interface{}) error {\r
- return m.Err\r
-}\r
-\r
-// MockDB uses simple JSON and not BSON\r
-func (m *MockDB) Unmarshal(inp []byte, out interface{}) error {\r
- err := json.Unmarshal(inp, out)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Unmarshaling json")\r
- }\r
- return nil\r
-}\r
-\r
-func (m *MockDB) Find(table string, key Key, tag string) ([][]byte, error) {\r
- if m.Err != nil {\r
- return nil, m.Err\r
- }\r
-\r
- str := fmt.Sprintf("%v", key)\r
- for k, v := range m.Items {\r
- if k == str {\r
-\r
- return [][]byte{v[tag]}, nil\r
- }\r
- }\r
-\r
- return nil, m.Err\r
-}\r
-\r
-func (m *MockDB) Remove(table string, key Key) error {\r
- return m.Err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "encoding/json"
+ "strings"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+type MockDB struct {
+ Items []map[string]map[string][]byte
+ Err error
+}
+
+func (m *MockDB) HealthCheck() error {
+ return m.Err
+}
+
+func (m *MockDB) Insert(table string, key Key, query interface{}, tag string, data interface{}) error {
+
+ i := make(map[string][]byte)
+ out, _ := json.Marshal(data)
+ i[tag] = out
+ e := make(map[string]map[string][]byte)
+ jkey, _ := json.Marshal(key)
+ e[string(jkey)] = i
+ m.Items = append(m.Items, e)
+ return m.Err
+}
+
+func (m *MockDB) Unmarshal(inp []byte, out interface{}) error {
+ err := json.Unmarshal(inp, out)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Unmarshaling json")
+ }
+ return nil
+}
+
+func (m *MockDB) Find(table string, key Key, tag string) ([][]byte, error) {
+
+ jkey, _ := json.Marshal(key)
+ str := (string(jkey))
+
+ var i int
+ var r [][]byte
+ i = 0
+ for _, item := range m.Items {
+ for k, _ := range item {
+ s := strings.Split(str, "\"\"}")
+ if len(s) == 2 {
+ ends := strings.TrimPrefix(k, s[0])
+ if ends != k && !strings.ContainsAny(ends, ",") && strings.HasSuffix(ends, "}") {
+ i++
+ }
+ } else {
+ if str == k {
+ break
+ }
+ }
+ }
+ }
+ if i > 0 {
+ r = make([][]byte, i)
+ } else {
+ r = nil
+ }
+ i = 0
+ for _, item := range m.Items {
+ for k, v := range item {
+ s := strings.Split(str, "\"\"}")
+ if len(s) == 2 {
+ ends := strings.TrimPrefix(k, s[0])
+ if ends != k && !strings.ContainsAny(ends, ",") && strings.HasSuffix(ends, "}") {
+ r[i] = v[tag]
+ i++
+ }
+ } else {
+ if str == k {
+ return [][]byte{v[tag]}, m.Err
+ }
+ }
+ }
+ }
+ if i > 0 {
+ return r, nil
+ } else {
+ if m.Err != nil {
+ return r, m.Err
+ } else {
+ return r, pkgerrors.New("Record not found")
+ }
+ }
+}
+
+func (m *MockDB) Remove(table string, key Key) error {
+ jkey, _ := json.Marshal(key)
+ str := (string(jkey))
+ for i, item := range m.Items {
+ for k, _ := range item {
+ if k == str {
+ m.Items[i] = m.Items[len(m.Items)-1]
+ m.Items = m.Items[:len(m.Items)-1]
+ return m.Err
+ }
+ }
+ }
+ return m.Err
+}
+
+func (m *MockDB) RemoveAll(table string, key Key) error {
+ return m.Err
+}
+
+func (m *MockDB) RemoveTag(table string, key Key, tag string) error {
+ return m.Err
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "encoding/json"\r
- "os"\r
- "sort"\r
-\r
- "golang.org/x/net/context"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
- "go.mongodb.org/mongo-driver/bson"\r
- "go.mongodb.org/mongo-driver/bson/primitive"\r
- "go.mongodb.org/mongo-driver/mongo"\r
- "go.mongodb.org/mongo-driver/mongo/options"\r
-)\r
-\r
-// MongoCollection defines the a subset of MongoDB operations\r
-// Note: This interface is defined mainly for mock testing\r
-type MongoCollection interface {\r
- InsertOne(ctx context.Context, document interface{},\r
- opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error)\r
- FindOne(ctx context.Context, filter interface{},\r
- opts ...*options.FindOneOptions) *mongo.SingleResult\r
- FindOneAndUpdate(ctx context.Context, filter interface{},\r
- update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult\r
- DeleteOne(ctx context.Context, filter interface{},\r
- opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)\r
- DeleteMany(ctx context.Context, filter interface{},\r
- opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)\r
- Find(ctx context.Context, filter interface{},\r
- opts ...*options.FindOptions) (*mongo.Cursor, error)\r
- UpdateOne(ctx context.Context, filter interface{}, update interface{},\r
- opts ...*options.UpdateOptions) (*mongo.UpdateResult, error)\r
- CountDocuments(ctx context.Context, filter interface{},\r
- opts ...*options.CountOptions) (int64, error)\r
-}\r
-\r
-// MongoStore is an implementation of the db.Store interface\r
-type MongoStore struct {\r
- db *mongo.Database\r
-}\r
-\r
-// This exists only for allowing us to mock the collection object\r
-// for testing purposes\r
-var getCollection = func(coll string, m *MongoStore) MongoCollection {\r
- return m.db.Collection(coll)\r
-}\r
-\r
-// This exists only for allowing us to mock the DecodeBytes function\r
-// Mainly because we cannot construct a SingleResult struct from our\r
-// tests. All fields in that struct are private.\r
-var decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {\r
- return sr.DecodeBytes()\r
-}\r
-\r
-// These exists only for allowing us to mock the cursor.Next function\r
-// Mainly because we cannot construct a mongo.Cursor struct from our\r
-// tests. All fields in that struct are private and there is no public\r
-// constructor method.\r
-var cursorNext = func(ctx context.Context, cursor *mongo.Cursor) bool {\r
- return cursor.Next(ctx)\r
-}\r
-var cursorClose = func(ctx context.Context, cursor *mongo.Cursor) error {\r
- return cursor.Close(ctx)\r
-}\r
-\r
-// NewMongoStore initializes a Mongo Database with the name provided\r
-// If a database with that name exists, it will be returned\r
-func NewMongoStore(name string, store *mongo.Database) (Store, error) {\r
- if store == nil {\r
- ip := "mongodb://" + config.GetConfiguration().DatabaseIP + ":27017"\r
- clientOptions := options.Client()\r
- clientOptions.ApplyURI(ip)\r
- if len(os.Getenv("DB_EMCO_USERNAME")) > 0 && len(os.Getenv("DB_EMCO_PASSWORD")) > 0 {\r
- clientOptions.SetAuth(options.Credential{\r
- AuthMechanism: "SCRAM-SHA-256",\r
- AuthSource: "mco",\r
- Username: os.Getenv("DB_EMCO_USERNAME"),\r
- Password: os.Getenv("DB_EMCO_PASSWORD")})\r
- }\r
- mongoClient, err := mongo.NewClient(clientOptions)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- err = mongoClient.Connect(context.Background())\r
- if err != nil {\r
- return nil, err\r
- }\r
- store = mongoClient.Database(name)\r
- }\r
-\r
- return &MongoStore{\r
- db: store,\r
- }, nil\r
-}\r
-\r
-// HealthCheck verifies if the database is up and running\r
-func (m *MongoStore) HealthCheck() error {\r
-\r
- _, err := decodeBytes(m.db.RunCommand(context.Background(), bson.D{{"serverStatus", 1}}))\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Error getting server status")\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// validateParams checks to see if any parameters are empty\r
-func (m *MongoStore) validateParams(args ...interface{}) bool {\r
- for _, v := range args {\r
- val, ok := v.(string)\r
- if ok {\r
- if val == "" {\r
- return false\r
- }\r
- } else {\r
- if v == nil {\r
- return false\r
- }\r
- }\r
- }\r
-\r
- return true\r
-}\r
-\r
-// Unmarshal implements an unmarshaler for bson data that\r
-// is produced from the mongo database\r
-func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error {\r
- err := bson.Unmarshal(inp, out)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Unmarshaling bson")\r
- }\r
- return nil\r
-}\r
-\r
-func (m *MongoStore) findFilter(key Key) (primitive.M, error) {\r
-\r
- var bsonMap bson.M\r
- st, err := json.Marshal(key)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())\r
- }\r
- err = json.Unmarshal([]byte(st), &bsonMap)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())\r
- }\r
- filter := bson.M{\r
- "$and": []bson.M{bsonMap},\r
- }\r
- return filter, nil\r
-}\r
-\r
-func (m *MongoStore) findFilterWithKey(key Key) (primitive.M, error) {\r
-\r
- var bsonMap bson.M\r
- var bsonMapFinal bson.M\r
- st, err := json.Marshal(key)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())\r
- }\r
- err = json.Unmarshal([]byte(st), &bsonMap)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())\r
- }\r
- bsonMapFinal = make(bson.M)\r
- for k, v := range bsonMap {\r
- if v == "" {\r
- if _, ok := bsonMapFinal["key"]; !ok {\r
- // add type of key to filter\r
- s, err := m.createKeyField(key)\r
- if err != nil {\r
- return primitive.M{}, err\r
- }\r
- bsonMapFinal["key"] = s\r
- }\r
- } else {\r
- bsonMapFinal[k] = v\r
- }\r
- }\r
- filter := bson.M{\r
- "$and": []bson.M{bsonMapFinal},\r
- }\r
- return filter, nil\r
-}\r
-\r
-func (m *MongoStore) updateFilter(key interface{}) (primitive.M, error) {\r
-\r
- var n map[string]string\r
- st, err := json.Marshal(key)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())\r
- }\r
- err = json.Unmarshal([]byte(st), &n)\r
- if err != nil {\r
- return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())\r
- }\r
- p := make(bson.M, len(n))\r
- for k, v := range n {\r
- p[k] = v\r
- }\r
- filter := bson.M{\r
- "$set": p,\r
- }\r
- return filter, nil\r
-}\r
-\r
-func (m *MongoStore) createKeyField(key interface{}) (string, error) {\r
-\r
- var n map[string]string\r
- st, err := json.Marshal(key)\r
- if err != nil {\r
- return "", pkgerrors.Errorf("Error Marshalling key: %s", err.Error())\r
- }\r
- err = json.Unmarshal([]byte(st), &n)\r
- if err != nil {\r
- return "", pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())\r
- }\r
- var keys []string\r
- for k := range n {\r
- keys = append(keys, k)\r
- }\r
- sort.Strings(keys)\r
- s := "{"\r
- for _, k := range keys {\r
- s = s + k + ","\r
- }\r
- s = s + "}"\r
- return s, nil\r
-}\r
-\r
-// Insert is used to insert/add element to a document\r
-func (m *MongoStore) Insert(coll string, key Key, query interface{}, tag string, data interface{}) error {\r
- if data == nil || !m.validateParams(coll, key, tag) {\r
- return pkgerrors.New("No Data to store")\r
- }\r
-\r
- c := getCollection(coll, m)\r
- ctx := context.Background()\r
-\r
- filter, err := m.findFilter(key)\r
- if err != nil {\r
- return err\r
- }\r
- // Create and add key tag\r
- s, err := m.createKeyField(key)\r
- if err != nil {\r
- return err\r
- }\r
- _, err = decodeBytes(\r
- c.FindOneAndUpdate(\r
- ctx,\r
- filter,\r
- bson.D{\r
- {"$set", bson.D{\r
- {tag, data},\r
- {"key", s},\r
- }},\r
- },\r
- options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)))\r
-\r
- if err != nil {\r
- return pkgerrors.Errorf("Error updating master table: %s", err.Error())\r
- }\r
- if query == nil {\r
- return nil\r
- }\r
-\r
- // Update to add Query fields\r
- update, err := m.updateFilter(query)\r
- if err != nil {\r
- return err\r
- }\r
- _, err = c.UpdateOne(\r
- ctx,\r
- filter,\r
- update)\r
-\r
- if err != nil {\r
- return pkgerrors.Errorf("Error updating Query fields: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// Find method returns the data stored for this key and for this particular tag\r
-func (m *MongoStore) Find(coll string, key Key, tag string) ([][]byte, error) {\r
-\r
- //result, err := m.findInternal(coll, key, tag, "")\r
- //return result, err\r
- if !m.validateParams(coll, key, tag) {\r
- return nil, pkgerrors.New("Mandatory fields are missing")\r
- }\r
-\r
- c := getCollection(coll, m)\r
- ctx := context.Background()\r
-\r
- filter, err := m.findFilterWithKey(key)\r
- if err != nil {\r
- return nil, err\r
- }\r
- // Find only the field requested\r
- projection := bson.D{\r
- {tag, 1},\r
- {"_id", 0},\r
- }\r
-\r
- cursor, err := c.Find(context.Background(), filter, options.Find().SetProjection(projection))\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error finding element: %s", err.Error())\r
- }\r
- defer cursorClose(ctx, cursor)\r
- var data []byte\r
- var result [][]byte\r
- for cursorNext(ctx, cursor) {\r
- d := cursor.Current\r
- switch d.Lookup(tag).Type {\r
- case bson.TypeString:\r
- data = []byte(d.Lookup(tag).StringValue())\r
- default:\r
- r, err := d.LookupErr(tag)\r
- if err != nil {\r
- // Throw error if not found\r
- pkgerrors.New("Unable to read data ")\r
- }\r
- data = r.Value\r
- }\r
- result = append(result, data)\r
- }\r
- return result, nil\r
-}\r
-\r
-// RemoveAll method to removes all the documet matching key\r
-func (m *MongoStore) RemoveAll(coll string, key Key) error {\r
- if !m.validateParams(coll, key) {\r
- return pkgerrors.New("Mandatory fields are missing")\r
- }\r
- c := getCollection(coll, m)\r
- ctx := context.Background()\r
- filter, err := m.findFilterWithKey(key)\r
- if err != nil {\r
- return err\r
- }\r
- _, err = c.DeleteMany(ctx, filter)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error Deleting from database: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// Remove method to remove the documet by key if no child references\r
-func (m *MongoStore) Remove(coll string, key Key) error {\r
- if !m.validateParams(coll, key) {\r
- return pkgerrors.New("Mandatory fields are missing")\r
- }\r
- c := getCollection(coll, m)\r
- ctx := context.Background()\r
- filter, err := m.findFilter(key)\r
- if err != nil {\r
- return err\r
- }\r
- count, err := c.CountDocuments(context.Background(), filter)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error finding: %s", err.Error())\r
- }\r
- if count > 1 {\r
- return pkgerrors.Errorf("Can't delete parent without deleting child references first")\r
- }\r
- _, err = c.DeleteOne(ctx, filter)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error Deleting from database: %s", err.Error())\r
- }\r
- return nil\r
-}\r
-\r
-// RemoveTag is used to remove an element from a document\r
-func (m *MongoStore) RemoveTag(coll string, key Key, tag string) error {\r
- c := getCollection(coll, m)\r
- ctx := context.Background()\r
-\r
- filter, err := m.findFilter(key)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- _, err = decodeBytes(\r
- c.FindOneAndUpdate(\r
- ctx,\r
- filter,\r
- bson.D{\r
- {"$unset", bson.D{\r
- {tag, ""},\r
- }},\r
- },\r
- options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)))\r
-\r
- if err != nil {\r
- return pkgerrors.Errorf("Error removing tag: %s", err.Error())\r
- }\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "encoding/json"
+ "os"
+ "sort"
+
+ "golang.org/x/net/context"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+
+ pkgerrors "github.com/pkg/errors"
+ "go.mongodb.org/mongo-driver/bson"
+ "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/mongo"
+ "go.mongodb.org/mongo-driver/mongo/options"
+)
+
+// MongoCollection defines the a subset of MongoDB operations
+// Note: This interface is defined mainly for mock testing
+type MongoCollection interface {
+ InsertOne(ctx context.Context, document interface{},
+ opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error)
+ FindOne(ctx context.Context, filter interface{},
+ opts ...*options.FindOneOptions) *mongo.SingleResult
+ FindOneAndUpdate(ctx context.Context, filter interface{},
+ update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult
+ DeleteOne(ctx context.Context, filter interface{},
+ opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
+ DeleteMany(ctx context.Context, filter interface{},
+ opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
+ Find(ctx context.Context, filter interface{},
+ opts ...*options.FindOptions) (*mongo.Cursor, error)
+ UpdateOne(ctx context.Context, filter interface{}, update interface{},
+ opts ...*options.UpdateOptions) (*mongo.UpdateResult, error)
+ CountDocuments(ctx context.Context, filter interface{},
+ opts ...*options.CountOptions) (int64, error)
+}
+
+// MongoStore is an implementation of the db.Store interface
+type MongoStore struct {
+ db *mongo.Database
+}
+
+// This exists only for allowing us to mock the collection object
+// for testing purposes
+var getCollection = func(coll string, m *MongoStore) MongoCollection {
+ return m.db.Collection(coll)
+}
+
+// This exists only for allowing us to mock the DecodeBytes function
+// Mainly because we cannot construct a SingleResult struct from our
+// tests. All fields in that struct are private.
+var decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {
+ return sr.DecodeBytes()
+}
+
+// These exists only for allowing us to mock the cursor.Next function
+// Mainly because we cannot construct a mongo.Cursor struct from our
+// tests. All fields in that struct are private and there is no public
+// constructor method.
+var cursorNext = func(ctx context.Context, cursor *mongo.Cursor) bool {
+ return cursor.Next(ctx)
+}
+var cursorClose = func(ctx context.Context, cursor *mongo.Cursor) error {
+ return cursor.Close(ctx)
+}
+
+// NewMongoStore initializes a Mongo Database with the name provided
+// If a database with that name exists, it will be returned
+func NewMongoStore(name string, store *mongo.Database) (Store, error) {
+ if store == nil {
+ ip := "mongodb://" + config.GetConfiguration().DatabaseIP + ":27017"
+ clientOptions := options.Client()
+ clientOptions.ApplyURI(ip)
+ if len(os.Getenv("DB_EMCO_USERNAME")) > 0 && len(os.Getenv("DB_EMCO_PASSWORD")) > 0 {
+ clientOptions.SetAuth(options.Credential{
+ AuthMechanism: "SCRAM-SHA-256",
+ AuthSource: "mco",
+ Username: os.Getenv("DB_EMCO_USERNAME"),
+ Password: os.Getenv("DB_EMCO_PASSWORD")})
+ }
+ mongoClient, err := mongo.NewClient(clientOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ err = mongoClient.Connect(context.Background())
+ if err != nil {
+ return nil, err
+ }
+ store = mongoClient.Database(name)
+ }
+
+ return &MongoStore{
+ db: store,
+ }, nil
+}
+
+// HealthCheck verifies if the database is up and running
+func (m *MongoStore) HealthCheck() error {
+
+ _, err := decodeBytes(m.db.RunCommand(context.Background(), bson.D{{"serverStatus", 1}}))
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error getting server status")
+ }
+
+ return nil
+}
+
+// validateParams checks to see if any parameters are empty
+func (m *MongoStore) validateParams(args ...interface{}) bool {
+ for _, v := range args {
+ val, ok := v.(string)
+ if ok {
+ if val == "" {
+ return false
+ }
+ } else {
+ if v == nil {
+ return false
+ }
+ }
+ }
+
+ return true
+}
+
+// Unmarshal implements an unmarshaler for bson data that
+// is produced from the mongo database
+func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error {
+ err := bson.Unmarshal(inp, out)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Unmarshaling bson")
+ }
+ return nil
+}
+
+func (m *MongoStore) findFilter(key Key) (primitive.M, error) {
+
+ var bsonMap bson.M
+ st, err := json.Marshal(key)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())
+ }
+ err = json.Unmarshal([]byte(st), &bsonMap)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())
+ }
+ filter := bson.M{
+ "$and": []bson.M{bsonMap},
+ }
+ return filter, nil
+}
+
+func (m *MongoStore) findFilterWithKey(key Key) (primitive.M, error) {
+
+ var bsonMap bson.M
+ var bsonMapFinal bson.M
+ st, err := json.Marshal(key)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())
+ }
+ err = json.Unmarshal([]byte(st), &bsonMap)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())
+ }
+ bsonMapFinal = make(bson.M)
+ for k, v := range bsonMap {
+ if v == "" {
+ if _, ok := bsonMapFinal["key"]; !ok {
+ // add type of key to filter
+ s, err := m.createKeyField(key)
+ if err != nil {
+ return primitive.M{}, err
+ }
+ bsonMapFinal["key"] = s
+ }
+ } else {
+ bsonMapFinal[k] = v
+ }
+ }
+ filter := bson.M{
+ "$and": []bson.M{bsonMapFinal},
+ }
+ return filter, nil
+}
+
+func (m *MongoStore) updateFilter(key interface{}) (primitive.M, error) {
+
+ var n map[string]string
+ st, err := json.Marshal(key)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Marshalling key: %s", err.Error())
+ }
+ err = json.Unmarshal([]byte(st), &n)
+ if err != nil {
+ return primitive.M{}, pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())
+ }
+ p := make(bson.M, len(n))
+ for k, v := range n {
+ p[k] = v
+ }
+ filter := bson.M{
+ "$set": p,
+ }
+ return filter, nil
+}
+
+func (m *MongoStore) createKeyField(key interface{}) (string, error) {
+
+ var n map[string]string
+ st, err := json.Marshal(key)
+ if err != nil {
+ return "", pkgerrors.Errorf("Error Marshalling key: %s", err.Error())
+ }
+ err = json.Unmarshal([]byte(st), &n)
+ if err != nil {
+ return "", pkgerrors.Errorf("Error Unmarshalling key to Bson Map: %s", err.Error())
+ }
+ var keys []string
+ for k := range n {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ s := "{"
+ for _, k := range keys {
+ s = s + k + ","
+ }
+ s = s + "}"
+ return s, nil
+}
+
+// Insert is used to insert/add element to a document
+func (m *MongoStore) Insert(coll string, key Key, query interface{}, tag string, data interface{}) error {
+ if data == nil || !m.validateParams(coll, key, tag) {
+ return pkgerrors.New("No Data to store")
+ }
+
+ c := getCollection(coll, m)
+ ctx := context.Background()
+
+ filter, err := m.findFilter(key)
+ if err != nil {
+ return err
+ }
+ // Create and add key tag
+ s, err := m.createKeyField(key)
+ if err != nil {
+ return err
+ }
+ _, err = decodeBytes(
+ c.FindOneAndUpdate(
+ ctx,
+ filter,
+ bson.D{
+ {"$set", bson.D{
+ {tag, data},
+ {"key", s},
+ }},
+ },
+ options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)))
+
+ if err != nil {
+ return pkgerrors.Errorf("Error updating master table: %s", err.Error())
+ }
+ if query == nil {
+ return nil
+ }
+
+ // Update to add Query fields
+ update, err := m.updateFilter(query)
+ if err != nil {
+ return err
+ }
+ _, err = c.UpdateOne(
+ ctx,
+ filter,
+ update)
+
+ if err != nil {
+ return pkgerrors.Errorf("Error updating Query fields: %s", err.Error())
+ }
+ return nil
+}
+
+// Find method returns the data stored for this key and for this particular tag
+func (m *MongoStore) Find(coll string, key Key, tag string) ([][]byte, error) {
+
+ //result, err := m.findInternal(coll, key, tag, "")
+ //return result, err
+ if !m.validateParams(coll, key, tag) {
+ return nil, pkgerrors.New("Mandatory fields are missing")
+ }
+
+ c := getCollection(coll, m)
+ ctx := context.Background()
+
+ filter, err := m.findFilterWithKey(key)
+ if err != nil {
+ return nil, err
+ }
+ // Find only the field requested
+ projection := bson.D{
+ {tag, 1},
+ {"_id", 0},
+ }
+
+ cursor, err := c.Find(context.Background(), filter, options.Find().SetProjection(projection))
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error finding element: %s", err.Error())
+ }
+ defer cursorClose(ctx, cursor)
+ var data []byte
+ var result [][]byte
+ for cursorNext(ctx, cursor) {
+ d := cursor.Current
+ switch d.Lookup(tag).Type {
+ case bson.TypeString:
+ data = []byte(d.Lookup(tag).StringValue())
+ default:
+ r, err := d.LookupErr(tag)
+ if err != nil {
+ // Throw error if not found
+ pkgerrors.New("Unable to read data ")
+ }
+ data = r.Value
+ }
+ result = append(result, data)
+ }
+ return result, nil
+}
+
+// RemoveAll method to removes all the documet matching key
+func (m *MongoStore) RemoveAll(coll string, key Key) error {
+ if !m.validateParams(coll, key) {
+ return pkgerrors.New("Mandatory fields are missing")
+ }
+ c := getCollection(coll, m)
+ ctx := context.Background()
+ filter, err := m.findFilterWithKey(key)
+ if err != nil {
+ return err
+ }
+ _, err = c.DeleteMany(ctx, filter)
+ if err != nil {
+ return pkgerrors.Errorf("Error Deleting from database: %s", err.Error())
+ }
+ return nil
+}
+
+// Remove method to remove the documet by key if no child references
+func (m *MongoStore) Remove(coll string, key Key) error {
+ if !m.validateParams(coll, key) {
+ return pkgerrors.New("Mandatory fields are missing")
+ }
+ c := getCollection(coll, m)
+ ctx := context.Background()
+ filter, err := m.findFilter(key)
+ if err != nil {
+ return err
+ }
+ count, err := c.CountDocuments(context.Background(), filter)
+ if err != nil {
+ return pkgerrors.Errorf("Error finding: %s", err.Error())
+ }
+ if count == 0 {
+ return pkgerrors.Errorf("key not found")
+ }
+ if count > 1 {
+ return pkgerrors.Errorf("Can't delete parent without deleting child references first")
+ }
+ _, err = c.DeleteOne(ctx, filter)
+ if err != nil {
+ return pkgerrors.Errorf("Error Deleting from database: %s", err.Error())
+ }
+ return nil
+}
+
+// RemoveTag is used to remove an element from a document
+func (m *MongoStore) RemoveTag(coll string, key Key, tag string) error {
+ c := getCollection(coll, m)
+ ctx := context.Background()
+
+ filter, err := m.findFilter(key)
+ if err != nil {
+ return err
+ }
+
+ _, err = decodeBytes(
+ c.FindOneAndUpdate(
+ ctx,
+ filter,
+ bson.D{
+ {"$unset", bson.D{
+ {tag, ""},
+ }},
+ },
+ options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)))
+
+ if err != nil {
+ return pkgerrors.Errorf("Error removing tag: %s", err.Error())
+ }
+
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "context"\r
-\r
- "go.mongodb.org/mongo-driver/mongo"\r
- "go.mongodb.org/mongo-driver/mongo/options"\r
-)\r
-\r
-//Implements the functions used currently in mongo.go\r
-type mockCollection struct {\r
- Err error\r
- mCursor *mongo.Cursor\r
- mCursorCount int\r
-}\r
-\r
-func (c *mockCollection) InsertOne(ctx context.Context, document interface{},\r
- opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {\r
-\r
- if c.Err != nil {\r
- return nil, c.Err\r
- }\r
-\r
- return &mongo.InsertOneResult{InsertedID: "_id1234"}, nil\r
-}\r
-\r
-func (c *mockCollection) FindOne(ctx context.Context, filter interface{},\r
- opts ...*options.FindOneOptions) *mongo.SingleResult {\r
-\r
- return &mongo.SingleResult{}\r
-}\r
-\r
-func (c *mockCollection) FindOneAndUpdate(ctx context.Context, filter interface{},\r
- update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {\r
-\r
- return &mongo.SingleResult{}\r
-}\r
-\r
-func (c *mockCollection) DeleteOne(ctx context.Context, filter interface{},\r
- opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {\r
-\r
- return nil, c.Err\r
-}\r
-\r
-func (c *mockCollection) Find(ctx context.Context, filter interface{},\r
- opts ...*options.FindOptions) (*mongo.Cursor, error) {\r
-\r
- return c.mCursor, c.Err\r
-}\r
-\r
-func (c *mockCollection) DeleteMany(ctx context.Context, filter interface{},\r
- opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {\r
- return nil, c.Err\r
-}\r
-\r
-func (c *mockCollection) UpdateOne(ctx context.Context, filter interface{}, update interface{},\r
- opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {\r
- return nil, c.Err\r
-}\r
-\r
-func (c *mockCollection) CountDocuments(ctx context.Context, filter interface{},\r
- opts ...*options.CountOptions) (int64, error) {\r
- return 1, c.Err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "context"
+
+ "go.mongodb.org/mongo-driver/mongo"
+ "go.mongodb.org/mongo-driver/mongo/options"
+)
+
+//Implements the functions used currently in mongo.go
+type mockCollection struct {
+ Err error
+ mCursor *mongo.Cursor
+ mCursorCount int
+}
+
+func (c *mockCollection) InsertOne(ctx context.Context, document interface{},
+ opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
+
+ if c.Err != nil {
+ return nil, c.Err
+ }
+
+ return &mongo.InsertOneResult{InsertedID: "_id1234"}, nil
+}
+
+func (c *mockCollection) FindOne(ctx context.Context, filter interface{},
+ opts ...*options.FindOneOptions) *mongo.SingleResult {
+
+ return &mongo.SingleResult{}
+}
+
+func (c *mockCollection) FindOneAndUpdate(ctx context.Context, filter interface{},
+ update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {
+
+ return &mongo.SingleResult{}
+}
+
+func (c *mockCollection) DeleteOne(ctx context.Context, filter interface{},
+ opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
+
+ return nil, c.Err
+}
+
+func (c *mockCollection) Find(ctx context.Context, filter interface{},
+ opts ...*options.FindOptions) (*mongo.Cursor, error) {
+
+ return c.mCursor, c.Err
+}
+
+func (c *mockCollection) DeleteMany(ctx context.Context, filter interface{},
+ opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
+ return nil, c.Err
+}
+
+func (c *mockCollection) UpdateOne(ctx context.Context, filter interface{}, update interface{},
+ opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
+ return nil, c.Err
+}
+
+func (c *mockCollection) CountDocuments(ctx context.Context, filter interface{},
+ opts ...*options.CountOptions) (int64, error) {
+ return 1, c.Err
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "encoding/json"\r
- "reflect"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// DBconn interface used to talk a concrete Database connection\r
-var DBconn Store\r
-\r
-// Key is an interface that will be implemented by anypackage\r
-// that wants to use the Store interface. This allows various\r
-// db backends and key types.\r
-type Key interface {\r
-}\r
-\r
-// Store is an interface for accessing the database\r
-type Store interface {\r
- // Returns nil if db health is good\r
- HealthCheck() error\r
-\r
- // Unmarshal implements any unmarshaling needed for the database\r
- Unmarshal(inp []byte, out interface{}) error\r
-\r
- // Inserts and Updates a tag with key and also adds query fields if provided\r
- Insert(coll string, key Key, query interface{}, tag string, data interface{}) error\r
-\r
- // Find the document(s) with key and get the tag values from the document(s)\r
- Find(coll string, key Key, tag string) ([][]byte, error)\r
-\r
- // Removes the document(s) matching the key if no child reference in collection\r
- Remove(coll string, key Key) error\r
-\r
- // Remove all the document(s) matching the key\r
- RemoveAll(coll string, key Key) error\r
-\r
- // Remove the specifiec tag from the document matching the key\r
- RemoveTag(coll string, key Key, tag string) error\r
-}\r
-\r
-// CreateDBClient creates the DB client\r
-func createDBClient(dbType string, dbName string) error {\r
- var err error\r
- switch dbType {\r
- case "mongo":\r
- // create a mongodb database with orchestrator as the name\r
- DBconn, err = NewMongoStore(dbName, nil)\r
- default:\r
- return pkgerrors.New(dbType + "DB not supported")\r
- }\r
- return err\r
-}\r
-\r
-// Serialize converts given data into a JSON string\r
-func Serialize(v interface{}) (string, error) {\r
- out, err := json.Marshal(v)\r
- if err != nil {\r
- return "", pkgerrors.Wrap(err, "Error serializing "+reflect.TypeOf(v).String())\r
- }\r
- return string(out), nil\r
-}\r
-\r
-// DeSerialize converts string to a json object specified by type\r
-func DeSerialize(str string, v interface{}) error {\r
- err := json.Unmarshal([]byte(str), &v)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Error deSerializing "+str)\r
- }\r
- return nil\r
-}\r
-\r
-// InitializeDatabaseConnection sets up the connection to the\r
-// configured database to allow the application to talk to it.\r
-func InitializeDatabaseConnection(dbName string) error {\r
- err := createDBClient(config.GetConfiguration().DatabaseType, dbName)\r
- if err != nil {\r
- return pkgerrors.Cause(err)\r
- }\r
-\r
- err = DBconn.HealthCheck()\r
- if err != nil {\r
- return pkgerrors.Cause(err)\r
- }\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "encoding/json"
+ "reflect"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// DBconn interface used to talk a concrete Database connection
+var DBconn Store
+
+// Key is an interface that will be implemented by anypackage
+// that wants to use the Store interface. This allows various
+// db backends and key types.
+type Key interface {
+}
+
+// Store is an interface for accessing the database
+type Store interface {
+ // Returns nil if db health is good
+ HealthCheck() error
+
+ // Unmarshal implements any unmarshaling needed for the database
+ Unmarshal(inp []byte, out interface{}) error
+
+ // Inserts and Updates a tag with key and also adds query fields if provided
+ Insert(coll string, key Key, query interface{}, tag string, data interface{}) error
+
+ // Find the document(s) with key and get the tag values from the document(s)
+ Find(coll string, key Key, tag string) ([][]byte, error)
+
+ // Removes the document(s) matching the key if no child reference in collection
+ Remove(coll string, key Key) error
+
+ // Remove all the document(s) matching the key
+ RemoveAll(coll string, key Key) error
+
+ // Remove the specifiec tag from the document matching the key
+ RemoveTag(coll string, key Key, tag string) error
+}
+
+// CreateDBClient creates the DB client
+func createDBClient(dbType string, dbName string) error {
+ var err error
+ switch dbType {
+ case "mongo":
+ // create a mongodb database with orchestrator as the name
+ DBconn, err = NewMongoStore(dbName, nil)
+ default:
+ return pkgerrors.New(dbType + "DB not supported")
+ }
+ return err
+}
+
+// Serialize converts given data into a JSON string
+func Serialize(v interface{}) (string, error) {
+ out, err := json.Marshal(v)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Error serializing "+reflect.TypeOf(v).String())
+ }
+ return string(out), nil
+}
+
+// DeSerialize converts string to a json object specified by type
+func DeSerialize(str string, v interface{}) error {
+ err := json.Unmarshal([]byte(str), &v)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error deSerializing "+str)
+ }
+ return nil
+}
+
+// InitializeDatabaseConnection sets up the connection to the
+// configured database to allow the application to talk to it.
+func InitializeDatabaseConnection(dbName string) error {
+ err := createDBClient(config.GetConfiguration().DatabaseType, dbName)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ err = DBconn.HealthCheck()
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package db\r
-\r
-import (\r
- "reflect"\r
- "strings"\r
- "testing"\r
-)\r
-\r
-func TestCreateDBClient(t *testing.T) {\r
- t.Run("Successfully create DB client", func(t *testing.T) {\r
- expected := &MongoStore{}\r
-\r
- err := createDBClient("mongo", "testdb")\r
- if err != nil {\r
- t.Fatalf("CreateDBClient returned an error (%s)", err)\r
- }\r
- if reflect.TypeOf(DBconn) != reflect.TypeOf(expected) {\r
- t.Fatalf("CreateDBClient set DBconn as:\n result=%T\n expected=%T", DBconn, expected)\r
- }\r
- })\r
- t.Run("Fail to create client for unsupported DB", func(t *testing.T) {\r
- err := createDBClient("fakeDB", "testdb2")\r
- if err == nil {\r
- t.Fatal("CreateDBClient didn't return an error")\r
- }\r
- if !strings.Contains(string(err.Error()), "DB not supported") {\r
- t.Fatalf("CreateDBClient method returned an error (%s)", err)\r
- }\r
- })\r
-}\r
-\r
-func TestSerialize(t *testing.T) {\r
-\r
- inp := map[string]interface{}{\r
- "UUID": "123e4567-e89b-12d3-a456-426655440000",\r
- "Data": "sdaijsdiodalkfjsdlagf",\r
- "Number": 23,\r
- "Float": 34.4,\r
- "Map": map[string]interface{}{\r
- "m1": "m1",\r
- "m2": 2,\r
- "m3": 3.0,\r
- },\r
- }\r
-\r
- got, err := Serialize(inp)\r
- if err != nil {\r
- t.Fatal(err)\r
- }\r
-\r
- expected := "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +\r
- "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m2\":2,\"m3\":3}," +\r
- "\"Number\":23,\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}"\r
-\r
- if expected != got {\r
- t.Errorf("Serialize returned unexpected string: %s;"+\r
- " expected %sv", got, expected)\r
- }\r
-}\r
-\r
-func TestDeSerialize(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- input string\r
- expected map[string]interface{}\r
- errMsg string\r
- }{\r
- {\r
- label: "Sucessful deserialize entry",\r
- input: "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +\r
- "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m3\":3}," +\r
- "\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}",\r
- expected: map[string]interface{}{\r
- "UUID": "123e4567-e89b-12d3-a456-426655440000",\r
- "Data": "sdaijsdiodalkfjsdlagf",\r
- "Float": 34.4,\r
- "Map": map[string]interface{}{\r
- "m1": "m1",\r
- "m3": 3.0,\r
- },\r
- },\r
- },\r
- {\r
- label: "Fail to deserialize invalid entry",\r
- input: "{invalid}",\r
- errMsg: "Error deSerializing {invalid}: invalid character 'i' looking for beginning of object key string",\r
- },\r
- }\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- got := make(map[string]interface{})\r
- err := DeSerialize(testCase.input, &got)\r
- if err != nil {\r
- if testCase.errMsg == "" {\r
- t.Fatalf("DeSerialize method return an un-expected (%s)", err)\r
- }\r
- if !strings.Contains(string(err.Error()), testCase.errMsg) {\r
- t.Fatalf("DeSerialize method returned an error (%s)", err)\r
- }\r
- } else {\r
- if !reflect.DeepEqual(testCase.expected, got) {\r
- t.Errorf("Serialize returned unexpected : %v;"+\r
- " expected %v", got, testCase.expected)\r
- }\r
- }\r
- })\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package db
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestCreateDBClient(t *testing.T) {
+ t.Run("Successfully create DB client", func(t *testing.T) {
+ expected := &MongoStore{}
+
+ err := createDBClient("mongo", "testdb")
+ if err != nil {
+ t.Fatalf("CreateDBClient returned an error (%s)", err)
+ }
+ if reflect.TypeOf(DBconn) != reflect.TypeOf(expected) {
+ t.Fatalf("CreateDBClient set DBconn as:\n result=%T\n expected=%T", DBconn, expected)
+ }
+ })
+ t.Run("Fail to create client for unsupported DB", func(t *testing.T) {
+ err := createDBClient("fakeDB", "testdb2")
+ if err == nil {
+ t.Fatal("CreateDBClient didn't return an error")
+ }
+ if !strings.Contains(string(err.Error()), "DB not supported") {
+ t.Fatalf("CreateDBClient method returned an error (%s)", err)
+ }
+ })
+}
+
+func TestSerialize(t *testing.T) {
+
+ inp := map[string]interface{}{
+ "UUID": "123e4567-e89b-12d3-a456-426655440000",
+ "Data": "sdaijsdiodalkfjsdlagf",
+ "Number": 23,
+ "Float": 34.4,
+ "Map": map[string]interface{}{
+ "m1": "m1",
+ "m2": 2,
+ "m3": 3.0,
+ },
+ }
+
+ got, err := Serialize(inp)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected := "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
+ "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m2\":2,\"m3\":3}," +
+ "\"Number\":23,\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}"
+
+ if expected != got {
+ t.Errorf("Serialize returned unexpected string: %s;"+
+ " expected %sv", got, expected)
+ }
+}
+
+func TestDeSerialize(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ expected map[string]interface{}
+ errMsg string
+ }{
+ {
+ label: "Sucessful deserialize entry",
+ input: "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
+ "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m3\":3}," +
+ "\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}",
+ expected: map[string]interface{}{
+ "UUID": "123e4567-e89b-12d3-a456-426655440000",
+ "Data": "sdaijsdiodalkfjsdlagf",
+ "Float": 34.4,
+ "Map": map[string]interface{}{
+ "m1": "m1",
+ "m3": 3.0,
+ },
+ },
+ },
+ {
+ label: "Fail to deserialize invalid entry",
+ input: "{invalid}",
+ errMsg: "Error deSerializing {invalid}: invalid character 'i' looking for beginning of object key string",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ got := make(map[string]interface{})
+ err := DeSerialize(testCase.input, &got)
+ if err != nil {
+ if testCase.errMsg == "" {
+ t.Fatalf("DeSerialize method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.errMsg) {
+ t.Fatalf("DeSerialize method returned an error (%s)", err)
+ }
+ } else {
+ if !reflect.DeepEqual(testCase.expected, got) {
+ t.Errorf("Serialize returned unexpected : %v;"+
+ " expected %v", got, testCase.expected)
+ }
+ }
+ })
+ }
+}
-package logutils\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- log "github.com/sirupsen/logrus"\r
- "strings"\r
-)\r
-\r
-//Fields is type that will be used by the calling function\r
-type Fields map[string]interface{}\r
-\r
-func init() {\r
- // Log as JSON instead of the default ASCII formatter.\r
- log.SetFormatter(&log.JSONFormatter{})\r
- if strings.EqualFold(config.GetConfiguration().LogLevel, "warn") {\r
- log.SetLevel(log.WarnLevel)\r
-\r
- }\r
- if strings.EqualFold(config.GetConfiguration().LogLevel, "info") {\r
- log.SetLevel(log.InfoLevel)\r
- }\r
-}\r
-\r
-// Error uses the fields provided and logs\r
-func Error(msg string, fields Fields) {\r
- log.WithFields(log.Fields(fields)).Error(msg)\r
-}\r
-\r
-// Warn uses the fields provided and logs\r
-func Warn(msg string, fields Fields) {\r
- log.WithFields(log.Fields(fields)).Warn(msg)\r
-}\r
-\r
-// Info uses the fields provided and logs\r
-func Info(msg string, fields Fields) {\r
- log.WithFields(log.Fields(fields)).Info(msg)\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package logutils
+
+import (
+ "fmt"
+ "path"
+ "runtime"
+ "strings"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ log "github.com/sirupsen/logrus"
+)
+
+//Fields is type that will be used by the calling function
+type Fields map[string]interface{}
+
+func init() {
+ // Log as JSON instead of the default ASCII formatter.
+ log.SetFormatter(&log.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.999999999Z07:00"})
+ if strings.EqualFold(config.GetConfiguration().LogLevel, "warn") {
+ log.SetLevel(log.WarnLevel)
+
+ }
+ if strings.EqualFold(config.GetConfiguration().LogLevel, "info") {
+ log.SetLevel(log.InfoLevel)
+ }
+}
+
+// Error uses the fields provided and logs
+func Error(msg string, fields Fields) {
+ if pc, file, line, ok := runtime.Caller(1); ok {
+ if fields != nil {
+ fields["SOURCE"] = fmt.Sprintf("file[%s:%d] func[%s]", path.Base(file), line, path.Base(runtime.FuncForPC(pc).Name()))
+ }
+ log.WithFields(log.Fields(fields)).Error(msg)
+ } else {
+ log.WithFields(log.Fields(fields)).Error(msg)
+ }
+}
+
+// Warn uses the fields provided and logs
+func Warn(msg string, fields Fields) {
+ if pc, file, line, ok := runtime.Caller(1); ok {
+ if fields != nil {
+ fields["SOURCE"] = fmt.Sprintf("file[%s:%d] func[%s]", path.Base(file), line, path.Base(runtime.FuncForPC(pc).Name()))
+ }
+ log.WithFields(log.Fields(fields)).Warn(msg)
+ } else {
+ log.WithFields(log.Fields(fields)).Warn(msg)
+ }
+}
+
+// Info uses the fields provided and logs
+func Info(msg string, fields Fields) {
+ if pc, file, line, ok := runtime.Caller(1); ok {
+ if fields != nil {
+ fields["SOURCE"] = fmt.Sprintf("file[%s:%d] func[%s]", path.Base(file), line, path.Base(runtime.FuncForPC(pc).Name()))
+ }
+ log.WithFields(log.Fields(fields)).Info(msg)
+ } else {
+ log.WithFields(log.Fields(fields)).Info(msg)
+ }
+}
+
+// SetLoglevel .. Set Log level
+func SetLoglevel(level log.Level) {
+ log.SetLevel(level)
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package rpc\r
-\r
-import (\r
- "context"\r
- "strconv"\r
- "strings"\r
- "sync"\r
- "time"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- pkgerrors "github.com/pkg/errors"\r
- "google.golang.org/grpc"\r
- "google.golang.org/grpc/connectivity"\r
- "google.golang.org/grpc/credentials"\r
- "google.golang.org/grpc/testdata"\r
-)\r
-\r
-type ContextUpdateRequest interface {\r
-}\r
-\r
-type ContextUpdateResponse interface {\r
-}\r
-\r
-type InstallAppRequest interface {\r
-}\r
-\r
-type InstallAppResponse interface {\r
-}\r
-\r
-type rpcInfo struct {\r
- conn *grpc.ClientConn\r
- host string\r
- port int\r
-}\r
-\r
-var mutex = &sync.Mutex{}\r
-var rpcConnections = make(map[string]rpcInfo)\r
-\r
-// GetRpcConn is used by RPC client code which needs the connection for a\r
-// given controller for doing RPC calls with that controller.\r
-func GetRpcConn(name string) *grpc.ClientConn {\r
- mutex.Lock()\r
- defer mutex.Unlock()\r
- if val, ok := rpcConnections[name]; ok {\r
- if val.conn.GetState() == connectivity.TransientFailure {\r
- val.conn.ResetConnectBackoff()\r
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)\r
- if !val.conn.WaitForStateChange(ctx, connectivity.TransientFailure) {\r
- log.Warn("Error re-establishing RPC connection", log.Fields{\r
- "Server": name,\r
- "Host": val.host,\r
- "Port": val.port,\r
- })\r
- }\r
- cancel()\r
- }\r
- return val.conn\r
- }\r
- return nil\r
-}\r
-\r
-func UpdateRpcConn(name, host string, port int) {\r
- mutex.Lock()\r
- defer mutex.Unlock()\r
- if val, ok := rpcConnections[name]; ok {\r
- // close connection if mismatch in update vs cached connect info\r
- if val.host != host || val.port != port {\r
- log.Info("Closing RPC connection due to mismatch", log.Fields{\r
- "Server": name,\r
- "Old Host": val.host,\r
- "Old Port": val.port,\r
- "New Host": host,\r
- "New Port": port,\r
- })\r
- err := val.conn.Close()\r
- if err != nil {\r
- log.Warn("Error closing RPC connection", log.Fields{\r
- "Server": name,\r
- "Host": val.host,\r
- "Port": val.port,\r
- "Error": err,\r
- })\r
- }\r
- } else {\r
- if val.conn.GetState() == connectivity.TransientFailure {\r
- val.conn.ResetConnectBackoff()\r
- }\r
- return\r
- }\r
- }\r
- // connect and update rpcConnection list - for new or modified connection\r
- conn, err := createClientConn(host, port)\r
- if err != nil {\r
- log.Warn("Failed to create RPC Client connection", log.Fields{\r
- "Error": err,\r
- })\r
- delete(rpcConnections, name)\r
- } else {\r
- log.Info("Added RPC Client connection", log.Fields{\r
- "Controller": name,\r
- })\r
- rpcConnections[name] = rpcInfo{\r
- conn: conn,\r
- host: host,\r
- port: port,\r
- }\r
- }\r
-}\r
-\r
-// CloseAllRpcConn closes all connections\r
-func CloseAllRpcConn() {\r
- mutex.Lock()\r
- for k, v := range rpcConnections {\r
- err := v.conn.Close()\r
- if err != nil {\r
- log.Warn("Error closing RPC connection", log.Fields{\r
- "Server": k,\r
- "Host": v.host,\r
- "Port": v.port,\r
- "Error": err,\r
- })\r
- }\r
- }\r
- mutex.Unlock()\r
-}\r
-\r
-// RemoveRpcConn closes the connection and removes from map\r
-func RemoveRpcConn(name string) {\r
- mutex.Lock()\r
- if val, ok := rpcConnections[name]; ok {\r
- err := val.conn.Close()\r
- if err != nil {\r
- log.Warn("Error closing RPC connection", log.Fields{\r
- "Server": name,\r
- "Host": val.host,\r
- "Port": val.port,\r
- "Error": err,\r
- })\r
- }\r
- delete(rpcConnections, name)\r
- }\r
- mutex.Unlock()\r
-}\r
-\r
-// createConn creates the Rpc Client Connection\r
-func createClientConn(Host string, Port int) (*grpc.ClientConn, error) {\r
- var err error\r
- var tls bool\r
- var opts []grpc.DialOption\r
-\r
- serverAddr := Host + ":" + strconv.Itoa(Port)\r
- serverNameOverride := config.GetConfiguration().GrpcServerNameOverride\r
-\r
- if strings.Contains(config.GetConfiguration().GrpcEnableTLS, "enable") {\r
- tls = true\r
- } else {\r
- tls = false\r
- }\r
-\r
- caFile := config.GetConfiguration().GrpcCAFile\r
-\r
- if tls {\r
- if caFile == "" {\r
- caFile = testdata.Path("ca.pem")\r
- }\r
- creds, err := credentials.NewClientTLSFromFile(caFile, serverNameOverride)\r
- if err != nil {\r
- log.Error("Failed to create TLS credentials", log.Fields{\r
- "Error": err,\r
- "Host": Host,\r
- "Port": Port,\r
- })\r
- }\r
- opts = append(opts, grpc.WithTransportCredentials(creds))\r
- } else {\r
- opts = append(opts, grpc.WithInsecure())\r
- }\r
-\r
- conn, err := grpc.Dial(serverAddr, opts...)\r
- if err != nil {\r
- pkgerrors.Wrap(err, "Grpc Client Initialization failed with error")\r
- }\r
-\r
- return conn, err\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package rpc
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config"
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pkgerrors "github.com/pkg/errors"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/connectivity"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/testdata"
+)
+
+type ContextUpdateRequest interface {
+}
+
+type ContextUpdateResponse interface {
+}
+
+type InstallAppRequest interface {
+}
+
+type InstallAppResponse interface {
+}
+
+type rpcInfo struct {
+ conn *grpc.ClientConn
+ host string
+ port int
+}
+
+var mutex = &sync.Mutex{}
+var rpcConnections = make(map[string]rpcInfo)
+
+// GetRpcConn is used by RPC client code which needs the connection for a
+// given controller for doing RPC calls with that controller.
+func GetRpcConn(name string) *grpc.ClientConn {
+ mutex.Lock()
+ defer mutex.Unlock()
+ if val, ok := rpcConnections[name]; ok {
+ log.Info("GetRpcConn .. RPC intermediate-connection info", log.Fields{"name": name, "conn": val.conn, "host": val.host, "port": val.port, "conn-state": val.conn.GetState().String()})
+
+ if val.conn.GetState() == connectivity.TransientFailure {
+ val.conn.ResetConnectBackoff()
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
+ defer cancel()
+ if !val.conn.WaitForStateChange(ctx, connectivity.TransientFailure) {
+ log.Warn("Error re-establishing RPC connection", log.Fields{
+ "Server": name,
+ "Host": val.host,
+ "Port": val.port,
+ "ConnState": val.conn.GetState().String(),
+ })
+ return nil
+ }
+ }
+
+ if val.conn.GetState() == connectivity.Connecting {
+ ctx, cancel := context.WithTimeout(context.Background(), 2000*time.Millisecond)
+ defer cancel()
+ if !val.conn.WaitForStateChange(ctx, connectivity.Connecting) {
+ log.Warn("GetRpcConn .. Error establishing RPC connection .. ClientConn is still in CONNECTING", log.Fields{
+ "Server": name,
+ "Host": val.host,
+ "Port": val.port,
+ "ConnState": val.conn.GetState().String(),
+ })
+ return nil
+ }
+ }
+
+ if val.conn.GetState() == connectivity.TransientFailure {
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
+ defer cancel()
+ if !val.conn.WaitForStateChange(ctx, connectivity.TransientFailure) {
+ log.Warn("Error establishing RPC connection", log.Fields{
+ "Server": name,
+ "Host": val.host,
+ "Port": val.port,
+ "ConnState": val.conn.GetState().String(),
+ })
+ return nil
+ }
+ }
+
+ log.Warn("GetRpcConn .. RPC final-connection info", log.Fields{"name": name, "conn": val.conn, "host": val.host, "port": val.port, "conn-state": val.conn.GetState().String()})
+ return val.conn
+ }
+ return nil
+}
+
+// UpdateRpcConn ... Update RPC connections
+func UpdateRpcConn(name, host string, port int) {
+ mutex.Lock()
+ defer mutex.Unlock()
+ if val, ok := rpcConnections[name]; ok {
+ // close connection if mismatch in update vs cached connect info
+ if val.host != host || val.port != port {
+ log.Info("Closing RPC connection due to mismatch", log.Fields{
+ "Server": name,
+ "Old Host": val.host,
+ "Old Port": val.port,
+ "New Host": host,
+ "New Port": port,
+ })
+ err := val.conn.Close()
+ if err != nil {
+ log.Error("Error closing RPC connection", log.Fields{
+ "Server": name,
+ "Host": val.host,
+ "Port": val.port,
+ "Error": err,
+ })
+ }
+ } else {
+ if val.conn.GetState() == connectivity.TransientFailure {
+ val.conn.ResetConnectBackoff()
+ }
+ return
+ }
+ }
+ // connect and update rpcConnection list - for new or modified connection
+ conn, err := createClientConn(host, port)
+ if err != nil {
+ log.Error("Failed to create RPC Client connection", log.Fields{
+ "Error": err,
+ })
+ delete(rpcConnections, name)
+ } else {
+ rpcConnections[name] = rpcInfo{
+ conn: conn,
+ host: host,
+ port: port,
+ }
+ log.Info("Added RPC Client connection", log.Fields{"Controller": name, "conn": conn, "rpcConnection": fmt.Sprintf("%v", rpcConnections[name])})
+ }
+ log.Info("UpdateRpcConn .. end", log.Fields{"conn": conn, "name": name, "host": host, "port": port})
+}
+
+// CloseAllRpcConn closes all connections
+func CloseAllRpcConn() {
+ mutex.Lock()
+ log.Info("CloseAllRpcConn..", nil)
+ for k, v := range rpcConnections {
+ err := v.conn.Close()
+ if err != nil {
+ log.Warn("Error closing RPC connection", log.Fields{
+ "Server": k,
+ "Host": v.host,
+ "Port": v.port,
+ "Error": err,
+ })
+ }
+ }
+ mutex.Unlock()
+}
+
+// RemoveRpcConn closes the connection and removes from map
+func RemoveRpcConn(name string) {
+ mutex.Lock()
+ if val, ok := rpcConnections[name]; ok {
+ err := val.conn.Close()
+ if err != nil {
+ log.Warn("Error closing RPC connection", log.Fields{
+ "Server": name,
+ "Host": val.host,
+ "Port": val.port,
+ "Error": err,
+ })
+ }
+ delete(rpcConnections, name)
+ }
+ mutex.Unlock()
+}
+
+// createConn creates the Rpc Client Connection
+func createClientConn(Host string, Port int) (*grpc.ClientConn, error) {
+ var err error
+ var tls bool
+ var opts []grpc.DialOption
+
+ serverAddr := Host + ":" + strconv.Itoa(Port)
+ serverNameOverride := config.GetConfiguration().GrpcServerNameOverride
+
+ if strings.Contains(config.GetConfiguration().GrpcEnableTLS, "enable") {
+ tls = true
+ } else {
+ tls = false
+ }
+
+ caFile := config.GetConfiguration().GrpcCAFile
+
+ if tls {
+ if caFile == "" {
+ caFile = testdata.Path("ca.pem")
+ }
+ creds, err := credentials.NewClientTLSFromFile(caFile, serverNameOverride)
+ if err != nil {
+ log.Error("Failed to create TLS credentials", log.Fields{
+ "Error": err,
+ "Host": Host,
+ "Port": Port,
+ })
+ }
+ opts = append(opts, grpc.WithTransportCredentials(creds))
+ } else {
+ opts = append(opts, grpc.WithInsecure())
+ }
+
+ conn, err := grpc.Dial(serverAddr, opts...)
+ if err != nil {
+ pkgerrors.Wrap(err, "Grpc Client Initialization failed with error")
+ }
+
+ return conn, err
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package utils
+
+// GetSliceSubtract .. (c1 - c2)
+func GetSliceSubtract(c1, c2 []string) (diffSlice []string) {
+ sliceMap := make(map[string]bool)
+
+ // Create a map for slice-2
+ for _, key := range c2 {
+ sliceMap[key] = true
+ }
+
+ for _, value := range c1 {
+ if _, ok := sliceMap[value]; !ok {
+ diffSlice = append(diffSlice, value)
+ }
+ }
+ return
+}
+
+// GetSliceIntersect .. intersect slices
+func GetSliceIntersect(c1 []string, c2 []string) []string {
+ var set = make([]string, 0)
+ for _, v1 := range c1 {
+ for _, v2 := range c2 {
+ if v1 == v2 {
+ set = append(set, v1)
+ }
+ }
+ }
+ return set
+}
+
+// GetSliceContains ... return element index, otherwise return -1 and a bool of false.
+func GetSliceContains(slice []string, element string) (int, bool) {
+ for index, val := range slice {
+ if val == element {
+ return index, true
+ }
+ }
+ return -1, false
+}
+
+// SliceRemove .. Remove a element from slice
+func SliceRemove(slice []string, item string) []string {
+ for i, element := range slice {
+ if element == item {
+ slice = append(slice[:i], slice[i+1:]...)
+ }
+ }
+ return slice
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package validation\r
-\r
-import (\r
- "archive/tar"\r
- "compress/gzip"\r
- "encoding/json"\r
- "fmt"\r
- "io"\r
- "io/ioutil"\r
- "net"\r
- "net/http"\r
- "os"\r
- "regexp"\r
- "strconv"\r
- "strings"\r
-\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- pkgerrors "github.com/pkg/errors"\r
- "github.com/xeipuuv/gojsonschema"\r
- "k8s.io/apimachinery/pkg/util/validation"\r
-)\r
-\r
-func IsTarGz(r io.Reader) error {\r
- //Check if it is a valid gz\r
- gzf, err := gzip.NewReader(r)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Invalid gzip format")\r
- }\r
-\r
- //Check if it is a valid tar file\r
- //Unfortunately this can only be done by inspecting all the tar contents\r
- tarR := tar.NewReader(gzf)\r
- first := true\r
-\r
- for true {\r
- header, err := tarR.Next()\r
-\r
- if err == io.EOF {\r
- //Check if we have just a gzip file without a tar archive inside\r
- if first {\r
- return pkgerrors.New("Empty or non-existant Tar file found")\r
- }\r
- //End of archive\r
- break\r
- }\r
-\r
- if err != nil {\r
- return pkgerrors.Errorf("Error reading tar file %s", err.Error())\r
- }\r
-\r
- //Check if files are of type directory and regular file\r
- if header.Typeflag != tar.TypeDir &&\r
- header.Typeflag != tar.TypeReg {\r
- return pkgerrors.Errorf("Unknown header in tar %s, %s",\r
- header.Name, string(header.Typeflag))\r
- }\r
-\r
- first = false\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func IsIpv4Cidr(cidr string) error {\r
- ip, _, err := net.ParseCIDR(cidr)\r
- if err != nil || ip.To4() == nil {\r
- return pkgerrors.Wrapf(err, "could not parse ipv4 cidr %v", cidr)\r
- }\r
- return nil\r
-}\r
-\r
-func IsIp(ip string) error {\r
- addr := net.ParseIP(ip)\r
- if addr == nil {\r
- return pkgerrors.Errorf("invalid ip address %v", ip)\r
- }\r
- return nil\r
-}\r
-\r
-func IsIpv4(ip string) error {\r
- addr := net.ParseIP(ip)\r
- if addr == nil || addr.To4() == nil {\r
- return pkgerrors.Errorf("invalid ipv4 address %v", ip)\r
- }\r
- return nil\r
-}\r
-\r
-func IsMac(mac string) error {\r
- _, err := net.ParseMAC(mac)\r
- if err != nil {\r
- return pkgerrors.Errorf("invalid MAC address %v", mac)\r
- }\r
- return nil\r
-}\r
-\r
-// default name check - matches valid label value with addtion that length > 0\r
-func IsValidName(name string) []string {\r
- var errs []string\r
-\r
- errs = validation.IsValidLabelValue(name)\r
- if len(name) == 0 {\r
- errs = append(errs, "name must have non-zero length")\r
- }\r
- return errs\r
-}\r
-\r
-const VALID_NAME_STR string = "NAME"\r
-\r
-var validNameRegEx = regexp.MustCompile("^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$")\r
-\r
-const VALID_ALPHA_STR string = "ALPHA"\r
-\r
-var validAlphaStrRegEx = regexp.MustCompile("^[A-Za-z]*$")\r
-\r
-const VALID_ALPHANUM_STR string = "ALPHANUM"\r
-\r
-var validAlphaNumStrRegEx = regexp.MustCompile("^[A-Za-z0-9]*$")\r
-\r
-// doesn't verify valid base64 length - just checks for proper base64 characters\r
-const VALID_BASE64_STR string = "BASE64"\r
-\r
-var validBase64StrRegEx = regexp.MustCompile("^[A-Za-z0-9+/]+={0,2}$")\r
-\r
-const VALID_ANY_STR string = "ANY"\r
-\r
-var validAnyStrRegEx = regexp.MustCompile("(?s)^.*$")\r
-\r
-// string check - validates for conformance to provided lengths and specified content\r
-// min and max - the string\r
-// if format string provided - check against matching predefined\r
-func IsValidString(str string, min, max int, format string) []string {\r
- var errs []string\r
-\r
- if min > max {\r
- errs = append(errs, "Invalid string length constraints - min is greater than max")\r
- return errs\r
- }\r
-\r
- if len(str) < min {\r
- errs = append(errs, "string length is less than the minimum constraint")\r
- return errs\r
- }\r
- if len(str) > max {\r
- errs = append(errs, "string length is greater than the maximum constraint")\r
- return errs\r
- }\r
-\r
- switch format {\r
- case VALID_ALPHA_STR:\r
- if !validAlphaStrRegEx.MatchString(str) {\r
- errs = append(errs, "string does not match the alpha only constraint")\r
- }\r
- case VALID_ALPHANUM_STR:\r
- if !validAlphaNumStrRegEx.MatchString(str) {\r
- errs = append(errs, "string does not match the alphanumeric only constraint")\r
- }\r
- case VALID_NAME_STR:\r
- if !validNameRegEx.MatchString(str) {\r
- errs = append(errs, "string does not match the valid k8s name constraint")\r
- }\r
- case VALID_BASE64_STR:\r
- if !validBase64StrRegEx.MatchString(str) {\r
- errs = append(errs, "string does not match the valid base64 characters constraint")\r
- }\r
- if len(str)%4 != 0 {\r
- errs = append(errs, "base64 string length should be a multiple of 4")\r
- }\r
- case VALID_ANY_STR:\r
- if !validAnyStrRegEx.MatchString(str) {\r
- errs = append(errs, "string does not match the any characters constraint")\r
- }\r
- default:\r
- // invalid string format supplied\r
- errs = append(errs, "an invalid string constraint was supplied")\r
- }\r
-\r
- return errs\r
-}\r
-\r
-// validate that label conforms to kubernetes label conventions\r
-// general label format expected is:\r
-// "<labelprefix>/<labelname>=<Labelvalue>"\r
-// where labelprefix matches DNS1123Subdomain format\r
-// labelname matches DNS1123Label format\r
-//\r
-// Input labels are allowed to match following formats:\r
-// "<DNS1123Subdomain>/<DNS1123Label>=<Labelvalue>"\r
-// "<DNS1123Label>=<LabelValue>"\r
-// "<LabelValue>"\r
-func IsValidLabel(label string) []string {\r
- var labelerrs []string\r
-\r
- expectLabelName := false\r
- expectLabelPrefix := false\r
-\r
- // split label up into prefix, name and value\r
- // format: prefix/name=value\r
- var labelprefix, labelname, labelvalue string\r
-\r
- kv := strings.SplitN(label, "=", 2)\r
- if len(kv) == 1 {\r
- labelprefix = ""\r
- labelname = ""\r
- labelvalue = kv[0]\r
- } else {\r
- pn := strings.SplitN(kv[0], "/", 2)\r
- if len(pn) == 1 {\r
- labelprefix = ""\r
- labelname = pn[0]\r
- } else {\r
- labelprefix = pn[0]\r
- labelname = pn[1]\r
- expectLabelPrefix = true\r
- }\r
- labelvalue = kv[1]\r
- // if "=" was in the label input, then expect a non-zero length name\r
- expectLabelName = true\r
- }\r
-\r
- // check label prefix validity - prefix is optional\r
- if len(labelprefix) > 0 {\r
- errs := validation.IsDNS1123Subdomain(labelprefix)\r
- if len(errs) > 0 {\r
- labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"], errors: ")\r
- for _, err := range errs {\r
- labelerrs = append(labelerrs, err)\r
- }\r
- }\r
- } else if expectLabelPrefix {\r
- labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"]")\r
- }\r
- if expectLabelName {\r
- errs := validation.IsDNS1123Label(labelname)\r
- if len(errs) > 0 {\r
- labelerrs = append(labelerrs, "Invalid label name - label=["+label+"%], labelname=["+labelname+"], errors: ")\r
- for _, err := range errs {\r
- labelerrs = append(labelerrs, err)\r
- }\r
- }\r
- }\r
- if len(labelvalue) > 0 {\r
- errs := validation.IsValidLabelValue(labelvalue)\r
- if len(errs) > 0 {\r
- labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"], errors: ")\r
- for _, err := range errs {\r
- labelerrs = append(labelerrs, err)\r
- }\r
- }\r
- } else {\r
- // expect a non-zero value\r
- labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"]")\r
- }\r
-\r
- return labelerrs\r
-}\r
-\r
-func IsValidNumber(value, min, max int) []string {\r
- var errs []string\r
-\r
- if min > max {\r
- errs = append(errs, "invalid constraints")\r
- return errs\r
- }\r
-\r
- if value < min {\r
- errs = append(errs, "value less than minimum")\r
- }\r
- if value > max {\r
- errs = append(errs, "value greater than maximum")\r
- }\r
- return errs\r
-}\r
-\r
-func IsValidNumberStr(value string, min, max int) []string {\r
- var errs []string\r
-\r
- if min > max {\r
- errs = append(errs, "invalid constraints")\r
- return errs\r
- }\r
-\r
- n, err := strconv.Atoi(value)\r
- if err != nil {\r
- errs = append(errs, err.Error())\r
- return errs\r
- }\r
- if n < min {\r
- errs = append(errs, "value less than minimum")\r
- }\r
- if n > max {\r
- errs = append(errs, "value greater than maximum")\r
- }\r
- return errs\r
-}\r
-\r
-/*\r
-IsValidParameterPresent method takes in a vars map and a array of string parameters\r
-that you expect to be present in the GET request.\r
-Returns Nil if all the parameters are present or else shall return error message.\r
-*/\r
-func IsValidParameterPresent(vars map[string]string, sp []string) error {\r
-\r
- for i := range sp {\r
- v := vars[sp[i]]\r
- if v == "" {\r
- errMessage := fmt.Sprintf("Missing %v in GET request", sp[i])\r
- return fmt.Errorf(errMessage)\r
- }\r
-\r
- }\r
- return nil\r
-\r
-}\r
-\r
-// ValidateJsonSchemaData function validates the document against the Json Schema\r
-func ValidateJsonSchemaData(jsonSchemaFile string, jsonData interface{}) (error, int) {\r
-\r
- // Read the Json Schema File\r
- if _, err := os.Stat(jsonSchemaFile); err != nil {\r
- if os.IsNotExist(err) {\r
- err = pkgerrors.New("JsonSchemaValidation: File " + jsonSchemaFile + " not found")\r
- } else {\r
- err = pkgerrors.Wrap(err, "JsonSchemaValidation: Stat file error")\r
- }\r
- return err, http.StatusInternalServerError\r
- }\r
- rawBytes, err := ioutil.ReadFile(jsonSchemaFile)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "JsonSchemaValidation: Read JSON file error"), http.StatusInternalServerError\r
- }\r
-\r
- // Json encode the data\r
- req, err := json.Marshal(jsonData)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "JsonSchemaValidation, Request Body error"), http.StatusBadRequest\r
- }\r
-\r
- // Load schema and document\r
- schemaLoader := gojsonschema.NewStringLoader(string(rawBytes))\r
- s, err := gojsonschema.NewSchema(schemaLoader)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "JsonSchemaValidation: Validation error"), http.StatusInternalServerError\r
- }\r
- documentLoader := gojsonschema.NewStringLoader(string(req))\r
- result, err := s.Validate(documentLoader)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "JsonSchemaValidation: Validation error"), http.StatusInternalServerError\r
- }\r
- // Validate document against Json Schema\r
- if !result.Valid() {\r
- for _, desc := range result.Errors() {\r
- log.Error("The document is not valid", log.Fields{\r
- "Error": desc.Description(),\r
- })\r
- }\r
- return pkgerrors.New("JsonSchemaValidation: Document Validation failed"), http.StatusBadRequest\r
- }\r
-\r
- return nil, 0\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package validation
+
+import (
+ "archive/tar"
+ "compress/gzip"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "net/http"
+ "os"
+ "regexp"
+ "strconv"
+ "strings"
+
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pkgerrors "github.com/pkg/errors"
+ "github.com/xeipuuv/gojsonschema"
+ "k8s.io/apimachinery/pkg/util/validation"
+)
+
+func IsTarGz(r io.Reader) error {
+ //Check if it is a valid gz
+ gzf, err := gzip.NewReader(r)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Invalid gzip format")
+ }
+
+ //Check if it is a valid tar file
+ //Unfortunately this can only be done by inspecting all the tar contents
+ tarR := tar.NewReader(gzf)
+ first := true
+
+ for true {
+ header, err := tarR.Next()
+
+ if err == io.EOF {
+ //Check if we have just a gzip file without a tar archive inside
+ if first {
+ return pkgerrors.New("Empty or non-existant Tar file found")
+ }
+ //End of archive
+ break
+ }
+
+ if err != nil {
+ return pkgerrors.Errorf("Error reading tar file %s", err.Error())
+ }
+
+ //Check if files are of type directory and regular file
+ if header.Typeflag != tar.TypeDir &&
+ header.Typeflag != tar.TypeReg {
+ return pkgerrors.Errorf("Unknown header in tar %s, %s",
+ header.Name, string(header.Typeflag))
+ }
+
+ first = false
+ }
+
+ return nil
+}
+
+func IsIpv4Cidr(cidr string) error {
+ ip, _, err := net.ParseCIDR(cidr)
+ if err != nil || ip.To4() == nil {
+ return pkgerrors.Wrapf(err, "could not parse ipv4 cidr %v", cidr)
+ }
+ return nil
+}
+
+func IsIp(ip string) error {
+ addr := net.ParseIP(ip)
+ if addr == nil {
+ return pkgerrors.Errorf("invalid ip address %v", ip)
+ }
+ return nil
+}
+
+func IsIpv4(ip string) error {
+ addr := net.ParseIP(ip)
+ if addr == nil || addr.To4() == nil {
+ return pkgerrors.Errorf("invalid ipv4 address %v", ip)
+ }
+ return nil
+}
+
+func IsMac(mac string) error {
+ _, err := net.ParseMAC(mac)
+ if err != nil {
+ return pkgerrors.Errorf("invalid MAC address %v", mac)
+ }
+ return nil
+}
+
+// default name check - matches valid label value with addtion that length > 0
+func IsValidName(name string) []string {
+ var errs []string
+
+ errs = validation.IsValidLabelValue(name)
+ if len(name) == 0 {
+ errs = append(errs, "name must have non-zero length")
+ }
+ return errs
+}
+
+const VALID_NAME_STR string = "NAME"
+
+var validNameRegEx = regexp.MustCompile("^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$")
+
+const VALID_ALPHA_STR string = "ALPHA"
+
+var validAlphaStrRegEx = regexp.MustCompile("^[A-Za-z]*$")
+
+const VALID_ALPHANUM_STR string = "ALPHANUM"
+
+var validAlphaNumStrRegEx = regexp.MustCompile("^[A-Za-z0-9]*$")
+
+// doesn't verify valid base64 length - just checks for proper base64 characters
+const VALID_BASE64_STR string = "BASE64"
+
+var validBase64StrRegEx = regexp.MustCompile("^[A-Za-z0-9+/]+={0,2}$")
+
+const VALID_ANY_STR string = "ANY"
+
+var validAnyStrRegEx = regexp.MustCompile("(?s)^.*$")
+
+// string check - validates for conformance to provided lengths and specified content
+// min and max - the string
+// if format string provided - check against matching predefined
+func IsValidString(str string, min, max int, format string) []string {
+ var errs []string
+
+ if min > max {
+ errs = append(errs, "Invalid string length constraints - min is greater than max")
+ return errs
+ }
+
+ if len(str) < min {
+ errs = append(errs, "string length is less than the minimum constraint")
+ return errs
+ }
+ if len(str) > max {
+ errs = append(errs, "string length is greater than the maximum constraint")
+ return errs
+ }
+
+ switch format {
+ case VALID_ALPHA_STR:
+ if !validAlphaStrRegEx.MatchString(str) {
+ errs = append(errs, "string does not match the alpha only constraint")
+ }
+ case VALID_ALPHANUM_STR:
+ if !validAlphaNumStrRegEx.MatchString(str) {
+ errs = append(errs, "string does not match the alphanumeric only constraint")
+ }
+ case VALID_NAME_STR:
+ if !validNameRegEx.MatchString(str) {
+ errs = append(errs, "string does not match the valid k8s name constraint")
+ }
+ case VALID_BASE64_STR:
+ if !validBase64StrRegEx.MatchString(str) {
+ errs = append(errs, "string does not match the valid base64 characters constraint")
+ }
+ if len(str)%4 != 0 {
+ errs = append(errs, "base64 string length should be a multiple of 4")
+ }
+ case VALID_ANY_STR:
+ if !validAnyStrRegEx.MatchString(str) {
+ errs = append(errs, "string does not match the any characters constraint")
+ }
+ default:
+ // invalid string format supplied
+ errs = append(errs, "an invalid string constraint was supplied")
+ }
+
+ return errs
+}
+
+// validate that label conforms to kubernetes label conventions
+// general label format expected is:
+// "<labelprefix>/<labelname>=<Labelvalue>"
+// where labelprefix matches DNS1123Subdomain format
+// labelname matches DNS1123Label format
+//
+// Input labels are allowed to match following formats:
+// "<DNS1123Subdomain>/<DNS1123Label>=<Labelvalue>"
+// "<DNS1123Label>=<LabelValue>"
+// "<LabelValue>"
+func IsValidLabel(label string) []string {
+ var labelerrs []string
+
+ expectLabelName := false
+ expectLabelPrefix := false
+
+ // split label up into prefix, name and value
+ // format: prefix/name=value
+ var labelprefix, labelname, labelvalue string
+
+ kv := strings.SplitN(label, "=", 2)
+ if len(kv) == 1 {
+ labelprefix = ""
+ labelname = ""
+ labelvalue = kv[0]
+ } else {
+ pn := strings.SplitN(kv[0], "/", 2)
+ if len(pn) == 1 {
+ labelprefix = ""
+ labelname = pn[0]
+ } else {
+ labelprefix = pn[0]
+ labelname = pn[1]
+ expectLabelPrefix = true
+ }
+ labelvalue = kv[1]
+ // if "=" was in the label input, then expect a non-zero length name
+ expectLabelName = true
+ }
+
+ // check label prefix validity - prefix is optional
+ if len(labelprefix) > 0 {
+ errs := validation.IsDNS1123Subdomain(labelprefix)
+ if len(errs) > 0 {
+ labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"], errors: ")
+ for _, err := range errs {
+ labelerrs = append(labelerrs, err)
+ }
+ }
+ } else if expectLabelPrefix {
+ labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"]")
+ }
+ if expectLabelName {
+ errs := validation.IsDNS1123Label(labelname)
+ if len(errs) > 0 {
+ labelerrs = append(labelerrs, "Invalid label name - label=["+label+"%], labelname=["+labelname+"], errors: ")
+ for _, err := range errs {
+ labelerrs = append(labelerrs, err)
+ }
+ }
+ }
+ if len(labelvalue) > 0 {
+ errs := validation.IsValidLabelValue(labelvalue)
+ if len(errs) > 0 {
+ labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"], errors: ")
+ for _, err := range errs {
+ labelerrs = append(labelerrs, err)
+ }
+ }
+ } else {
+ // expect a non-zero value
+ labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"]")
+ }
+
+ return labelerrs
+}
+
+func IsValidNumber(value, min, max int) []string {
+ var errs []string
+
+ if min > max {
+ errs = append(errs, "invalid constraints")
+ return errs
+ }
+
+ if value < min {
+ errs = append(errs, "value less than minimum")
+ }
+ if value > max {
+ errs = append(errs, "value greater than maximum")
+ }
+ return errs
+}
+
+func IsValidNumberStr(value string, min, max int) []string {
+ var errs []string
+
+ if min > max {
+ errs = append(errs, "invalid constraints")
+ return errs
+ }
+
+ n, err := strconv.Atoi(value)
+ if err != nil {
+ errs = append(errs, err.Error())
+ return errs
+ }
+ if n < min {
+ errs = append(errs, "value less than minimum")
+ }
+ if n > max {
+ errs = append(errs, "value greater than maximum")
+ }
+ return errs
+}
+
+/*
+IsValidParameterPresent method takes in a vars map and a array of string parameters
+that you expect to be present in the GET request.
+Returns Nil if all the parameters are present or else shall return error message.
+*/
+func IsValidParameterPresent(vars map[string]string, sp []string) error {
+
+ for i := range sp {
+ v := vars[sp[i]]
+ if v == "" {
+ errMessage := fmt.Sprintf("Missing %v in GET request", sp[i])
+ return fmt.Errorf(errMessage)
+ }
+
+ }
+ return nil
+
+}
+
+// ValidateJsonSchemaData function validates the document against the Json Schema
+func ValidateJsonSchemaData(jsonSchemaFile string, jsonData interface{}) (error, int) {
+
+ // Read the Json Schema File
+ if _, err := os.Stat(jsonSchemaFile); err != nil {
+ if os.IsNotExist(err) {
+ err = pkgerrors.New("JsonSchemaValidation: File " + jsonSchemaFile + " not found")
+ } else {
+ err = pkgerrors.Wrap(err, "JsonSchemaValidation: Stat file error")
+ }
+ return err, http.StatusInternalServerError
+ }
+ rawBytes, err := ioutil.ReadFile(jsonSchemaFile)
+ if err != nil {
+ return pkgerrors.Wrap(err, "JsonSchemaValidation: Read JSON file error"), http.StatusInternalServerError
+ }
+
+ // Json encode the data
+ req, err := json.Marshal(jsonData)
+ if err != nil {
+ return pkgerrors.Wrap(err, "JsonSchemaValidation, Request Body error"), http.StatusBadRequest
+ }
+
+ // Load schema and document
+ schemaLoader := gojsonschema.NewStringLoader(string(rawBytes))
+ s, err := gojsonschema.NewSchema(schemaLoader)
+ if err != nil {
+ return pkgerrors.Wrap(err, "JsonSchemaValidation: Validation error"), http.StatusInternalServerError
+ }
+ documentLoader := gojsonschema.NewStringLoader(string(req))
+ result, err := s.Validate(documentLoader)
+ if err != nil {
+ return pkgerrors.Wrap(err, "JsonSchemaValidation: Validation error"), http.StatusInternalServerError
+ }
+
+ // Validate document against Json Schema
+ if !result.Valid() {
+ for _, desc := range result.Errors() {
+ log.Error("The document is not valid", log.Fields{
+ "param": desc.Field(), "reason": desc.Description(), "req": string(req),
+ })
+ }
+ return pkgerrors.New("JsonSchemaValidation: Document Validation failed"), http.StatusBadRequest
+ }
+
+ return nil, 0
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package validation\r
-\r
-import (\r
- "bytes"\r
- "testing"\r
-)\r
-\r
-func TestIsTarGz(t *testing.T) {\r
-\r
- t.Run("Valid tar.gz", func(t *testing.T) {\r
- content := []byte{\r
- 0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,\r
- 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,\r
- 0x61, 0x72, 0x00, 0xed, 0xce, 0x41, 0x0a, 0xc2,\r
- 0x30, 0x10, 0x85, 0xe1, 0xac, 0x3d, 0x45, 0x4e,\r
- 0x50, 0x12, 0xd2, 0xc4, 0xe3, 0x48, 0xa0, 0x01,\r
- 0x4b, 0x52, 0x0b, 0xed, 0x88, 0x1e, 0xdf, 0x48,\r
- 0x11, 0x5c, 0x08, 0xa5, 0x8b, 0x52, 0x84, 0xff,\r
- 0xdb, 0xbc, 0x61, 0x66, 0x16, 0x4f, 0xd2, 0x2c,\r
- 0x8d, 0x3c, 0x45, 0xed, 0xc8, 0x54, 0x21, 0xb4,\r
- 0xef, 0xb4, 0x67, 0x6f, 0xbe, 0x73, 0x61, 0x9d,\r
- 0xb2, 0xce, 0xd5, 0x55, 0xf0, 0xde, 0xd7, 0x3f,\r
- 0xdb, 0xd6, 0x49, 0x69, 0xb3, 0x67, 0xa9, 0x8f,\r
- 0xfb, 0x2c, 0x71, 0xd2, 0x5a, 0xc5, 0xee, 0x92,\r
- 0x73, 0x8e, 0x43, 0x7f, 0x4b, 0x3f, 0xff, 0xd6,\r
- 0xee, 0x7f, 0xea, 0x9a, 0x4a, 0x19, 0x1f, 0xe3,\r
- 0x54, 0xba, 0xd3, 0xd1, 0x55, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x1b, 0xbc, 0x00, 0xb5, 0xe8,\r
- 0x4a, 0xf9, 0x00, 0x28, 0x00, 0x00,\r
- }\r
-\r
- err := IsTarGz(bytes.NewBuffer(content))\r
- if err != nil {\r
- t.Errorf("Error reading valid tar.gz file %s", err.Error())\r
- }\r
- })\r
-\r
- t.Run("Invalid tar.gz", func(t *testing.T) {\r
- content := []byte{\r
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0xff, 0xf2, 0x48, 0xcd,\r
- }\r
-\r
- err := IsTarGz(bytes.NewBuffer(content))\r
- if err == nil {\r
- t.Errorf("Error should NOT be nil")\r
- }\r
- })\r
-\r
- t.Run("Empty tar.gz", func(t *testing.T) {\r
- content := []byte{}\r
- err := IsTarGz(bytes.NewBuffer(content))\r
- if err == nil {\r
- t.Errorf("Error should NOT be nil")\r
- }\r
- })\r
-}\r
-\r
-func TestIsValidName(t *testing.T) {\r
- t.Run("Valid Names", func(t *testing.T) {\r
- validnames := []string{\r
- "abc123",\r
- "1_abc123.ONE",\r
- "0abcABC_-.5",\r
- "123456789012345678901234567890123456789012345678901234567890123", // max of 63 characters\r
- }\r
- for _, name := range validnames {\r
- errs := IsValidName(name)\r
- if len(errs) > 0 {\r
- t.Errorf("Valid name failed to pass: %v", name)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid Names", func(t *testing.T) {\r
- invalidnames := []string{\r
- "", // empty\r
- "_abc123", // starts with non-alphanum\r
- "-abc123", // starts with non-alphanum\r
- ".abc123", // starts with non-alphanum\r
- "abc123-", // ends with non-alphanum\r
- "abc123_", // ends with non-alphanum\r
- "abc123.", // ends with non-alphanum\r
- "1_abc-123.O=NE", // contains not allowed character\r
- "1_a/bc-123.ONE", // contains not allowed character\r
- "1234567890123456789012345678901234567890123456789012345678901234", // longer than 63 characters\r
- }\r
- for _, name := range invalidnames {\r
- errs := IsValidName(name)\r
- if len(errs) == 0 {\r
- t.Errorf("Invalid name passed: %v", name)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsIpv4Cidr(t *testing.T) {\r
- t.Run("Valid IPv4 Cidr", func(t *testing.T) {\r
- validipv4cidr := []string{\r
- "1.2.3.4/32",\r
- "10.11.12.0/24",\r
- "192.168.1.2/8",\r
- "255.0.0.0/16",\r
- }\r
- for _, ip := range validipv4cidr {\r
- err := IsIpv4Cidr(ip)\r
- if err != nil {\r
- t.Errorf("Valid IPv4 CIDR string failed to pass: %v", ip)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid IPv4 Cidr", func(t *testing.T) {\r
- invalidipv4cidr := []string{\r
- "",\r
- "1.2.3.4.5/32",\r
- "1.2.3.415/16",\r
- "1.2.3.4/33",\r
- "2.3.4/24",\r
- "1.2.3.4",\r
- "1.2.3.4/",\r
- }\r
- for _, ip := range invalidipv4cidr {\r
- err := IsIpv4Cidr(ip)\r
- if err == nil {\r
- t.Errorf("Invalid IPv4 Cidr passed: %v", ip)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsIpv4(t *testing.T) {\r
- t.Run("Valid IPv4", func(t *testing.T) {\r
- validipv4 := []string{\r
- "1.2.3.42",\r
- "10.11.12.0",\r
- "192.168.1.2",\r
- "255.0.0.0",\r
- "255.255.255.255",\r
- "0.0.0.0",\r
- }\r
- for _, ip := range validipv4 {\r
- err := IsIpv4(ip)\r
- if err != nil {\r
- t.Errorf("Valid IPv4 string failed to pass: %v", ip)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid IPv4", func(t *testing.T) {\r
- invalidipv4 := []string{\r
- "",\r
- "1.2.3.4.5",\r
- "1.2.3.45/32",\r
- "1.2.3.4a",\r
- "2.3.4",\r
- "1.2.3.400",\r
- "256.255.255.255",\r
- "10,11,12,13",\r
- "1.2.3.4/",\r
- }\r
- for _, ip := range invalidipv4 {\r
- err := IsIpv4(ip)\r
- if err == nil {\r
- t.Errorf("Invalid IPv4 passed: %v", ip)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsMac(t *testing.T) {\r
- t.Run("Valid MAC", func(t *testing.T) {\r
- validmacs := []string{\r
- "11:22:33:44:55:66",\r
- "ab-cd-ef-12-34-56",\r
- "AB-CD-EF-12-34-56",\r
- }\r
- for _, mac := range validmacs {\r
- err := IsMac(mac)\r
- if err != nil {\r
- t.Errorf("Valid MAC string failed to pass: %v", mac)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid MAC", func(t *testing.T) {\r
- invalidmacs := []string{\r
- "",\r
- "1.2.3.4.5",\r
- "1.2.3.45/32",\r
- "ab:cd:ef:gh:12:34",\r
- "11:22-33-44:55:66",\r
- "11,22,33,44,55,66",\r
- "11|22|33|44|55|66",\r
- "11:22:33:44:55:66:77",\r
- "11-22-33-44-55",\r
- "11-22-33-44-55-66-77",\r
- }\r
- for _, mac := range invalidmacs {\r
- err := IsMac(mac)\r
- if err == nil {\r
- t.Errorf("Invalid MAC passed: %v", mac)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsValidString(t *testing.T) {\r
- t.Run("Valid Strings", func(t *testing.T) {\r
- validStrings := []struct {\r
- str string\r
- min int\r
- max int\r
- format string\r
- }{\r
- {\r
- str: "abc123",\r
- min: 0,\r
- max: 16,\r
- format: VALID_NAME_STR,\r
- },\r
- {\r
- str: "ab-c1_2.3",\r
- min: 0,\r
- max: 16,\r
- format: VALID_NAME_STR,\r
- },\r
- {\r
- str: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",\r
- min: 0,\r
- max: 62,\r
- format: VALID_ALPHANUM_STR,\r
- },\r
- {\r
- str: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",\r
- min: 0,\r
- max: 52,\r
- format: VALID_ALPHA_STR,\r
- },\r
- {\r
- str: "",\r
- min: 0,\r
- max: 52,\r
- format: VALID_ALPHA_STR,\r
- },\r
- {\r
- str: "",\r
- min: 0,\r
- max: 52,\r
- format: VALID_ALPHANUM_STR,\r
- },\r
- {\r
- str: "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg==",\r
- min: 0,\r
- max: 52,\r
- format: VALID_BASE64_STR,\r
- },\r
- {\r
- str: "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",\r
- min: 0,\r
- max: 256,\r
- format: VALID_ANY_STR,\r
- },\r
- }\r
- for _, test := range validStrings {\r
- errs := IsValidString(test.str, test.min, test.max, test.format)\r
- if len(errs) > 0 {\r
- t.Errorf("Valid string failed to pass: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid Strings", func(t *testing.T) {\r
- inValidStrings := []struct {\r
- str string\r
- min int\r
- max int\r
- format string\r
- }{\r
- {\r
- str: "abc123",\r
- min: 0,\r
- max: 5,\r
- format: VALID_NAME_STR,\r
- },\r
- {\r
- str: "",\r
- min: 0,\r
- max: 5,\r
- format: VALID_NAME_STR,\r
- },\r
- {\r
- str: "-ab-c1_2.3",\r
- min: 0,\r
- max: 16,\r
- format: VALID_NAME_STR,\r
- },\r
- {\r
- str: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=",\r
- min: 0,\r
- max: 100,\r
- format: VALID_ALPHANUM_STR,\r
- },\r
- {\r
- str: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456",\r
- min: 0,\r
- max: 62,\r
- format: VALID_ALPHA_STR,\r
- },\r
- {\r
- str: "",\r
- min: 1,\r
- max: 52,\r
- format: VALID_ALPHA_STR,\r
- },\r
- {\r
- str: "abc123",\r
- min: 1,\r
- max: 3,\r
- format: VALID_ALPHA_STR,\r
- },\r
- {\r
- str: "",\r
- min: 1,\r
- max: 52,\r
- format: VALID_ALPHANUM_STR,\r
- },\r
- {\r
- str: "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg===",\r
- min: 0,\r
- max: 52,\r
- format: VALID_BASE64_STR,\r
- },\r
- {\r
- str: "dGhpcyBpcyBhCnRlc3=Qgc3RyaW5nCg==",\r
- min: 0,\r
- max: 52,\r
- format: VALID_BASE64_STR,\r
- },\r
- {\r
- str: "dGhpcyBpcyBhCnRlc3#Qgc3RyaW5nCg==",\r
- min: 0,\r
- max: 52,\r
- format: VALID_BASE64_STR,\r
- },\r
- {\r
- str: "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",\r
- min: 0,\r
- max: 10,\r
- format: VALID_ANY_STR,\r
- },\r
- {\r
- str: "abc123",\r
- min: 0,\r
- max: 10,\r
- format: "unknownformat",\r
- },\r
- }\r
- for _, test := range inValidStrings {\r
- errs := IsValidString(test.str, test.min, test.max, test.format)\r
- if len(errs) == 0 {\r
- t.Errorf("Invalid string passed: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsValidLabel(t *testing.T) {\r
- t.Run("Valid Labels", func(t *testing.T) {\r
- validlabels := []string{\r
- "kubernetes.io/hostname=localhost",\r
- "hostname=localhost",\r
- "localhost",\r
- }\r
- for _, label := range validlabels {\r
- errs := IsValidLabel(label)\r
- if len(errs) > 0 {\r
- t.Errorf("Valid label failed to pass: %v %v", label, errs)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid Labels", func(t *testing.T) {\r
- invalidlabels := []string{\r
- "",\r
- "kubernetes$.io/hostname=localhost",\r
- "hostname==localhost",\r
- "=localhost",\r
- "/hostname=localhost",\r
- ".a.b/hostname=localhost",\r
- "kubernetes.io/hostname",\r
- "kubernetes.io/hostname=",\r
- "kubernetes.io/1234567890123456789012345678901234567890123456789012345678901234=localhost", // too long name\r
- "kubernetes.io/hostname=localhost1234567890123456789012345678901234567890123456789012345678901234", // too long value\r
- "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234/hostname=localhost", // too long prefix\r
- }\r
- for _, label := range invalidlabels {\r
- errs := IsValidLabel(label)\r
- if len(errs) == 0 {\r
- t.Errorf("Invalid label passed: %v", label)\r
- }\r
- }\r
- })\r
-}\r
-\r
-func TestIsValidNumber(t *testing.T) {\r
- t.Run("Valid Number", func(t *testing.T) {\r
- validNumbers := []struct {\r
- value int\r
- min int\r
- max int\r
- }{\r
- {\r
- value: 0,\r
- min: 0,\r
- max: 5,\r
- },\r
- {\r
- value: 1000,\r
- min: 0,\r
- max: 4095,\r
- },\r
- {\r
- value: 0,\r
- min: 0,\r
- max: 0,\r
- },\r
- {\r
- value: -100,\r
- min: -200,\r
- max: -99,\r
- },\r
- {\r
- value: 123,\r
- min: 123,\r
- max: 123,\r
- },\r
- }\r
- for _, test := range validNumbers {\r
- err := IsValidNumber(test.value, test.min, test.max)\r
- if len(err) > 0 {\r
- t.Errorf("Valid number failed to pass - value:%v, min:%v, max:%v", test.value, test.min, test.max)\r
- }\r
- }\r
- })\r
-\r
- t.Run("Invalid Number", func(t *testing.T) {\r
- inValidNumbers := []struct {\r
- value int\r
- min int\r
- max int\r
- }{\r
- {\r
- value: 6,\r
- min: 0,\r
- max: 5,\r
- },\r
- {\r
- value: 4096,\r
- min: 0,\r
- max: 4095,\r
- },\r
- {\r
- value: 11,\r
- min: 10,\r
- max: 10,\r
- },\r
- {\r
- value: -100,\r
- min: -99,\r
- max: -200,\r
- },\r
- {\r
- value: 123,\r
- min: 223,\r
- max: 123,\r
- },\r
- }\r
- for _, test := range inValidNumbers {\r
- err := IsValidNumber(test.value, test.min, test.max)\r
- if len(err) == 0 {\r
- t.Errorf("Invalid number passed - value:%v, min:%v, max:%v", test.value, test.min, test.max)\r
- }\r
- }\r
- })\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package validation
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestIsTarGz(t *testing.T) {
+
+ t.Run("Valid tar.gz", func(t *testing.T) {
+ content := []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
+ 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
+ 0x61, 0x72, 0x00, 0xed, 0xce, 0x41, 0x0a, 0xc2,
+ 0x30, 0x10, 0x85, 0xe1, 0xac, 0x3d, 0x45, 0x4e,
+ 0x50, 0x12, 0xd2, 0xc4, 0xe3, 0x48, 0xa0, 0x01,
+ 0x4b, 0x52, 0x0b, 0xed, 0x88, 0x1e, 0xdf, 0x48,
+ 0x11, 0x5c, 0x08, 0xa5, 0x8b, 0x52, 0x84, 0xff,
+ 0xdb, 0xbc, 0x61, 0x66, 0x16, 0x4f, 0xd2, 0x2c,
+ 0x8d, 0x3c, 0x45, 0xed, 0xc8, 0x54, 0x21, 0xb4,
+ 0xef, 0xb4, 0x67, 0x6f, 0xbe, 0x73, 0x61, 0x9d,
+ 0xb2, 0xce, 0xd5, 0x55, 0xf0, 0xde, 0xd7, 0x3f,
+ 0xdb, 0xd6, 0x49, 0x69, 0xb3, 0x67, 0xa9, 0x8f,
+ 0xfb, 0x2c, 0x71, 0xd2, 0x5a, 0xc5, 0xee, 0x92,
+ 0x73, 0x8e, 0x43, 0x7f, 0x4b, 0x3f, 0xff, 0xd6,
+ 0xee, 0x7f, 0xea, 0x9a, 0x4a, 0x19, 0x1f, 0xe3,
+ 0x54, 0xba, 0xd3, 0xd1, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0xbc, 0x00, 0xb5, 0xe8,
+ 0x4a, 0xf9, 0x00, 0x28, 0x00, 0x00,
+ }
+
+ err := IsTarGz(bytes.NewBuffer(content))
+ if err != nil {
+ t.Errorf("Error reading valid tar.gz file %s", err.Error())
+ }
+ })
+
+ t.Run("Invalid tar.gz", func(t *testing.T) {
+ content := []byte{
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xf2, 0x48, 0xcd,
+ }
+
+ err := IsTarGz(bytes.NewBuffer(content))
+ if err == nil {
+ t.Errorf("Error should NOT be nil")
+ }
+ })
+
+ t.Run("Empty tar.gz", func(t *testing.T) {
+ content := []byte{}
+ err := IsTarGz(bytes.NewBuffer(content))
+ if err == nil {
+ t.Errorf("Error should NOT be nil")
+ }
+ })
+}
+
+func TestIsValidName(t *testing.T) {
+ t.Run("Valid Names", func(t *testing.T) {
+ validnames := []string{
+ "abc123",
+ "1_abc123.ONE",
+ "0abcABC_-.5",
+ "123456789012345678901234567890123456789012345678901234567890123", // max of 63 characters
+ }
+ for _, name := range validnames {
+ errs := IsValidName(name)
+ if len(errs) > 0 {
+ t.Errorf("Valid name failed to pass: %v", name)
+ }
+ }
+ })
+
+ t.Run("Invalid Names", func(t *testing.T) {
+ invalidnames := []string{
+ "", // empty
+ "_abc123", // starts with non-alphanum
+ "-abc123", // starts with non-alphanum
+ ".abc123", // starts with non-alphanum
+ "abc123-", // ends with non-alphanum
+ "abc123_", // ends with non-alphanum
+ "abc123.", // ends with non-alphanum
+ "1_abc-123.O=NE", // contains not allowed character
+ "1_a/bc-123.ONE", // contains not allowed character
+ "1234567890123456789012345678901234567890123456789012345678901234", // longer than 63 characters
+ }
+ for _, name := range invalidnames {
+ errs := IsValidName(name)
+ if len(errs) == 0 {
+ t.Errorf("Invalid name passed: %v", name)
+ }
+ }
+ })
+}
+
+func TestIsIpv4Cidr(t *testing.T) {
+ t.Run("Valid IPv4 Cidr", func(t *testing.T) {
+ validipv4cidr := []string{
+ "1.2.3.4/32",
+ "10.11.12.0/24",
+ "192.168.1.2/8",
+ "255.0.0.0/16",
+ }
+ for _, ip := range validipv4cidr {
+ err := IsIpv4Cidr(ip)
+ if err != nil {
+ t.Errorf("Valid IPv4 CIDR string failed to pass: %v", ip)
+ }
+ }
+ })
+
+ t.Run("Invalid IPv4 Cidr", func(t *testing.T) {
+ invalidipv4cidr := []string{
+ "",
+ "1.2.3.4.5/32",
+ "1.2.3.415/16",
+ "1.2.3.4/33",
+ "2.3.4/24",
+ "1.2.3.4",
+ "1.2.3.4/",
+ }
+ for _, ip := range invalidipv4cidr {
+ err := IsIpv4Cidr(ip)
+ if err == nil {
+ t.Errorf("Invalid IPv4 Cidr passed: %v", ip)
+ }
+ }
+ })
+}
+
+func TestIsIpv4(t *testing.T) {
+ t.Run("Valid IPv4", func(t *testing.T) {
+ validipv4 := []string{
+ "1.2.3.42",
+ "10.11.12.0",
+ "192.168.1.2",
+ "255.0.0.0",
+ "255.255.255.255",
+ "0.0.0.0",
+ }
+ for _, ip := range validipv4 {
+ err := IsIpv4(ip)
+ if err != nil {
+ t.Errorf("Valid IPv4 string failed to pass: %v", ip)
+ }
+ }
+ })
+
+ t.Run("Invalid IPv4", func(t *testing.T) {
+ invalidipv4 := []string{
+ "",
+ "1.2.3.4.5",
+ "1.2.3.45/32",
+ "1.2.3.4a",
+ "2.3.4",
+ "1.2.3.400",
+ "256.255.255.255",
+ "10,11,12,13",
+ "1.2.3.4/",
+ }
+ for _, ip := range invalidipv4 {
+ err := IsIpv4(ip)
+ if err == nil {
+ t.Errorf("Invalid IPv4 passed: %v", ip)
+ }
+ }
+ })
+}
+
+func TestIsMac(t *testing.T) {
+ t.Run("Valid MAC", func(t *testing.T) {
+ validmacs := []string{
+ "11:22:33:44:55:66",
+ "ab-cd-ef-12-34-56",
+ "AB-CD-EF-12-34-56",
+ }
+ for _, mac := range validmacs {
+ err := IsMac(mac)
+ if err != nil {
+ t.Errorf("Valid MAC string failed to pass: %v", mac)
+ }
+ }
+ })
+
+ t.Run("Invalid MAC", func(t *testing.T) {
+ invalidmacs := []string{
+ "",
+ "1.2.3.4.5",
+ "1.2.3.45/32",
+ "ab:cd:ef:gh:12:34",
+ "11:22-33-44:55:66",
+ "11,22,33,44,55,66",
+ "11|22|33|44|55|66",
+ "11:22:33:44:55:66:77",
+ "11-22-33-44-55",
+ "11-22-33-44-55-66-77",
+ }
+ for _, mac := range invalidmacs {
+ err := IsMac(mac)
+ if err == nil {
+ t.Errorf("Invalid MAC passed: %v", mac)
+ }
+ }
+ })
+}
+
+func TestIsValidString(t *testing.T) {
+ t.Run("Valid Strings", func(t *testing.T) {
+ validStrings := []struct {
+ str string
+ min int
+ max int
+ format string
+ }{
+ {
+ str: "abc123",
+ min: 0,
+ max: 16,
+ format: VALID_NAME_STR,
+ },
+ {
+ str: "ab-c1_2.3",
+ min: 0,
+ max: 16,
+ format: VALID_NAME_STR,
+ },
+ {
+ str: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ min: 0,
+ max: 62,
+ format: VALID_ALPHANUM_STR,
+ },
+ {
+ str: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ min: 0,
+ max: 52,
+ format: VALID_ALPHA_STR,
+ },
+ {
+ str: "",
+ min: 0,
+ max: 52,
+ format: VALID_ALPHA_STR,
+ },
+ {
+ str: "",
+ min: 0,
+ max: 52,
+ format: VALID_ALPHANUM_STR,
+ },
+ {
+ str: "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg==",
+ min: 0,
+ max: 52,
+ format: VALID_BASE64_STR,
+ },
+ {
+ str: "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",
+ min: 0,
+ max: 256,
+ format: VALID_ANY_STR,
+ },
+ }
+ for _, test := range validStrings {
+ errs := IsValidString(test.str, test.min, test.max, test.format)
+ if len(errs) > 0 {
+ t.Errorf("Valid string failed to pass: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)
+ }
+ }
+ })
+
+ t.Run("Invalid Strings", func(t *testing.T) {
+ inValidStrings := []struct {
+ str string
+ min int
+ max int
+ format string
+ }{
+ {
+ str: "abc123",
+ min: 0,
+ max: 5,
+ format: VALID_NAME_STR,
+ },
+ {
+ str: "",
+ min: 0,
+ max: 5,
+ format: VALID_NAME_STR,
+ },
+ {
+ str: "-ab-c1_2.3",
+ min: 0,
+ max: 16,
+ format: VALID_NAME_STR,
+ },
+ {
+ str: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=",
+ min: 0,
+ max: 100,
+ format: VALID_ALPHANUM_STR,
+ },
+ {
+ str: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456",
+ min: 0,
+ max: 62,
+ format: VALID_ALPHA_STR,
+ },
+ {
+ str: "",
+ min: 1,
+ max: 52,
+ format: VALID_ALPHA_STR,
+ },
+ {
+ str: "abc123",
+ min: 1,
+ max: 3,
+ format: VALID_ALPHA_STR,
+ },
+ {
+ str: "",
+ min: 1,
+ max: 52,
+ format: VALID_ALPHANUM_STR,
+ },
+ {
+ str: "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg===",
+ min: 0,
+ max: 52,
+ format: VALID_BASE64_STR,
+ },
+ {
+ str: "dGhpcyBpcyBhCnRlc3=Qgc3RyaW5nCg==",
+ min: 0,
+ max: 52,
+ format: VALID_BASE64_STR,
+ },
+ {
+ str: "dGhpcyBpcyBhCnRlc3#Qgc3RyaW5nCg==",
+ min: 0,
+ max: 52,
+ format: VALID_BASE64_STR,
+ },
+ {
+ str: "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",
+ min: 0,
+ max: 10,
+ format: VALID_ANY_STR,
+ },
+ {
+ str: "abc123",
+ min: 0,
+ max: 10,
+ format: "unknownformat",
+ },
+ }
+ for _, test := range inValidStrings {
+ errs := IsValidString(test.str, test.min, test.max, test.format)
+ if len(errs) == 0 {
+ t.Errorf("Invalid string passed: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)
+ }
+ }
+ })
+}
+
+func TestIsValidLabel(t *testing.T) {
+ t.Run("Valid Labels", func(t *testing.T) {
+ validlabels := []string{
+ "kubernetes.io/hostname=localhost",
+ "hostname=localhost",
+ "localhost",
+ }
+ for _, label := range validlabels {
+ errs := IsValidLabel(label)
+ if len(errs) > 0 {
+ t.Errorf("Valid label failed to pass: %v %v", label, errs)
+ }
+ }
+ })
+
+ t.Run("Invalid Labels", func(t *testing.T) {
+ invalidlabels := []string{
+ "",
+ "kubernetes$.io/hostname=localhost",
+ "hostname==localhost",
+ "=localhost",
+ "/hostname=localhost",
+ ".a.b/hostname=localhost",
+ "kubernetes.io/hostname",
+ "kubernetes.io/hostname=",
+ "kubernetes.io/1234567890123456789012345678901234567890123456789012345678901234=localhost", // too long name
+ "kubernetes.io/hostname=localhost1234567890123456789012345678901234567890123456789012345678901234", // too long value
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234/hostname=localhost", // too long prefix
+ }
+ for _, label := range invalidlabels {
+ errs := IsValidLabel(label)
+ if len(errs) == 0 {
+ t.Errorf("Invalid label passed: %v", label)
+ }
+ }
+ })
+}
+
+func TestIsValidNumber(t *testing.T) {
+ t.Run("Valid Number", func(t *testing.T) {
+ validNumbers := []struct {
+ value int
+ min int
+ max int
+ }{
+ {
+ value: 0,
+ min: 0,
+ max: 5,
+ },
+ {
+ value: 1000,
+ min: 0,
+ max: 4095,
+ },
+ {
+ value: 0,
+ min: 0,
+ max: 0,
+ },
+ {
+ value: -100,
+ min: -200,
+ max: -99,
+ },
+ {
+ value: 123,
+ min: 123,
+ max: 123,
+ },
+ }
+ for _, test := range validNumbers {
+ err := IsValidNumber(test.value, test.min, test.max)
+ if len(err) > 0 {
+ t.Errorf("Valid number failed to pass - value:%v, min:%v, max:%v", test.value, test.min, test.max)
+ }
+ }
+ })
+
+ t.Run("Invalid Number", func(t *testing.T) {
+ inValidNumbers := []struct {
+ value int
+ min int
+ max int
+ }{
+ {
+ value: 6,
+ min: 0,
+ max: 5,
+ },
+ {
+ value: 4096,
+ min: 0,
+ max: 4095,
+ },
+ {
+ value: 11,
+ min: 10,
+ max: 10,
+ },
+ {
+ value: -100,
+ min: -99,
+ max: -200,
+ },
+ {
+ value: 123,
+ min: 223,
+ max: 123,
+ },
+ }
+ for _, test := range inValidNumbers {
+ err := IsValidNumber(test.value, test.min, test.max)
+ if len(err) == 0 {
+ t.Errorf("Invalid number passed - value:%v, min:%v, max:%v", test.value, test.min, test.max)
+ }
+ }
+ })
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package controller\r
-\r
-import (\r
- "encoding/json"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- rpc "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"\r
- mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// Controller contains the parameters needed for Controllers\r
-// It implements the interface for managing the Controllers\r
-type Controller struct {\r
- Metadata mtypes.Metadata `json:"metadata"`\r
- Spec ControllerSpec `json:"spec"`\r
-}\r
-\r
-type ControllerSpec struct {\r
- Host string `json:"host"`\r
- Port int `json:"port"`\r
- Type string `json:"type"`\r
- Priority int `json:"priority"`\r
-}\r
-\r
-const MinControllerPriority = 1\r
-const MaxControllerPriority = 1000000\r
-const CONTROLLER_TYPE_ACTION string = "action"\r
-const CONTROLLER_TYPE_PLACEMENT string = "placement"\r
-\r
-var CONTROLLER_TYPES = [...]string{CONTROLLER_TYPE_ACTION, CONTROLLER_TYPE_PLACEMENT}\r
-\r
-// ControllerKey is the key structure that is used in the database\r
-type ControllerKey struct {\r
- ControllerName string `json:"controller-name"`\r
-}\r
-\r
-// We will use json marshalling to convert to string to\r
-// preserve the underlying structure.\r
-func (mk ControllerKey) String() string {\r
- out, err := json.Marshal(mk)\r
- if err != nil {\r
- return ""\r
- }\r
-\r
- return string(out)\r
-}\r
-\r
-// ControllerManager is an interface exposes the Controller functionality\r
-type ControllerManager interface {\r
- CreateController(ms Controller, mayExist bool) (Controller, error)\r
- GetController(name string) (Controller, error)\r
- GetControllers() ([]Controller, error)\r
- InitControllers()\r
- DeleteController(name string) error\r
-}\r
-\r
-// ControllerClient implements the Manager\r
-// It will also be used to maintain some localized state\r
-type ControllerClient struct {\r
- collectionName string\r
- tagMeta string\r
-}\r
-\r
-// NewControllerClient returns an instance of the ControllerClient\r
-// which implements the Manager\r
-func NewControllerClient() *ControllerClient {\r
- return &ControllerClient{\r
- collectionName: "controller",\r
- tagMeta: "controllermetadata",\r
- }\r
-}\r
-\r
-// CreateController a new collection based on the Controller\r
-func (mc *ControllerClient) CreateController(m Controller, mayExist bool) (Controller, error) {\r
-\r
- //Construct the composite key to select the entry\r
- key := ControllerKey{\r
- ControllerName: m.Metadata.Name,\r
- }\r
-\r
- //Check if this Controller already exists\r
- _, err := mc.GetController(m.Metadata.Name)\r
- if err == nil && !mayExist {\r
- return Controller{}, pkgerrors.New("Controller already exists")\r
- }\r
-\r
- err = db.DBconn.Insert(mc.collectionName, key, nil, mc.tagMeta, m)\r
- if err != nil {\r
- return Controller{}, pkgerrors.Wrap(err, "Creating DB Entry")\r
- }\r
-\r
- // send message to create/update the rpc connection\r
- rpc.UpdateRpcConn(m.Metadata.Name, m.Spec.Host, m.Spec.Port)\r
-\r
- return m, nil\r
-}\r
-\r
-// GetController returns the Controller for corresponding name\r
-func (mc *ControllerClient) GetController(name string) (Controller, error) {\r
-\r
- //Construct the composite key to select the entry\r
- key := ControllerKey{\r
- ControllerName: name,\r
- }\r
- value, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)\r
- if err != nil {\r
- return Controller{}, pkgerrors.Wrap(err, "Get Controller")\r
- }\r
-\r
- if value != nil {\r
- microserv := Controller{}\r
- err = db.DBconn.Unmarshal(value[0], µserv)\r
- if err != nil {\r
- return Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")\r
- }\r
- return microserv, nil\r
- }\r
-\r
- return Controller{}, pkgerrors.New("Error getting Controller")\r
-}\r
-\r
-// GetControllers returns all the Controllers that are registered\r
-func (mc *ControllerClient) GetControllers() ([]Controller, error) {\r
-\r
- //Construct the composite key to select the entry\r
- key := ControllerKey{\r
- ControllerName: "",\r
- }\r
-\r
- var resp []Controller\r
- values, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)\r
- if err != nil {\r
- return []Controller{}, pkgerrors.Wrap(err, "Get Controller")\r
- }\r
-\r
- for _, value := range values {\r
- microserv := Controller{}\r
- err = db.DBconn.Unmarshal(value, µserv)\r
- if err != nil {\r
- return []Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")\r
- }\r
-\r
- resp = append(resp, microserv)\r
- }\r
-\r
- return resp, nil\r
-}\r
-\r
-// DeleteController the Controller from database\r
-func (mc *ControllerClient) DeleteController(name string) error {\r
-\r
- //Construct the composite key to select the entry\r
- key := ControllerKey{\r
- ControllerName: name,\r
- }\r
- err := db.DBconn.Remove(mc.collectionName, key)\r
- if err != nil {\r
- return pkgerrors.Wrap(err, "Delete Controller Entry;")\r
- }\r
-\r
- // send message to close rpc connection\r
- rpc.RemoveRpcConn(name)\r
-\r
- return nil\r
-}\r
-\r
-// InitControllers initializes connctions for controllers in the DB\r
-func (mc *ControllerClient) InitControllers() {\r
- vals, _ := mc.GetControllers()\r
- for _, v := range vals {\r
- log.Info("Initializing RPC connection for controller", log.Fields{\r
- "Controller": v.Metadata.Name,\r
- })\r
- rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package controller
+
+import (
+ "encoding/json"
+ "strings"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ rpc "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
+ mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// Controller contains the parameters needed for Controllers
+// It implements the interface for managing the Controllers
+type Controller struct {
+ Metadata mtypes.Metadata `json:"metadata"`
+ Spec ControllerSpec `json:"spec"`
+}
+
+type ControllerSpec struct {
+ Host string `json:"host"`
+ Port int `json:"port"`
+ Type string `json:"type"`
+ Priority int `json:"priority"`
+}
+
+const MinControllerPriority = 1
+const MaxControllerPriority = 1000000
+const CONTROLLER_TYPE_ACTION string = "action"
+const CONTROLLER_TYPE_PLACEMENT string = "placement"
+
+var CONTROLLER_TYPES = [...]string{CONTROLLER_TYPE_ACTION, CONTROLLER_TYPE_PLACEMENT}
+
+// ControllerKey is the key structure that is used in the database
+type ControllerKey struct {
+ ControllerName string `json:"controller-name"`
+}
+
+// We will use json marshalling to convert to string to
+// preserve the underlying structure.
+func (mk ControllerKey) String() string {
+ out, err := json.Marshal(mk)
+ if err != nil {
+ return ""
+ }
+
+ return string(out)
+}
+
+// ControllerManager is an interface exposes the Controller functionality
+type ControllerManager interface {
+ CreateController(ms Controller, mayExist bool) (Controller, error)
+ GetController(name string) (Controller, error)
+ GetControllers() ([]Controller, error)
+ InitControllers()
+ DeleteController(name string) error
+}
+
+// ControllerClient implements the Manager
+// It will also be used to maintain some localized state
+type ControllerClient struct {
+ collectionName string
+ tagMeta string
+}
+
+// NewControllerClient returns an instance of the ControllerClient
+// which implements the Manager
+func NewControllerClient() *ControllerClient {
+ return &ControllerClient{
+ collectionName: "controller",
+ tagMeta: "controllermetadata",
+ }
+}
+
+// CreateController a new collection based on the Controller
+func (mc *ControllerClient) CreateController(m Controller, mayExist bool) (Controller, error) {
+
+ log.Info("CreateController .. start", log.Fields{"Controller": m, "exists": mayExist})
+
+ //Construct the composite key to select the entry
+ key := ControllerKey{
+ ControllerName: m.Metadata.Name,
+ }
+
+ //Check if this Controller already exists
+ _, err := mc.GetController(m.Metadata.Name)
+ if err == nil && !mayExist {
+ return Controller{}, pkgerrors.New("Controller already exists")
+ }
+
+ err = db.DBconn.Insert(mc.collectionName, key, nil, mc.tagMeta, m)
+ if err != nil {
+ return Controller{}, pkgerrors.Wrap(err, "Creating DB Entry")
+ }
+
+ // send message to create/update the rpc connection
+ rpc.UpdateRpcConn(m.Metadata.Name, m.Spec.Host, m.Spec.Port)
+
+ log.Info("CreateController .. end", log.Fields{"Controller": m, "exists": mayExist})
+ return m, nil
+}
+
+// GetController returns the Controller for corresponding name
+func (mc *ControllerClient) GetController(name string) (Controller, error) {
+
+ //Construct the composite key to select the entry
+ key := ControllerKey{
+ ControllerName: name,
+ }
+ value, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)
+ if err != nil {
+ return Controller{}, pkgerrors.Wrap(err, "db Find error")
+ } else if len(value) == 0 {
+ return Controller{}, pkgerrors.New("Controller not found")
+ }
+
+ if value != nil {
+ microserv := Controller{}
+ err = db.DBconn.Unmarshal(value[0], µserv)
+ if err != nil {
+ return Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ }
+ return microserv, nil
+ }
+
+ return Controller{}, pkgerrors.New("Error getting Controller")
+}
+
+// GetControllers returns all the Controllers that are registered
+func (mc *ControllerClient) GetControllers() ([]Controller, error) {
+
+ //Construct the composite key to select the entry
+ key := ControllerKey{
+ ControllerName: "",
+ }
+
+ var resp []Controller
+ values, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)
+ if err != nil {
+ return []Controller{}, pkgerrors.Wrap(err, "db Find error")
+ }
+
+ for _, value := range values {
+ microserv := Controller{}
+ err = db.DBconn.Unmarshal(value, µserv)
+ if err != nil {
+ return []Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ }
+
+ resp = append(resp, microserv)
+ }
+
+ return resp, nil
+}
+
+// DeleteController the Controller from database
+func (mc *ControllerClient) DeleteController(name string) error {
+
+ //Construct the composite key to select the entry
+ key := ControllerKey{
+ ControllerName: name,
+ }
+ err := db.DBconn.Remove(mc.collectionName, key)
+ if err != nil {
+ if strings.Contains(err.Error(), "Error finding:") {
+ return pkgerrors.Wrap(err, "db Remove error - not found")
+ } else if strings.Contains(err.Error(), "Can't delete parent without deleting child") {
+ return pkgerrors.Wrap(err, "db Remove error - conflict")
+ } else {
+ return pkgerrors.Wrap(err, "db Remove error - general")
+ }
+ }
+
+ // send message to close rpc connection
+ rpc.RemoveRpcConn(name)
+
+ return nil
+}
+
+// InitControllers initializes connctions for controllers in the DB
+func (mc *ControllerClient) InitControllers() {
+ vals, _ := mc.GetControllers()
+ for _, v := range vals {
+ log.Info("Initializing RPC connection for controller", log.Fields{
+ "Controller": v.Metadata.Name,
+ })
+ rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package controller\r
-\r
-import (\r
- "reflect"\r
- "strings"\r
- "testing"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"\r
-\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-func TestCreateController(t *testing.T) {\r
- testCases := []struct {\r
- label string\r
- inp Controller\r
- expectedError string\r
- mockdb *db.MockDB\r
- expected Controller\r
- }{\r
- {\r
- label: "Create Controller",\r
- inp: Controller{\r
- Metadata: types.Metadata{\r
- Name: "testController",\r
- },\r
- Spec: ControllerSpec{\r
- Host: "132.156.0.10",\r
- Port: 8080,\r
- },\r
- },\r
- expected: Controller{\r
- Metadata: types.Metadata{\r
- Name: "testController",\r
- },\r
- Spec: ControllerSpec{\r
- Host: "132.156.0.10",\r
- Port: 8080,\r
- },\r
- },\r
- expectedError: "",\r
- mockdb: &db.MockDB{},\r
- },\r
- {\r
- label: "Failed Create Controller",\r
- expectedError: "Error Creating Controller",\r
- mockdb: &db.MockDB{\r
- Err: pkgerrors.New("Error Creating Controller"),\r
- },\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- db.DBconn = testCase.mockdb\r
- impl := NewControllerClient()\r
- got, err := impl.CreateController(testCase.inp, false)\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Create returned an unexpected error %s", err)\r
- }\r
- if strings.Contains(err.Error(), testCase.expectedError) == false {\r
- t.Fatalf("Create returned an unexpected error %s", err)\r
- }\r
- } else {\r
- if reflect.DeepEqual(testCase.expected, got) == false {\r
- t.Errorf("Create returned unexpected body: got %v;"+\r
- " expected %v", got, testCase.expected)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestGetController(t *testing.T) {\r
-\r
- testCases := []struct {\r
- label string\r
- name string\r
- expectedError string\r
- mockdb *db.MockDB\r
- inp string\r
- expected Controller\r
- }{\r
- {\r
- label: "Get Controller",\r
- name: "testController",\r
- expected: Controller{\r
- Metadata: types.Metadata{\r
- Name: "testController",\r
- },\r
- Spec: ControllerSpec{\r
- Host: "132.156.0.10",\r
- Port: 8080,\r
- },\r
- },\r
- expectedError: "",\r
- mockdb: &db.MockDB{\r
- Items: map[string]map[string][]byte{\r
- ControllerKey{ControllerName: "testController"}.String(): {\r
- "controllermetadata": []byte(\r
- "{\"metadata\":{" +\r
- "\"name\":\"testController\"" +\r
- "}," +\r
- "\"spec\":{" +\r
- "\"host\":\"132.156.0.10\"," +\r
- "\"port\": 8080 }}"),\r
- },\r
- },\r
- },\r
- },\r
- {\r
- label: "Get Error",\r
- expectedError: "DB Error",\r
- mockdb: &db.MockDB{\r
- Err: pkgerrors.New("DB Error"),\r
- },\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- db.DBconn = testCase.mockdb\r
- impl := NewControllerClient()\r
- got, err := impl.GetController(testCase.name)\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Get returned an unexpected error: %s", err)\r
- }\r
- if strings.Contains(err.Error(), testCase.expectedError) == false {\r
- t.Fatalf("Get returned an unexpected error: %s", err)\r
- }\r
- } else {\r
- if reflect.DeepEqual(testCase.expected, got) == false {\r
- t.Errorf("Get returned unexpected body: got %v;"+\r
- " expected %v", got, testCase.expected)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestDeleteController(t *testing.T) {\r
-\r
- testCases := []struct {\r
- label string\r
- name string\r
- expectedError string\r
- mockdb *db.MockDB\r
- }{\r
- {\r
- label: "Delete Controller",\r
- name: "testController",\r
- mockdb: &db.MockDB{},\r
- },\r
- {\r
- label: "Delete Error",\r
- expectedError: "DB Error",\r
- mockdb: &db.MockDB{\r
- Err: pkgerrors.New("DB Error"),\r
- },\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- db.DBconn = testCase.mockdb\r
- impl := NewControllerClient()\r
- err := impl.DeleteController(testCase.name)\r
- if err != nil {\r
- if testCase.expectedError == "" {\r
- t.Fatalf("Delete returned an unexpected error %s", err)\r
- }\r
- if strings.Contains(err.Error(), testCase.expectedError) == false {\r
- t.Fatalf("Delete returned an unexpected error %s", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package controller
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+func TestCreateController(t *testing.T) {
+ testCases := []struct {
+ label string
+ inp Controller
+ expectedError string
+ mockdb *db.MockDB
+ expected Controller
+ }{
+ {
+ label: "Create Controller",
+ inp: Controller{
+ Metadata: types.Metadata{
+ Name: "testController",
+ },
+ Spec: ControllerSpec{
+ Host: "132.156.0.10",
+ Port: 8080,
+ },
+ },
+ expected: Controller{
+ Metadata: types.Metadata{
+ Name: "testController",
+ },
+ Spec: ControllerSpec{
+ Host: "132.156.0.10",
+ Port: 8080,
+ },
+ },
+ expectedError: "",
+ mockdb: &db.MockDB{},
+ },
+ {
+ label: "Failed Create Controller",
+ expectedError: "Error Creating Controller",
+ mockdb: &db.MockDB{
+ Err: pkgerrors.New("Error Creating Controller"),
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ db.DBconn = testCase.mockdb
+ impl := NewControllerClient()
+ got, err := impl.CreateController(testCase.inp, false)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Create returned an unexpected error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Create returned an unexpected error %s", err)
+ }
+ } else {
+ if reflect.DeepEqual(testCase.expected, got) == false {
+ t.Errorf("Create returned unexpected body: got %v;"+
+ " expected %v", got, testCase.expected)
+ }
+ }
+ })
+ }
+}
+
+func TestGetController(t *testing.T) {
+
+ testCases := []struct {
+ label string
+ name string
+ expectedError string
+ mockdb *db.MockDB
+ inp string
+ expected Controller
+ }{
+ {
+ label: "Get Controller",
+ name: "testController",
+ expected: Controller{
+ Metadata: types.Metadata{
+ Name: "testController",
+ },
+ Spec: ControllerSpec{
+ Host: "132.156.0.10",
+ Port: 8080,
+ },
+ },
+ expectedError: "",
+ mockdb: &db.MockDB{
+ Items: []map[string]map[string][]byte{
+ {
+ ControllerKey{ControllerName: "testController"}.String(): {
+ "controllermetadata": []byte(
+ "{\"metadata\":{" +
+ "\"name\":\"testController\"" +
+ "}," +
+ "\"spec\":{" +
+ "\"host\":\"132.156.0.10\"," +
+ "\"port\": 8080 }}"),
+ },
+ },
+ },
+ },
+ },
+ {
+ label: "Get Error",
+ expectedError: "DB Error",
+ mockdb: &db.MockDB{
+ Err: pkgerrors.New("DB Error"),
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ db.DBconn = testCase.mockdb
+ impl := NewControllerClient()
+ got, err := impl.GetController(testCase.name)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Get returned an unexpected error: %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Get returned an unexpected error: %s", err)
+ }
+ } else {
+ if reflect.DeepEqual(testCase.expected, got) == false {
+ t.Errorf("Get returned unexpected body: got %v;"+
+ " expected %v", got, testCase.expected)
+ }
+ }
+ })
+ }
+}
+
+func TestDeleteController(t *testing.T) {
+
+ testCases := []struct {
+ label string
+ name string
+ expectedError string
+ mockdb *db.MockDB
+ }{
+ {
+ label: "Delete Controller",
+ name: "testController",
+ mockdb: &db.MockDB{},
+ },
+ {
+ label: "Delete Error",
+ expectedError: "DB Error",
+ mockdb: &db.MockDB{
+ Err: pkgerrors.New("DB Error"),
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ db.DBconn = testCase.mockdb
+ impl := NewControllerClient()
+ err := impl.DeleteController(testCase.name)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Delete returned an unexpected error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Delete returned an unexpected error %s", err)
+ }
+ }
+ })
+ }
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package types\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/validation"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-// It implements the interface for managing the ClusterProviders\r
-const MAX_DESCRIPTION_LEN int = 1024\r
-const MAX_USERDATA_LEN int = 4096\r
-\r
-type Metadata struct {\r
- Name string `json:"name" yaml:"name"`\r
- Description string `json:"description" yaml:"-"`\r
- UserData1 string `json:"userData1" yaml:"-"`\r
- UserData2 string `json:"userData2" yaml:"-"`\r
-}\r
-\r
-// Check for valid format Metadata\r
-func IsValidMetadata(metadata Metadata) error {\r
- errs := validation.IsValidName(metadata.Name)\r
- if len(errs) > 0 {\r
- return pkgerrors.Errorf("Invalid Metadata name=[%v], errors: %v", metadata.Name, errs)\r
- }\r
-\r
- errs = validation.IsValidString(metadata.Description, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)\r
- if len(errs) > 0 {\r
- return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.Description, errs)\r
- }\r
-\r
- errs = validation.IsValidString(metadata.UserData1, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)\r
- if len(errs) > 0 {\r
- return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.UserData1, errs)\r
- }\r
-\r
- errs = validation.IsValidString(metadata.UserData2, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)\r
- if len(errs) > 0 {\r
- return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.UserData2, errs)\r
- }\r
-\r
- return nil\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package types
+
+import (
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/validation"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// It implements the interface for managing the ClusterProviders
+const MAX_DESCRIPTION_LEN int = 1024
+const MAX_USERDATA_LEN int = 4096
+
+type Metadata struct {
+ Name string `json:"name" yaml:"name"`
+ Description string `json:"description" yaml:"-"`
+ UserData1 string `json:"userData1" yaml:"-"`
+ UserData2 string `json:"userData2" yaml:"-"`
+}
+
+// Check for valid format Metadata
+func IsValidMetadata(metadata Metadata) error {
+ errs := validation.IsValidName(metadata.Name)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid Metadata name=[%v], errors: %v", metadata.Name, errs)
+ }
+
+ errs = validation.IsValidString(metadata.Description, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.Description, errs)
+ }
+
+ errs = validation.IsValidString(metadata.UserData1, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.UserData1, errs)
+ }
+
+ errs = validation.IsValidString(metadata.UserData2, 0, MAX_DESCRIPTION_LEN, validation.VALID_ANY_STR)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid Metadata description=[%v], errors: %v", metadata.UserData2, errs)
+ }
+
+ return nil
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package resourcestatus\r
-\r
-// ResourceStatus struct is used to maintain the rsync status for resources in the appcontext\r
-// that rsync is synchronizing to clusters\r
-type ResourceStatus struct {\r
- Status RsyncStatus\r
-}\r
-\r
-type RsyncStatus = string\r
-\r
-type statusValues struct {\r
- Pending RsyncStatus\r
- Applied RsyncStatus\r
- Failed RsyncStatus\r
- Retrying RsyncStatus\r
- Deleted RsyncStatus\r
-}\r
-\r
-var RsyncStatusEnum = &statusValues{\r
- Pending: "Pending",\r
- Applied: "Applied",\r
- Failed: "Failed",\r
- Retrying: "Retrying",\r
- Deleted: "Deleted",\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package resourcestatus
+
+// ResourceStatus struct is used to maintain the rsync status for resources in the appcontext
+// that rsync is synchronizing to clusters
+type ResourceStatus struct {
+ Status RsyncStatus
+}
+
+type RsyncStatus = string
+
+type statusValues struct {
+ Pending RsyncStatus
+ Applied RsyncStatus
+ Failed RsyncStatus
+ Retrying RsyncStatus
+ Deleted RsyncStatus
+}
+
+var RsyncStatusEnum = &statusValues{
+ Pending: "Pending",
+ Applied: "Applied",
+ Failed: "Failed",
+ Retrying: "Retrying",
+ Deleted: "Deleted",
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package rtcontext\r
-\r
-import (\r
- "fmt"\r
- "math/rand"\r
- "strings"\r
- "time"\r
-\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"\r
- pkgerrors "github.com/pkg/errors"\r
-)\r
-\r
-const maxrand = 0x7fffffffffffffff\r
-const prefix string = "/context/"\r
-\r
-type RunTimeContext struct {\r
- cid interface{}\r
- meta interface{}\r
-}\r
-\r
-type Rtcontext interface {\r
- RtcInit() (interface{}, error)\r
- RtcLoad(interface{}) (interface{}, error)\r
- RtcCreate() (interface{}, error)\r
- RtcAddMeta(meta interface{}) error\r
- RtcGet() (interface{}, error)\r
- RtcAddLevel(handle interface{}, level string, value string) (interface{}, error)\r
- RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error)\r
- RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error)\r
- RtcDeletePair(handle interface{}) error\r
- RtcDeletePrefix(handle interface{}) error\r
- RtcGetHandles(handle interface{}) ([]interface{}, error)\r
- RtcGetValue(handle interface{}, value interface{}) error\r
- RtcUpdateValue(handle interface{}, value interface{}) error\r
- RtcGetMeta() (interface{}, error)\r
- RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error)\r
-}\r
-\r
-//Intialize context by assiging a new id\r
-func (rtc *RunTimeContext) RtcInit() (interface{}, error) {\r
- if rtc.cid != nil {\r
- return nil, pkgerrors.Errorf("Error, context already initialized")\r
- }\r
- ra := rand.New(rand.NewSource(time.Now().UnixNano()))\r
- rn := ra.Int63n(maxrand)\r
- id := fmt.Sprintf("%v", rn)\r
- cid := (prefix + id + "/")\r
- rtc.cid = interface{}(cid)\r
- return interface{}(id), nil\r
-\r
-}\r
-\r
-//Load context using the given id\r
-func (rtc *RunTimeContext) RtcLoad(id interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", id)\r
- if str == "" {\r
- return nil, pkgerrors.Errorf("Not a valid context id")\r
- }\r
- cid := (prefix + str + "/")\r
- rtc.cid = interface{}(cid)\r
- handle, err := rtc.RtcGet()\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error finding the context id: %s", err.Error())\r
- }\r
- return handle, nil\r
-}\r
-\r
-func (rtc *RunTimeContext) RtcCreate() (interface{}, error) {\r
- cid := fmt.Sprintf("%v", rtc.cid)\r
- if cid == "" {\r
- return nil, pkgerrors.Errorf("Error, context not intialized")\r
- }\r
- if !strings.HasPrefix(cid, prefix) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context prefix")\r
- }\r
- id := strings.SplitN(cid, "/", 4)[2]\r
- err := contextdb.Db.Put(cid, id)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error creating run time context: %s", err.Error())\r
- }\r
-\r
- return rtc.cid, nil\r
-}\r
-\r
-//RtcAddMeta is used for saving meta data of appContext into ETCD.\r
-func (rtc *RunTimeContext) RtcAddMeta(meta interface{}) error {\r
- cid := fmt.Sprintf("%v", rtc.cid)\r
- if cid == "" {\r
- return pkgerrors.Errorf("Error, context not intialized")\r
- }\r
- if !strings.HasPrefix(cid, prefix) {\r
- return pkgerrors.Errorf("Not a valid run time context prefix")\r
- }\r
-\r
- rtc.meta = meta\r
- k := cid + "meta" + "/"\r
- err := contextdb.Db.Put(k, rtc.meta)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error saving metadata in run time context: %s", err.Error())\r
- }\r
-\r
- return nil\r
-}\r
-\r
-//Get the root handle\r
-func (rtc *RunTimeContext) RtcGet() (interface{}, error) {\r
- str := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, prefix) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context")\r
- }\r
-\r
- var value string\r
- err := contextdb.Db.Get(str, &value)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())\r
- }\r
- if !strings.Contains(str, value) {\r
- return nil, pkgerrors.Errorf("Error matching run time context metadata")\r
- }\r
-\r
- return rtc.cid, nil\r
-}\r
-\r
-// RtcGetMeta method fetches the meta data of the rtc object and returns it.\r
-func (rtc *RunTimeContext) RtcGetMeta() (interface{}, error) {\r
- str := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, prefix) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context")\r
- }\r
-\r
- var value interface{}\r
- k := str + "meta" + "/"\r
- err := contextdb.Db.Get(k, &value)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())\r
- }\r
- return value, nil\r
-\r
-}\r
-\r
-//Add a new level at a given handle and return the new handle\r
-func (rtc *RunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- if level == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context level")\r
- }\r
- if value == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context level value")\r
- }\r
-\r
- key := str + level + "/" + value + "/"\r
- err := contextdb.Db.Put(key, value)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())\r
- }\r
-\r
- return (interface{})(key), nil\r
-}\r
-\r
-// RtcAddOneLevel adds one more level to the existing context prefix.RtcAddOneLevel. It takes in PreviousContentLevel as inteface, new level to be appended as string and the value to be saved of any type. It returns the updated interface and nil if no error.\r
-//\r
-func (rtc *RunTimeContext) RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", pl)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- if level == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context level")\r
- }\r
- if value == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context level value")\r
- }\r
-\r
- key := str + level + "/"\r
- err := contextdb.Db.Put(key, value)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())\r
- }\r
- return (interface{})(key), nil\r
-}\r
-\r
-// Add a resource under the given level and return new handle\r
-func (rtc *RunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {\r
-\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
- if resname == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context resource name")\r
- }\r
- if value == nil {\r
- return nil, pkgerrors.Errorf("Not a valid run time context resource value")\r
- }\r
-\r
- k := str + "resource" + "/" + resname + "/"\r
- err := contextdb.Db.Put(k, value)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error adding run time context resource: %s", err.Error())\r
- }\r
- return (interface{})(k), nil\r
-}\r
-\r
-// Add instruction at a given level and type, return the new handle\r
-func (rtc *RunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- if level == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context level")\r
- }\r
- if insttype == "" {\r
- return nil, pkgerrors.Errorf("Not a valid run time context instruction type")\r
- }\r
- if value == nil {\r
- return nil, pkgerrors.Errorf("Not a valid run time context instruction value")\r
- }\r
- k := str + level + "/" + "instruction" + "/" + insttype + "/"\r
- err := contextdb.Db.Put(k, fmt.Sprintf("%v", value))\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error adding run time context instruction: %s", err.Error())\r
- }\r
-\r
- return (interface{})(k), nil\r
-}\r
-\r
-//Delete the key value pair using given handle\r
-func (rtc *RunTimeContext) RtcDeletePair(handle interface{}) error {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
- err := contextdb.Db.Delete(str)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error deleting run time context pair: %s", err.Error())\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// Delete all handles underneath the given handle\r
-func (rtc *RunTimeContext) RtcDeletePrefix(handle interface{}) error {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- err := contextdb.Db.DeleteAll(str)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error deleting run time context with prefix: %s", err.Error())\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// Return the list of handles under the given handle\r
-func (rtc *RunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return nil, pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- s, err := contextdb.Db.GetAllKeys(str)\r
- if err != nil {\r
- return nil, pkgerrors.Errorf("Error getting run time context handles: %s", err.Error())\r
- }\r
- r := make([]interface{}, len(s))\r
- for i, v := range s {\r
- r[i] = v\r
- }\r
- return r, nil\r
-}\r
-\r
-// Get the value for a given handle\r
-func (rtc *RunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
-\r
- err := contextdb.Db.Get(str, value)\r
- if err != nil {\r
- logutils.Error("contextdb str", logutils.Fields{"str": str})\r
- return pkgerrors.Errorf("Error getting run time context value: %s", err.Error())\r
- }\r
-\r
- return nil\r
-}\r
-\r
-// Update the value of a given handle\r
-func (rtc *RunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {\r
- str := fmt.Sprintf("%v", handle)\r
- sid := fmt.Sprintf("%v", rtc.cid)\r
- if !strings.HasPrefix(str, sid) {\r
- return pkgerrors.Errorf("Not a valid run time context handle")\r
- }\r
- err := contextdb.Db.Put(str, value)\r
- if err != nil {\r
- return pkgerrors.Errorf("Error updating run time context value: %s", err.Error())\r
- }\r
- return nil\r
-\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package rtcontext
+
+import (
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const maxrand = 0x7fffffffffffffff
+const prefix string = "/context/"
+
+type RunTimeContext struct {
+ cid interface{}
+ meta interface{}
+}
+
+type Rtcontext interface {
+ RtcInit() (interface{}, error)
+ RtcLoad(interface{}) (interface{}, error)
+ RtcCreate() (interface{}, error)
+ RtcAddMeta(meta interface{}) error
+ RtcGet() (interface{}, error)
+ RtcAddLevel(handle interface{}, level string, value string) (interface{}, error)
+ RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error)
+ RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error)
+ RtcDeletePair(handle interface{}) error
+ RtcDeletePrefix(handle interface{}) error
+ RtcGetHandles(handle interface{}) ([]interface{}, error)
+ RtcGetValue(handle interface{}, value interface{}) error
+ RtcUpdateValue(handle interface{}, value interface{}) error
+ RtcGetMeta() (interface{}, error)
+ RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error)
+}
+
+//Intialize context by assiging a new id
+func (rtc *RunTimeContext) RtcInit() (interface{}, error) {
+ if rtc.cid != nil {
+ return nil, pkgerrors.Errorf("Error, context already initialized")
+ }
+ ra := rand.New(rand.NewSource(time.Now().UnixNano()))
+ rn := ra.Int63n(maxrand)
+ id := fmt.Sprintf("%v", rn)
+ cid := (prefix + id + "/")
+ rtc.cid = interface{}(cid)
+ return interface{}(id), nil
+
+}
+
+//Load context using the given id
+func (rtc *RunTimeContext) RtcLoad(id interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", id)
+ if str == "" {
+ return nil, pkgerrors.Errorf("Not a valid context id")
+ }
+ cid := (prefix + str + "/")
+ rtc.cid = interface{}(cid)
+ handle, err := rtc.RtcGet()
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error finding the context id: %s", err.Error())
+ }
+ return handle, nil
+}
+
+func (rtc *RunTimeContext) RtcCreate() (interface{}, error) {
+ cid := fmt.Sprintf("%v", rtc.cid)
+ if cid == "" {
+ return nil, pkgerrors.Errorf("Error, context not intialized")
+ }
+ if !strings.HasPrefix(cid, prefix) {
+ return nil, pkgerrors.Errorf("Not a valid run time context prefix")
+ }
+ id := strings.SplitN(cid, "/", 4)[2]
+ err := contextdb.Db.Put(cid, id)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error creating run time context: %s", err.Error())
+ }
+
+ return rtc.cid, nil
+}
+
+//RtcAddMeta is used for saving meta data of appContext into ETCD.
+func (rtc *RunTimeContext) RtcAddMeta(meta interface{}) error {
+ cid := fmt.Sprintf("%v", rtc.cid)
+ if cid == "" {
+ return pkgerrors.Errorf("Error, context not intialized")
+ }
+ if !strings.HasPrefix(cid, prefix) {
+ return pkgerrors.Errorf("Not a valid run time context prefix")
+ }
+
+ rtc.meta = meta
+ k := cid + "meta" + "/"
+ err := contextdb.Db.Put(k, rtc.meta)
+ if err != nil {
+ return pkgerrors.Errorf("Error saving metadata in run time context: %s", err.Error())
+ }
+
+ return nil
+}
+
+//Get the root handle
+func (rtc *RunTimeContext) RtcGet() (interface{}, error) {
+ str := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, prefix) {
+ return nil, pkgerrors.Errorf("Not a valid run time context")
+ }
+
+ var value string
+ err := contextdb.Db.Get(str, &value)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())
+ }
+ if !strings.Contains(str, value) {
+ return nil, pkgerrors.Errorf("Error matching run time context metadata")
+ }
+
+ return rtc.cid, nil
+}
+
+// RtcGetMeta method fetches the meta data of the rtc object and returns it.
+func (rtc *RunTimeContext) RtcGetMeta() (interface{}, error) {
+ str := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, prefix) {
+ return nil, pkgerrors.Errorf("Not a valid run time context")
+ }
+
+ var value interface{}
+ k := str + "meta" + "/"
+ err := contextdb.Db.Get(k, &value)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())
+ }
+ return value, nil
+
+}
+
+//Add a new level at a given handle and return the new handle
+func (rtc *RunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return nil, pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ if level == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context level")
+ }
+ if value == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context level value")
+ }
+
+ key := str + level + "/" + value + "/"
+ err := contextdb.Db.Put(key, value)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())
+ }
+
+ return (interface{})(key), nil
+}
+
+// RtcAddOneLevel adds one more level to the existing context prefix.RtcAddOneLevel. It takes in PreviousContentLevel as inteface, new level to be appended as string and the value to be saved of any type. It returns the updated interface and nil if no error.
+//
+func (rtc *RunTimeContext) RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", pl)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return nil, pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ if level == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context level")
+ }
+ if value == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context level value")
+ }
+
+ key := str + level + "/"
+ err := contextdb.Db.Put(key, value)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())
+ }
+ return (interface{})(key), nil
+}
+
+// Add a resource under the given level and return new handle
+func (rtc *RunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {
+
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return nil, pkgerrors.Errorf("Not a valid run time context handle")
+ }
+ if resname == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context resource name")
+ }
+ if value == nil {
+ return nil, pkgerrors.Errorf("Not a valid run time context resource value")
+ }
+
+ k := str + "resource" + "/" + resname + "/"
+ err := contextdb.Db.Put(k, value)
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error adding run time context resource: %s", err.Error())
+ }
+ return (interface{})(k), nil
+}
+
+// Add instruction at a given level and type, return the new handle
+func (rtc *RunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return nil, pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ if level == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context level")
+ }
+ if insttype == "" {
+ return nil, pkgerrors.Errorf("Not a valid run time context instruction type")
+ }
+ if value == nil {
+ return nil, pkgerrors.Errorf("Not a valid run time context instruction value")
+ }
+ k := str + level + "/" + "instruction" + "/" + insttype + "/"
+ err := contextdb.Db.Put(k, fmt.Sprintf("%v", value))
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error adding run time context instruction: %s", err.Error())
+ }
+
+ return (interface{})(k), nil
+}
+
+//Delete the key value pair using given handle
+func (rtc *RunTimeContext) RtcDeletePair(handle interface{}) error {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return pkgerrors.Errorf("Not a valid run time context handle")
+ }
+ err := contextdb.Db.Delete(str)
+ if err != nil {
+ return pkgerrors.Errorf("Error deleting run time context pair: %s", err.Error())
+ }
+
+ return nil
+}
+
+// Delete all handles underneath the given handle
+func (rtc *RunTimeContext) RtcDeletePrefix(handle interface{}) error {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ logutils.Error("Not a valid run time context handle", logutils.Fields{"key ::": str, "sid :: ": sid})
+ return pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ err := contextdb.Db.DeleteAll(str)
+ if err != nil {
+ return pkgerrors.Errorf("Error deleting run time context with prefix: %s", err.Error())
+ }
+
+ return nil
+}
+
+// Return the list of handles under the given handle
+func (rtc *RunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return nil, pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ s, err := contextdb.Db.GetAllKeys(str)
+ if err != nil {
+
+ return nil, pkgerrors.Errorf("Error getting run time context handles: %s", err.Error())
+ }
+ r := make([]interface{}, len(s))
+ for i, v := range s {
+ r[i] = v
+ }
+ return r, nil
+}
+
+// Get the value for a given handle
+func (rtc *RunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return pkgerrors.Errorf("Not a valid run time context handle")
+ }
+
+ err := contextdb.Db.Get(str, value)
+ if err != nil {
+ logutils.Error("contextdb str", logutils.Fields{"str": str})
+ return pkgerrors.Errorf("Error getting run time context value: %s", err.Error())
+ }
+
+ return nil
+}
+
+// Update the value of a given handle
+func (rtc *RunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {
+ str := fmt.Sprintf("%v", handle)
+ sid := fmt.Sprintf("%v", rtc.cid)
+ if !strings.HasPrefix(str, sid) {
+ return pkgerrors.Errorf("Not a valid run time context handle")
+ }
+ err := contextdb.Db.Put(str, value)
+ if err != nil {
+ return pkgerrors.Errorf("Error updating run time context value: %s", err.Error())
+ }
+ return nil
+
+}
-// SPDX-License-Identifier: Apache-2.0\r
-// Copyright (c) 2020 Intel Corporation\r
-\r
-package rtcontext\r
-\r
-import (\r
- "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"\r
- pkgerrors "github.com/pkg/errors"\r
- "strings"\r
- "testing"\r
-)\r
-\r
-// MockContextDb for mocking contextdb\r
-type MockContextDb struct {\r
- Items map[string]interface{}\r
- Err error\r
-}\r
-\r
-// Put function\r
-func (c *MockContextDb) Put(key string, val interface{}) error {\r
- if c.Items == nil {\r
- c.Items = make(map[string]interface{})\r
- }\r
- c.Items[key] = val\r
- return c.Err\r
-}\r
-\r
-// Get function\r
-func (c *MockContextDb) Get(key string, val interface{}) error {\r
- var s *string\r
- s = val.(*string)\r
- for kvKey, kvValue := range c.Items {\r
- if kvKey == key {\r
- *s = kvValue.(string)\r
- return c.Err\r
- }\r
- }\r
- return c.Err\r
-}\r
-\r
-// Delete function\r
-func (c *MockContextDb) Delete(key string) error {\r
- delete(c.Items, key)\r
- return c.Err\r
-}\r
-\r
-// Delete all function\r
-func (c *MockContextDb) DeleteAll(key string) error {\r
- for kvKey := range c.Items {\r
- delete(c.Items, kvKey)\r
- }\r
- return c.Err\r
-}\r
-\r
-// GetAllKeys function\r
-func (c *MockContextDb) GetAllKeys(path string) ([]string, error) {\r
- var keys []string\r
-\r
- for k := range c.Items {\r
- keys = append(keys, string(k))\r
- }\r
- return keys, c.Err\r
-}\r
-\r
-func (c *MockContextDb) HealthCheck() error {\r
- return nil\r
-}\r
-\r
-func TestRtcInit(t *testing.T) {\r
- var rtc = RunTimeContext{}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- },\r
- {\r
- label: "Init returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- expectedError: "Error, context already initialized",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcInit()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestRtcLoad(t *testing.T) {\r
- var rtc = RunTimeContext{"", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- id string\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- id: "5345674458787728",\r
- mockContextDb: &MockContextDb{},\r
- },\r
- {\r
- label: "reinit returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- id: "8885674458787728",\r
- expectedError: "Error finding the context id:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcLoad("5345674458787728")\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestRtcCreate(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- },\r
- {\r
- label: "Create returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- expectedError: "Error creating run time context:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcCreate()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
-\r
- })\r
- }\r
-}\r
-\r
-func TestRtcGet(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- },\r
- {\r
- label: "Get returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- expectedError: "Error getting run time context metadata:",\r
- },\r
- {\r
- label: "Context handle does not match",\r
- mockContextDb: &MockContextDb{Err: nil},\r
- expectedError: "Error matching run time context metadata",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- switch testCase.label {\r
- case "Success case":\r
- contextdb.Db = testCase.mockContextDb\r
- chandle, err := rtc.RtcCreate()\r
- if err != nil {\r
- t.Fatalf("Create returned an error (%s)", err)\r
- }\r
- ghandle, err := rtc.RtcGet()\r
- if err != nil {\r
- t.Fatalf("Get returned an error (%s)", err)\r
- }\r
- if chandle != ghandle {\r
- t.Fatalf("Create and Get does not match")\r
- }\r
- case "Get returns error case":\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcGet()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- case "Context handle does not match":\r
- contextdb.Db = testCase.mockContextDb\r
- contextdb.Db.Put("/context/5345674458787728/", "6345674458787728")\r
- _, err := rtc.RtcGet()\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcAddLevel(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/3528435435454354/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- handle interface{}\r
- level string\r
- value string\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/",\r
- level: "app",\r
- value: "testapp1",\r
- },\r
- {\r
- label: "Not a valid rtc handle",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/9528435435454354/",\r
- level: "app",\r
- value: "testapp1",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Not a valid rtc level",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/",\r
- level: "",\r
- value: "testapp1",\r
- expectedError: "Not a valid run time context level",\r
- },\r
- {\r
- label: "Not a valid rtc value",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/",\r
- level: "app",\r
- value: "",\r
- expectedError: "Not a valid run time context level value",\r
- },\r
- {\r
- label: "Put returns error",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- handle: "/context/3528435435454354/",\r
- level: "app",\r
- value: "testapp1",\r
- expectedError: "Error adding run time context level:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcAddLevel(testCase.handle, testCase.level, testCase.value)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcAddResource(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/3528435435454354/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- handle interface{}\r
- resname string\r
- value interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- resname: "R1",\r
- value: "res1",\r
- },\r
- {\r
- label: "Not a valid rtc handle",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/9528435435454354/app/apptest1/cluster/cluster1/",\r
- resname: "R1",\r
- value: "res1",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Not a valid rtc resource name",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- resname: "",\r
- value: "res1",\r
- expectedError: "Not a valid run time context resource name",\r
- },\r
- {\r
- label: "Not a valid rtc value",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- resname: "R1",\r
- value: nil,\r
- expectedError: "Not a valid run time context resource value",\r
- },\r
- {\r
- label: "Put returns error",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- resname: "R1",\r
- value: "res1",\r
- expectedError: "Error adding run time context resource:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcAddResource(testCase.handle, testCase.resname, testCase.value)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcAddInstruction(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/3528435435454354/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- handle interface{}\r
- level string\r
- insttype string\r
- value interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "resource",\r
- insttype: "order",\r
- value: "{resorder: [R3, R1, R2]}",\r
- },\r
- {\r
- label: "Not a valid rtc handle",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/9528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "resource",\r
- insttype: "order",\r
- value: "{resorder: [R3, R1, R2]}",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Not a valid rtc level name",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "",\r
- insttype: "order",\r
- value: "{resorder: [R3, R1, R2]}",\r
- expectedError: "Not a valid run time context level",\r
- },\r
- {\r
- label: "Not a valid rtc instruction type",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "resource",\r
- insttype: "",\r
- value: "{resorder: [R3, R1, R2]}",\r
- expectedError: "Not a valid run time context instruction type",\r
- },\r
- {\r
- label: "Not a valid rtc value",\r
- mockContextDb: &MockContextDb{},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "resource",\r
- insttype: "order",\r
- value: nil,\r
- expectedError: "Not a valid run time context instruction value",\r
- },\r
- {\r
- label: "Put returns error",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},\r
- handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",\r
- level: "resource",\r
- insttype: "order",\r
- value: "{resorder: [R3, R1, R2]}",\r
- expectedError: "Error adding run time context instruction:",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- _, err := rtc.RtcAddInstruction(testCase.handle, testCase.level, testCase.insttype, testCase.value)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcGetHandles(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- key interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Not valid input handle case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/3528435435454354/",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Contextdb call returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},\r
- key: "/context/5345674458787728/",\r
- expectedError: "Error getting run time context handles:",\r
- },\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/5345674458787728/",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- if testCase.label == "Success case" {\r
- contextdb.Db.Put("/context/5345674458787728/", 5345674458787728)\r
- }\r
- _, err := rtc.RtcGetHandles(testCase.key)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcGetValue(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- key interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Not valid input handle case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/3528435435454354/",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Contextdb call returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},\r
- key: "/context/5345674458787728/",\r
- expectedError: "Error getting run time context value:",\r
- },\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/5345674458787728/",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- if testCase.label == "Success case" {\r
- contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")\r
- }\r
- var val string\r
- err := rtc.RtcGetValue(testCase.key, &val)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcUpdateValue(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- key interface{}\r
- value interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Not valid input handle case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/3528435435454354/",\r
- value: "{apporder: [app1, app2, app3]}",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Contextdb call returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},\r
- key: "/context/5345674458787728/",\r
- value: "{apporder: [app1, app2, app3]}",\r
- expectedError: "Error updating run time context value:",\r
- },\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/5345674458787728/",\r
- value: "{apporder: [app2, app3, app1]}",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- if testCase.label == "Success case" {\r
- contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")\r
- }\r
- err := rtc.RtcUpdateValue(testCase.key, testCase.value)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcDeletePair(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- key interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Not valid input handle case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/3528435435454354/",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Contextdb call returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},\r
- key: "/context/5345674458787728/",\r
- expectedError: "Error deleting run time context pair:",\r
- },\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/5345674458787728/",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- err := rtc.RtcDeletePair(testCase.key)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
-\r
-func TestRtcDeletePrefix(t *testing.T) {\r
- var rtc = RunTimeContext{"/context/5345674458787728/", ""}\r
- testCases := []struct {\r
- label string\r
- mockContextDb *MockContextDb\r
- key interface{}\r
- expectedError string\r
- }{\r
- {\r
- label: "Not valid input handle case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/3528435435454354/",\r
- expectedError: "Not a valid run time context handle",\r
- },\r
- {\r
- label: "Contextdb call returns error case",\r
- mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},\r
- key: "/context/5345674458787728/",\r
- expectedError: "Error deleting run time context with prefix:",\r
- },\r
- {\r
- label: "Success case",\r
- mockContextDb: &MockContextDb{},\r
- key: "/context/5345674458787728/",\r
- },\r
- }\r
-\r
- for _, testCase := range testCases {\r
- t.Run(testCase.label, func(t *testing.T) {\r
- contextdb.Db = testCase.mockContextDb\r
- err := rtc.RtcDeletePrefix(testCase.key)\r
- if err != nil {\r
- if !strings.Contains(string(err.Error()), testCase.expectedError) {\r
- t.Fatalf("Method returned an error (%s)", err)\r
- }\r
- }\r
- })\r
- }\r
-}\r
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (c) 2020 Intel Corporation
+
+package rtcontext
+
+import (
+ "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"
+ pkgerrors "github.com/pkg/errors"
+ "strings"
+ "testing"
+)
+
+// MockContextDb for mocking contextdb
+type MockContextDb struct {
+ Items map[string]interface{}
+ Err error
+}
+
+// Put function
+func (c *MockContextDb) Put(key string, val interface{}) error {
+ if c.Items == nil {
+ c.Items = make(map[string]interface{})
+ }
+ c.Items[key] = val
+ return c.Err
+}
+
+// Get function
+func (c *MockContextDb) Get(key string, val interface{}) error {
+ var s *string
+ s = val.(*string)
+ for kvKey, kvValue := range c.Items {
+ if kvKey == key {
+ *s = kvValue.(string)
+ return c.Err
+ }
+ }
+ return c.Err
+}
+
+// Delete function
+func (c *MockContextDb) Delete(key string) error {
+ delete(c.Items, key)
+ return c.Err
+}
+
+// Delete all function
+func (c *MockContextDb) DeleteAll(key string) error {
+ for kvKey := range c.Items {
+ delete(c.Items, kvKey)
+ }
+ return c.Err
+}
+
+// GetAllKeys function
+func (c *MockContextDb) GetAllKeys(path string) ([]string, error) {
+ var keys []string
+
+ for k := range c.Items {
+ keys = append(keys, string(k))
+ }
+ return keys, c.Err
+}
+
+func (c *MockContextDb) HealthCheck() error {
+ return nil
+}
+
+func TestRtcInit(t *testing.T) {
+ var rtc = RunTimeContext{}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ },
+ {
+ label: "Init returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ expectedError: "Error, context already initialized",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcInit()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestRtcLoad(t *testing.T) {
+ var rtc = RunTimeContext{"", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ id string
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ id: "5345674458787728",
+ mockContextDb: &MockContextDb{},
+ },
+ {
+ label: "reinit returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ id: "8885674458787728",
+ expectedError: "Error finding the context id:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcLoad("5345674458787728")
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestRtcCreate(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ },
+ {
+ label: "Create returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ expectedError: "Error creating run time context:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcCreate()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+
+ })
+ }
+}
+
+func TestRtcGet(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ },
+ {
+ label: "Get returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ expectedError: "Error getting run time context metadata:",
+ },
+ {
+ label: "Context handle does not match",
+ mockContextDb: &MockContextDb{Err: nil},
+ expectedError: "Error matching run time context metadata",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ switch testCase.label {
+ case "Success case":
+ contextdb.Db = testCase.mockContextDb
+ chandle, err := rtc.RtcCreate()
+ if err != nil {
+ t.Fatalf("Create returned an error (%s)", err)
+ }
+ ghandle, err := rtc.RtcGet()
+ if err != nil {
+ t.Fatalf("Get returned an error (%s)", err)
+ }
+ if chandle != ghandle {
+ t.Fatalf("Create and Get does not match")
+ }
+ case "Get returns error case":
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcGet()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ case "Context handle does not match":
+ contextdb.Db = testCase.mockContextDb
+ contextdb.Db.Put("/context/5345674458787728/", "6345674458787728")
+ _, err := rtc.RtcGet()
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ }
+ })
+ }
+}
+
+func TestRtcAddLevel(t *testing.T) {
+ var rtc = RunTimeContext{"/context/3528435435454354/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ handle interface{}
+ level string
+ value string
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/",
+ level: "app",
+ value: "testapp1",
+ },
+ {
+ label: "Not a valid rtc handle",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/9528435435454354/",
+ level: "app",
+ value: "testapp1",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Not a valid rtc level",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/",
+ level: "",
+ value: "testapp1",
+ expectedError: "Not a valid run time context level",
+ },
+ {
+ label: "Not a valid rtc value",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/",
+ level: "app",
+ value: "",
+ expectedError: "Not a valid run time context level value",
+ },
+ {
+ label: "Put returns error",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ handle: "/context/3528435435454354/",
+ level: "app",
+ value: "testapp1",
+ expectedError: "Error adding run time context level:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcAddLevel(testCase.handle, testCase.level, testCase.value)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcAddResource(t *testing.T) {
+ var rtc = RunTimeContext{"/context/3528435435454354/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ handle interface{}
+ resname string
+ value interface{}
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ resname: "R1",
+ value: "res1",
+ },
+ {
+ label: "Not a valid rtc handle",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/9528435435454354/app/apptest1/cluster/cluster1/",
+ resname: "R1",
+ value: "res1",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Not a valid rtc resource name",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ resname: "",
+ value: "res1",
+ expectedError: "Not a valid run time context resource name",
+ },
+ {
+ label: "Not a valid rtc value",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ resname: "R1",
+ value: nil,
+ expectedError: "Not a valid run time context resource value",
+ },
+ {
+ label: "Put returns error",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ resname: "R1",
+ value: "res1",
+ expectedError: "Error adding run time context resource:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcAddResource(testCase.handle, testCase.resname, testCase.value)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcAddInstruction(t *testing.T) {
+ var rtc = RunTimeContext{"/context/3528435435454354/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ handle interface{}
+ level string
+ insttype string
+ value interface{}
+ expectedError string
+ }{
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ level: "resource",
+ insttype: "order",
+ value: "{resorder: [R3, R1, R2]}",
+ },
+ {
+ label: "Not a valid rtc handle",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/9528435435454354/app/apptest1/cluster/cluster1/",
+ level: "resource",
+ insttype: "order",
+ value: "{resorder: [R3, R1, R2]}",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Not a valid rtc level name",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ level: "",
+ insttype: "order",
+ value: "{resorder: [R3, R1, R2]}",
+ expectedError: "Not a valid run time context level",
+ },
+ {
+ label: "Not a valid rtc instruction type",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ level: "resource",
+ insttype: "",
+ value: "{resorder: [R3, R1, R2]}",
+ expectedError: "Not a valid run time context instruction type",
+ },
+ {
+ label: "Not a valid rtc value",
+ mockContextDb: &MockContextDb{},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ level: "resource",
+ insttype: "order",
+ value: nil,
+ expectedError: "Not a valid run time context instruction value",
+ },
+ {
+ label: "Put returns error",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
+ handle: "/context/3528435435454354/app/apptest1/cluster/cluster1/",
+ level: "resource",
+ insttype: "order",
+ value: "{resorder: [R3, R1, R2]}",
+ expectedError: "Error adding run time context instruction:",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ _, err := rtc.RtcAddInstruction(testCase.handle, testCase.level, testCase.insttype, testCase.value)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcGetHandles(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ key interface{}
+ expectedError string
+ }{
+ {
+ label: "Not valid input handle case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/3528435435454354/",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Contextdb call returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
+ key: "/context/5345674458787728/",
+ expectedError: "Error getting run time context handles:",
+ },
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/5345674458787728/",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ if testCase.label == "Success case" {
+ contextdb.Db.Put("/context/5345674458787728/", 5345674458787728)
+ }
+ _, err := rtc.RtcGetHandles(testCase.key)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcGetValue(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ key interface{}
+ expectedError string
+ }{
+ {
+ label: "Not valid input handle case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/3528435435454354/",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Contextdb call returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
+ key: "/context/5345674458787728/",
+ expectedError: "Error getting run time context value:",
+ },
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/5345674458787728/",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ if testCase.label == "Success case" {
+ contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")
+ }
+ var val string
+ err := rtc.RtcGetValue(testCase.key, &val)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcUpdateValue(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ key interface{}
+ value interface{}
+ expectedError string
+ }{
+ {
+ label: "Not valid input handle case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/3528435435454354/",
+ value: "{apporder: [app1, app2, app3]}",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Contextdb call returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
+ key: "/context/5345674458787728/",
+ value: "{apporder: [app1, app2, app3]}",
+ expectedError: "Error updating run time context value:",
+ },
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/5345674458787728/",
+ value: "{apporder: [app2, app3, app1]}",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ if testCase.label == "Success case" {
+ contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")
+ }
+ err := rtc.RtcUpdateValue(testCase.key, testCase.value)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcDeletePair(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ key interface{}
+ expectedError string
+ }{
+ {
+ label: "Not valid input handle case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/3528435435454354/",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Contextdb call returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
+ key: "/context/5345674458787728/",
+ expectedError: "Error deleting run time context pair:",
+ },
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/5345674458787728/",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ err := rtc.RtcDeletePair(testCase.key)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestRtcDeletePrefix(t *testing.T) {
+ var rtc = RunTimeContext{"/context/5345674458787728/", ""}
+ testCases := []struct {
+ label string
+ mockContextDb *MockContextDb
+ key interface{}
+ expectedError string
+ }{
+ {
+ label: "Not valid input handle case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/3528435435454354/",
+ expectedError: "Not a valid run time context handle",
+ },
+ {
+ label: "Contextdb call returns error case",
+ mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
+ key: "/context/5345674458787728/",
+ expectedError: "Error deleting run time context with prefix:",
+ },
+ {
+ label: "Success case",
+ mockContextDb: &MockContextDb{},
+ key: "/context/5345674458787728/",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ contextdb.Db = testCase.mockContextDb
+ err := rtc.RtcDeletePrefix(testCase.key)
+ if err != nil {
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}