Esempio n. 1
0
// Deploy allows the creation of deploy.Deployments remotely
func (s *SpreadCli) Deploy() *cli.Command {
	return &cli.Command{
		Name:        "deploy",
		Usage:       "spread deploy [-s] PATH | COMMIT [kubectl context]",
		Description: "Deploys objects to a remote Kubernetes cluster.",
		ArgsUsage:   "-s will deploy only if no other deployment found (otherwise fails)",
		Action: func(c *cli.Context) {
			ref := c.Args().First()
			var dep *deploy.Deployment

			proj, err := s.project()
			if err == nil {
				var docs map[string]*pb.Document
				if len(ref) == 0 {
					s.printf("Deploying from index...")
					docs, err = proj.Index()
					if err != nil {
						s.fatalf("Error getting index: %v", err)
					}

					if err = s.promptForArgs(docs, false); err == nil {
						dep, err = deploy.DeploymentFromDocMap(docs)
					}

				} else {
					if docs, err = proj.ResolveCommit(ref); err == nil {
						if err = s.promptForArgs(docs, false); err == nil {
							dep, err = deploy.DeploymentFromDocMap(docs)
						}
					} else {
						dep, err = s.globalDeploy(ref)
					}
				}
			} else {
				dep, err = s.globalDeploy(ref)
			}

			if err != nil {
				s.fatalf("Failed to assemble deployment: %v", err)
			}

			context := c.Args().Get(1)
			cluster, err := deploy.NewKubeClusterFromContext(context)
			if err != nil {
				s.fatalf("Failed to deploy: %v", err)
			}

			s.printf("Deploying %d objects using the %s.", dep.Len(), displayContext(context))

			update := !c.Bool("s")
			err = cluster.Deploy(dep, update, false)
			if err != nil {
				//TODO: make better error messages (one to indicate a deployment already existed; another one if a deployment did not exist but some other error was thrown
				s.fatalf("Did not deploy.: %v", err)
			}

			s.printf("Deployment successful!")
		},
	}
}
Esempio n. 2
0
// Status returns information about the current state of the project.
func (s SpreadCli) Status() *cli.Command {
	return &cli.Command{
		Name:        "status",
		Usage:       "spread status",
		Description: "Information about what's commited, changed, and staged.",
		Action: func(c *cli.Context) {
			proj := s.projectOrDie()
			indexDocs, err := proj.Index()
			if err != nil {
				s.fatalf("Could not load Index: %v", err)
			}

			index, err := deploy.DeploymentFromDocMap(indexDocs)
			if err != nil {
				s.fatalf("Failed to create KubeObject from index doc: %v", err)
			}

			var head *deploy.Deployment
			headDocs, err := proj.Head()
			if err == nil {
				head, err = deploy.DeploymentFromDocMap(headDocs)
				if err != nil {
					s.fatalf("Failed to create KubeObject from HEAD doc: %v", err)
				}
			} else {
				head = new(deploy.Deployment)
			}

			client, err := deploy.NewKubeClusterFromContext("")
			if err != nil {
				s.fatalf("Failed to connect to Kubernetes cluster: %v", err)
			}

			cluster, err := client.Deployment()
			if err != nil {
				s.fatalf("Could not load deployment from cluster: %v", err)
			}

			stat := deploy.Stat(index, head, cluster)
			s.printStatus(stat)
		},
	}
}
Esempio n. 3
0
func (s *SpreadCli) globalDeploy(ref string) (*deploy.Deployment, error) {
	// check if reference is local file
	dep, err := s.fileDeploy(ref)
	if err != nil {
		ref, err = packages.ExpandPackageName(ref)
		if err == nil {
			var info packages.PackageInfo
			info, err = packages.DiscoverPackage(ref, true, false)
			if err != nil {
				s.fatalf("failed to retrieve package info: %v", err)
			}

			proj, err := s.globalProject()
			if err != nil {
				s.fatalf("error setting up global project: %v", err)
			}

			remote, err := proj.Remotes().Lookup(ref)
			// if does not exist or has different URL, create new remote
			if err != nil {
				remote, err = proj.Remotes().Create(ref, info.RepoURL)
				if err != nil {
					return nil, fmt.Errorf("could not create remote: %v", err)
				}
			} else if remote.Url() != info.RepoURL {
				s.printf("changing remote URL for %s, current: '%s' new: '%s'", ref, remote.Url(), info.RepoURL)
				err = proj.Remotes().SetUrl(ref, info.RepoURL)
				if err != nil {
					return nil, fmt.Errorf("failed to change URL for %s: %v", ref, err)
				}
			}

			s.printf("pulling repo from %s", info.RepoURL)
			branch := fmt.Sprintf("%s/master", ref)
			err = proj.Fetch(remote.Name(), "master")
			if err != nil {
				return nil, fmt.Errorf("failed to fetch '%s': %v", ref, err)
			}

			docs, err := proj.Branch(branch)
			if err != nil {
				return nil, err
			}

			if err = s.promptForArgs(docs, false); err != nil {
				return nil, err
			}

			return deploy.DeploymentFromDocMap(docs)
		}
	}
	return dep, err
}
Esempio n. 4
0
// Diff shows the difference bettwen the cluster and the index.
func (s SpreadCli) Diff() *cli.Command {
	return &cli.Command{
		Name:        "diff",
		Usage:       "spread diff",
		Description: "Diffs index against state of cluster",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "context",
				Value: "",
				Usage: "kubectl context to use for requests",
			},
		},
		Action: func(c *cli.Context) {
			proj := s.projectOrDie()
			docs, err := proj.Index()
			if err != nil {
				s.fatalf("Could not load Index: %v", err)
			}

			index, err := deploy.DeploymentFromDocMap(docs)
			if err != nil {
				s.fatalf("Failed to create Deployment from Documents: %v", err)
			}

			context := c.String("context")
			client, err := deploy.NewKubeClusterFromContext(context)
			if err != nil {
				s.fatalf("Failed to connect to Kubernetes cluster: %v", err)
			}

			cluster, err := client.Deployment()
			if err != nil {
				s.fatalf("Could not load deployment from cluster: %v", err)
			}

			s.printf(index.Diff(cluster))
		},
	}
}