Exemple #1
0
// iam injects info into the environment about a host's self.
//
// Sets the following environment variables. (Values represent the data format.
// Instances will get its own values.)
//
//	MY_NODEIP=10.245.1.3
//	MY_SERVICE_IP=10.22.1.4
// 	MY_PORT_PEER=2380
// 	MY_PORT_CLIENT=2379
//	MY_NAMESPACE=default
//	MY_SELFLINK=/api/v1/namespaces/default/pods/deis-etcd-1-336jp
//	MY_UID=62a3b54a-6956-11e5-b8ab-0800279dd272
//	MY_APISERVER=https://10.247.0.1:443
//	MY_NAME=deis-etcd-1-336jp
//	MY_IP=10.246.44.7
//	MY_LABEL_NAME=deis-etcd-1   # One entry per label in the JSON
// 	MY_ANNOTATION_NAME=deis-etcd-1  # One entry per annitation in the JSON
//	MY_PORT_CLIENT=4100
//	MY_PORT_PEER=2380
func iam(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	me, err := aboutme.FromEnv()
	if err != nil {
		log.Errf(c, "Failed aboutme.FromEnv: %s", err)
	} else {

		if strings.TrimSpace(me.IP) == "" {
			log.Warn(c, "No IP found by API query.")
			ip, err := aboutme.MyIP()
			if err != nil || ip == "" {
				// Force pod death.
				log.Errf(c, "Failed to get an IP address: %s", err)
				os.Exit(5)
			}
		}

		me.ShuntEnv()
		os.Setenv("ETCD_NAME", me.Name)
		c.Put("ETCD_NAME", me.Name)
	}

	passEnv("MY_PORT_CLIENT", "$DEIS_ETCD_1_SERVICE_PORT_CLIENT")
	passEnv("MY_PORT_PEER", "$DEIS_ETCD_1_SERVICE_PORT_PEER")
	return nil, nil
}
Exemple #2
0
// iam injects info into the environment about a host's self.
//
// Sets the following environment variables. (Values represent the data format.
// Instances will get its own values.)
//
//	MY_NODEIP=10.245.1.3
//	MY_SERVICE_IP=10.22.1.4
// 	MY_PORT_PEER=2380
// 	MY_PORT_CLIENT=2379
//	MY_NAMESPACE=default
//	MY_SELFLINK=/api/v1/namespaces/default/pods/deis-etcd-1-336jp
//	MY_UID=62a3b54a-6956-11e5-b8ab-0800279dd272
//	MY_APISERVER=https://10.247.0.1:443
//	MY_NAME=deis-etcd-1-336jp
//	MY_IP=10.246.44.7
//	MY_LABEL_NAME=deis-etcd-1   # One entry per label in the JSON
// 	MY_ANNOTATION_NAME=deis-etcd-1  # One entry per annitation in the JSON
//	MY_PORT_CLIENT=4100
//	MY_PORT_PEER=2380
func iam(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	me, err := aboutme.FromEnv()
	if err != nil {
		log.Errf(c, "Failed aboutme.FromEnv: %s", err)
		log.Warn(c, "Attempting to recover.")
	}

	// This will try to recover whenever IP is not set. Only some fields
	// can be recovered. But all we really need is IP and Name.
	if strings.TrimSpace(me.IP) == "" {
		log.Warn(c, "No IP found by API query.")
		ip, err := aboutme.MyIP()
		if err != nil || ip == "" {
			// Force pod death.
			log.Errf(c, "Failed to get an IP address: %s", err)
			os.Exit(5)
		}
		me.IP = ip
	}
	if strings.TrimSpace(me.Name) == "" {
		// Try to set name from DAPI.
		me.Name = os.Getenv("POD_NAME")
		log.Warnf(c, "Setting name to %q", me.Name)
	}
	if strings.TrimSpace(me.Namespace) == "" {
		// Try to set namespace from DAPI.
		me.Namespace = os.Getenv("POD_NAMESPACE")
		log.Warnf(c, "Setting name to %q", me.Namespace)
	}

	me.ShuntEnv()
	os.Setenv("ETCD_NAME", me.Name)
	c.Put("ETCD_NAME", me.Name)

	passEnv("MY_PORT_CLIENT", "$DEIS_ETCD_1_SERVICE_PORT_CLIENT")
	passEnv("MY_PORT_PEER", "$DEIS_ETCD_1_SERVICE_PORT_PEER")
	return nil, nil
}
Exemple #3
0
// answer handles answering requests and channel requests
//
// Currently, an exec must be either "ping", "git-receive-pack" or
// "git-upload-pack". Anything else will result in a failure response. Right
// now, we leave the channel open on failure because it is unclear what the
// correct behavior for a failed exec is.
//
// Support for setting environment variables via `env` has been disabled.
func (s *server) answer(channel ssh.Channel, requests <-chan *ssh.Request, sshConn string) error {
	defer channel.Close()

	// Answer all the requests on this connection.
	for req := range requests {
		ok := false

		// I think that ideally what we want to do here is pass this on to
		// the Cookoo router and let it handle each Type on its own.
		switch req.Type {
		case "env":
			o := &EnvVar{}
			ssh.Unmarshal(req.Payload, o)
			fmt.Printf("Key='%s', Value='%s'\n", o.Name, o.Value)
			req.Reply(true, nil)
		case "exec":
			clean := cleanExec(req.Payload)
			parts := strings.SplitN(clean, " ", 2)

			router := s.c.Get("cookoo.Router", nil).(*cookoo.Router)

			// TODO: Should we unset the context value 'cookoo.Router'?
			// We need a shallow copy of the context to avoid race conditions.
			cxt := s.c.Copy()
			cxt.Put("SSH_CONNECTION", sshConn)

			// Only allow commands that we know about.
			switch parts[0] {
			case "ping":
				cxt.Put("channel", channel)
				cxt.Put("request", req)
				sshPing := cxt.Get("route.sshd.sshPing", "sshPing").(string)
				err := router.HandleRequest(sshPing, cxt, true)
				if err != nil {
					log.Warnf(s.c, "Error pinging: %s", err)
				}
				return err
			case "git-receive-pack", "git-upload-pack":
				if len(parts) < 2 {
					log.Warn(s.c, "Expected two-part command.\n")
					req.Reply(ok, nil)
					break
				}
				req.Reply(true, nil) // We processed. Yay.

				cxt.Put("channel", channel)
				cxt.Put("request", req)
				cxt.Put("operation", parts[0])
				cxt.Put("repository", parts[1])
				sshGitReceive := cxt.Get("route.sshd.sshGitReceive", "sshGitReceive").(string)
				err := router.HandleRequest(sshGitReceive, cxt, true)
				var xs uint32
				if err != nil {
					log.Errf(s.c, "Failed git receive: %v", err)
					xs = 1
				}
				sendExitStatus(xs, channel)
				return nil
			default:
				log.Warnf(s.c, "Illegal command is '%s'\n", clean)
				req.Reply(false, nil)
				return nil
			}

			if err := sendExitStatus(0, channel); err != nil {
				log.Errf(s.c, "Failed to write exit status: %s", err)
			}
			return nil
		default:
			// We simply ignore all of the other cases and leave the
			// channel open to take additional requests.
			log.Infof(s.c, "Received request of type %s\n", req.Type)
			req.Reply(false, nil)
		}
	}

	return nil
}