<commit_before>package application

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"path"
	"text/template"

	"github.com/GeertJohan/go.rice"
	"github.com/jarosser06/fastfood/pkg/cookbook"
	"github.com/jarosser06/fastfood/pkg/util"
)

const (
	defaultRoot      = "/var/www"
	defaultType      = "generic"
	defaultOwner     = "node['apache']['user']"
	defaultWebserver = "apache"
	defaultRepo      = "github.com/jarosser06/magic"
)

type Application struct {
	Cookbook  cookbook.Cookbook
	Path      string `json:"name,omitempty"`
	Name      string `json:"name,omitempty"`
	Owner     string `json:"owner,omitempty"`
	Repo      string `json:"repo,omitempty"`
	Root      string `json:"docroot,omitempty"`
	Type      string `json:"type,omitempty"`
	Webserver string `json:"webserver,omitempty"`
}

// Return an application with the defaults
func NewApplication(name string, ckbk cookbook.Cookbook) Application {

	return Application{
		Cookbook:  ckbk,
		Path:      path.Join(defaultRoot, name),
		Name:      name,
		Owner:     defaultOwner,
		Repo:      defaultRepo,
		Root:      defaultRoot,
		Type:      defaultType,
		Webserver: defaultWebserver,
	}
}

// Using set root also updates the Path variable
func (a *Application) SetRoot(root string) {
	a.Root = root
	a.Path = path.Join(root, a.Name)
}

func (a *Application) GenFiles() error {

	cookbookFiles := map[string]string{
		fmt.Sprintf("%s.rb", a.Name):      "recipes/application.rb",
		fmt.Sprintf("%s_spec.rb", a.Name): "test/unit/spec/application_spec.rb",
	}

	templateBox, _ := rice.FindBox("templates")
	for cookbookFile, templateFile := range cookbookFiles {
		tmpStr, _ := templateBox.String(templateFile)
		t, _ := template.New(templateFile).Parse(tmpStr)

		f, err := os.Create(path.Join(a.Cookbook.Path, cookbookFile))
		defer f.Close()

		if err != nil {
			return errors.New(fmt.Sprintf("application.GenFiles(): %v", err))
		}

		var buffer bytes.Buffer
		t.Execute(&buffer, a)

		cleanStr := util.CollapseNewlines(buffer.String())
		io.WriteString(f, cleanStr)
	}
	return nil
}
<commit_msg>replace Path attribute with Path method, removed SetRoot()<commit_after>package application

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"path"
	"text/template"

	"github.com/GeertJohan/go.rice"
	"github.com/jarosser06/fastfood/pkg/cookbook"
	"github.com/jarosser06/fastfood/pkg/util"
)

const (
	defaultRoot      = "/var/www"
	defaultType      = "generic"
	defaultOwner     = "node['apache']['user']"
	defaultWebserver = "apache"
	defaultRepo      = "github.com/jarosser06/magic"
)

type Application struct {
	Cookbook  cookbook.Cookbook
	Name      string `json:"name,omitempty"`
	Owner     string `json:"owner,omitempty"`
	Repo      string `json:"repo,omitempty"`
	Root      string `json:"docroot,omitempty"`
	Type      string `json:"type,omitempty"`
	Webserver string `json:"webserver,omitempty"`
}

// Return an application with the defaults
func NewApplication(name string, ckbk cookbook.Cookbook) Application {

	return Application{
		Cookbook:  ckbk,
		Name:      name,
		Owner:     defaultOwner,
		Repo:      defaultRepo,
		Root:      defaultRoot,
		Type:      defaultType,
		Webserver: defaultWebserver,
	}
}

func (a *Application) Path() string {
	return path.Join(a.Root, a.Name)
}

func (a *Application) GenFiles() error {

	cookbookFiles := map[string]string{
		fmt.Sprintf("%s.rb", a.Name):      "recipes/application.rb",
		fmt.Sprintf("%s_spec.rb", a.Name): "test/unit/spec/application_spec.rb",
	}

	templateBox, _ := rice.FindBox("templates")
	for cookbookFile, templateFile := range cookbookFiles {
		tmpStr, _ := templateBox.String(templateFile)
		t, _ := template.New(templateFile).Parse(tmpStr)

		f, err := os.Create(path.Join(a.Cookbook.Path, cookbookFile))
		defer f.Close()

		if err != nil {
			return errors.New(fmt.Sprintf("application.GenFiles(): %v", err))
		}

		var buffer bytes.Buffer
		t.Execute(&buffer, a)

		cleanStr := util.CollapseNewlines(buffer.String())
		io.WriteString(f, cleanStr)
	}
	return nil
}
<|endoftext|>


<commit_before>package cliserv

import (
	"fmt"
	"strings"
	"time"

	"github.com/containerum/chkit/pkg/configuration"
	. "github.com/containerum/chkit/pkg/context"
	"github.com/containerum/chkit/pkg/model"
	"github.com/containerum/chkit/pkg/model/service"
	"github.com/containerum/chkit/pkg/util/animation"
	"github.com/containerum/chkit/pkg/util/strset"
	"github.com/containerum/chkit/pkg/util/trasher"
	"github.com/spf13/cobra"
)

var aliases = []string{"srv", "services", "svc"}

var getServiceConfig = struct {
	configuration.ExportConfig
}{}

var Get = &cobra.Command{
	Use:     "service",
	Aliases: aliases,
	Short:   "shows service info",
	Long:    "chkit get service service_label [-o yaml/json] [-f output_file]",
	Example: "shows service info. Aliases: " + strings.Join(aliases, ", "),
	Run: func(cmd *cobra.Command, args []string) {
		anime := &animation.Animation{
			Framerate:      0.4,
			ClearLastFrame: true,
			Source:         trasher.NewSilly(),
		}
		go func() {
			time.Sleep(4 * time.Second)
			anime.Run()
		}()
		serviceData, err := func() (model.Renderer, error) {
			defer anime.Stop()
			switch len(args) {
			case 0:
				list, err := Context.Client.GetServiceList(Context.Namespace)
				return list, err
			case 1:
				svc, err := Context.Client.GetDeployment(Context.Namespace, args[0])
				return svc, err
			default:
				list, err := Context.Client.GetServiceList(Context.Namespace)
				var filteredList service.ServiceList
				names := strset.NewSet(args)
				for _, svc := range list {
					if names.Have(svc.Name) {
						filteredList = append(filteredList, svc)
					}
				}
				return filteredList, err
			}
		}()
		if err != nil {
			fmt.Println(err)
			return
		}
		if err := configuration.ExportData(serviceData, getServiceConfig.ExportConfig); err != nil {
			fmt.Println(err)
			return
		}
	},
}

func init() {
	Get.PersistentFlags().
		StringVarP((*string)(&getServiceConfig.Format), "output", "o", "", "output format [yaml/json]")
	Get.PersistentFlags().
		StringVarP(&getServiceConfig.Filename, "file", "f", "-", "output file")
}
<commit_msg>remove animation<commit_after>package cliserv

import (
	"fmt"
	"strings"

	"github.com/containerum/chkit/pkg/configuration"
	. "github.com/containerum/chkit/pkg/context"
	"github.com/containerum/chkit/pkg/model"
	"github.com/containerum/chkit/pkg/model/service"
	"github.com/containerum/chkit/pkg/util/strset"
	"github.com/spf13/cobra"
)

var aliases = []string{"srv", "services", "svc"}

var getServiceConfig = struct {
	configuration.ExportConfig
}{}

var Get = &cobra.Command{
	Use:     "service",
	Aliases: aliases,
	Short:   "shows service info",
	Long:    "chkit get service service_label [-o yaml/json] [-f output_file]",
	Example: "shows service info. Aliases: " + strings.Join(aliases, ", "),
	Run: func(cmd *cobra.Command, args []string) {
		serviceData, err := func() (model.Renderer, error) {
			switch len(args) {
			case 0:
				list, err := Context.Client.GetServiceList(Context.Namespace)
				return list, err
			case 1:
				svc, err := Context.Client.GetDeployment(Context.Namespace, args[0])
				return svc, err
			default:
				list, err := Context.Client.GetServiceList(Context.Namespace)
				var filteredList service.ServiceList
				names := strset.NewSet(args)
				for _, svc := range list {
					if names.Have(svc.Name) {
						filteredList = append(filteredList, svc)
					}
				}
				return filteredList, err
			}
		}()
		if err != nil {
			fmt.Println(err)
			return
		}
		if err := configuration.ExportData(serviceData, getServiceConfig.ExportConfig); err != nil {
			fmt.Println(err)
			return
		}
	},
}

func init() {
	Get.PersistentFlags().
		StringVarP((*string)(&getServiceConfig.Format), "output", "o", "", "output format [yaml/json]")
	Get.PersistentFlags().
		StringVarP(&getServiceConfig.Filename, "file", "f", "-", "output file")
}
<|endoftext|>


<commit_before>// Copyright 2019 Authors of Cilium
//
// 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 linux

import (
	"io"

	"github.com/cilium/cilium/pkg/datapath"
	"github.com/cilium/cilium/pkg/datapath/linux/config"
	"github.com/cilium/cilium/pkg/datapath/loader"
	"github.com/cilium/cilium/pkg/endpoint/connector"
	"github.com/cilium/cilium/pkg/logging/logfields"
)

// DatapathConfiguration is the static configuration of the datapath. The
// configuration cannot change throughout the lifetime of a datapath object.
type DatapathConfiguration struct {
	// HostDevice is the name of the device to be used to access the host.
	HostDevice string
	// EncryptInterface is the name of the device to be used for direct ruoting encryption
	EncryptInterface string
}

type rulesManager interface {
	InstallProxyRules(proxyPort uint16, ingress bool, name string) error
	RemoveProxyRules(proxyPort uint16, ingress bool, name string) error
}

type linuxDatapath struct {
	node           datapath.NodeHandler
	nodeAddressing datapath.NodeAddressing
	config         DatapathConfiguration
	configWriter   *config.HeaderfileWriter
	loader         *loader.Loader
	ruleManager    rulesManager
}

// NewDatapath creates a new Linux datapath
func NewDatapath(cfg DatapathConfiguration, ruleManager rulesManager) datapath.Datapath {
	dp := &linuxDatapath{
		nodeAddressing: NewNodeAddressing(),
		config:         cfg,
		configWriter:   &config.HeaderfileWriter{},
		loader:         &loader.Loader{},
		ruleManager:    ruleManager,
	}

	dp.node = NewNodeHandler(cfg, dp.nodeAddressing)

	if cfg.EncryptInterface != "" {
		if err := connector.DisableRpFilter(cfg.EncryptInterface); err != nil {
			log.WithField(logfields.Interface, cfg.EncryptInterface).Warn("Rpfilter could not be disabled, node to node encryption may fail")
		}
	}

	return dp
}

// Node returns the handler for node events
func (l *linuxDatapath) Node() datapath.NodeHandler {
	return l.node
}

// LocalNodeAddressing returns the node addressing implementation of the local
// node
func (l *linuxDatapath) LocalNodeAddressing() datapath.NodeAddressing {
	return l.nodeAddressing
}

func (l *linuxDatapath) InstallProxyRules(proxyPort uint16, ingress bool, name string) error {
	return l.ruleManager.InstallProxyRules(proxyPort, ingress, name)
}

func (l *linuxDatapath) RemoveProxyRules(proxyPort uint16, ingress bool, name string) error {
	return l.ruleManager.RemoveProxyRules(proxyPort, ingress, name)
}

func (l *linuxDatapath) WriteTemplateConfig(w io.Writer, e datapath.EndpointConfiguration) error {
	return l.configWriter.WriteTemplateConfig(w, e)
}

func (l *linuxDatapath) WriteEndpointConfig(w io.Writer, e datapath.EndpointConfiguration) error {
	return l.configWriter.WriteEndpointConfig(w, e)
}

func (l *linuxDatapath) WriteNetdevConfig(w io.Writer, cfg datapath.DeviceConfiguration) error {
	return l.configWriter.WriteNetdevConfig(w, cfg)
}

func (l *linuxDatapath) WriteNodeConfig(w io.Writer, cfg *datapath.LocalNodeConfiguration) error {
	return l.configWriter.WriteNodeConfig(w, cfg)
}

func (l *linuxDatapath) Loader() datapath.Loader {
	return l.loader
}
<commit_msg>loader: make linuxDatapath composed of a ConfigWriter<commit_after>// Copyright 2019 Authors of Cilium
//
// 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 linux

import (
	"github.com/cilium/cilium/pkg/datapath"
	"github.com/cilium/cilium/pkg/datapath/linux/config"
	"github.com/cilium/cilium/pkg/datapath/loader"
	"github.com/cilium/cilium/pkg/endpoint/connector"
	"github.com/cilium/cilium/pkg/logging/logfields"
)

// DatapathConfiguration is the static configuration of the datapath. The
// configuration cannot change throughout the lifetime of a datapath object.
type DatapathConfiguration struct {
	// HostDevice is the name of the device to be used to access the host.
	HostDevice string
	// EncryptInterface is the name of the device to be used for direct ruoting encryption
	EncryptInterface string
}

type rulesManager interface {
	InstallProxyRules(proxyPort uint16, ingress bool, name string) error
	RemoveProxyRules(proxyPort uint16, ingress bool, name string) error
}

type linuxDatapath struct {
	datapath.ConfigWriter
	node           datapath.NodeHandler
	nodeAddressing datapath.NodeAddressing
	config         DatapathConfiguration
	configWriter   *config.HeaderfileWriter
	loader         *loader.Loader
	ruleManager    rulesManager
}

// NewDatapath creates a new Linux datapath
func NewDatapath(cfg DatapathConfiguration, ruleManager rulesManager) datapath.Datapath {
	dp := &linuxDatapath{
		nodeAddressing: NewNodeAddressing(),
		config:         cfg,
		ConfigWriter:   &config.HeaderfileWriter{},
		loader:         &loader.Loader{},
		ruleManager:    ruleManager,
	}

	dp.node = NewNodeHandler(cfg, dp.nodeAddressing)

	if cfg.EncryptInterface != "" {
		if err := connector.DisableRpFilter(cfg.EncryptInterface); err != nil {
			log.WithField(logfields.Interface, cfg.EncryptInterface).Warn("Rpfilter could not be disabled, node to node encryption may fail")
		}
	}

	return dp
}

// Node returns the handler for node events
func (l *linuxDatapath) Node() datapath.NodeHandler {
	return l.node
}

// LocalNodeAddressing returns the node addressing implementation of the local
// node
func (l *linuxDatapath) LocalNodeAddressing() datapath.NodeAddressing {
	return l.nodeAddressing
}

func (l *linuxDatapath) InstallProxyRules(proxyPort uint16, ingress bool, name string) error {
	return l.ruleManager.InstallProxyRules(proxyPort, ingress, name)
}

func (l *linuxDatapath) RemoveProxyRules(proxyPort uint16, ingress bool, name string) error {
	return l.ruleManager.RemoveProxyRules(proxyPort, ingress, name)
}

func (l *linuxDatapath) Loader() datapath.Loader {
	return l.loader
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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 kubelet

import (
	"fmt"
	"io/ioutil"
	"net"
	"path"

	"github.com/golang/glog"
	"k8s.io/kubernetes/cmd/kubelet/app/options"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/kubelet/cm"
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
	"k8s.io/kubernetes/pkg/types"
	"k8s.io/kubernetes/pkg/util"
	nodeutil "k8s.io/kubernetes/pkg/util/node"
)

// getRootDir returns the full path to the directory under which kubelet can
// store data.  These functions are useful to pass interfaces to other modules
// that may need to know where to write data without getting a whole kubelet
// instance.
func (kl *Kubelet) getRootDir() string {
	return kl.rootDirectory
}

// getPodsDir returns the full path to the directory under which pod
// directories are created.
func (kl *Kubelet) getPodsDir() string {
	return path.Join(kl.getRootDir(), options.DefaultKubeletPodsDirName)
}

// getPluginsDir returns the full path to the directory under which plugin
// directories are created.  Plugins can use these directories for data that
// they need to persist.  Plugins should create subdirectories under this named
// after their own names.
func (kl *Kubelet) getPluginsDir() string {
	return path.Join(kl.getRootDir(), options.DefaultKubeletPluginsDirName)
}

// getPluginDir returns a data directory name for a given plugin name.
// Plugins can use these directories to store data that they need to persist.
// For per-pod plugin data, see getPodPluginDir.
func (kl *Kubelet) getPluginDir(pluginName string) string {
	return path.Join(kl.getPluginsDir(), pluginName)
}

// GetPodDir returns the full path to the per-pod data directory for the
// specified pod. This directory may not exist if the pod does not exist.
func (kl *Kubelet) GetPodDir(podUID types.UID) string {
	return kl.getPodDir(podUID)
}

// getPodDir returns the full path to the per-pod directory for the pod with
// the given UID.
func (kl *Kubelet) getPodDir(podUID types.UID) string {
	// Backwards compat.  The "old" stuff should be removed before 1.0
	// release.  The thinking here is this:
	//     !old && !new = use new
	//     !old && new  = use new
	//     old && !new  = use old
	//     old && new   = use new (but warn)
	oldPath := path.Join(kl.getRootDir(), string(podUID))
	oldExists := dirExists(oldPath)
	newPath := path.Join(kl.getPodsDir(), string(podUID))
	newExists := dirExists(newPath)
	if oldExists && !newExists {
		return oldPath
	}
	if oldExists {
		glog.Warningf("Data dir for pod %q exists in both old and new form, using new", podUID)
	}
	return newPath
}

// getPodVolumesDir returns the full path to the per-pod data directory under
// which volumes are created for the specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodVolumesDir(podUID types.UID) string {
	return path.Join(kl.getPodDir(podUID), options.DefaultKubeletVolumesDirName)
}

// getPodVolumeDir returns the full path to the directory which represents the
// named volume under the named plugin for specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
	return path.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName)
}

// getPodPluginsDir returns the full path to the per-pod data directory under
// which plugins may store data for the specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodPluginsDir(podUID types.UID) string {
	return path.Join(kl.getPodDir(podUID), options.DefaultKubeletPluginsDirName)
}

// getPodPluginDir returns a data directory name for a given plugin name for a
// given pod UID.  Plugins can use these directories to store data that they
// need to persist.  For non-per-pod plugin data, see getPluginDir.
func (kl *Kubelet) getPodPluginDir(podUID types.UID, pluginName string) string {
	return path.Join(kl.getPodPluginsDir(podUID), pluginName)
}

// getPodContainerDir returns the full path to the per-pod data directory under
// which container data is held for the specified pod.  This directory may not
// exist if the pod or container does not exist.
func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string {
	// Backwards compat.  The "old" stuff should be removed before 1.0
	// release.  The thinking here is this:
	//     !old && !new = use new
	//     !old && new  = use new
	//     old && !new  = use old
	//     old && new   = use new (but warn)
	oldPath := path.Join(kl.getPodDir(podUID), ctrName)
	oldExists := dirExists(oldPath)
	newPath := path.Join(kl.getPodDir(podUID), options.DefaultKubeletContainersDirName, ctrName)
	newExists := dirExists(newPath)
	if oldExists && !newExists {
		return oldPath
	}
	if oldExists {
		glog.Warningf("Data dir for pod %q, container %q exists in both old and new form, using new", podUID, ctrName)
	}
	return newPath
}

// GetPods returns all pods bound to the kubelet and their spec, and the mirror
// pods.
func (kl *Kubelet) GetPods() []*api.Pod {
	return kl.podManager.GetPods()
}

// GetRunningPods returns all pods running on kubelet from looking at the
// container runtime cache. This function converts kubecontainer.Pod to
// api.Pod, so only the fields that exist in both kubecontainer.Pod and
// api.Pod are considered meaningful.
func (kl *Kubelet) GetRunningPods() ([]*api.Pod, error) {
	pods, err := kl.runtimeCache.GetPods()
	if err != nil {
		return nil, err
	}

	apiPods := make([]*api.Pod, 0, len(pods))
	for _, pod := range pods {
		apiPods = append(apiPods, pod.ToAPIPod())
	}
	return apiPods, nil
}

// GetPodByFullName gets the pod with the given 'full' name, which
// incorporates the namespace as well as whether the pod was found.
func (kl *Kubelet) GetPodByFullName(podFullName string) (*api.Pod, bool) {
	return kl.podManager.GetPodByFullName(podFullName)
}

// GetPodByName provides the first pod that matches namespace and name, as well
// as whether the pod was found.
func (kl *Kubelet) GetPodByName(namespace, name string) (*api.Pod, bool) {
	return kl.podManager.GetPodByName(namespace, name)
}

// GetHostname Returns the hostname as the kubelet sees it.
func (kl *Kubelet) GetHostname() string {
	return kl.hostname
}

// GetRuntime returns the current Runtime implementation in use by the kubelet. This func
// is exported to simplify integration with third party kubelet extensions (e.g. kubernetes-mesos).
func (kl *Kubelet) GetRuntime() kubecontainer.Runtime {
	return kl.containerRuntime
}

// GetNode returns the node info for the configured node name of this Kubelet.
func (kl *Kubelet) GetNode() (*api.Node, error) {
	if kl.standaloneMode {
		return kl.initialNode()
	}
	return kl.nodeInfo.GetNodeInfo(kl.nodeName)
}

// getNodeAnyWay() must return a *api.Node which is required by RunGeneralPredicates().
// The *api.Node is obtained as follows:
// Return kubelet's nodeInfo for this node, except on error or if in standalone mode,
// in which case return a manufactured nodeInfo representing a node with no pods,
// zero capacity, and the default labels.
func (kl *Kubelet) getNodeAnyWay() (*api.Node, error) {
	if !kl.standaloneMode {
		if n, err := kl.nodeInfo.GetNodeInfo(kl.nodeName); err == nil {
			return n, nil
		}
	}
	return kl.initialNode()
}

// GetNodeConfig returns the container manager node config.
func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
	return kl.containerManager.GetNodeConfig()
}

// Returns host IP or nil in case of error.
func (kl *Kubelet) GetHostIP() (net.IP, error) {
	node, err := kl.GetNode()
	if err != nil {
		return nil, fmt.Errorf("cannot get node: %v", err)
	}
	return nodeutil.GetNodeHostIP(node)
}

// getHostIPAnyway attempts to return the host IP from kubelet's nodeInfo, or
// the initialNode.
func (kl *Kubelet) getHostIPAnyWay() (net.IP, error) {
	node, err := kl.getNodeAnyWay()
	if err != nil {
		return nil, err
	}
	return nodeutil.GetNodeHostIP(node)
}

// GetExtraSupplementalGroupsForPod returns a list of the extra
// supplemental groups for the Pod. These extra supplemental groups come
// from annotations on persistent volumes that the pod depends on.
func (kl *Kubelet) GetExtraSupplementalGroupsForPod(pod *api.Pod) []int64 {
	return kl.volumeManager.GetExtraSupplementalGroupsForPod(pod)
}

// getPodVolumePathListFromDisk returns a list of the volume paths by reading the
// volume directories for the given pod from the disk.
func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, error) {
	volumes := []string{}
	podVolDir := kl.getPodVolumesDir(podUID)
	volumePluginDirs, err := ioutil.ReadDir(podVolDir)
	if err != nil {
		glog.Errorf("Could not read directory %s: %v", podVolDir, err)
		return volumes, err
	}
	for _, volumePluginDir := range volumePluginDirs {
		volumePluginName := volumePluginDir.Name()
		volumePluginPath := path.Join(podVolDir, volumePluginName)
		volumeDirs, volumeDirsStatErrs, err := util.ReadDirNoExit(volumePluginPath)
		if err != nil {
			return volumes, fmt.Errorf("Could not read directory %s: %v", volumePluginPath, err)
		}
		for i, volumeDir := range volumeDirs {
			if volumeDir != nil {
				volumes = append(volumes, path.Join(volumePluginPath, volumeDir.Name()))
				continue
			}
			glog.Errorf("Could not read directory %s: %v", podVolDir, volumeDirsStatErrs[i])
		}
	}
	return volumes, nil
}
<commit_msg>Add path exist check in getPodVolumePathListFromDisk<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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 kubelet

import (
	"fmt"
	"io/ioutil"
	"net"
	"path"

	"github.com/golang/glog"
	"k8s.io/kubernetes/cmd/kubelet/app/options"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/kubelet/cm"
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
	"k8s.io/kubernetes/pkg/types"
	"k8s.io/kubernetes/pkg/util"
	nodeutil "k8s.io/kubernetes/pkg/util/node"
	volumeutil "k8s.io/kubernetes/pkg/volume/util"
)

// getRootDir returns the full path to the directory under which kubelet can
// store data.  These functions are useful to pass interfaces to other modules
// that may need to know where to write data without getting a whole kubelet
// instance.
func (kl *Kubelet) getRootDir() string {
	return kl.rootDirectory
}

// getPodsDir returns the full path to the directory under which pod
// directories are created.
func (kl *Kubelet) getPodsDir() string {
	return path.Join(kl.getRootDir(), options.DefaultKubeletPodsDirName)
}

// getPluginsDir returns the full path to the directory under which plugin
// directories are created.  Plugins can use these directories for data that
// they need to persist.  Plugins should create subdirectories under this named
// after their own names.
func (kl *Kubelet) getPluginsDir() string {
	return path.Join(kl.getRootDir(), options.DefaultKubeletPluginsDirName)
}

// getPluginDir returns a data directory name for a given plugin name.
// Plugins can use these directories to store data that they need to persist.
// For per-pod plugin data, see getPodPluginDir.
func (kl *Kubelet) getPluginDir(pluginName string) string {
	return path.Join(kl.getPluginsDir(), pluginName)
}

// GetPodDir returns the full path to the per-pod data directory for the
// specified pod. This directory may not exist if the pod does not exist.
func (kl *Kubelet) GetPodDir(podUID types.UID) string {
	return kl.getPodDir(podUID)
}

// getPodDir returns the full path to the per-pod directory for the pod with
// the given UID.
func (kl *Kubelet) getPodDir(podUID types.UID) string {
	// Backwards compat.  The "old" stuff should be removed before 1.0
	// release.  The thinking here is this:
	//     !old && !new = use new
	//     !old && new  = use new
	//     old && !new  = use old
	//     old && new   = use new (but warn)
	oldPath := path.Join(kl.getRootDir(), string(podUID))
	oldExists := dirExists(oldPath)
	newPath := path.Join(kl.getPodsDir(), string(podUID))
	newExists := dirExists(newPath)
	if oldExists && !newExists {
		return oldPath
	}
	if oldExists {
		glog.Warningf("Data dir for pod %q exists in both old and new form, using new", podUID)
	}
	return newPath
}

// getPodVolumesDir returns the full path to the per-pod data directory under
// which volumes are created for the specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodVolumesDir(podUID types.UID) string {
	return path.Join(kl.getPodDir(podUID), options.DefaultKubeletVolumesDirName)
}

// getPodVolumeDir returns the full path to the directory which represents the
// named volume under the named plugin for specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
	return path.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName)
}

// getPodPluginsDir returns the full path to the per-pod data directory under
// which plugins may store data for the specified pod.  This directory may not
// exist if the pod does not exist.
func (kl *Kubelet) getPodPluginsDir(podUID types.UID) string {
	return path.Join(kl.getPodDir(podUID), options.DefaultKubeletPluginsDirName)
}

// getPodPluginDir returns a data directory name for a given plugin name for a
// given pod UID.  Plugins can use these directories to store data that they
// need to persist.  For non-per-pod plugin data, see getPluginDir.
func (kl *Kubelet) getPodPluginDir(podUID types.UID, pluginName string) string {
	return path.Join(kl.getPodPluginsDir(podUID), pluginName)
}

// getPodContainerDir returns the full path to the per-pod data directory under
// which container data is held for the specified pod.  This directory may not
// exist if the pod or container does not exist.
func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string {
	// Backwards compat.  The "old" stuff should be removed before 1.0
	// release.  The thinking here is this:
	//     !old && !new = use new
	//     !old && new  = use new
	//     old && !new  = use old
	//     old && new   = use new (but warn)
	oldPath := path.Join(kl.getPodDir(podUID), ctrName)
	oldExists := dirExists(oldPath)
	newPath := path.Join(kl.getPodDir(podUID), options.DefaultKubeletContainersDirName, ctrName)
	newExists := dirExists(newPath)
	if oldExists && !newExists {
		return oldPath
	}
	if oldExists {
		glog.Warningf("Data dir for pod %q, container %q exists in both old and new form, using new", podUID, ctrName)
	}
	return newPath
}

// GetPods returns all pods bound to the kubelet and their spec, and the mirror
// pods.
func (kl *Kubelet) GetPods() []*api.Pod {
	return kl.podManager.GetPods()
}

// GetRunningPods returns all pods running on kubelet from looking at the
// container runtime cache. This function converts kubecontainer.Pod to
// api.Pod, so only the fields that exist in both kubecontainer.Pod and
// api.Pod are considered meaningful.
func (kl *Kubelet) GetRunningPods() ([]*api.Pod, error) {
	pods, err := kl.runtimeCache.GetPods()
	if err != nil {
		return nil, err
	}

	apiPods := make([]*api.Pod, 0, len(pods))
	for _, pod := range pods {
		apiPods = append(apiPods, pod.ToAPIPod())
	}
	return apiPods, nil
}

// GetPodByFullName gets the pod with the given 'full' name, which
// incorporates the namespace as well as whether the pod was found.
func (kl *Kubelet) GetPodByFullName(podFullName string) (*api.Pod, bool) {
	return kl.podManager.GetPodByFullName(podFullName)
}

// GetPodByName provides the first pod that matches namespace and name, as well
// as whether the pod was found.
func (kl *Kubelet) GetPodByName(namespace, name string) (*api.Pod, bool) {
	return kl.podManager.GetPodByName(namespace, name)
}

// GetHostname Returns the hostname as the kubelet sees it.
func (kl *Kubelet) GetHostname() string {
	return kl.hostname
}

// GetRuntime returns the current Runtime implementation in use by the kubelet. This func
// is exported to simplify integration with third party kubelet extensions (e.g. kubernetes-mesos).
func (kl *Kubelet) GetRuntime() kubecontainer.Runtime {
	return kl.containerRuntime
}

// GetNode returns the node info for the configured node name of this Kubelet.
func (kl *Kubelet) GetNode() (*api.Node, error) {
	if kl.standaloneMode {
		return kl.initialNode()
	}
	return kl.nodeInfo.GetNodeInfo(kl.nodeName)
}

// getNodeAnyWay() must return a *api.Node which is required by RunGeneralPredicates().
// The *api.Node is obtained as follows:
// Return kubelet's nodeInfo for this node, except on error or if in standalone mode,
// in which case return a manufactured nodeInfo representing a node with no pods,
// zero capacity, and the default labels.
func (kl *Kubelet) getNodeAnyWay() (*api.Node, error) {
	if !kl.standaloneMode {
		if n, err := kl.nodeInfo.GetNodeInfo(kl.nodeName); err == nil {
			return n, nil
		}
	}
	return kl.initialNode()
}

// GetNodeConfig returns the container manager node config.
func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
	return kl.containerManager.GetNodeConfig()
}

// Returns host IP or nil in case of error.
func (kl *Kubelet) GetHostIP() (net.IP, error) {
	node, err := kl.GetNode()
	if err != nil {
		return nil, fmt.Errorf("cannot get node: %v", err)
	}
	return nodeutil.GetNodeHostIP(node)
}

// getHostIPAnyway attempts to return the host IP from kubelet's nodeInfo, or
// the initialNode.
func (kl *Kubelet) getHostIPAnyWay() (net.IP, error) {
	node, err := kl.getNodeAnyWay()
	if err != nil {
		return nil, err
	}
	return nodeutil.GetNodeHostIP(node)
}

// GetExtraSupplementalGroupsForPod returns a list of the extra
// supplemental groups for the Pod. These extra supplemental groups come
// from annotations on persistent volumes that the pod depends on.
func (kl *Kubelet) GetExtraSupplementalGroupsForPod(pod *api.Pod) []int64 {
	return kl.volumeManager.GetExtraSupplementalGroupsForPod(pod)
}

// getPodVolumePathListFromDisk returns a list of the volume paths by reading the
// volume directories for the given pod from the disk.
func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, error) {
	volumes := []string{}
	podVolDir := kl.getPodVolumesDir(podUID)

	if pathExists, pathErr := volumeutil.PathExists(podVolDir); pathErr != nil {
		return volumes, fmt.Errorf("Error checking if path %q exists: %v", podVolDir, pathErr)
	} else if !pathExists {
		glog.Warningf("Warning: path %q does not exist: %q", podVolDir)
		return volumes, nil
	}

	volumePluginDirs, err := ioutil.ReadDir(podVolDir)
	if err != nil {
		glog.Errorf("Could not read directory %s: %v", podVolDir, err)
		return volumes, err
	}
	for _, volumePluginDir := range volumePluginDirs {
		volumePluginName := volumePluginDir.Name()
		volumePluginPath := path.Join(podVolDir, volumePluginName)
		volumeDirs, volumeDirsStatErrs, err := util.ReadDirNoExit(volumePluginPath)
		if err != nil {
			return volumes, fmt.Errorf("Could not read directory %s: %v", volumePluginPath, err)
		}
		for i, volumeDir := range volumeDirs {
			if volumeDir != nil {
				volumes = append(volumes, path.Join(volumePluginPath, volumeDir.Name()))
				continue
			}
			glog.Errorf("Could not read directory %s: %v", podVolDir, volumeDirsStatErrs[i])
		}
	}
	return volumes, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 cni

import (
	"fmt"
	"net"
	"sort"
	"strings"

	"github.com/appc/cni/libcni"
	cnitypes "github.com/appc/cni/pkg/types"
	"github.com/golang/glog"
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
	"k8s.io/kubernetes/pkg/kubelet/dockertools"
	"k8s.io/kubernetes/pkg/kubelet/network"
)

const (
	CNIPluginName        = "cni"
	DefaultNetDir        = "/etc/cni/net.d"
	DefaultCNIDir        = "/opt/cni/bin"
	VendorCNIDirTemplate = "%s/opt/%s/bin"
)

type cniNetworkPlugin struct {
	defaultNetwork *cniNetwork
	host           network.Host
}

type cniNetwork struct {
	name          string
	NetworkConfig *libcni.NetworkConfig
	CNIConfig     *libcni.CNIConfig
}

func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, vendorCNIDirPrefix string) []network.NetworkPlugin {
	configList := make([]network.NetworkPlugin, 0)
	network, err := getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix)
	if err != nil {
		return configList
	}
	return append(configList, &cniNetworkPlugin{defaultNetwork: network})
}

func ProbeNetworkPlugins(pluginDir string) []network.NetworkPlugin {
	return probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, "")
}

func getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix string) (*cniNetwork, error) {
	if pluginDir == "" {
		pluginDir = DefaultNetDir
	}
	files, err := libcni.ConfFiles(pluginDir)
	switch {
	case err != nil:
		return nil, err
	case len(files) == 0:
		return nil, fmt.Errorf("No networks found in %s", pluginDir)
	}

	sort.Strings(files)
	for _, confFile := range files {
		conf, err := libcni.ConfFromFile(confFile)
		if err != nil {
			glog.Warningf("Error loading CNI config file %s: %v", confFile, err)
			continue
		}
		// Search for vendor-specific plugins as well as default plugins in the CNI codebase.
		vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, vendorCNIDirPrefix, conf.Network.Type)
		cninet := &libcni.CNIConfig{
			Path: []string{DefaultCNIDir, vendorCNIDir},
		}
		network := &cniNetwork{name: conf.Network.Name, NetworkConfig: conf, CNIConfig: cninet}
		return network, nil
	}
	return nil, fmt.Errorf("No valid networks found in %s", pluginDir)
}

func (plugin *cniNetworkPlugin) Init(host network.Host) error {
	plugin.host = host
	return nil
}

func (plugin *cniNetworkPlugin) Event(name string, details map[string]interface{}) {
}

func (plugin *cniNetworkPlugin) Name() string {
	return CNIPluginName
}

func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.DockerID) error {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return fmt.Errorf("CNI execution called on non-docker runtime")
	}
	netns, err := runtime.GetNetNS(id.ContainerID())
	if err != nil {
		return err
	}

	_, err = plugin.defaultNetwork.addToNetwork(name, namespace, id.ContainerID(), netns)
	if err != nil {
		glog.Errorf("Error while adding to cni network: %s", err)
		return err
	}

	return err
}

func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id kubecontainer.DockerID) error {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return fmt.Errorf("CNI execution called on non-docker runtime")
	}
	netns, err := runtime.GetNetNS(id.ContainerID())
	if err != nil {
		return err
	}

	return plugin.defaultNetwork.deleteFromNetwork(name, namespace, id.ContainerID(), netns)
}

// TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin.
// Also fix the runtime's call to Status function to be done only in the case that the IP is lost, no need to do periodic calls
func (plugin *cniNetworkPlugin) Status(namespace string, name string, id kubecontainer.DockerID) (*network.PodNetworkStatus, error) {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return nil, fmt.Errorf("CNI execution called on non-docker runtime")
	}
	ipStr, err := runtime.GetContainerIP(string(id), network.DefaultInterfaceName)
	if err != nil {
		return nil, err
	}
	ip, _, err := net.ParseCIDR(strings.Trim(ipStr, "\n"))
	if err != nil {
		return nil, err
	}
	return &network.PodNetworkStatus{IP: ip}, nil
}

func (network *cniNetwork) addToNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*cnitypes.Result, error) {
	rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
	if err != nil {
		glog.Errorf("Error adding network: %v", err)
		return nil, err
	}

	netconf, cninet := network.NetworkConfig, network.CNIConfig
	glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path)
	res, err := cninet.AddNetwork(netconf, rt)
	if err != nil {
		glog.Errorf("Error adding network: %v", err)
		return nil, err
	}

	return res, nil
}

func (network *cniNetwork) deleteFromNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) error {
	rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
	if err != nil {
		glog.Errorf("Error deleting network: %v", err)
		return err
	}

	netconf, cninet := network.NetworkConfig, network.CNIConfig
	glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path)
	err = cninet.DelNetwork(netconf, rt)
	if err != nil {
		glog.Errorf("Error deleting network: %v", err)
		return err
	}
	return nil
}

func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*libcni.RuntimeConf, error) {
	glog.V(4).Infof("Got netns path %v", podNetnsPath)
	glog.V(4).Infof("Using netns path %v", podNs)

	rt := &libcni.RuntimeConf{
		ContainerID: podInfraContainerID.ID,
		NetNS:       podNetnsPath,
		IfName:      network.DefaultInterfaceName,
		Args: [][2]string{
			{"K8S_POD_NAMESPACE", podNs},
			{"K8S_POD_NAME", podName},
			{"K8S_POD_INFRA_CONTAINER_ID", podInfraContainerID.ID},
		},
	}

	return rt, nil
}
<commit_msg>Sets IgnoreUnknown=1 in CNI_ARGS<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 cni

import (
	"fmt"
	"net"
	"sort"
	"strings"

	"github.com/appc/cni/libcni"
	cnitypes "github.com/appc/cni/pkg/types"
	"github.com/golang/glog"
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
	"k8s.io/kubernetes/pkg/kubelet/dockertools"
	"k8s.io/kubernetes/pkg/kubelet/network"
)

const (
	CNIPluginName        = "cni"
	DefaultNetDir        = "/etc/cni/net.d"
	DefaultCNIDir        = "/opt/cni/bin"
	VendorCNIDirTemplate = "%s/opt/%s/bin"
)

type cniNetworkPlugin struct {
	defaultNetwork *cniNetwork
	host           network.Host
}

type cniNetwork struct {
	name          string
	NetworkConfig *libcni.NetworkConfig
	CNIConfig     *libcni.CNIConfig
}

func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, vendorCNIDirPrefix string) []network.NetworkPlugin {
	configList := make([]network.NetworkPlugin, 0)
	network, err := getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix)
	if err != nil {
		return configList
	}
	return append(configList, &cniNetworkPlugin{defaultNetwork: network})
}

func ProbeNetworkPlugins(pluginDir string) []network.NetworkPlugin {
	return probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, "")
}

func getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix string) (*cniNetwork, error) {
	if pluginDir == "" {
		pluginDir = DefaultNetDir
	}
	files, err := libcni.ConfFiles(pluginDir)
	switch {
	case err != nil:
		return nil, err
	case len(files) == 0:
		return nil, fmt.Errorf("No networks found in %s", pluginDir)
	}

	sort.Strings(files)
	for _, confFile := range files {
		conf, err := libcni.ConfFromFile(confFile)
		if err != nil {
			glog.Warningf("Error loading CNI config file %s: %v", confFile, err)
			continue
		}
		// Search for vendor-specific plugins as well as default plugins in the CNI codebase.
		vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, vendorCNIDirPrefix, conf.Network.Type)
		cninet := &libcni.CNIConfig{
			Path: []string{DefaultCNIDir, vendorCNIDir},
		}
		network := &cniNetwork{name: conf.Network.Name, NetworkConfig: conf, CNIConfig: cninet}
		return network, nil
	}
	return nil, fmt.Errorf("No valid networks found in %s", pluginDir)
}

func (plugin *cniNetworkPlugin) Init(host network.Host) error {
	plugin.host = host
	return nil
}

func (plugin *cniNetworkPlugin) Event(name string, details map[string]interface{}) {
}

func (plugin *cniNetworkPlugin) Name() string {
	return CNIPluginName
}

func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.DockerID) error {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return fmt.Errorf("CNI execution called on non-docker runtime")
	}
	netns, err := runtime.GetNetNS(id.ContainerID())
	if err != nil {
		return err
	}

	_, err = plugin.defaultNetwork.addToNetwork(name, namespace, id.ContainerID(), netns)
	if err != nil {
		glog.Errorf("Error while adding to cni network: %s", err)
		return err
	}

	return err
}

func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id kubecontainer.DockerID) error {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return fmt.Errorf("CNI execution called on non-docker runtime")
	}
	netns, err := runtime.GetNetNS(id.ContainerID())
	if err != nil {
		return err
	}

	return plugin.defaultNetwork.deleteFromNetwork(name, namespace, id.ContainerID(), netns)
}

// TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin.
// Also fix the runtime's call to Status function to be done only in the case that the IP is lost, no need to do periodic calls
func (plugin *cniNetworkPlugin) Status(namespace string, name string, id kubecontainer.DockerID) (*network.PodNetworkStatus, error) {
	runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
	if !ok {
		return nil, fmt.Errorf("CNI execution called on non-docker runtime")
	}
	ipStr, err := runtime.GetContainerIP(string(id), network.DefaultInterfaceName)
	if err != nil {
		return nil, err
	}
	ip, _, err := net.ParseCIDR(strings.Trim(ipStr, "\n"))
	if err != nil {
		return nil, err
	}
	return &network.PodNetworkStatus{IP: ip}, nil
}

func (network *cniNetwork) addToNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*cnitypes.Result, error) {
	rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
	if err != nil {
		glog.Errorf("Error adding network: %v", err)
		return nil, err
	}

	netconf, cninet := network.NetworkConfig, network.CNIConfig
	glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path)
	res, err := cninet.AddNetwork(netconf, rt)
	if err != nil {
		glog.Errorf("Error adding network: %v", err)
		return nil, err
	}

	return res, nil
}

func (network *cniNetwork) deleteFromNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) error {
	rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
	if err != nil {
		glog.Errorf("Error deleting network: %v", err)
		return err
	}

	netconf, cninet := network.NetworkConfig, network.CNIConfig
	glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path)
	err = cninet.DelNetwork(netconf, rt)
	if err != nil {
		glog.Errorf("Error deleting network: %v", err)
		return err
	}
	return nil
}

func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*libcni.RuntimeConf, error) {
	glog.V(4).Infof("Got netns path %v", podNetnsPath)
	glog.V(4).Infof("Using netns path %v", podNs)

	rt := &libcni.RuntimeConf{
		ContainerID: podInfraContainerID.ID,
		NetNS:       podNetnsPath,
		IfName:      network.DefaultInterfaceName,
		Args: [][2]string{
			{"IgnoreUnknown", "1"},
			{"K8S_POD_NAMESPACE", podNs},
			{"K8S_POD_NAME", podName},
			{"K8S_POD_INFRA_CONTAINER_ID", podInfraContainerID.ID},
		},
	}

	return rt, nil
}
<|endoftext|>


<commit_before>// Copyright 2016-2018 Authors of Cilium
//
// 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 allocator

import (
	"fmt"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/cilium/cilium/pkg/kvstore"
	"github.com/cilium/cilium/pkg/lock"

	"github.com/sirupsen/logrus"
)

// idMap provides mapping from ID to an AllocatorKey
type idMap map[ID]AllocatorKey

// keyMap provides mapping from AllocatorKey to ID
type keyMap map[string]ID

type cache struct {
	backend  kvstore.BackendOperations
	prefix   string
	stopChan chan bool

	// mutex protects all cache data structures
	mutex lock.RWMutex

	// cache is a local cache of all IDs allocated in the kvstore. It is
	// being maintained by watching for kvstore events and can thus lag
	// behind.
	cache idMap

	// keyCache shadows cache and allows access by key
	keyCache keyMap

	// nextCache is the cache is constantly being filled by startWatch(),
	// when startWatch has successfully performed the initial fill using
	// ListPrefix, the cache above will be pointed to nextCache. If the
	// startWatch() fails to perform the initial list, then the cache is
	// never pointed to nextCache. This guarantees that a valid cache is
	// kept at all times.
	nextCache idMap

	// nextKeyCache follows the same logic as nextCache but for keyCache
	nextKeyCache keyMap

	// stopWatchWg is a wait group that gets conditions added when a
	// watcher is started with the conditions marked as done when the
	// watcher has exited
	stopWatchWg sync.WaitGroup

	// deleteInvalid enables deletion of identities outside of the valid
	// prefix
	deleteInvalidPrefixes bool
}

func newCache(backend kvstore.BackendOperations, prefix string) cache {
	return cache{
		backend:  backend,
		prefix:   prefix,
		cache:    idMap{},
		keyCache: keyMap{},
		stopChan: make(chan bool, 1),
	}
}

type waitChan chan bool

func (c *cache) getLogger() *logrus.Entry {
	status, err := c.backend.Status()

	return log.WithFields(logrus.Fields{
		"kvstoreStatus": status,
		"kvstoreErr":    err,
		"prefix":        c.prefix,
	})
}

func (c *cache) restart(a *Allocator) error {
	c.stop()
	return c.startAndWait(a)
}

func (c *cache) keyToID(key string, deleteInvalid bool) ID {
	if !strings.HasPrefix(key, c.prefix) {
		invalidKey(key, c.prefix, deleteInvalid)
		return NoID
	}

	suffix := strings.TrimPrefix(key, c.prefix)
	if suffix[0] == '/' {
		suffix = suffix[1:]
	}

	id, err := strconv.ParseUint(suffix, 10, 64)
	if err != nil {
		invalidKey(key, c.prefix, deleteInvalid)
		return NoID
	}

	return ID(id)
}

// start requests a LIST operation from the kvstore and starts watching the
// prefix in a go subroutine.
func (c *cache) start(a *Allocator) waitChan {
	listDone := make(waitChan)

	logger := c.getLogger()
	logger.Info("Starting to watch allocation changes")

	c.mutex.Lock()

	// start with a fresh nextCache
	c.nextCache = idMap{}
	c.nextKeyCache = keyMap{}
	c.mutex.Unlock()

	c.stopWatchWg.Add(1)

	go func() {
		watcher := c.backend.ListAndWatch(c.prefix, c.prefix, 512)

		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					goto abort
				}
				if event.Typ == kvstore.EventTypeListDone {
					c.mutex.Lock()
					// nextCache is valid, point the live cache to it
					c.cache = c.nextCache
					c.keyCache = c.nextKeyCache
					c.mutex.Unlock()

					// report that the list operation has
					// been completed and the allocator is
					// ready to use
					close(listDone)
					continue
				}

				id := c.keyToID(event.Key, c.deleteInvalidPrefixes)
				if id != 0 {
					c.mutex.Lock()

					var key AllocatorKey

					if len(event.Value) > 0 {
						var err error
						key, err = a.keyType.PutKey(string(event.Value))
						if err != nil {
							logger.WithError(err).WithField(fieldKey, event.Value).
								Warning("Unable to unmarshal allocator key")
						}
					}
					debugFields := logger.WithFields(logrus.Fields{fieldKey: key, fieldID: id})

					switch event.Typ {
					case kvstore.EventTypeCreate:
						kvstore.Trace("Adding id to cache", nil, debugFields.Data)
						c.nextCache[id] = key
						if key != nil {
							c.nextKeyCache[key.GetKey()] = id
						}

					case kvstore.EventTypeModify:
						kvstore.Trace("Modifying id in cache", nil, debugFields.Data)
						if k, ok := c.nextCache[id]; ok {
							delete(c.nextKeyCache, k.GetKey())
						}

						c.nextCache[id] = key
						if key != nil {
							c.nextKeyCache[key.GetKey()] = id
						}

					case kvstore.EventTypeDelete:
						kvstore.Trace("Removing id from cache", nil, debugFields.Data)

						if k, ok := c.nextCache[id]; ok {
							delete(c.nextKeyCache, k.GetKey())
						}

						delete(c.nextCache, id)
					}
					c.mutex.Unlock()

					if a.events != nil {
						a.events <- AllocatorEvent{
							Typ: event.Typ,
							ID:  ID(id),
							Key: key,
						}
					}
				}

			case <-c.stopChan:
				goto abort
			}
		}

	abort:
		watcher.Stop()
		// Signal that watcher is done
		c.stopWatchWg.Done()
	}()

	return listDone
}

func (c *cache) startAndWait(a *Allocator) error {
	listDone := c.start(a)

	// Wait for watcher to be started and for list operation to succeed
	select {
	case <-listDone:
	case <-time.After(listTimeout):
		return fmt.Errorf("Time out while waiting for list operation to complete")
	}

	return nil
}

func (c *cache) stop() {
	select {
	case c.stopChan <- true:
	default:
	}
	c.stopWatchWg.Wait()
}

func (c *cache) get(key string) ID {
	c.mutex.RLock()
	if id, ok := c.keyCache[key]; ok {
		c.mutex.RUnlock()
		return id
	}
	c.mutex.RUnlock()

	return NoID
}

func (c *cache) getByID(id ID) AllocatorKey {
	c.mutex.RLock()
	if v, ok := c.cache[id]; ok {
		c.mutex.RUnlock()
		return v
	}
	c.mutex.RUnlock()

	return nil
}

func (c *cache) foreach(cb RangeFunc) {
	c.mutex.RLock()
	for k, v := range c.cache {
		cb(k, v)
	}
	c.mutex.RUnlock()
}

func (c *cache) insert(key AllocatorKey, val ID) {
	c.mutex.Lock()
	c.nextCache[val] = key
	c.nextKeyCache[key.GetKey()] = val
	c.mutex.Unlock()
}
<commit_msg>allocator: nextCache can hold a nil value for a id/key<commit_after>// Copyright 2016-2018 Authors of Cilium
//
// 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 allocator

import (
	"fmt"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/cilium/cilium/pkg/kvstore"
	"github.com/cilium/cilium/pkg/lock"

	"github.com/sirupsen/logrus"
)

// idMap provides mapping from ID to an AllocatorKey
type idMap map[ID]AllocatorKey

// keyMap provides mapping from AllocatorKey to ID
type keyMap map[string]ID

type cache struct {
	backend  kvstore.BackendOperations
	prefix   string
	stopChan chan bool

	// mutex protects all cache data structures
	mutex lock.RWMutex

	// cache is a local cache of all IDs allocated in the kvstore. It is
	// being maintained by watching for kvstore events and can thus lag
	// behind.
	cache idMap

	// keyCache shadows cache and allows access by key
	keyCache keyMap

	// nextCache is the cache is constantly being filled by startWatch(),
	// when startWatch has successfully performed the initial fill using
	// ListPrefix, the cache above will be pointed to nextCache. If the
	// startWatch() fails to perform the initial list, then the cache is
	// never pointed to nextCache. This guarantees that a valid cache is
	// kept at all times.
	nextCache idMap

	// nextKeyCache follows the same logic as nextCache but for keyCache
	nextKeyCache keyMap

	// stopWatchWg is a wait group that gets conditions added when a
	// watcher is started with the conditions marked as done when the
	// watcher has exited
	stopWatchWg sync.WaitGroup

	// deleteInvalid enables deletion of identities outside of the valid
	// prefix
	deleteInvalidPrefixes bool
}

func newCache(backend kvstore.BackendOperations, prefix string) cache {
	return cache{
		backend:  backend,
		prefix:   prefix,
		cache:    idMap{},
		keyCache: keyMap{},
		stopChan: make(chan bool, 1),
	}
}

type waitChan chan bool

func (c *cache) getLogger() *logrus.Entry {
	status, err := c.backend.Status()

	return log.WithFields(logrus.Fields{
		"kvstoreStatus": status,
		"kvstoreErr":    err,
		"prefix":        c.prefix,
	})
}

func (c *cache) restart(a *Allocator) error {
	c.stop()
	return c.startAndWait(a)
}

func (c *cache) keyToID(key string, deleteInvalid bool) ID {
	if !strings.HasPrefix(key, c.prefix) {
		invalidKey(key, c.prefix, deleteInvalid)
		return NoID
	}

	suffix := strings.TrimPrefix(key, c.prefix)
	if suffix[0] == '/' {
		suffix = suffix[1:]
	}

	id, err := strconv.ParseUint(suffix, 10, 64)
	if err != nil {
		invalidKey(key, c.prefix, deleteInvalid)
		return NoID
	}

	return ID(id)
}

// start requests a LIST operation from the kvstore and starts watching the
// prefix in a go subroutine.
func (c *cache) start(a *Allocator) waitChan {
	listDone := make(waitChan)

	logger := c.getLogger()
	logger.Info("Starting to watch allocation changes")

	c.mutex.Lock()

	// start with a fresh nextCache
	c.nextCache = idMap{}
	c.nextKeyCache = keyMap{}
	c.mutex.Unlock()

	c.stopWatchWg.Add(1)

	go func() {
		watcher := c.backend.ListAndWatch(c.prefix, c.prefix, 512)

		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					goto abort
				}
				if event.Typ == kvstore.EventTypeListDone {
					c.mutex.Lock()
					// nextCache is valid, point the live cache to it
					c.cache = c.nextCache
					c.keyCache = c.nextKeyCache
					c.mutex.Unlock()

					// report that the list operation has
					// been completed and the allocator is
					// ready to use
					close(listDone)
					continue
				}

				id := c.keyToID(event.Key, c.deleteInvalidPrefixes)
				if id != 0 {
					c.mutex.Lock()

					var key AllocatorKey

					if len(event.Value) > 0 {
						var err error
						key, err = a.keyType.PutKey(string(event.Value))
						if err != nil {
							logger.WithError(err).WithField(fieldKey, event.Value).
								Warning("Unable to unmarshal allocator key")
						}
					}
					debugFields := logger.WithFields(logrus.Fields{fieldKey: key, fieldID: id})

					switch event.Typ {
					case kvstore.EventTypeCreate:
						kvstore.Trace("Adding id to cache", nil, debugFields.Data)
						c.nextCache[id] = key
						if key != nil {
							c.nextKeyCache[key.GetKey()] = id
						}

					case kvstore.EventTypeModify:
						kvstore.Trace("Modifying id in cache", nil, debugFields.Data)
						if k, ok := c.nextCache[id]; ok {
							delete(c.nextKeyCache, k.GetKey())
						}

						c.nextCache[id] = key
						if key != nil {
							c.nextKeyCache[key.GetKey()] = id
						}

					case kvstore.EventTypeDelete:
						kvstore.Trace("Removing id from cache", nil, debugFields.Data)

						if k, ok := c.nextCache[id]; ok && k != nil {
							delete(c.nextKeyCache, k.GetKey())
						}

						delete(c.nextCache, id)
					}
					c.mutex.Unlock()

					if a.events != nil {
						a.events <- AllocatorEvent{
							Typ: event.Typ,
							ID:  ID(id),
							Key: key,
						}
					}
				}

			case <-c.stopChan:
				goto abort
			}
		}

	abort:
		watcher.Stop()
		// Signal that watcher is done
		c.stopWatchWg.Done()
	}()

	return listDone
}

func (c *cache) startAndWait(a *Allocator) error {
	listDone := c.start(a)

	// Wait for watcher to be started and for list operation to succeed
	select {
	case <-listDone:
	case <-time.After(listTimeout):
		return fmt.Errorf("Time out while waiting for list operation to complete")
	}

	return nil
}

func (c *cache) stop() {
	select {
	case c.stopChan <- true:
	default:
	}
	c.stopWatchWg.Wait()
}

func (c *cache) get(key string) ID {
	c.mutex.RLock()
	if id, ok := c.keyCache[key]; ok {
		c.mutex.RUnlock()
		return id
	}
	c.mutex.RUnlock()

	return NoID
}

func (c *cache) getByID(id ID) AllocatorKey {
	c.mutex.RLock()
	if v, ok := c.cache[id]; ok {
		c.mutex.RUnlock()
		return v
	}
	c.mutex.RUnlock()

	return nil
}

func (c *cache) foreach(cb RangeFunc) {
	c.mutex.RLock()
	for k, v := range c.cache {
		cb(k, v)
	}
	c.mutex.RUnlock()
}

func (c *cache) insert(key AllocatorKey, val ID) {
	c.mutex.Lock()
	c.nextCache[val] = key
	c.nextKeyCache[key.GetKey()] = val
	c.mutex.Unlock()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"time"
)

const (
	vultrMetaDataURL = "http://169.254.169.254/v1/"
)

// ProviderVultr is the type implementing the Provider interface for Vultr
type ProviderVultr struct {
}

// NewVultr returns a new ProviderVultr
func NewVultr() *ProviderVultr {
	return &ProviderVultr{}
}

func (p *ProviderVultr) String() string {
	return "Vultr"
}

// Probe checks if we are running on Vultr
func (p *ProviderVultr) Probe() bool {
	// Getting the index should always work...
	_, err := vultrGet(vultrMetaDataURL)
	return (err == nil)
}

// Extract gets both the Vultr specific and generic userdata
func (p *ProviderVultr) Extract() ([]byte, error) {
	// Get host name. This must not fail
	hostname, err := vultrGet(vultrMetaDataURL + "hostname")
	if err != nil {
		return nil, err
	}
	err = ioutil.WriteFile(path.Join(ConfigPath, Hostname), hostname, 0644)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Failed to write hostname: %s", err)
	}

	// public ipv4
	vultrMetaGet("interfaces/0/ipv4/address", "public_ipv4", 0644)

	// private ipv4
	vultrMetaGet("interfaces/1/ipv4/address", "private_ipv4", 0644)

	// private netmask
	vultrMetaGet("interfaces/1/ipv4/netmask", "private_netmask", 0644)

	// region code
	vultrMetaGet("region/regioncode", "region_code", 0644)

	// instance-id
	vultrMetaGet("instanceid", "instance_id", 0644)

	// ssh
	if err := p.handleSSH(); err != nil {
		log.Printf("Vultr: Failed to get ssh data: %s", err)
	}

	return nil, nil
}

// lookup a value (lookupName) in Vultr metaservice and store in given fileName
func vultrMetaGet(lookupName string, fileName string, fileMode os.FileMode) {
	if lookupValue, err := vultrGet(vultrMetaDataURL + lookupName); err == nil {
		// we got a value from the metadata server, now save to filesystem
		err = ioutil.WriteFile(path.Join(ConfigPath, fileName), lookupValue, fileMode)
		if err != nil {
			// we couldn't save the file for some reason
			log.Printf("Vultr: Failed to write %s:%s %s", fileName, lookupValue, err)
		}
	} else {
		// we did not get a value back from the metadata server
		log.Printf("Vultr: Failed to get %s: %s", lookupName, err)
	}
}

// vultrGet requests and extracts the requested URL
func vultrGet(url string) ([]byte, error) {
	var client = &http.Client{
		Timeout: time.Second * 2,
	}

	req, err := http.NewRequest("", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Vultr: http.NewRequest failed: %s", err)
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Could not contact metadata service: %s", err)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Vultr: Status not ok: %d", resp.StatusCode)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Failed to read http response: %s", err)
	}
	return body, nil
}

// SSH keys:
func (p *ProviderVultr) handleSSH() error {
	sshKeys, err := vultrGet(vultrMetaDataURL + "public-keys")
	if err != nil {
		return fmt.Errorf("Failed to get sshKeys: %s", err)
	}

	if err := os.Mkdir(path.Join(ConfigPath, SSH), 0755); err != nil {
		return fmt.Errorf("Failed to create %s: %s", SSH, err)
	}

	err = ioutil.WriteFile(path.Join(ConfigPath, SSH, "authorized_keys"), sshKeys, 0600)
	if err != nil {
		return fmt.Errorf("Failed to write ssh keys: %s", err)
	}
	return nil
}
<commit_msg>Add BGP to Vultr provder's loaded data<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"time"
)

const (
	vultrMetaDataURL = "http://169.254.169.254/v1/"
)

// ProviderVultr is the type implementing the Provider interface for Vultr
type ProviderVultr struct {
}

// NewVultr returns a new ProviderVultr
func NewVultr() *ProviderVultr {
	return &ProviderVultr{}
}

func (p *ProviderVultr) String() string {
	return "Vultr"
}

// Probe checks if we are running on Vultr
func (p *ProviderVultr) Probe() bool {
	// Getting the index should always work...
	_, err := vultrGet(vultrMetaDataURL)
	return (err == nil)
}

// Extract gets both the Vultr specific and generic userdata
func (p *ProviderVultr) Extract() ([]byte, error) {
	// Get host name. This must not fail
	hostname, err := vultrGet(vultrMetaDataURL + "hostname")
	if err != nil {
		return nil, err
	}
	err = ioutil.WriteFile(path.Join(ConfigPath, Hostname), hostname, 0644)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Failed to write hostname: %s", err)
	}

	// public ipv4
	vultrMetaGet("interfaces/0/ipv4/address", "public_ipv4", 0644)

	// private ipv4
	vultrMetaGet("interfaces/1/ipv4/address", "private_ipv4", 0644)

	// private netmask
	vultrMetaGet("interfaces/1/ipv4/netmask", "private_netmask", 0644)

	// region code
	vultrMetaGet("region/regioncode", "region_code", 0644)

	// instance-id
	vultrMetaGet("instanceid", "instance_id", 0644)

	// BGP my asn
	vultrMetaGet("bgp/ipv4/my-asn", "my_asn_ipv4", 0644)

	// ssh
	if err := p.handleSSH(); err != nil {
		log.Printf("Vultr: Failed to get ssh data: %s", err)
	}

	return nil, nil
}

// lookup a value (lookupName) in Vultr metaservice and store in given fileName
func vultrMetaGet(lookupName string, fileName string, fileMode os.FileMode) {
	if lookupValue, err := vultrGet(vultrMetaDataURL + lookupName); err == nil {
		// we got a value from the metadata server, now save to filesystem
		err = ioutil.WriteFile(path.Join(ConfigPath, fileName), lookupValue, fileMode)
		if err != nil {
			// we couldn't save the file for some reason
			log.Printf("Vultr: Failed to write %s:%s %s", fileName, lookupValue, err)
		}
	} else {
		// we did not get a value back from the metadata server
		log.Printf("Vultr: Failed to get %s: %s", lookupName, err)
	}
}

// vultrGet requests and extracts the requested URL
func vultrGet(url string) ([]byte, error) {
	var client = &http.Client{
		Timeout: time.Second * 2,
	}

	req, err := http.NewRequest("", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Vultr: http.NewRequest failed: %s", err)
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Could not contact metadata service: %s", err)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Vultr: Status not ok: %d", resp.StatusCode)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("Vultr: Failed to read http response: %s", err)
	}
	return body, nil
}

// SSH keys:
func (p *ProviderVultr) handleSSH() error {
	sshKeys, err := vultrGet(vultrMetaDataURL + "public-keys")
	if err != nil {
		return fmt.Errorf("Failed to get sshKeys: %s", err)
	}

	if err := os.Mkdir(path.Join(ConfigPath, SSH), 0755); err != nil {
		return fmt.Errorf("Failed to create %s: %s", SSH, err)
	}

	err = ioutil.WriteFile(path.Join(ConfigPath, SSH, "authorized_keys"), sshKeys, 0600)
	if err != nil {
		return fmt.Errorf("Failed to write ssh keys: %s", err)
	}
	return nil
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * 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 search

import (
	"fmt"
	"github.com/ctdk/goas/v2/logger"
	"github.com/ctdk/goiardi/indexer"
	//"github.com/ctdk/goiardi/util"
	"regexp"
)

type PostgresSearch struct {
}

type PgQuery struct {
	queryChain Queryable
	paths []string
	queryStrs []string
	arguments []string
}

func (p *PostgresSearch) Search(idx string, q string, rows int, sortOrder string, start int, partialData map[string]interface{}) ([]map[string]interface{}, error) {
	// keep up with the ersatz solr.
	qq := &Tokenizer{Buffer: q}
	qq.Init()
	if err := qq.Parse(); err != nil {
		return nil, err
	}
	qq.Execute()
	qchain := qq.Evaluate()

	pgQ := &PgQuery{ queryChain: qchain }

	logger.Debugf("what on earth is the chain? %q", qchain)
	err := pgQ.execute()
	if err != nil {
		return nil, err
	}

	// dummy
	dres := make([]map[string]interface{}, 0)
	return dres, nil
}

func (p *PostgresSearch) GetEndpoints() []string {
	// TODO: deal with possible errors
	endpoints, err := indexer.Endpoints()
	return endpoints
	if err != nil {
		panic(err)
	}
	return endpoints
}

func (pq *PgQuery) execute(startTableID ...*int) error {
	p := pq.queryChain
	//curOp := OpNotAnOp
	opMap := map[Op]string{
		OpNotAnOp: "(not an op)",
		OpUnaryNot: "not",
		OpUnaryReq: "req",
		OpUnaryPro: "pro",
		OpBinAnd: "and",
		OpBinOr: "or",
		OpBoost: "boost",
		OpFuzzy: "fuzzy",
		OpStartGroup: "start group",
		OpEndGroup: "end group",
		OpStartIncl: "start inc",
		OpEndIncl: "end inc",
		OpStartExcl: "start exc",
		OpEndExcl: "end exc",
	}
	var t *int
	if len(startTableID) == 0 {
		z := 0
		t = &z
	} else {
		t = startTableID[0]
	}
	for p != nil {
		switch c := p.(type) {
		case *BasicQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("basic t%d: field: %s op: %s term: %+v complete %v", *t, c.field, opMap[c.op], c.term, c.complete)
			args, qstr := buildBasicQuery(c.field, c.term, t)
			pq.args = append(pq.args, args...)
			pq.queryStrs = append(pq.queryStrs, qstr)
			*t++
		case *GroupedQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("grouped t%d: field: %s op: %s terms: %+v complete %v", *t, c.field, opMap[c.op], c.terms, c.complete)
			*t++
		case *RangeQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("range t%d: field %s op %s start %s end %s inclusive %v complete %v", *t, c.field, opMap[c.op], c.start, c.end, c.inclusive, c.complete)
			*t++
		case *SubQuery:
			logger.Debugf("STARTING SUBQUERY: op %s complete %v", opMap[c.op], c.complete)
			newq, nend, nerr := extractSubQuery(c)
			if nerr != nil {
				return nerr
			}
			p = nend
			logger.Debugf("OP NOW: %s", opMap[p.Op()])
			np := &PgQuery{ queryChain: newq }
			err := np.execute(t)
			if err != nil {
				return err
			}
			pq.paths = append(pq.paths, np.paths...)
			logger.Debugf("ENDING SUBQUERY")
		default:
			err := fmt.Errorf("Unknown type %T for query", c)
			return err
		}
		//curOp = p.Op()
		p = p.Next()
	}
	logger.Debugf("paths: %v", pq.paths)
	logger.Debugf("number of tables: %d", *t)
	return nil
}

func buildBasicQuery(field Field, term Term, tNum *int) ([]string, string) {
	var op string
	r := regex.MustCompile(`\*|\?`)
	if r.MatchString(term) {
		op = "LIKE"
	} else {
		op = "="
	}
	var q string
	args := []string{ field }
	if term == "*" {
		q = fmt.Sprintf("f%d.path ~ _ARG_")
	} else {
		q = fmt.Sprintf("f%d.path ~ _ARG_ AND f%d.value %s _ARG_", tNum, tNum, op)
		args = append(args, term)
	}

	return args, q
}
<commit_msg>don't neglect unary ops, fix up a little<commit_after>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * 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 search

import (
	"fmt"
	"github.com/ctdk/goas/v2/logger"
	"github.com/ctdk/goiardi/indexer"
	//"github.com/ctdk/goiardi/util"
	"regexp"
)

type PostgresSearch struct {
}

type PgQuery struct {
	queryChain Queryable
	paths []string
	queryStrs []string
	arguments []string
}

func (p *PostgresSearch) Search(idx string, q string, rows int, sortOrder string, start int, partialData map[string]interface{}) ([]map[string]interface{}, error) {
	// keep up with the ersatz solr.
	qq := &Tokenizer{Buffer: q}
	qq.Init()
	if err := qq.Parse(); err != nil {
		return nil, err
	}
	qq.Execute()
	qchain := qq.Evaluate()

	pgQ := &PgQuery{ queryChain: qchain }

	logger.Debugf("what on earth is the chain? %q", qchain)
	err := pgQ.execute()
	if err != nil {
		return nil, err
	}

	// dummy
	dres := make([]map[string]interface{}, 0)
	return dres, nil
}

func (p *PostgresSearch) GetEndpoints() []string {
	// TODO: deal with possible errors
	endpoints, err := indexer.Endpoints()
	return endpoints
	if err != nil {
		panic(err)
	}
	return endpoints
}

func (pq *PgQuery) execute(startTableID ...*int) error {
	p := pq.queryChain
	curOp := OpNotAnOp
	opMap := map[Op]string{
		OpNotAnOp: "(not an op)",
		OpUnaryNot: "not",
		OpUnaryReq: "req",
		OpUnaryPro: "pro",
		OpBinAnd: "and",
		OpBinOr: "or",
		OpBoost: "boost",
		OpFuzzy: "fuzzy",
		OpStartGroup: "start group",
		OpEndGroup: "end group",
		OpStartIncl: "start inc",
		OpEndIncl: "end inc",
		OpStartExcl: "start exc",
		OpEndExcl: "end exc",
	}
	var t *int
	if len(startTableID) == 0 {
		z := 0
		t = &z
	} else {
		t = startTableID[0]
	}
	for p != nil {
		switch c := p.(type) {
		case *BasicQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("basic t%d: field: %s op: %s term: %+v complete %v", *t, c.field, opMap[c.op], c.term, c.complete)
			args, qstr := buildBasicQuery(c.field, c.term, t)
			pq.args = append(pq.args, args...)
			pq.queryStrs = append(pq.queryStrs, qstr)
			*t++
		case *GroupedQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("grouped t%d: field: %s op: %s terms: %+v complete %v", *t, c.field, opMap[c.op], c.terms, c.complete)
			*t++
		case *RangeQuery:
			pq.paths = append(pq.paths, string(c.field))
			logger.Debugf("range t%d: field %s op %s start %s end %s inclusive %v complete %v", *t, c.field, opMap[c.op], c.start, c.end, c.inclusive, c.complete)
			*t++
		case *SubQuery:
			logger.Debugf("STARTING SUBQUERY: op %s complete %v", opMap[c.op], c.complete)
			newq, nend, nerr := extractSubQuery(c)
			if nerr != nil {
				return nerr
			}
			p = nend
			logger.Debugf("OP NOW: %s", opMap[p.Op()])
			np := &PgQuery{ queryChain: newq }
			err := np.execute(t)
			if err != nil {
				return err
			}
			pq.paths = append(pq.paths, np.paths...)
			logger.Debugf("ENDING SUBQUERY")
		default:
			err := fmt.Errorf("Unknown type %T for query", c)
			return err
		}
		//curOp = p.Op()
		p = p.Next()
	}
	logger.Debugf("paths: %v", pq.paths)
	logger.Debugf("number of tables: %d", *t)
	return nil
}

func buildBasicQuery(field Field, term QueryTerm, tNum *int, op Op) ([]string, string) {
	var cop string
	r := regex.MustCompile(`\*|\?`)
	if r.MatchString(term) {
		cop = "LIKE"
	} else {
		cop = "="
	}
	var opStr string
	if op != OpNotAnOp {
		if op == OpBinAnd {
			opStr = " AND "
		} else {
			opStr = " OR "
		}
	}
	var unaryOp string

	var q string
	args := []string{ field }
	if term == "*" {
		q = fmt.Sprintf("(f%d.path ~ _ARG_)", tNum)
	} else {
		q = fmt.Sprintf("(f%d.path ~ _ARG_ AND f%d.value %s _ARG_)", tNum, tNum, cop)
		args = append(args, term.term)
	}

	return args, q
}
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc. All rights reserved.
// 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 writing, software distributed
// under the License is distributed on a "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 app

import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
)

// Person contains the name and age of a person.
type Person struct {
	Name     string
	AgeYears int
}

func completeHandler(w http.ResponseWriter, r *http.Request) {
	// create a new App Engine context from the HTTP request.
	ctx := appengine.NewContext(r)

	p := &Person{Name: "gopher", AgeYears: 5}

	// create a new complete key of kind Person and value gopher.
	key := datastore.NewKey(ctx, "Person", "gopher", 0, nil)
	// put p in the datastore.
	key, err := datastore.Put(ctx, key, p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "gopher stored with key %v", key)
}

func incompleteHandler(w http.ResponseWriter, r *http.Request) {
	// create a new App Engine context from the HTTP request.
	ctx := appengine.NewContext(r)

	p := &Person{Name: "gopher", AgeYears: 5}

	// create a new complete key of kind Person.
	key := datastore.NewIncompleteKey(ctx, "Person", nil)
	// put p in the datastore.
	key, err := datastore.Put(ctx, key, p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "gopher stored with key %v", key)
}

func getHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	key := datastore.NewKey(ctx, "Person", "gopher", 0, nil)

	var p Person
	err := datastore.Get(ctx, key, &p)
	if err != nil {
		http.Error(w, "Person not found", http.StatusNotFound)
		return
	}
	fmt.Fprintln(w, p)
}

func queryHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	var p []Person

	// create a new query on the kind Person
	q := datastore.NewQuery("Person")

	// select only values where field Age is 10 or lower
	q = q.Filter("Age <=", 10)

	// order all the values by the Name field
	q = q.Order("Name")

	// and finally execute the query retrieving all values into p.
	_, err := q.GetAll(ctx, &p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, p)
}

func chainedQueryHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	var p []Person

	// create a new query on the kind Person
	q := datastore.NewQuery("Person").
		Filter("Age <=", 10).
		Order("Name")

	// and finally execute the query retrieving all values into p.
	_, err := q.GetAll(ctx, &p)
	if err != nil {
		// handle the error
	}
}

func init() {
	http.HandleFunc("/complete", completeHandler)
	http.HandleFunc("/incomplete", incompleteHandler)
	http.HandleFunc("/query", queryHandler)
	http.HandleFunc("/chainedQuery", chainedQueryHandler)
}
<commit_msg>register all endpoints for later testing<commit_after>// Copyright 2017 Google Inc. All rights reserved.
// 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 writing, software distributed
// under the License is distributed on a "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 app

import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
)

// Person contains the name and age of a person.
type Person struct {
	Name     string
	AgeYears int
}

func completeHandler(w http.ResponseWriter, r *http.Request) {
	// create a new App Engine context from the HTTP request.
	ctx := appengine.NewContext(r)

	p := &Person{Name: "gopher", AgeYears: 5}

	// create a new complete key of kind Person and value gopher.
	key := datastore.NewKey(ctx, "Person", "gopher", 0, nil)
	// put p in the datastore.
	key, err := datastore.Put(ctx, key, p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "gopher stored with key %v", key)
}

func incompleteHandler(w http.ResponseWriter, r *http.Request) {
	// create a new App Engine context from the HTTP request.
	ctx := appengine.NewContext(r)

	p := &Person{Name: "gopher", AgeYears: 5}

	// create a new complete key of kind Person.
	key := datastore.NewIncompleteKey(ctx, "Person", nil)
	// put p in the datastore.
	key, err := datastore.Put(ctx, key, p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "gopher stored with key %v", key)
}

func getHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	key := datastore.NewKey(ctx, "Person", "gopher", 0, nil)

	var p Person
	err := datastore.Get(ctx, key, &p)
	if err != nil {
		http.Error(w, "Person not found", http.StatusNotFound)
		return
	}
	fmt.Fprintln(w, p)
}

func queryHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	var p []Person

	// create a new query on the kind Person
	q := datastore.NewQuery("Person")

	// select only values where field Age is 10 or lower
	q = q.Filter("Age <=", 10)

	// order all the values by the Name field
	q = q.Order("Name")

	// and finally execute the query retrieving all values into p.
	_, err := q.GetAll(ctx, &p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, p)
}

func chainedQueryHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	var p []Person

	// create a new query on the kind Person
	q := datastore.NewQuery("Person").
		Filter("Age <=", 10).
		Order("Name")

	// and finally execute the query retrieving all values into p.
	_, err := q.GetAll(ctx, &p)
	if err != nil {
		// handle the error
	}
}

func init() {
	http.HandleFunc("/complete", completeHandler)
	http.HandleFunc("/incomplete", incompleteHandler)
	http.HandleFunc("/query", queryHandler)
	http.HandleFunc("/chainedQuery", chainedQueryHandler)
	http.HandleFunc("/get", getHandler)
}
<|endoftext|>


<commit_before>package main

import (
	"testing"
	"encoding/json"
	"fmt"
	"os"
)

var theEvent Event

func TestChannelInference(t *testing.T) {

	tables := []struct {
        json string
        channel string
    }{
        {"{\"channel\":\"algo\"}", "algo"},
        {"{\"otherfields\":\"somevals\"}", "undefined"},
    }

    for _, table := range tables {
		var rawEvent map[string]interface{} = nil
		thejson := []byte(table.json)
		json.Unmarshal(thejson, &rawEvent)
		theEvent = getEvent(rawEvent)
		inferredchan := string(theEvent.Channel)
		if inferredchan != table.channel {
			t.Errorf("Wrong inferred channel, got: %s, want: %s.", inferredchan, table.channel)
		}
	}
}

func TestSumAggSignal(t *testing.T) {
	aggSignal := AggregatedSignal{[]Signal{}, aggregatorsMap["avg"]}
	sample := aggSignal.Sample()
	if (sample != UNDEFINED) {
			t.Errorf("Wrong aggregated value, got: %s, wanted nil.", sample)
	}
}

var five interface{} = 5
var sampledSignal SampledSignal = SampledSignal{ &five }

func TestSampleSampled(t *testing.T) {
	sample := sampledSignal.Sample()
	if ((*sample).(int) != 5) {
		t.Errorf("Wrong sampledsignal sample value, got: %v, want: %v.", sample, 5)
	}
}

var aggSignal AggregatedSignal = AggregatedSignal{ nil, func(vals []interface{}) *interface{} {return nil} }

func TestAddSource(t *testing.T) {
	aggSignal.AddSource(sampledSignal)
	aggSignal.Sample()
}

var baseSession BaseSessionSignal = BaseSessionSignal{true}
var condSignal ConditionalSignal = ConditionalSignal{aggSignal, baseSession}
var signalNameAndPars SignalNameAndPars = SignalNameAndPars{"signal", map[Param]string{}}
var otherSignalNameAndPars SignalNameAndPars = SignalNameAndPars{"othersignal", map[Param]string{}}

func TestCreate(t *testing.T) {
	theGlobalAggregatedSignalDefs = map[SignalName]AggregatedSignalDefinition {
	"signal" : AggregatedSignalDefinition {
				"signal",
				[]Param{},
				"avg",
				[]Param{"x"},
				"cpuload",
				[]Param{"x"},
			},
	}
	createBaseSession(signalNameAndPars)
	createSampledSignal(signalNameAndPars)
	createConditionalSignal(signalNameAndPars, baseSession, aggSignal)
	createAggregatedSignal(signalNameAndPars)
}

func TestRest(t *testing.T) {
	condSignal.Sample()
	checkWriteDefs("ts")
	checkSamples(theEvent)
	extractParamsMap(theEvent, map[Param]JSONPath{})
	extractFromMap(map[string]interface{} {"a":5,}, "a")
	//readAndRegister(map[string]interface{}{})
	baseSession.getState()
	getSessionSignals("sessionName", map[Param]string{})
	registerBaseSessionSignal(signalNameAndPars, &baseSession)
	getBaseSession(signalNameAndPars)
	updateBaseSession(signalNameAndPars, false)
	reportSessionSignalCreation(otherSignalNameAndPars, baseSession)
fmt.Println("")
	signalNameAndPars.equals(signalNameAndPars)
	getSignals("signal", map[Param]string{})
	registerSampledSignal(signalNameAndPars, &sampledSignal)
	getSampledSignal(signalNameAndPars)
	registerAggregatedSignal(signalNameAndPars, &aggSignal)
	getAggregatedSignal(signalNameAndPars)
	registerConditionalSignal(signalNameAndPars, &condSignal)
	reportSample(signalNameAndPars, 8)

	theGlobalWriteDefs = []SignalWriteDefinition {
		SignalWriteDefinition{
			"signal",
			"out",
			map[JSONPath]WriteValue{
			},
			SNameAndRebound{
				"signal",
				map[Param]Param{
				},
			},
		},
	}
	registerWriteDefs(signalNameAndPars, aggSignal)
	getWriters(signalNameAndPars)[0]("ts")
	//main()
	file, err := os.Open("testinputs/testdefs.json")
    if err != nil {
        panic(err)
    }
	scanAPIPipe(file)
	file, err = os.Open("testinputs/testEvents.txt")
    if err != nil {
        panic(err)
    }
	scanStdIn(file)
}

var ssdef SampledSignalDefinition = SampledSignalDefinition {
            "cpuload",
            map[Param]JSONPath {
                "x": "beat.hostname",
            },
            "in",
            "system.load.1",
        }

var bsdef BaseSessionDefinition = BaseSessionDefinition {
        "timeIsEven",
        []EventDefinition {
            EventDefinition {
                "in_condition_true",
                nil,
            },
        },
        []EventDefinition {
            EventDefinition {
                "in_condition_false",
                nil,
            },
        },
    }

func TestGetParams(t *testing.T) {
	ssdef.getParams()
	bsdef.getParams()
}

/*
*/
<commit_msg>fixing error format (#100)<commit_after>package main

import (
	"testing"
	"encoding/json"
	"fmt"
	"os"
)

var theEvent Event

func TestChannelInference(t *testing.T) {

	tables := []struct {
        json string
        channel string
    }{
        {"{\"channel\":\"algo\"}", "algo"},
        {"{\"otherfields\":\"somevals\"}", "undefined"},
    }

    for _, table := range tables {
		var rawEvent map[string]interface{} = nil
		thejson := []byte(table.json)
		json.Unmarshal(thejson, &rawEvent)
		theEvent = getEvent(rawEvent)
		inferredchan := string(theEvent.Channel)
		if inferredchan != table.channel {
			t.Errorf("Wrong inferred channel, got: %s, want: %s.", inferredchan, table.channel)
		}
	}
}

func TestSumAggSignal(t *testing.T) {
	aggSignal := AggregatedSignal{[]Signal{}, aggregatorsMap["avg"]}
	sample := aggSignal.Sample()
	if (sample != UNDEFINED) {
			t.Errorf("Wrong aggregated value, got: %s, wanted nil.", (*sample).(int))
	}
}

var five interface{} = 5
var sampledSignal SampledSignal = SampledSignal{ &five }

func TestSampleSampled(t *testing.T) {
	sample := sampledSignal.Sample()
	if ((*sample).(int) != 5) {
		t.Errorf("Wrong sampledsignal sample value, got: %v, want: %v.", sample, 5)
	}
}

var aggSignal AggregatedSignal = AggregatedSignal{ nil, func(vals []interface{}) *interface{} {return nil} }

func TestAddSource(t *testing.T) {
	aggSignal.AddSource(sampledSignal)
	aggSignal.Sample()
}

var baseSession BaseSessionSignal = BaseSessionSignal{true}
var condSignal ConditionalSignal = ConditionalSignal{aggSignal, baseSession}
var signalNameAndPars SignalNameAndPars = SignalNameAndPars{"signal", map[Param]string{}}
var otherSignalNameAndPars SignalNameAndPars = SignalNameAndPars{"othersignal", map[Param]string{}}

func TestCreate(t *testing.T) {
	theGlobalAggregatedSignalDefs = map[SignalName]AggregatedSignalDefinition {
	"signal" : AggregatedSignalDefinition {
				"signal",
				[]Param{},
				"avg",
				[]Param{"x"},
				"cpuload",
				[]Param{"x"},
			},
	}
	createBaseSession(signalNameAndPars)
	createSampledSignal(signalNameAndPars)
	createConditionalSignal(signalNameAndPars, baseSession, aggSignal)
	createAggregatedSignal(signalNameAndPars)
}

func TestRest(t *testing.T) {
	condSignal.Sample()
	checkWriteDefs("ts")
	checkSamples(theEvent)
	extractParamsMap(theEvent, map[Param]JSONPath{})
	extractFromMap(map[string]interface{} {"a":5,}, "a")
	//readAndRegister(map[string]interface{}{})
	baseSession.getState()
	getSessionSignals("sessionName", map[Param]string{})
	registerBaseSessionSignal(signalNameAndPars, &baseSession)
	getBaseSession(signalNameAndPars)
	updateBaseSession(signalNameAndPars, false)
	reportSessionSignalCreation(otherSignalNameAndPars, baseSession)
fmt.Println("")
	signalNameAndPars.equals(signalNameAndPars)
	getSignals("signal", map[Param]string{})
	registerSampledSignal(signalNameAndPars, &sampledSignal)
	getSampledSignal(signalNameAndPars)
	registerAggregatedSignal(signalNameAndPars, &aggSignal)
	getAggregatedSignal(signalNameAndPars)
	registerConditionalSignal(signalNameAndPars, &condSignal)
	reportSample(signalNameAndPars, 8)

	theGlobalWriteDefs = []SignalWriteDefinition {
		SignalWriteDefinition{
			"signal",
			"out",
			map[JSONPath]WriteValue{
			},
			SNameAndRebound{
				"signal",
				map[Param]Param{
				},
			},
		},
	}
	registerWriteDefs(signalNameAndPars, aggSignal)
	getWriters(signalNameAndPars)[0]("ts")
	//main()
	file, err := os.Open("testinputs/testdefs.json")
    if err != nil {
        panic(err)
    }
	scanAPIPipe(file)
	file, err = os.Open("testinputs/testEvents.txt")
    if err != nil {
        panic(err)
    }
	scanStdIn(file)
}

var ssdef SampledSignalDefinition = SampledSignalDefinition {
            "cpuload",
            map[Param]JSONPath {
                "x": "beat.hostname",
            },
            "in",
            "system.load.1",
        }

var bsdef BaseSessionDefinition = BaseSessionDefinition {
        "timeIsEven",
        []EventDefinition {
            EventDefinition {
                "in_condition_true",
                nil,
            },
        },
        []EventDefinition {
            EventDefinition {
                "in_condition_false",
                nil,
            },
        },
    }

func TestGetParams(t *testing.T) {
	ssdef.getParams()
	bsdef.getParams()
}

/*
*/
<|endoftext|>