Exemple #1
0
func parse(c *setup.Controller) ([]Rule, error) {
	var rules []Rule

	for c.Next() {
		r := Rule{BasePath: "/"}
		if c.NextArg() {
			r.BasePath = c.Val()
		}
		if c.NextArg() {
			return rules, c.ArgErr()
		}
		rules = append(rules, r)
	}

	return rules, nil
}
Exemple #2
0
// Setup creates a new middleware with the given configuration
func Setup(c *setup.Controller) (mid middleware.Middleware, err error) {
	var config *Config

	config, err = parseSearch(c)
	if err != nil {
		panic(err)
	}

	index, err := NewIndexer(config.Engine, indexer.Config{
		HostName:       config.HostName,
		IndexDirectory: config.IndexDirectory,
	})

	if err != nil {
		panic(err)
	}

	ppl, err := NewPipeline(config, index)

	if err != nil {
		panic(err)
	}

	c.Startup = append(c.Startup, func() error {
		return ScanToPipe(c.Root, config, ppl, index)
	})

	mid = func(next middleware.Handler) middleware.Handler {
		return Handler(next, config, index, ppl)
	}

	return
}
Exemple #3
0
// Git configures a new Git service routine.
func Setup(c *setup.Controller) (middleware.Middleware, error) {
	git, err := parse(c)
	if err != nil {
		return nil, err
	}

	// loop through all repos and and start monitoring
	for i := range git {
		repo := git.Repo(i)

		// If a HookUrl is set, we switch to event based pulling.
		// Install the url handler
		if repo.HookUrl != "" {

			c.Startup = append(c.Startup, func() error {
				return repo.Pull()
			})

			webhook := &WebHook{Repo: repo}
			return func(next middleware.Handler) middleware.Handler {
				webhook.Next = next
				return webhook
			}, nil

		} else {
			c.Startup = append(c.Startup, func() error {

				// Start service routine in background
				Start(repo)

				// Do a pull right away to return error
				return repo.Pull()
			})
		}
	}

	return nil, err
}
Exemple #4
0
// parseSearch controller information to create a IndexSearch config
func parseSearch(c *setup.Controller) (*Config, error) {
	conf := &Config{
		HostName:       c.Address(),
		Engine:         `bleve`,
		IndexDirectory: `/tmp/caddyIndex`,
		IncludePaths:   []*regexp.Regexp{},
		ExcludePaths:   []*regexp.Regexp{},
		Endpoint:       `/search`,
		SiteRoot:       c.Root,
	}

	incPaths := []string{}
	excPaths := []string{}

	for c.Next() {
		args := c.RemainingArgs()

		if len(args) == 1 {
			incPaths = append(incPaths, c.Val())
		}

		for c.NextBlock() {
			switch c.Val() {
			case "engine":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Engine = c.Val()
			case "+path":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				incPaths = append(incPaths, c.Val())
				incPaths = append(incPaths, c.RemainingArgs()...)
			case "-path":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				excPaths = append(excPaths, c.Val())
				excPaths = append(excPaths, c.RemainingArgs()...)
			case "endpoint":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Endpoint = c.Val()
			case "datadir":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.IndexDirectory = c.Val()
			case "template":
				var err error
				if c.NextArg() {
					conf.Template, err = template.ParseFiles(filepath.Join(conf.SiteRoot, c.Val()))
					if err != nil {
						return nil, err
					}
				} else {
					conf.Template, err = template.New("search-results").Parse(defaultTemplate)
					if err != nil {
						return nil, err
					}
				}
			}
		}
	}

	if len(incPaths) == 0 {
		incPaths = append(incPaths, "^/")
	}

	conf.IncludePaths = convertToRegExp(incPaths)
	conf.ExcludePaths = convertToRegExp(excPaths)

	dir := conf.IndexDirectory
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		if err := os.MkdirAll(dir, os.ModePerm); err != nil {
			return nil, c.Err("Given 'datadir' not a valid path.")
		}
	}

	return conf, nil
}
Exemple #5
0
// parseSearch controller information to create a IndexSearch config
func parseSearch(c *setup.Controller) (conf *Config, err error) {
	conf = &Config{
		HostName:       c.Address(),
		Engine:         `bleve`,
		IndexDirectory: `/tmp/caddyIndex`,
		IncludePaths:   []*regexp.Regexp{},
		ExcludePaths:   []*regexp.Regexp{},
		Endpoint:       `/search`,
	}

	incPaths := []string{}
	excPaths := []string{}

	for c.Next() {

		args := c.RemainingArgs()

		if len(args) == 1 {
			incPaths = append(incPaths, c.Val())
		}

		for c.NextBlock() {
			switch c.Val() {
			case "engine":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Engine = c.Val()
			case "+path":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				incPaths = append(incPaths, c.Val())
				incPaths = append(incPaths, c.RemainingArgs()...)
			case "-path":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				excPaths = append(excPaths, c.Val())
				excPaths = append(excPaths, c.RemainingArgs()...)
			case "endpoint":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Endpoint = c.Val()
			case "datadir":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.IndexDirectory = c.Val()
			}
		}
	}

	if len(incPaths) == 0 {
		incPaths = append(incPaths, "^/")
	}

	conf.IncludePaths = convertToRegExp(incPaths)
	conf.ExcludePaths = convertToRegExp(excPaths)

	dir := conf.IndexDirectory
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		if err := os.MkdirAll(dir, os.ModePerm); err != nil {
			return nil, c.Err("Given `datadir` not a valid path.")
		}
	}

	return
}
func newMesosUpstreams(c *setup.Controller) ([]proxy.Upstream, error) {
	var upstreams []proxy.Upstream

	for c.Next() {
		upstream := &mesosUpstream{
			from:        "",
			hosts:       new(atomic.Value),
			Policy:      &proxy.Random{},
			FailTimeout: 10 * time.Second,
			MaxFails:    1,

			SyncInterval: 120 * time.Second,
			Scheme:       "http",
		}
		upstream.hosts.Store(proxy.HostPool([]*proxy.UpstreamHost{}))
		var proxyHeaders http.Header
		var port string
		if !c.Args(&upstream.from, &upstream.mesosMaster, &upstream.framework, &upstream.taskName, &port) {
			return upstreams, c.ArgErr()
		}
		if p, err := strconv.Atoi(port); err == nil {
			if p == 0 {
				return upstreams, errInvalidPort
			} else {
				upstream.Port = p
			}
		} else {
			return upstreams, err
		}

		for c.NextBlock() {
			switch c.Val() {
			case "policy":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				switch c.Val() {
				case "random":
					upstream.Policy = &proxy.Random{}
				case "round_robin":
					upstream.Policy = &proxy.RoundRobin{}
				case "least_conn":
					upstream.Policy = &proxy.LeastConn{}
				default:
					return upstreams, c.ArgErr()
				}
			case "fail_timeout":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				if dur, err := time.ParseDuration(c.Val()); err == nil {
					upstream.FailTimeout = dur
				} else {
					return upstreams, err
				}
			case "max_fails":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				if n, err := strconv.Atoi(c.Val()); err == nil {
					upstream.MaxFails = int32(n)
				} else {
					return upstreams, err
				}
			case "health_check":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				upstream.HealthCheck.Path = c.Val()
				upstream.HealthCheck.Interval = 30 * time.Second
				if c.NextArg() {
					if dur, err := time.ParseDuration(c.Val()); err == nil {
						upstream.HealthCheck.Interval = dur
					} else {
						return upstreams, err
					}
				}
			case "proxy_header":
				var header, value string
				if !c.Args(&header, &value) {
					return upstreams, c.ArgErr()
				}
				if proxyHeaders == nil {
					proxyHeaders = make(map[string][]string)
				}
				proxyHeaders.Add(header, value)
			case "sync_interval":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				if dur, err := time.ParseDuration(c.Val()); err == nil {
					upstream.SyncInterval = dur
				} else {
					return upstreams, err
				}
			case "scheme":
				if !c.NextArg() {
					return upstreams, c.ArgErr()
				}
				upstream.Scheme = c.Val()
			}
		}
		upstream.proxyHeaders = proxyHeaders

		go upstream.syncWorker(nil)
		if upstream.HealthCheck.Path != "" {
			go upstream.healthCheckWorker(nil)
		}

		upstreams = append(upstreams, upstream)
	}
	return upstreams, nil
}
Exemple #7
0
// ParseHugo parses the configuration file
func ParseHugo(c *setup.Controller) (*Config, error) {
	conf := &Config{
		Styles: "",
	}

	for c.Next() {
		for c.NextBlock() {
			switch c.Val() {
			case "styles":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Styles = c.Val()
				// Remove the beginning slash if it exists or not
				conf.Styles = strings.TrimPrefix(conf.Styles, "/")
				// Add a beginning slash to make a
				conf.Styles = "/" + conf.Styles
			case "flags":
				conf.Flags = c.RemainingArgs()
				if len(conf.Flags) == 0 {
					return conf, c.ArgErr()
				}
			}
		}
	}

	conf.parseFlags()
	return conf, nil
}
Exemple #8
0
func parse(c *setup.Controller) (Git, error) {
	var git Git

	for c.Next() {
		repo := &Repo{Branch: "master", Interval: DefaultInterval, Path: c.Root}

		args := c.RemainingArgs()

		switch len(args) {
		case 2:
			repo.Path = filepath.Clean(c.Root + string(filepath.Separator) + args[1])
			fallthrough
		case 1:
			repo.URL = args[0]
		}

		for c.NextBlock() {
			switch c.Val() {
			case "repo":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				repo.URL = c.Val()
			case "path":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				repo.Path = filepath.Clean(c.Root + string(filepath.Separator) + c.Val())
			case "branch":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				repo.Branch = c.Val()
			case "key":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				repo.KeyPath = c.Val()
			case "interval":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				t, _ := strconv.Atoi(c.Val())
				if t > 0 {
					repo.Interval = time.Duration(t) * time.Second
				}
			case "hook":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				repo.HookUrl = c.Val()

				// optional secret for validation
				if c.NextArg() {
					repo.HookSecret = c.Val()
				}

			case "then":
				thenArgs := c.RemainingArgs()
				if len(thenArgs) == 0 {
					return nil, c.ArgErr()
				}
				repo.Then = strings.Join(thenArgs, " ")
			default:
				return nil, c.ArgErr()
			}
		}

		// if repo is not specified, return error
		if repo.URL == "" {
			return nil, c.ArgErr()
		}

		// if private key is not specified, convert repository URL to https
		// to avoid ssh authentication
		// else validate git URL
		// Note: private key support not yet available on Windows
		var err error
		if repo.KeyPath == "" {
			repo.URL, repo.Host, err = sanitizeHTTP(repo.URL)
		} else {
			repo.URL, repo.Host, err = sanitizeGit(repo.URL)
			// TODO add Windows support for private repos
			if runtime.GOOS == "windows" {
				return nil, fmt.Errorf("private repository not yet supported on Windows")
			}
		}

		if err != nil {
			return nil, err
		}

		// validate git requirements
		if err = Init(); err != nil {
			return nil, err
		}

		// prepare repo for use
		if err = repo.Prepare(); err != nil {
			return nil, err
		}

		git = append(git, repo)

	}

	return git, nil
}
Exemple #9
0
// ParseCMS parses the configuration file
func ParseCMS(c *setup.Controller) (*Config, error) {
	conf := &Config{Content: "content"}

	for c.Next() {
		for c.NextBlock() {
			switch c.Val() {
			case "styles":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Styles = c.Val()
				// Remove the beginning slash if it exists or not
				conf.Styles = strings.TrimPrefix(conf.Styles, "/")
				// Add a beginning slash to make a
				conf.Styles = "/" + conf.Styles
			case "content":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Content = c.Val()
				conf.Content = strings.TrimPrefix(conf.Content, "/")
				conf.Content = strings.TrimSuffix(conf.Content, "/")
			case "command":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Command = c.Val()
			case "args":
				conf.Args = c.RemainingArgs()
				if len(conf.Args) == 0 {
					return conf, c.ArgErr()
				}
			}
		}
	}

	conf.parseArgs()
	return conf, nil
}
Exemple #10
0
// ParseCMS parses the configuration file
func ParseCMS(c *setup.Controller) (*Config, error) {
	conf := &Config{
		Public:  strings.Replace(c.Root, "./", "", -1),
		Content: "content",
		Hugo:    true,
		Path:    "./",
	}

	for c.Next() {
		args := c.RemainingArgs()

		switch len(args) {
		case 1:
			conf.Path = args[0]
			conf.Path = strings.TrimSuffix(conf.Path, "/")
			conf.Path += "/"
		}

		for c.NextBlock() {
			switch c.Val() {
			case "styles":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Styles = c.Val()
				// Remove the beginning slash if it exists or not
				conf.Styles = strings.TrimPrefix(conf.Styles, "/")
				// Add a beginning slash to make a
				conf.Styles = "/" + conf.Styles
			case "content":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Content = c.Val()
			case "command":
				if !c.NextArg() {
					return nil, c.ArgErr()
				}
				conf.Command = c.Val()

				if conf.Command != "" && !strings.HasPrefix(conf.Command, "-") {
					conf.Hugo = false
				}
			}
		}
	}

	return conf, nil
}