<commit_before>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/Unknwon/com"
	git "github.com/libgit2/git2go"

	"github.com/gogits/gogs/modules/base"
	"github.com/gogits/gogs/modules/log"
)

type Repository struct {
	Id          int64
	OwnerId     int64 `xorm:"unique(s)"`
	ForkId      int64
	LowerName   string `xorm:"unique(s) index not null"`
	Name        string `xorm:"index not null"`
	Description string
	Private     bool
	NumWatchs   int
	NumStars    int
	NumForks    int
	Created     time.Time `xorm:"created"`
	Updated     time.Time `xorm:"updated"`
}

type Star struct {
	Id      int64
	RepoId  int64
	UserId  int64
	Created time.Time `xorm:"created"`
}

var (
	LanguageIgns, Licenses []string
)

var (
	ErrRepoAlreadyExist = errors.New("Repository already exist")
)

func init() {
	LanguageIgns = strings.Split(base.Cfg.MustValue("repository", "LANG_IGNS"), "|")
	Licenses = strings.Split(base.Cfg.MustValue("repository", "LICENSES"), "|")
}

// check if repository is exist
func IsRepositoryExist(user *User, repoName string) (bool, error) {
	repo := Repository{OwnerId: user.Id}
	has, err := orm.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo)
	if err != nil {
		return has, err
	}
	s, err := os.Stat(RepoPath(user.Name, repoName))
	if err != nil {
		return false, nil
	}
	return s.IsDir(), nil
}

// CreateRepository creates a repository for given user or orgnaziation.
func CreateRepository(user *User, repoName, desc, repoLang, license string, private bool, initReadme bool) (*Repository, error) {
	isExist, err := IsRepositoryExist(user, repoName)
	if err != nil {
		return nil, err
	} else if isExist {
		return nil, ErrRepoAlreadyExist
	}

	repo := &Repository{
		OwnerId:     user.Id,
		Name:        repoName,
		LowerName:   strings.ToLower(repoName),
		Description: desc,
		Private:     private,
	}

	f := RepoPath(user.Name, repoName)
	if err = initRepository(f, user, repo, initReadme, repoLang, license); err != nil {
		return nil, err
	}
	session := orm.NewSession()
	defer session.Close()
	session.Begin()

	if _, err = session.Insert(repo); err != nil {
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		session.Rollback()
		return nil, err
	}

	// TODO: RemoveAll may fail due to not root access.
	access := Access{
		UserName: user.Name,
		RepoName: repo.Name,
		Mode:     AU_WRITABLE,
	}
	if _, err = session.Insert(&access); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}

	if _, err = session.Exec("update user set num_repos = num_repos + 1 where id = ?", user.Id); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}

	if err = session.Commit(); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}
	return repo, nil
}

// InitRepository initializes README and .gitignore if needed.
func initRepository(f string, user *User, repo *Repository, initReadme bool, repoLang, license string) error {
	fileName := map[string]string{}

	if initReadme {
		fileName["readme"] = "README.md"
	}
	if repoLang != "" {
		fileName["gitign"] = ".gitignore"
	}
	if license != "" {
		fileName["license"] = "LICENSE"
	}

	workdir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
	os.MkdirAll(workdir, os.ModePerm)

	sig := user.NewGitSig()

	// README
	if initReadme {
		defaultReadme := repo.Name + "\n" + strings.Repeat("=",
			utf8.RuneCountInString(repo.Name)) + "\n\n" + repo.Description
		if err := ioutil.WriteFile(filepath.Join(workdir, fileName["readme"]),
			[]byte(defaultReadme), 0644); err != nil {
			return err
		}
	}

	if repoLang != "" {
		// .gitignore
		filePath := "conf/gitignore/" + repoLang
		if com.IsFile(filePath) {
			if _, err := com.Copy(filePath,
				filepath.Join(workdir, fileName["gitign"])); err != nil {
				return err
			}
		}
	}

	if license != "" {
		// LICENSE
		filePath := "conf/license/" + license
		if com.IsFile(filePath) {
			if _, err := com.Copy(filePath,
				filepath.Join(workdir, fileName["license"])); err != nil {
				return err
			}
		}
	}

	rp, err := git.InitRepository(f, true)
	if err != nil {
		return err
	}
	rp.SetWorkdir(workdir, false)

	idx, err := rp.Index()
	if err != nil {
		return err
	}

	for _, name := range fileName {
		if err = idx.AddByPath(name); err != nil {
			return err
		}
	}

	treeId, err := idx.WriteTree()
	if err != nil {
		return err
	}

	message := "Init commit"
	tree, err := rp.LookupTree(treeId)
	if err != nil {
		return err
	}

	if _, err = rp.CreateCommit("HEAD", sig, sig, message, tree); err != nil {
		return err
	}

	return nil
}

// GetRepositories returns the list of repositories of given user.
func GetRepositories(user *User) ([]Repository, error) {
	repos := make([]Repository, 0, 10)
	err := orm.Find(&repos, &Repository{OwnerId: user.Id})
	return repos, err
}

func GetRepositoryCount(user *User) (int64, error) {
	return orm.Count(&Repository{OwnerId: user.Id})
}

const (
	RFile = iota + 1
	RDir
)

type RepoFile struct {
	Type int
	Name string

	Created time.Time
}

func GetReposFiles(userName, reposName, treeName, rpath string) ([]RepoFile, error) {
	f := RepoPath(userName, reposName)
	repo, err := git.OpenRepository(f)
	if err != nil {
		return nil, err
	}

	obj, err := repo.RevparseSingle("HEAD")
	if err != nil {
		return nil, err
	}
	lastCommit := obj.(*git.Commit)
	var repofiles []RepoFile
	tree, err := lastCommit.Tree()
	if err != nil {
		return nil, err
	}
	var i uint64 = 0
	for ; i < tree.EntryCount(); i++ {
		entry := tree.EntryByIndex(i)
		repofiles = append(repofiles, RepoFile{
			entry.Filemode,
			entry.Name,
			time.Now(),
		})
	}

	return repofiles, nil
}

func StarReposiory(user *User, repoName string) error {
	return nil
}

func UnStarRepository() {

}

func WatchRepository() {

}

func UnWatchRepository() {

}

func ForkRepository(reposName string, userId int64) {

}

func RepoPath(userName, repoName string) string {
	return filepath.Join(UserPath(userName), repoName+".git")
}

// DeleteRepository deletes a repository for a user or orgnaztion.
func DeleteRepository(user *User, reposName string) (err error) {
	session := orm.NewSession()
	if _, err = session.Delete(&Repository{OwnerId: user.Id, Name: reposName}); err != nil {
		session.Rollback()
		return err
	}
	if _, err = session.Exec("update user set num_repos = num_repos - 1 where id = ?", user.Id); err != nil {
		session.Rollback()
		return err
	}
	if err = session.Commit(); err != nil {
		session.Rollback()
		return err
	}
	if err = os.RemoveAll(RepoPath(user.Name, reposName)); err != nil {
		// TODO: log and delete manully
		log.Error("delete repo %s/%s failed", user.Name, reposName)
		return err
	}
	return nil
}
<commit_msg>Add GetRepositoryByName and GetRepositoryById<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/Unknwon/com"
	git "github.com/libgit2/git2go"

	"github.com/gogits/gogs/modules/base"
	"github.com/gogits/gogs/modules/log"
)

type Repository struct {
	Id          int64
	OwnerId     int64 `xorm:"unique(s)"`
	ForkId      int64
	LowerName   string `xorm:"unique(s) index not null"`
	Name        string `xorm:"index not null"`
	Description string
	Private     bool
	NumWatchs   int
	NumStars    int
	NumForks    int
	Created     time.Time `xorm:"created"`
	Updated     time.Time `xorm:"updated"`
}

type Star struct {
	Id      int64
	RepoId  int64
	UserId  int64
	Created time.Time `xorm:"created"`
}

var (
	LanguageIgns, Licenses []string
)

var (
	ErrRepoAlreadyExist = errors.New("Repository already exist")
	ErrRepoNotExist     = errors.New("Repository does not exist")
)

func init() {
	LanguageIgns = strings.Split(base.Cfg.MustValue("repository", "LANG_IGNS"), "|")
	Licenses = strings.Split(base.Cfg.MustValue("repository", "LICENSES"), "|")
}

// check if repository is exist
func IsRepositoryExist(user *User, repoName string) (bool, error) {
	repo := Repository{OwnerId: user.Id}
	has, err := orm.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo)
	if err != nil {
		return has, err
	}
	s, err := os.Stat(RepoPath(user.Name, repoName))
	if err != nil {
		return false, nil
	}
	return s.IsDir(), nil
}

// CreateRepository creates a repository for given user or orgnaziation.
func CreateRepository(user *User, repoName, desc, repoLang, license string, private bool, initReadme bool) (*Repository, error) {
	isExist, err := IsRepositoryExist(user, repoName)
	if err != nil {
		return nil, err
	} else if isExist {
		return nil, ErrRepoAlreadyExist
	}

	repo := &Repository{
		OwnerId:     user.Id,
		Name:        repoName,
		LowerName:   strings.ToLower(repoName),
		Description: desc,
		Private:     private,
	}

	f := RepoPath(user.Name, repoName)
	if err = initRepository(f, user, repo, initReadme, repoLang, license); err != nil {
		return nil, err
	}
	session := orm.NewSession()
	defer session.Close()
	session.Begin()

	if _, err = session.Insert(repo); err != nil {
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		session.Rollback()
		return nil, err
	}

	// TODO: RemoveAll may fail due to not root access.
	access := Access{
		UserName: user.Name,
		RepoName: repo.Name,
		Mode:     AU_WRITABLE,
	}
	if _, err = session.Insert(&access); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}

	if _, err = session.Exec("update user set num_repos = num_repos + 1 where id = ?", user.Id); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}

	if err = session.Commit(); err != nil {
		session.Rollback()
		if err2 := os.RemoveAll(f); err2 != nil {
			return nil, errors.New(fmt.Sprintf(
				"delete repo directory %s/%s failed", user.Name, repoName))
		}
		return nil, err
	}
	return repo, nil
}

// InitRepository initializes README and .gitignore if needed.
func initRepository(f string, user *User, repo *Repository, initReadme bool, repoLang, license string) error {
	fileName := map[string]string{}

	if initReadme {
		fileName["readme"] = "README.md"
	}
	if repoLang != "" {
		fileName["gitign"] = ".gitignore"
	}
	if license != "" {
		fileName["license"] = "LICENSE"
	}

	workdir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
	os.MkdirAll(workdir, os.ModePerm)

	sig := user.NewGitSig()

	// README
	if initReadme {
		defaultReadme := repo.Name + "\n" + strings.Repeat("=",
			utf8.RuneCountInString(repo.Name)) + "\n\n" + repo.Description
		if err := ioutil.WriteFile(filepath.Join(workdir, fileName["readme"]),
			[]byte(defaultReadme), 0644); err != nil {
			return err
		}
	}

	if repoLang != "" {
		// .gitignore
		filePath := "conf/gitignore/" + repoLang
		if com.IsFile(filePath) {
			if _, err := com.Copy(filePath,
				filepath.Join(workdir, fileName["gitign"])); err != nil {
				return err
			}
		}
	}

	if license != "" {
		// LICENSE
		filePath := "conf/license/" + license
		if com.IsFile(filePath) {
			if _, err := com.Copy(filePath,
				filepath.Join(workdir, fileName["license"])); err != nil {
				return err
			}
		}
	}

	rp, err := git.InitRepository(f, true)
	if err != nil {
		return err
	}
	rp.SetWorkdir(workdir, false)

	idx, err := rp.Index()
	if err != nil {
		return err
	}

	for _, name := range fileName {
		if err = idx.AddByPath(name); err != nil {
			return err
		}
	}

	treeId, err := idx.WriteTree()
	if err != nil {
		return err
	}

	message := "Init commit"
	tree, err := rp.LookupTree(treeId)
	if err != nil {
		return err
	}

	if _, err = rp.CreateCommit("HEAD", sig, sig, message, tree); err != nil {
		return err
	}

	return nil
}

func GetRepositoryByName(user *User, repoName string) (*Repository, error) {
	repo := &Repository{
		OwnerId:   user.Id,
		LowerName: strings.ToLower(repoName),
	}
	has, err := orm.Get(repo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrRepoNotExist
	}
	return repo, err
}

func GetRepositoryById(id int64) (repo *Repository, err error) {
	has, err := orm.Id(id).Get(repo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrRepoNotExist
	}
	return repo, err
}

// GetRepositories returns the list of repositories of given user.
func GetRepositories(user *User) ([]Repository, error) {
	repos := make([]Repository, 0, 10)
	err := orm.Find(&repos, &Repository{OwnerId: user.Id})
	return repos, err
}

func GetRepositoryCount(user *User) (int64, error) {
	return orm.Count(&Repository{OwnerId: user.Id})
}

const (
	RFile = iota + 1
	RDir
)

type RepoFile struct {
	Type int
	Name string

	Created time.Time
}

func GetReposFiles(userName, reposName, treeName, rpath string) ([]RepoFile, error) {
	f := RepoPath(userName, reposName)
	repo, err := git.OpenRepository(f)
	if err != nil {
		return nil, err
	}

	obj, err := repo.RevparseSingle("HEAD")
	if err != nil {
		return nil, err
	}
	lastCommit := obj.(*git.Commit)
	var repofiles []RepoFile
	tree, err := lastCommit.Tree()
	if err != nil {
		return nil, err
	}
	var i uint64 = 0
	for ; i < tree.EntryCount(); i++ {
		entry := tree.EntryByIndex(i)
		repofiles = append(repofiles, RepoFile{
			entry.Filemode,
			entry.Name,
			time.Now(),
		})
	}

	return repofiles, nil
}

func StarReposiory(user *User, repoName string) error {
	return nil
}

func UnStarRepository() {

}

func WatchRepository() {

}

func UnWatchRepository() {

}

func ForkRepository(reposName string, userId int64) {

}

func RepoPath(userName, repoName string) string {
	return filepath.Join(UserPath(userName), repoName+".git")
}

// DeleteRepository deletes a repository for a user or orgnaztion.
func DeleteRepository(user *User, reposName string) (err error) {
	session := orm.NewSession()
	if _, err = session.Delete(&Repository{OwnerId: user.Id, Name: reposName}); err != nil {
		session.Rollback()
		return err
	}
	if _, err = session.Exec("update user set num_repos = num_repos - 1 where id = ?", user.Id); err != nil {
		session.Rollback()
		return err
	}
	if err = session.Commit(); err != nil {
		session.Rollback()
		return err
	}
	if err = os.RemoveAll(RepoPath(user.Name, reposName)); err != nil {
		// TODO: log and delete manully
		log.Error("delete repo %s/%s failed", user.Name, reposName)
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package secp256k1fx

import (
	"encoding/json"
	"errors"

	"github.com/ava-labs/avalanchego/ids"
	"github.com/ava-labs/avalanchego/snow"
	"github.com/ava-labs/avalanchego/utils/constants"
	"github.com/ava-labs/avalanchego/utils/formatting"
	"github.com/ava-labs/avalanchego/vms/components/verify"
)

var (
	errNilOutput                         = errors.New("nil output")
	errOutputUnspendable                 = errors.New("output is unspendable")
	errOutputUnoptimized                 = errors.New("output representation should be optimized")
	errAddrsNotSortedUnique              = errors.New("addresses not sorted and unique")
	errMarshal                           = errors.New("cannot marshal without ctx")
	_                       verify.State = &OutputOwners{}
)

type OutputOwners struct {
	Locktime  uint64        `serialize:"true" json:"locktime"`
	Threshold uint32        `serialize:"true" json:"threshold"`
	Addrs     []ids.ShortID `serialize:"true" json:"addresses"`
	// ctx is used in MarshalJSON to convert Addrs into human readable
	// format with ChainID and NetworkID. Unexported because we don't use
	// it outside this object.
	ctx *snow.Context `serialize:"false"`
}

// InitCtx assigns the OutputOwners.ctx object to given [ctx] object
// Must be called at least once for MarshalJSON to work successfully
func (out *OutputOwners) InitCtx(ctx *snow.Context) {
	out.ctx = ctx
}

// MarshalJSON marshals OutputOwners as JSON with human readable addresses.
// OutputOwners.InitCtx must be called before marshalling this or one of
// the parent objects to json. Uses the OutputOwners.ctx method to format
// the addresses. Returns errMarshal error if OutputOwners.ctx is not set.
func (out *OutputOwners) MarshalJSON() ([]byte, error) {
	addrsLen := len(out.Addrs)

	// we need out.ctx to do this, if its absent, throw error
	if addrsLen > 0 && out.ctx == nil {
		return nil, errMarshal
	}

	addresses := make([]string, addrsLen)
	for i, addr := range out.Addrs {
		// for each [addr] in [Addrs] we attempt to format it given
		// the [out.ctx] object
		fAddr, err := FormatAddress(out.ctx, addr)
		if err != nil {
			// we expect these addresses to be valid, return error
			// if they are not
			return nil, err
		}
		addresses[i] = fAddr
	}
	result := map[string]interface{}{
		"locktime":  out.Locktime,
		"threshold": out.Threshold,
		"addresses": addresses,
	}
	return json.Marshal(result)
}

// Addresses returns the addresses that manage this output
func (out *OutputOwners) Addresses() [][]byte {
	addrs := make([][]byte, len(out.Addrs))
	for i, addr := range out.Addrs {
		addrs[i] = addr.Bytes()
	}
	return addrs
}

// AddressesSet returns addresses as a set
func (out *OutputOwners) AddressesSet() ids.ShortSet {
	set := ids.NewShortSet(len(out.Addrs))
	set.Add(out.Addrs...)
	return set
}

// Equals returns true if the provided owners create the same condition
func (out *OutputOwners) Equals(other *OutputOwners) bool {
	if out == other {
		return true
	}
	if out == nil || other == nil || out.Locktime != other.Locktime || out.Threshold != other.Threshold || len(out.Addrs) != len(other.Addrs) {
		return false
	}
	for i, addr := range out.Addrs {
		otherAddr := other.Addrs[i]
		if addr != otherAddr {
			return false
		}
	}
	return true
}

func (out *OutputOwners) Verify() error {
	switch {
	case out == nil:
		return errNilOutput
	case out.Threshold > uint32(len(out.Addrs)):
		return errOutputUnspendable
	case out.Threshold == 0 && len(out.Addrs) > 0:
		return errOutputUnoptimized
	case !ids.IsSortedAndUniqueShortIDs(out.Addrs):
		return errAddrsNotSortedUnique
	default:
		return nil
	}
}

func (out *OutputOwners) VerifyState() error { return out.Verify() }

func (out *OutputOwners) Sort() { ids.SortShortIDs(out.Addrs) }

// formatAddress formats a given [addr] into human readable format using
// [ChainID] and [NetworkID] from the provided [ctx].
func formatAddress(ctx *snow.Context, addr ids.ShortID) (string, error) {
	chainIDAlias, err := ctx.BCLookup.PrimaryAlias(ctx.ChainID)
	if err != nil {
		return "", err
	}

	hrp := constants.GetHRP(ctx.NetworkID)
	return formatting.FormatAddress(chainIDAlias, hrp, addr.Bytes())
}
<commit_msg>fixed rename<commit_after>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package secp256k1fx

import (
	"encoding/json"
	"errors"

	"github.com/ava-labs/avalanchego/ids"
	"github.com/ava-labs/avalanchego/snow"
	"github.com/ava-labs/avalanchego/utils/constants"
	"github.com/ava-labs/avalanchego/utils/formatting"
	"github.com/ava-labs/avalanchego/vms/components/verify"
)

var (
	errNilOutput                         = errors.New("nil output")
	errOutputUnspendable                 = errors.New("output is unspendable")
	errOutputUnoptimized                 = errors.New("output representation should be optimized")
	errAddrsNotSortedUnique              = errors.New("addresses not sorted and unique")
	errMarshal                           = errors.New("cannot marshal without ctx")
	_                       verify.State = &OutputOwners{}
)

type OutputOwners struct {
	Locktime  uint64        `serialize:"true" json:"locktime"`
	Threshold uint32        `serialize:"true" json:"threshold"`
	Addrs     []ids.ShortID `serialize:"true" json:"addresses"`
	// ctx is used in MarshalJSON to convert Addrs into human readable
	// format with ChainID and NetworkID. Unexported because we don't use
	// it outside this object.
	ctx *snow.Context `serialize:"false"`
}

// InitCtx assigns the OutputOwners.ctx object to given [ctx] object
// Must be called at least once for MarshalJSON to work successfully
func (out *OutputOwners) InitCtx(ctx *snow.Context) {
	out.ctx = ctx
}

// MarshalJSON marshals OutputOwners as JSON with human readable addresses.
// OutputOwners.InitCtx must be called before marshalling this or one of
// the parent objects to json. Uses the OutputOwners.ctx method to format
// the addresses. Returns errMarshal error if OutputOwners.ctx is not set.
func (out *OutputOwners) MarshalJSON() ([]byte, error) {
	addrsLen := len(out.Addrs)

	// we need out.ctx to do this, if its absent, throw error
	if addrsLen > 0 && out.ctx == nil {
		return nil, errMarshal
	}

	addresses := make([]string, addrsLen)
	for i, addr := range out.Addrs {
		// for each [addr] in [Addrs] we attempt to format it given
		// the [out.ctx] object
		fAddr, err := formatAddress(out.ctx, addr)
		if err != nil {
			// we expect these addresses to be valid, return error
			// if they are not
			return nil, err
		}
		addresses[i] = fAddr
	}
	result := map[string]interface{}{
		"locktime":  out.Locktime,
		"threshold": out.Threshold,
		"addresses": addresses,
	}
	return json.Marshal(result)
}

// Addresses returns the addresses that manage this output
func (out *OutputOwners) Addresses() [][]byte {
	addrs := make([][]byte, len(out.Addrs))
	for i, addr := range out.Addrs {
		addrs[i] = addr.Bytes()
	}
	return addrs
}

// AddressesSet returns addresses as a set
func (out *OutputOwners) AddressesSet() ids.ShortSet {
	set := ids.NewShortSet(len(out.Addrs))
	set.Add(out.Addrs...)
	return set
}

// Equals returns true if the provided owners create the same condition
func (out *OutputOwners) Equals(other *OutputOwners) bool {
	if out == other {
		return true
	}
	if out == nil || other == nil || out.Locktime != other.Locktime || out.Threshold != other.Threshold || len(out.Addrs) != len(other.Addrs) {
		return false
	}
	for i, addr := range out.Addrs {
		otherAddr := other.Addrs[i]
		if addr != otherAddr {
			return false
		}
	}
	return true
}

func (out *OutputOwners) Verify() error {
	switch {
	case out == nil:
		return errNilOutput
	case out.Threshold > uint32(len(out.Addrs)):
		return errOutputUnspendable
	case out.Threshold == 0 && len(out.Addrs) > 0:
		return errOutputUnoptimized
	case !ids.IsSortedAndUniqueShortIDs(out.Addrs):
		return errAddrsNotSortedUnique
	default:
		return nil
	}
}

func (out *OutputOwners) VerifyState() error { return out.Verify() }

func (out *OutputOwners) Sort() { ids.SortShortIDs(out.Addrs) }

// formatAddress formats a given [addr] into human readable format using
// [ChainID] and [NetworkID] from the provided [ctx].
func formatAddress(ctx *snow.Context, addr ids.ShortID) (string, error) {
	chainIDAlias, err := ctx.BCLookup.PrimaryAlias(ctx.ChainID)
	if err != nil {
		return "", err
	}

	hrp := constants.GetHRP(ctx.NetworkID)
	return formatting.FormatAddress(chainIDAlias, hrp, addr.Bytes())
}
<|endoftext|>


<commit_before>package models

import (
	"github.com/techjanitor/pram-get/config"
	e "github.com/techjanitor/pram-get/errors"
	u "github.com/techjanitor/pram-get/utils"
)

// TagsModel holds the parameters from the request and also the key for the cache
type TagsModel struct {
	Ib     uint
	Page   uint
	Result TagsType
}

// TagsType is the top level of the JSON response
type TagsType struct {
	Body u.PagedResponse `json:"tags"`
}

// Taglist struct
type Tags struct {
	Id    uint   `json:"id"`
	Tag   string `json:"tag"`
	Total uint   `json:"total"`
	Type  uint   `json:"type"`
}

// Get will gather the information from the database and return it as JSON serialized data
func (i *TagsModel) Get() (err error) {

	// Initialize response header
	response := TagsType{}

	// tags slice
	tags := []Tags{}

	// Initialize struct for pagination
	paged := u.PagedResponse{}
	// Set current page to parameter
	paged.CurrentPage = i.Page
	// Set threads per index page to config setting
	paged.PerPage = config.Settings.Limits.PostsPerPage

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	// Get total tag count and put it in pagination struct
	err = db.QueryRow("SELECT count(*) FROM tags WHERE ib_id = ?", i.Ib).Scan(&paged.Total)
	if err != nil {
		return
	}

	// Calculate Limit and total Pages
	paged.Get()

	// check page number
	switch {
	case i.Page == 0:
		paged.PerPage = paged.Total
		paged.Limit = 0
	case i.Page > paged.Pages:
		return e.ErrNotFound
	}

	rows, err := db.Query(`SELECT count,tag_id,tag_name,tagtype_id
	FROM (SELECT count(image_id) as count,ib_id,tags.tag_id,tag_name,tagtype_id
	FROM tags
	LEFT JOIN tagmap on tags.tag_id = tagmap.tag_id
	WHERE ib_id = ?
	GROUP by tag_id) as a
	ORDER BY count DESC LIMIT ?,?`, i.Ib, paged.Limit, paged.PerPage)
	if err != nil {
		return
	}

	for rows.Next() {
		// Initialize posts struct
		tag := Tags{}
		// Scan rows and place column into struct
		err := rows.Scan(&tag.Total, &tag.Id, &tag.Tag, &tag.Type)
		if err != nil {
			return err
		}

		// Append rows to info struct
		tags = append(tags, tag)
	}
	err = rows.Err()
	if err != nil {
		return
	}

	// Return 404 if there are no threads in ib
	if len(tags) == 0 {
		return e.ErrNotFound
	}

	// Add threads slice to items interface
	paged.Items = tags

	// Add pagedresponse to the response struct
	response.Body = paged

	// This is the data we will serialize
	i.Result = response

	return

}
<commit_msg>add deleted check to tag pages<commit_after>package models

import (
	"github.com/techjanitor/pram-get/config"
	e "github.com/techjanitor/pram-get/errors"
	u "github.com/techjanitor/pram-get/utils"
)

// TagsModel holds the parameters from the request and also the key for the cache
type TagsModel struct {
	Ib     uint
	Page   uint
	Result TagsType
}

// TagsType is the top level of the JSON response
type TagsType struct {
	Body u.PagedResponse `json:"tags"`
}

// Taglist struct
type Tags struct {
	Id    uint   `json:"id"`
	Tag   string `json:"tag"`
	Total uint   `json:"total"`
	Type  uint   `json:"type"`
}

// Get will gather the information from the database and return it as JSON serialized data
func (i *TagsModel) Get() (err error) {

	// Initialize response header
	response := TagsType{}

	// tags slice
	tags := []Tags{}

	// Initialize struct for pagination
	paged := u.PagedResponse{}
	// Set current page to parameter
	paged.CurrentPage = i.Page
	// Set threads per index page to config setting
	paged.PerPage = config.Settings.Limits.PostsPerPage

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	// Get total tag count and put it in pagination struct
	err = db.QueryRow("SELECT count(*) FROM tags WHERE ib_id = ?", i.Ib).Scan(&paged.Total)
	if err != nil {
		return
	}

	// Calculate Limit and total Pages
	paged.Get()

	// check page number
	switch {
	case i.Page == 0:
		paged.PerPage = paged.Total
		paged.Limit = 0
	case i.Page > paged.Pages:
		return e.ErrNotFound
	}

	// get image counts from tagmap
	rows, err := db.Query(`SELECT * FROM
    (SELECT count(tagmap.image_id) as count,tags.tag_id,tag_name,tagtype_id FROM tags
    LEFT JOIN tagmap on tags.tag_id = tagmap.tag_id
    LEFT JOIN images on tagmap.image_id = images.image_id
    LEFT JOIN posts on images.post_id = posts.post_id
    LEFT JOIN threads on posts.thread_id = threads.thread_id
    WHERE tags.ib_id = ? AND (thread_deleted != 1 OR thread_deleted IS NULL) AND (post_deleted != 1 OR post_deleted IS NULL)
    GROUP by tag_id) as a
    ORDER BY count DESC LIMIT ?,?`, i.Ib, paged.Limit, paged.PerPage)
	if err != nil {
		return
	}

	for rows.Next() {
		// Initialize posts struct
		tag := Tags{}
		// Scan rows and place column into struct
		err := rows.Scan(&tag.Total, &tag.Id, &tag.Tag, &tag.Type)
		if err != nil {
			return err
		}

		// Append rows to info struct
		tags = append(tags, tag)
	}
	err = rows.Err()
	if err != nil {
		return
	}

	// Return 404 if there are no threads in ib
	if len(tags) == 0 {
		return e.ErrNotFound
	}

	// Add threads slice to items interface
	paged.Items = tags

	// Add pagedresponse to the response struct
	response.Body = paged

	// This is the data we will serialize
	i.Result = response

	return

}
<|endoftext|>


<commit_before>package agent

import (
	"context"
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	systemd "github.com/coreos/go-systemd/daemon"
	"github.com/rancher/k3s/pkg/agent/config"
	"github.com/rancher/k3s/pkg/agent/containerd"
	"github.com/rancher/k3s/pkg/agent/flannel"
	"github.com/rancher/k3s/pkg/agent/netpol"
	"github.com/rancher/k3s/pkg/agent/proxy"
	"github.com/rancher/k3s/pkg/agent/syssetup"
	"github.com/rancher/k3s/pkg/agent/tunnel"
	"github.com/rancher/k3s/pkg/cli/cmds"
	"github.com/rancher/k3s/pkg/clientaccess"
	"github.com/rancher/k3s/pkg/daemons/agent"
	daemonconfig "github.com/rancher/k3s/pkg/daemons/config"
	"github.com/rancher/k3s/pkg/datadir"
	"github.com/rancher/k3s/pkg/nodeconfig"
	"github.com/rancher/k3s/pkg/rootless"
	"github.com/rancher/k3s/pkg/version"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/client-go/kubernetes"
	v1 "k8s.io/client-go/kubernetes/typed/core/v1"
	"k8s.io/client-go/tools/clientcmd"
)

var (
	InternalIPLabel = version.Program + ".io/internal-ip"
	ExternalIPLabel = version.Program + ".io/external-ip"
	HostnameLabel   = version.Program + ".io/hostname"
)

const (
	dockershimSock = "unix:///var/run/dockershim.sock"
	containerdSock = "unix:///run/k3s/containerd/containerd.sock"
)

// setupCriCtlConfig creates the crictl config file and populates it
// with the given data from config.
func setupCriCtlConfig(cfg cmds.Agent, nodeConfig *daemonconfig.Node) error {
	cre := nodeConfig.ContainerRuntimeEndpoint
	if cre == "" {
		switch {
		case cfg.Docker:
			cre = dockershimSock
		default:
			cre = containerdSock
		}
	}

	agentConfDir := datadir.DefaultDataDir + "/agent/etc"
	if _, err := os.Stat(agentConfDir); os.IsNotExist(err) {
		if err := os.MkdirAll(agentConfDir, 0755); err != nil {
			return err
		}
	}

	crp := "runtime-endpoint: " + cre + "\n"
	return ioutil.WriteFile(agentConfDir+"/crictl.yaml", []byte(crp), 0600)
}

func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
	nodeConfig := config.Get(ctx, cfg, proxy)

	if err := setupCriCtlConfig(cfg, nodeConfig); err != nil {
		return err
	}

	if !nodeConfig.NoFlannel {
		if err := flannel.Prepare(ctx, nodeConfig); err != nil {
			return err
		}
	}

	if !nodeConfig.Docker && nodeConfig.ContainerRuntimeEndpoint == "" {
		if err := containerd.Run(ctx, nodeConfig); err != nil {
			return err
		}
	}

	if err := tunnel.Setup(ctx, nodeConfig, proxy); err != nil {
		return err
	}

	if err := agent.Agent(&nodeConfig.AgentConfig); err != nil {
		return err
	}

	coreClient, err := coreClient(nodeConfig.AgentConfig.KubeConfigKubelet)
	if err != nil {
		return err
	}
	if !nodeConfig.NoFlannel {
		if err := flannel.Run(ctx, nodeConfig, coreClient.CoreV1().Nodes()); err != nil {
			return err
		}
	}

	if err := configureNode(ctx, &nodeConfig.AgentConfig, coreClient.CoreV1().Nodes()); err != nil {
		return err
	}

	if !nodeConfig.AgentConfig.DisableNPC {
		if err := netpol.Run(ctx, nodeConfig); err != nil {
			return err
		}
	}

	<-ctx.Done()
	return ctx.Err()
}

func coreClient(cfg string) (kubernetes.Interface, error) {
	restConfig, err := clientcmd.BuildConfigFromFlags("", cfg)
	if err != nil {
		return nil, err
	}

	return kubernetes.NewForConfig(restConfig)
}

func Run(ctx context.Context, cfg cmds.Agent) error {
	if err := validate(); err != nil {
		return err
	}
	syssetup.Configure()

	if cfg.Rootless && !cfg.RootlessAlreadyUnshared {
		if err := rootless.Rootless(cfg.DataDir); err != nil {
			return err
		}
	}

	cfg.DataDir = filepath.Join(cfg.DataDir, "agent")
	if err := os.MkdirAll(cfg.DataDir, 0700); err != nil {
		return err
	}

	proxy, err := proxy.NewAPIProxy(!cfg.DisableLoadBalancer, cfg.DataDir, cfg.ServerURL)
	if err != nil {
		return err
	}

	for {
		newToken, err := clientaccess.ParseAndValidateTokenForUser(proxy.SupervisorURL(), cfg.Token, "node")
		if err != nil {
			logrus.Error(err)
			select {
			case <-ctx.Done():
				return ctx.Err()
			case <-time.After(2 * time.Second):
			}
			continue
		}
		cfg.Token = newToken.String()
		break
	}

	systemd.SdNotify(true, "READY=1\n")
	return run(ctx, cfg, proxy)
}

func validate() error {
	cgroups, err := ioutil.ReadFile("/proc/self/cgroup")
	if err != nil {
		return err
	}

	if !strings.Contains(string(cgroups), "cpuset") {
		logrus.Warn(`Failed to find cpuset cgroup, you may need to add "cgroup_enable=cpuset" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)`)
	}

	if !strings.Contains(string(cgroups), "memory") {
		msg := "ailed to find memory cgroup, you may need to add \"cgroup_memory=1 cgroup_enable=memory\" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)"
		logrus.Error("F" + msg)
		return errors.New("f" + msg)
	}

	return nil
}

func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v1.NodeInterface) error {
	count := 0
	for {
		node, err := nodes.Get(ctx, agentConfig.NodeName, metav1.GetOptions{})
		if err != nil {
			if count%30 == 0 {
				logrus.Infof("Waiting for kubelet to be ready on node %s: %v", agentConfig.NodeName, err)
			}
			count++
			time.Sleep(1 * time.Second)
			continue
		}

		newLabels, updateMutables := updateMutableLabels(agentConfig, node.Labels)

		updateAddresses := !agentConfig.DisableCCM
		if updateAddresses {
			newLabels, updateAddresses = updateAddressLabels(agentConfig, newLabels)
		}

		// inject node config
		updateNode, err := nodeconfig.SetNodeConfigAnnotations(node)
		if err != nil {
			return err
		}
		if updateAddresses || updateMutables {
			node.Labels = newLabels
			updateNode = true
		}
		if updateNode {
			if _, err := nodes.Update(ctx, node, metav1.UpdateOptions{}); err != nil {
				logrus.Infof("Failed to update node %s: %v", agentConfig.NodeName, err)
				select {
				case <-ctx.Done():
					return ctx.Err()
				case <-time.After(time.Second):
					continue
				}
			}
			logrus.Infof("labels have been set successfully on node: %s", agentConfig.NodeName)
		} else {
			logrus.Infof("labels have already set on node: %s", agentConfig.NodeName)
		}

		break
	}

	return nil
}

func updateMutableLabels(agentConfig *daemonconfig.Agent, nodeLabels map[string]string) (map[string]string, bool) {
	result := map[string]string{}

	for _, m := range agentConfig.NodeLabels {
		var (
			v string
			p = strings.SplitN(m, `=`, 2)
			k = p[0]
		)
		if len(p) > 1 {
			v = p[1]
		}
		result[k] = v
	}
	result = labels.Merge(nodeLabels, result)
	return result, !equality.Semantic.DeepEqual(nodeLabels, result)
}

func updateAddressLabels(agentConfig *daemonconfig.Agent, nodeLabels map[string]string) (map[string]string, bool) {
	result := map[string]string{
		InternalIPLabel: agentConfig.NodeIP,
		HostnameLabel:   agentConfig.NodeName,
	}

	if agentConfig.NodeExternalIP != "" {
		result[ExternalIPLabel] = agentConfig.NodeExternalIP
	}

	result = labels.Merge(nodeLabels, result)
	return result, !equality.Semantic.DeepEqual(nodeLabels, result)
}
<commit_msg>Respect --data-dir path for crictl.yaml<commit_after>package agent

import (
	"context"
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	systemd "github.com/coreos/go-systemd/daemon"
	"github.com/rancher/k3s/pkg/agent/config"
	"github.com/rancher/k3s/pkg/agent/containerd"
	"github.com/rancher/k3s/pkg/agent/flannel"
	"github.com/rancher/k3s/pkg/agent/netpol"
	"github.com/rancher/k3s/pkg/agent/proxy"
	"github.com/rancher/k3s/pkg/agent/syssetup"
	"github.com/rancher/k3s/pkg/agent/tunnel"
	"github.com/rancher/k3s/pkg/cli/cmds"
	"github.com/rancher/k3s/pkg/clientaccess"
	"github.com/rancher/k3s/pkg/daemons/agent"
	daemonconfig "github.com/rancher/k3s/pkg/daemons/config"
	"github.com/rancher/k3s/pkg/nodeconfig"
	"github.com/rancher/k3s/pkg/rootless"
	"github.com/rancher/k3s/pkg/version"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/client-go/kubernetes"
	v1 "k8s.io/client-go/kubernetes/typed/core/v1"
	"k8s.io/client-go/tools/clientcmd"
)

var (
	InternalIPLabel = version.Program + ".io/internal-ip"
	ExternalIPLabel = version.Program + ".io/external-ip"
	HostnameLabel   = version.Program + ".io/hostname"
)

const (
	dockershimSock = "unix:///var/run/dockershim.sock"
	containerdSock = "unix:///run/k3s/containerd/containerd.sock"
)

// setupCriCtlConfig creates the crictl config file and populates it
// with the given data from config.
func setupCriCtlConfig(cfg cmds.Agent, nodeConfig *daemonconfig.Node) error {
	cre := nodeConfig.ContainerRuntimeEndpoint
	if cre == "" {
		switch {
		case cfg.Docker:
			cre = dockershimSock
		default:
			cre = containerdSock
		}
	}

	agentConfDir := filepath.Join(cfg.DataDir, "agent", "etc")
	if _, err := os.Stat(agentConfDir); os.IsNotExist(err) {
		if err := os.MkdirAll(agentConfDir, 0700); err != nil {
			return err
		}
	}

	crp := "runtime-endpoint: " + cre + "\n"
	return ioutil.WriteFile(agentConfDir+"/crictl.yaml", []byte(crp), 0600)
}

func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
	nodeConfig := config.Get(ctx, cfg, proxy)

	if err := setupCriCtlConfig(cfg, nodeConfig); err != nil {
		return err
	}

	if !nodeConfig.NoFlannel {
		if err := flannel.Prepare(ctx, nodeConfig); err != nil {
			return err
		}
	}

	if !nodeConfig.Docker && nodeConfig.ContainerRuntimeEndpoint == "" {
		if err := containerd.Run(ctx, nodeConfig); err != nil {
			return err
		}
	}

	if err := tunnel.Setup(ctx, nodeConfig, proxy); err != nil {
		return err
	}

	if err := agent.Agent(&nodeConfig.AgentConfig); err != nil {
		return err
	}

	coreClient, err := coreClient(nodeConfig.AgentConfig.KubeConfigKubelet)
	if err != nil {
		return err
	}
	if !nodeConfig.NoFlannel {
		if err := flannel.Run(ctx, nodeConfig, coreClient.CoreV1().Nodes()); err != nil {
			return err
		}
	}

	if err := configureNode(ctx, &nodeConfig.AgentConfig, coreClient.CoreV1().Nodes()); err != nil {
		return err
	}

	if !nodeConfig.AgentConfig.DisableNPC {
		if err := netpol.Run(ctx, nodeConfig); err != nil {
			return err
		}
	}

	<-ctx.Done()
	return ctx.Err()
}

func coreClient(cfg string) (kubernetes.Interface, error) {
	restConfig, err := clientcmd.BuildConfigFromFlags("", cfg)
	if err != nil {
		return nil, err
	}

	return kubernetes.NewForConfig(restConfig)
}

func Run(ctx context.Context, cfg cmds.Agent) error {
	if err := validate(); err != nil {
		return err
	}
	syssetup.Configure()

	if cfg.Rootless && !cfg.RootlessAlreadyUnshared {
		if err := rootless.Rootless(cfg.DataDir); err != nil {
			return err
		}
	}

	agentDir := filepath.Join(cfg.DataDir, "agent")
	if err := os.MkdirAll(agentDir, 0700); err != nil {
		return err
	}

	proxy, err := proxy.NewAPIProxy(!cfg.DisableLoadBalancer, agentDir, cfg.ServerURL)
	if err != nil {
		return err
	}

	for {
		newToken, err := clientaccess.ParseAndValidateTokenForUser(proxy.SupervisorURL(), cfg.Token, "node")
		if err != nil {
			logrus.Error(err)
			select {
			case <-ctx.Done():
				return ctx.Err()
			case <-time.After(2 * time.Second):
			}
			continue
		}
		cfg.Token = newToken.String()
		break
	}

	systemd.SdNotify(true, "READY=1\n")
	return run(ctx, cfg, proxy)
}

func validate() error {
	cgroups, err := ioutil.ReadFile("/proc/self/cgroup")
	if err != nil {
		return err
	}

	if !strings.Contains(string(cgroups), "cpuset") {
		logrus.Warn(`Failed to find cpuset cgroup, you may need to add "cgroup_enable=cpuset" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)`)
	}

	if !strings.Contains(string(cgroups), "memory") {
		msg := "ailed to find memory cgroup, you may need to add \"cgroup_memory=1 cgroup_enable=memory\" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)"
		logrus.Error("F" + msg)
		return errors.New("f" + msg)
	}

	return nil
}

func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v1.NodeInterface) error {
	count := 0
	for {
		node, err := nodes.Get(ctx, agentConfig.NodeName, metav1.GetOptions{})
		if err != nil {
			if count%30 == 0 {
				logrus.Infof("Waiting for kubelet to be ready on node %s: %v", agentConfig.NodeName, err)
			}
			count++
			time.Sleep(1 * time.Second)
			continue
		}

		newLabels, updateMutables := updateMutableLabels(agentConfig, node.Labels)

		updateAddresses := !agentConfig.DisableCCM
		if updateAddresses {
			newLabels, updateAddresses = updateAddressLabels(agentConfig, newLabels)
		}

		// inject node config
		updateNode, err := nodeconfig.SetNodeConfigAnnotations(node)
		if err != nil {
			return err
		}
		if updateAddresses || updateMutables {
			node.Labels = newLabels
			updateNode = true
		}
		if updateNode {
			if _, err := nodes.Update(ctx, node, metav1.UpdateOptions{}); err != nil {
				logrus.Infof("Failed to update node %s: %v", agentConfig.NodeName, err)
				select {
				case <-ctx.Done():
					return ctx.Err()
				case <-time.After(time.Second):
					continue
				}
			}
			logrus.Infof("labels have been set successfully on node: %s", agentConfig.NodeName)
		} else {
			logrus.Infof("labels have already set on node: %s", agentConfig.NodeName)
		}

		break
	}

	return nil
}

func updateMutableLabels(agentConfig *daemonconfig.Agent, nodeLabels map[string]string) (map[string]string, bool) {
	result := map[string]string{}

	for _, m := range agentConfig.NodeLabels {
		var (
			v string
			p = strings.SplitN(m, `=`, 2)
			k = p[0]
		)
		if len(p) > 1 {
			v = p[1]
		}
		result[k] = v
	}
	result = labels.Merge(nodeLabels, result)
	return result, !equality.Semantic.DeepEqual(nodeLabels, result)
}

func updateAddressLabels(agentConfig *daemonconfig.Agent, nodeLabels map[string]string) (map[string]string, bool) {
	result := map[string]string{
		InternalIPLabel: agentConfig.NodeIP,
		HostnameLabel:   agentConfig.NodeName,
	}

	if agentConfig.NodeExternalIP != "" {
		result[ExternalIPLabel] = agentConfig.NodeExternalIP
	}

	result = labels.Merge(nodeLabels, result)
	return result, !equality.Semantic.DeepEqual(nodeLabels, result)
}
<|endoftext|>


<commit_before>/*
Copyright 2014 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 in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

// ContainerManifest corresponds to the Container Manifest format, documented at:
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
// This is used as the representation of Kubernete's workloads.
type ContainerManifest struct {
	Version    string      `yaml:"version" json:"version"`
	Volumes    []Volume    `yaml:"volumes" json:"volumes"`
	Containers []Container `yaml:"containers" json:"containers"`
	Id         string      `yaml:"id,omitempty" json:"id,omitempty"`
}

// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
type Volume struct {
	Name string `yaml:"name" json:"name"`
}

// Port represents a network port in a single container
type Port struct {
	Name          string `yaml:"name,omitempty" json:"name,omitempty"`
	HostPort      int    `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
	ContainerPort int    `yaml:"containerPort,omitempty" json:"containerPort,omitempty"`
	Protocol      string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
}

// VolumeMount describes a mounting of a Volume within a container
type VolumeMount struct {
	// Name must match the Name of a volume [above]
	Name      string `yaml:"name,omitempty" json:"name,omitempty"`
	ReadOnly  bool   `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
	MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`
	// One of: "LOCAL" (local volume) or "HOST" (external mount from the host). Default: LOCAL.
	MountType string `yaml:"mountType,omitempty" json:"mountType,omitempty"`
}

// EnvVar represents an environment variable present in a Container
type EnvVar struct {
	Name  string `yaml:"name,omitempty" json:"name,omitempty"`
	Value string `yaml:"value,omitempty" json:"value,omitempty"`
}

// Container represents a single container that is expected to be run on the host.
type Container struct {
	Name         string        `yaml:"name,omitempty" json:"name,omitempty"`
	Image        string        `yaml:"image,omitempty" json:"image,omitempty"`
	Command      []string      `yaml:"command,omitempty" json:"command,omitempty"`
	WorkingDir   string        `yaml:"workingDir,omitempty" json:"workingDir,omitempty"`
	Ports        []Port        `yaml:"ports,omitempty" json:"ports,omitempty"`
	Env          []EnvVar      `yaml:"env,omitempty" json:"env,omitempty"`
	Memory       int           `yaml:"memory,omitempty" json:"memory,omitempty"`
	CPU          int           `yaml:"cpu,omitempty" json:"cpu,omitempty"`
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`
}

// Percentile represents a pair which contains a percentage from 0 to 100 and
// its corresponding value.
type Percentile struct {
	Percentage int    `json:"percentage,omitempty"`
	Value      uint64 `json:"value,omitempty"`
}

// ContainerStats represents statistical information of a container
type ContainerStats struct {
	CpuUsagePercentiles    []Percentile `json:"cpu_usage_percentiles,omitempty"`
	MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
	MaxMemoryUsage         uint64       `json:"max_memory_usage,omitempty"`
}

// Event is the representation of an event logged to etcd backends
type Event struct {
	Event     string             `json:"event,omitempty"`
	Manifest  *ContainerManifest `json:"manifest,omitempty"`
	Container *Container         `json:"container,omitempty"`
	Timestamp int64              `json:"timestamp"`
}

// The below types are used by kube_client and api_server.

// JSONBase is shared by all objects sent to, or returned from the client
type JSONBase struct {
	Kind              string `json:"kind,omitempty" yaml:"kind,omitempty"`
	ID                string `json:"id,omitempty" yaml:"id,omitempty"`
	CreationTimestamp string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
	SelfLink          string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
}

// PodState is the state of a pod, used as either input (desired state) or output (current state)
type PodState struct {
	Manifest ContainerManifest `json:"manifest,omitempty" yaml:"manifest,omitempty"`
	Status   string            `json:"status,omitempty" yaml:"status,omitempty"`
	Host     string            `json:"host,omitempty" yaml:"host,omitempty"`
	HostIP   string            `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
	Info     interface{}       `json:"info,omitempty" yaml:"info,omitempty"`
}

type PodList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Pod `json:"items" yaml:"items,omitempty"`
}

// Pod is a collection of containers, used as either input (create, update) or as output (list, get)
type Pod struct {
	JSONBase     `json:",inline" yaml:",inline"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	CurrentState PodState          `json:"currentState,omitempty" yaml:"currentState,omitempty"`
}

// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get)
type ReplicationControllerState struct {
	Replicas        int               `json:"replicas" yaml:"replicas"`
	ReplicaSelector map[string]string `json:"replicaSelector,omitempty" yaml:"replicaSelector,omitempty"`
	PodTemplate     PodTemplate       `json:"podTemplate,omitempty" yaml:"podTemplate,omitempty"`
}

type ReplicationControllerList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
}

// ReplicationController represents the configuration of a replication controller
type ReplicationController struct {
	JSONBase     `json:",inline" yaml:",inline"`
	DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string          `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// PodTemplate holds the information used for creating pods
type PodTemplate struct {
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// ServiceList holds a list of services
type ServiceList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Service `json:"items" yaml:"items"`
}

// Defines a service abstraction by a name (for example, mysql) consisting of local port
// (for example 3306) that the proxy listens on, and the selector that determines which pods
// will answer requests sent through the proxy.
type Service struct {
	JSONBase `json:",inline" yaml:",inline"`
	Port     int `json:"port,omitempty" yaml:"port,omitempty"`

	// This service's labels.
	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

	// This service will route traffic to pods having labels matching this selector.
	Selector                   map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
	CreateExternalLoadBalancer bool              `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
}

// Defines the endpoints that implement the actual service, for example:
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
type Endpoints struct {
	Name      string
	Endpoints []string
}

// Information about a single Minion; the name of the minion according to etcd
// is in JSONBase.ID.
type Minion struct {
	JSONBase `json:",inline" yaml:",inline"`
	// Queried from cloud provider, if available.
	HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
}

// A list of minions.
type MinionList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Minions  []Minion `json:"minions,omitempty" yaml:"minions,omitempty"`
}

// Status is a return value for calls that don't return other objects.
// Arguably, this could go in apiserver, but I'm including it here so clients needn't
// import both.
type Status struct {
	JSONBase `json:",inline" yaml:",inline"`
	// One of: "success", "failure", "working" (for operations not yet completed)
	// TODO: if "working", include an operation identifier so final status can be
	// checked.
	Status string `json:"status,omitempty" yaml:"status,omitempty"`
}

// Values of Status.Status
const (
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusWorking = "working"
)
<commit_msg>Update the proxy server.<commit_after>/*
Copyright 2014 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 in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

// ContainerManifest corresponds to the Container Manifest format, documented at:
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
// This is used as the representation of Kubernete's workloads.
type ContainerManifest struct {
	Version    string      `yaml:"version" json:"version"`
	Volumes    []Volume    `yaml:"volumes" json:"volumes"`
	Containers []Container `yaml:"containers" json:"containers"`
	Id         string      `yaml:"id,omitempty" json:"id,omitempty"`
}

// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
type Volume struct {
	Name string `yaml:"name" json:"name"`
}

// Port represents a network port in a single container
type Port struct {
	Name          string `yaml:"name,omitempty" json:"name,omitempty"`
	HostPort      int    `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
	ContainerPort int    `yaml:"containerPort,omitempty" json:"containerPort,omitempty"`
	Protocol      string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
}

// VolumeMount describes a mounting of a Volume within a container
type VolumeMount struct {
	// Name must match the Name of a volume [above]
	Name      string `yaml:"name,omitempty" json:"name,omitempty"`
	ReadOnly  bool   `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
	MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`
	// One of: "LOCAL" (local volume) or "HOST" (external mount from the host). Default: LOCAL.
	MountType string `yaml:"mountType,omitempty" json:"mountType,omitempty"`
}

// EnvVar represents an environment variable present in a Container
type EnvVar struct {
	Name  string `yaml:"name,omitempty" json:"name,omitempty"`
	Value string `yaml:"value,omitempty" json:"value,omitempty"`
}

// Container represents a single container that is expected to be run on the host.
type Container struct {
	Name         string        `yaml:"name,omitempty" json:"name,omitempty"`
	Image        string        `yaml:"image,omitempty" json:"image,omitempty"`
	Command      []string      `yaml:"command,omitempty" json:"command,omitempty"`
	WorkingDir   string        `yaml:"workingDir,omitempty" json:"workingDir,omitempty"`
	Ports        []Port        `yaml:"ports,omitempty" json:"ports,omitempty"`
	Env          []EnvVar      `yaml:"env,omitempty" json:"env,omitempty"`
	Memory       int           `yaml:"memory,omitempty" json:"memory,omitempty"`
	CPU          int           `yaml:"cpu,omitempty" json:"cpu,omitempty"`
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`
}

// Percentile represents a pair which contains a percentage from 0 to 100 and
// its corresponding value.
type Percentile struct {
	Percentage int    `json:"percentage,omitempty"`
	Value      uint64 `json:"value,omitempty"`
}

// ContainerStats represents statistical information of a container
type ContainerStats struct {
	CpuUsagePercentiles    []Percentile `json:"cpu_usage_percentiles,omitempty"`
	MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
	MaxMemoryUsage         uint64       `json:"max_memory_usage,omitempty"`
}

// Event is the representation of an event logged to etcd backends
type Event struct {
	Event     string             `json:"event,omitempty"`
	Manifest  *ContainerManifest `json:"manifest,omitempty"`
	Container *Container         `json:"container,omitempty"`
	Timestamp int64              `json:"timestamp"`
}

// The below types are used by kube_client and api_server.

// JSONBase is shared by all objects sent to, or returned from the client
type JSONBase struct {
	Kind              string `json:"kind,omitempty" yaml:"kind,omitempty"`
	ID                string `json:"id,omitempty" yaml:"id,omitempty"`
	CreationTimestamp string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
	SelfLink          string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
}

// PodState is the state of a pod, used as either input (desired state) or output (current state)
type PodState struct {
	Manifest ContainerManifest `json:"manifest,omitempty" yaml:"manifest,omitempty"`
	Status   string            `json:"status,omitempty" yaml:"status,omitempty"`
	Host     string            `json:"host,omitempty" yaml:"host,omitempty"`
	HostIP   string            `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
	Info     interface{}       `json:"info,omitempty" yaml:"info,omitempty"`
}

type PodList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Pod `json:"items" yaml:"items,omitempty"`
}

// Pod is a collection of containers, used as either input (create, update) or as output (list, get)
type Pod struct {
	JSONBase     `json:",inline" yaml:",inline"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	CurrentState PodState          `json:"currentState,omitempty" yaml:"currentState,omitempty"`
}

// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get)
type ReplicationControllerState struct {
	Replicas        int               `json:"replicas" yaml:"replicas"`
	ReplicaSelector map[string]string `json:"replicaSelector,omitempty" yaml:"replicaSelector,omitempty"`
	PodTemplate     PodTemplate       `json:"podTemplate,omitempty" yaml:"podTemplate,omitempty"`
}

type ReplicationControllerList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
}

// ReplicationController represents the configuration of a replication controller
type ReplicationController struct {
	JSONBase     `json:",inline" yaml:",inline"`
	DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string          `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// PodTemplate holds the information used for creating pods
type PodTemplate struct {
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// ServiceList holds a list of services
type ServiceList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Service `json:"items" yaml:"items"`
}

// Defines a service abstraction by a name (for example, mysql) consisting of local port
// (for example 3306) that the proxy listens on, and the selector that determines which pods
// will answer requests sent through the proxy.
type Service struct {
	JSONBase `json:",inline" yaml:",inline"`
	Port     int `json:"port,omitempty" yaml:"port,omitempty"`

	// This service's labels.
	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

	// This service will route traffic to pods having labels matching this selector.
	Selector                   map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
	CreateExternalLoadBalancer bool              `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
}

// Defines the endpoints that implement the actual service, for example:
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
type Endpoints struct {
	Name      string
	Endpoints []string
}

// Information about a single Minion; the name of the minion according to etcd
// is in JSONBase.ID.
type Minion struct {
	JSONBase `json:",inline" yaml:",inline"`
	// Queried from cloud provider, if available.
	HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
}

// A list of minions.
type MinionList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Minions  []Minion `json:"minions,omitempty" yaml:"minions,omitempty"`
}

// Status is a return value for calls that don't return other objects.
// Arguably, this could go in apiserver, but I'm including it here so clients needn't
// import both.
type Status struct {
	JSONBase `json:",inline" yaml:",inline"`
	// One of: "success", "failure", "working" (for operations not yet completed)
	// TODO: if "working", include an operation identifier so final status can be
	// checked.
	Status  string `json:"status,omitempty" yaml:"status,omitempty"`
	Details string `json:"details,omitempty" yaml:"details,omitempty"`
}

// Values of Status.Status
const (
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusWorking = "working"
)
<|endoftext|>


<commit_before>package app

import (
	"path/filepath"
	"strings"

	"github.com/materials-commons/config"
)

type mcdir struct{}

// MCDir gives access to methods on the MCDIR directory.
var MCDir mcdir

func (d mcdir) Path() string {
	dir := config.GetString("MCDIR")
	if dir == "" {
		panic("MCDIR not set")
	}
	return dir
}

func (d mcdir) FileDir(fileID string) string {
	idSegments := strings.Split(fileID, "-")
	switch {
	case len(idSegments) < 2:
		Log.Debug(Logf("FileDir: Got bad fileID: %s", fileID))
		return ""
	case len(idSegments[1]) < 4:
		Log.Debug(Logf("FileDir: Got bad fileID: %s", fileID))
		return ""
	default:
		return filepath.Join(d.Path(), idSegments[1][0:2], idSegments[1][2:4])
	}
}

func (d mcdir) FileConversionDir(fileID string) string {
	dir := d.FileDir(fileID)
	if dir == "" {
		return ""
	}
	return filepath.Join(dir, ".conversion")
}

func (d mcdir) FilePath(fileID string) string {
	dir := d.FileDir(fileID)
	if dir == "" {
		return ""
	}
	return filepath.Join(dir, fileID)
}

func (d mcdir) FilePathImageConversion(fileID string) string {
	dir := d.FileConversionDir(fileID)
	if dir == "" {
		return ""
	}
	return filepath.Join(dir, fileID+".jpg")
}
<commit_msg>Refactor code to rmove common pathway into a single function.<commit_after>package app

import (
	"path/filepath"
	"strings"

	"github.com/materials-commons/config"
)

type mcdir struct{}

// MCDir gives access to methods on the MCDIR directory. It will
// panic if MCDIR is not set.
var MCDir mcdir

func (d mcdir) Path() string {
	dir := config.GetString("MCDIR")
	if dir == "" {
		panic("MCDIR not set")
	}
	return dir
}

// FileDir returns the directory path for a given fileID. It returns the
// empty string if a bad fileID is given.
func (d mcdir) FileDir(fileID string) string {
	idSegments := strings.Split(fileID, "-")
	switch {
	case len(idSegments) < 2:
		Log.Debug(Logf("FileDir: Got bad fileID: %s", fileID))
		return ""
	case len(idSegments[1]) < 4:
		Log.Debug(Logf("FileDir: Got bad fileID: %s", fileID))
		return ""
	default:
		return filepath.Join(d.Path(), idSegments[1][0:2], idSegments[1][2:4])
	}
}

// FileConversionDir returns the conversion directory path for a fileID. The
// conversion directory is the directory where converted image files are kept.
// It returns the empty string if a bad fileID is given.
func (d mcdir) FileConversionDir(fileID string) string {
	dir := d.FileDir(fileID)
	return makePath(dir, ".conversion")
}

// FilePath returns the full path including the file for a fileID.
// It returns the empty string if a bad fileID is given.
func (d mcdir) FilePath(fileID string) string {
	dir := d.FileDir(fileID)
	return makePath(dir, fileID)
}

// FilePathImageConversion returns the full path, include the file,
// to the converted image file. It returns the empty string if a
// bad fileID is given.
func (d mcdir) FilePathImageConversion(fileID string) string {
	dir := d.FileConversionDir(fileID)
	return makePath(dir, fileID+".jpg")
}

// makePath constructs the file path. It handles checking
// for bad segments and empty directory paths. It returns
// the empty string if the first segment is empty, or
// if the list of segments is empty.
func makePath(pathSegments ...string) string {
	switch {
	case len(pathSegments) == 0:
		return ""
	case pathSegments[0] == "":
		return ""
	default:
		return filepath.Join(pathSegments...)
	}
}
<|endoftext|>


<commit_before>package asset

import (
	"crypto/rsa"
	"crypto/x509"
	"net"
	"net/url"

	"github.com/pborman/uuid"

	"github.com/kubernetes-sigs/bootkube/pkg/tlsutil"
)

func newTLSAssets(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, altNames tlsutil.AltNames) ([]Asset, error) {
	var (
		assets []Asset
		err    error
	)

	apiKey, apiCert, err := newAPIKeyAndCert(caCert, caPrivKey, altNames)
	if err != nil {
		return assets, err
	}

	aggregatorCAPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	cfg := tlsutil.CertConfig{
		CommonName: "front-proxy",
	}

	aggregatorCACert, err := tlsutil.NewSelfSignedCACertificate(cfg, aggregatorCAPrivKey)
	if err != nil {
		return assets, err
	}

	frontProxyPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	cfg = tlsutil.CertConfig{
		CommonName: "front-proxy-client",
	}

	frontProxyCert, err := tlsutil.NewSignedCertificate(cfg, frontProxyPrivKey, aggregatorCACert, aggregatorCAPrivKey)
	if err != nil {
		return assets, err
	}

	saPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	saPubKey, err := tlsutil.EncodePublicKeyPEM(&saPrivKey.PublicKey)
	if err != nil {
		return assets, err
	}

	adminKey, adminCert, err := newAdminKeyAndCert(caCert, caPrivKey)
	if err != nil {
		return assets, err
	}

	assets = append(assets, []Asset{
		{Name: AssetPathCAKey, Data: tlsutil.EncodePrivateKeyPEM(caPrivKey)},
		{Name: AssetPathCACert, Data: tlsutil.EncodeCertificatePEM(caCert)},
		{Name: AssetPathAPIServerKey, Data: tlsutil.EncodePrivateKeyPEM(apiKey)},
		{Name: AssetPathAPIServerCert, Data: tlsutil.EncodeCertificatePEM(apiCert)},
		{Name: AssetPathServiceAccountPrivKey, Data: tlsutil.EncodePrivateKeyPEM(saPrivKey)},
		{Name: AssetPathAggregatorCA, Data: tlsutil.EncodeCertificatePEM(aggregatorCACert)},
		{Name: AssetPathFrontProxyClientCert, Data: tlsutil.EncodeCertificatePEM(frontProxyCert)},
		{Name: AssetPathFrontProxyClientKey, Data: tlsutil.EncodePrivateKeyPEM(frontProxyPrivKey)},
		{Name: AssetPathServiceAccountPubKey, Data: saPubKey},
		{Name: AssetPathAdminKey, Data: tlsutil.EncodePrivateKeyPEM(adminKey)},
		{Name: AssetPathAdminCert, Data: tlsutil.EncodeCertificatePEM(adminCert)},
	}...)
	return assets, nil
}

func newCACert() (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}

	config := tlsutil.CertConfig{
		CommonName:         "kube-ca",
		Organization:       []string{uuid.New()},
		OrganizationalUnit: []string{"bootkube"},
	}

	cert, err := tlsutil.NewSelfSignedCACertificate(config, key)
	if err != nil {
		return nil, nil, err
	}

	return key, cert, err
}

func newAPIKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, altNames tlsutil.AltNames) (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	altNames.DNSNames = append(altNames.DNSNames, []string{
		"kubernetes",
		"kubernetes.default",
		"kubernetes.default.svc",
		"kubernetes.default.svc.cluster.local",
	}...)

	config := tlsutil.CertConfig{
		CommonName:   "kube-apiserver",
		Organization: []string{"kube-master"},
		AltNames:     altNames,
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}

func newAdminKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey) (*rsa.PrivateKey, *x509.Certificate, error) {
	// TLS organizations map to Kubernetes groups, and "system:masters"
	// is a well-known Kubernetes group that gives a user admin power.
	const orgSystemMasters = "system:masters"

	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	config := tlsutil.CertConfig{
		CommonName:   "admin",
		Organization: []string{orgSystemMasters},
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}

func newEtcdTLSAssets(etcdCACert, etcdClientCert *x509.Certificate, etcdClientKey *rsa.PrivateKey, caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, etcdServers []*url.URL) ([]Asset, error) {
	var assets []Asset
	if etcdCACert == nil {
		// Use the master CA to generate etcd assets.
		etcdCACert = caCert

		// Create an etcd client cert.
		var err error
		etcdClientKey, etcdClientCert, err = newEtcdKeyAndCert(caCert, caPrivKey, "etcd-client", etcdServers)
		if err != nil {
			return nil, err
		}

		// Create an etcd peer cert (not consumed by self-hosted components).
		etcdPeerKey, etcdPeerCert, err := newEtcdKeyAndCert(caCert, caPrivKey, "etcd-peer", etcdServers)
		if err != nil {
			return nil, err
		}
		etcdServerKey, etcdServerCert, err := newEtcdKeyAndCert(caCert, caPrivKey, "etcd-server", etcdServers)
		if err != nil {
			return nil, err
		}

		assets = append(assets, []Asset{
			{Name: AssetPathEtcdPeerCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
			{Name: AssetPathEtcdPeerKey, Data: tlsutil.EncodePrivateKeyPEM(etcdPeerKey)},
			{Name: AssetPathEtcdPeerCert, Data: tlsutil.EncodeCertificatePEM(etcdPeerCert)},
			{Name: AssetPathEtcdServerCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
			{Name: AssetPathEtcdServerKey, Data: tlsutil.EncodePrivateKeyPEM(etcdServerKey)},
			{Name: AssetPathEtcdServerCert, Data: tlsutil.EncodeCertificatePEM(etcdServerCert)},
		}...)
	}

	assets = append(assets, []Asset{
		{Name: AssetPathEtcdClientCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
		{Name: AssetPathEtcdClientKey, Data: tlsutil.EncodePrivateKeyPEM(etcdClientKey)},
		{Name: AssetPathEtcdClientCert, Data: tlsutil.EncodeCertificatePEM(etcdClientCert)},
	}...)

	return assets, nil
}

func newEtcdKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, commonName string, etcdServers []*url.URL) (*rsa.PrivateKey, *x509.Certificate, error) {
	addrs := make([]string, len(etcdServers))
	for i := range etcdServers {
		addrs[i] = etcdServers[i].Hostname()
	}
	return newKeyAndCert(caCert, caPrivKey, commonName, addrs)
}

func newKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, commonName string, addrs []string) (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	var altNames tlsutil.AltNames
	for _, addr := range addrs {
		if ip := net.ParseIP(addr); ip != nil {
			altNames.IPs = append(altNames.IPs, ip)
		} else {
			altNames.DNSNames = append(altNames.DNSNames, addr)
		}
	}
	config := tlsutil.CertConfig{
		CommonName:   commonName,
		Organization: []string{"etcd"},
		AltNames:     altNames,
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}
<commit_msg>moves api-server tls org to system:masters<commit_after>package asset

import (
	"crypto/rsa"
	"crypto/x509"
	"net"
	"net/url"

	"github.com/pborman/uuid"

	"github.com/kubernetes-sigs/bootkube/pkg/tlsutil"
)

// TLS organizations map to Kubernetes groups, and "system:masters"
// is a well-known Kubernetes group that gives a user admin power.
const orgSystemMasters = "system:masters"

func newTLSAssets(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, altNames tlsutil.AltNames) ([]Asset, error) {
	var (
		assets []Asset
		err    error
	)

	apiKey, apiCert, err := newAPIKeyAndCert(caCert, caPrivKey, altNames)
	if err != nil {
		return assets, err
	}

	aggregatorCAPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	cfg := tlsutil.CertConfig{
		CommonName: "front-proxy",
	}

	aggregatorCACert, err := tlsutil.NewSelfSignedCACertificate(cfg, aggregatorCAPrivKey)
	if err != nil {
		return assets, err
	}

	frontProxyPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	cfg = tlsutil.CertConfig{
		CommonName: "front-proxy-client",
	}

	frontProxyCert, err := tlsutil.NewSignedCertificate(cfg, frontProxyPrivKey, aggregatorCACert, aggregatorCAPrivKey)
	if err != nil {
		return assets, err
	}

	saPrivKey, err := tlsutil.NewPrivateKey()
	if err != nil {
		return assets, err
	}

	saPubKey, err := tlsutil.EncodePublicKeyPEM(&saPrivKey.PublicKey)
	if err != nil {
		return assets, err
	}

	adminKey, adminCert, err := newAdminKeyAndCert(caCert, caPrivKey)
	if err != nil {
		return assets, err
	}

	assets = append(assets, []Asset{
		{Name: AssetPathCAKey, Data: tlsutil.EncodePrivateKeyPEM(caPrivKey)},
		{Name: AssetPathCACert, Data: tlsutil.EncodeCertificatePEM(caCert)},
		{Name: AssetPathAPIServerKey, Data: tlsutil.EncodePrivateKeyPEM(apiKey)},
		{Name: AssetPathAPIServerCert, Data: tlsutil.EncodeCertificatePEM(apiCert)},
		{Name: AssetPathServiceAccountPrivKey, Data: tlsutil.EncodePrivateKeyPEM(saPrivKey)},
		{Name: AssetPathAggregatorCA, Data: tlsutil.EncodeCertificatePEM(aggregatorCACert)},
		{Name: AssetPathFrontProxyClientCert, Data: tlsutil.EncodeCertificatePEM(frontProxyCert)},
		{Name: AssetPathFrontProxyClientKey, Data: tlsutil.EncodePrivateKeyPEM(frontProxyPrivKey)},
		{Name: AssetPathServiceAccountPubKey, Data: saPubKey},
		{Name: AssetPathAdminKey, Data: tlsutil.EncodePrivateKeyPEM(adminKey)},
		{Name: AssetPathAdminCert, Data: tlsutil.EncodeCertificatePEM(adminCert)},
	}...)
	return assets, nil
}

func newCACert() (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}

	config := tlsutil.CertConfig{
		CommonName:         "kube-ca",
		Organization:       []string{uuid.New()},
		OrganizationalUnit: []string{"bootkube"},
	}

	cert, err := tlsutil.NewSelfSignedCACertificate(config, key)
	if err != nil {
		return nil, nil, err
	}

	return key, cert, err
}

func newAPIKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, altNames tlsutil.AltNames) (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	altNames.DNSNames = append(altNames.DNSNames, []string{
		"kubernetes",
		"kubernetes.default",
		"kubernetes.default.svc",
		"kubernetes.default.svc.cluster.local",
	}...)

	config := tlsutil.CertConfig{
		CommonName:   "kube-apiserver",
		Organization: []string{orgSystemMasters},
		AltNames:     altNames,
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}

func newAdminKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey) (*rsa.PrivateKey, *x509.Certificate, error) {

	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	config := tlsutil.CertConfig{
		CommonName:   "admin",
		Organization: []string{orgSystemMasters},
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}

func newEtcdTLSAssets(etcdCACert, etcdClientCert *x509.Certificate, etcdClientKey *rsa.PrivateKey, caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, etcdServers []*url.URL) ([]Asset, error) {
	var assets []Asset
	if etcdCACert == nil {
		// Use the master CA to generate etcd assets.
		etcdCACert = caCert

		// Create an etcd client cert.
		var err error
		etcdClientKey, etcdClientCert, err = newEtcdKeyAndCert(caCert, caPrivKey, "etcd-client", etcdServers)
		if err != nil {
			return nil, err
		}

		// Create an etcd peer cert (not consumed by self-hosted components).
		etcdPeerKey, etcdPeerCert, err := newEtcdKeyAndCert(caCert, caPrivKey, "etcd-peer", etcdServers)
		if err != nil {
			return nil, err
		}
		etcdServerKey, etcdServerCert, err := newEtcdKeyAndCert(caCert, caPrivKey, "etcd-server", etcdServers)
		if err != nil {
			return nil, err
		}

		assets = append(assets, []Asset{
			{Name: AssetPathEtcdPeerCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
			{Name: AssetPathEtcdPeerKey, Data: tlsutil.EncodePrivateKeyPEM(etcdPeerKey)},
			{Name: AssetPathEtcdPeerCert, Data: tlsutil.EncodeCertificatePEM(etcdPeerCert)},
			{Name: AssetPathEtcdServerCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
			{Name: AssetPathEtcdServerKey, Data: tlsutil.EncodePrivateKeyPEM(etcdServerKey)},
			{Name: AssetPathEtcdServerCert, Data: tlsutil.EncodeCertificatePEM(etcdServerCert)},
		}...)
	}

	assets = append(assets, []Asset{
		{Name: AssetPathEtcdClientCA, Data: tlsutil.EncodeCertificatePEM(etcdCACert)},
		{Name: AssetPathEtcdClientKey, Data: tlsutil.EncodePrivateKeyPEM(etcdClientKey)},
		{Name: AssetPathEtcdClientCert, Data: tlsutil.EncodeCertificatePEM(etcdClientCert)},
	}...)

	return assets, nil
}

func newEtcdKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, commonName string, etcdServers []*url.URL) (*rsa.PrivateKey, *x509.Certificate, error) {
	addrs := make([]string, len(etcdServers))
	for i := range etcdServers {
		addrs[i] = etcdServers[i].Hostname()
	}
	return newKeyAndCert(caCert, caPrivKey, commonName, addrs)
}

func newKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, commonName string, addrs []string) (*rsa.PrivateKey, *x509.Certificate, error) {
	key, err := tlsutil.NewPrivateKey()
	if err != nil {
		return nil, nil, err
	}
	var altNames tlsutil.AltNames
	for _, addr := range addrs {
		if ip := net.ParseIP(addr); ip != nil {
			altNames.IPs = append(altNames.IPs, ip)
		} else {
			altNames.DNSNames = append(altNames.DNSNames, addr)
		}
	}
	config := tlsutil.CertConfig{
		CommonName:   commonName,
		Organization: []string{"etcd"},
		AltNames:     altNames,
	}
	cert, err := tlsutil.NewSignedCertificate(config, key, caCert, caPrivKey)
	if err != nil {
		return nil, nil, err
	}
	return key, cert, err
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This package implements the 32-bit cyclic redundancy check, or CRC-32, checksum.
// See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for information.
package crc32

import (
	"hash";
	"os";
)

// The size of a CRC-32 checksum in bytes.
const Size = 4;

// Predefined polynomials.
const (
	// Far and away the most common CRC-32 polynomial.
	// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, mpeg-2, ...
	IEEE = 0xedb88320;

	// Castagnoli's polynomial, used in iSCSI.
	// Has better error detection characteristics than IEEE.
	// http://dx.doi.org/10.1109/26.231911
	Castagnoli = 0x82f63b78;

	// Koopman's polynomial.
	// Also has better error detection characteristics than IEEE.
	// http://dx.doi.org/10.1109/DSN.2002.1028931
	Koopman = 0xeb31d82e;
)

// Table is a 256-word table representing the polynomial for efficient processing.
type Table [256]uint32

// MakeTable returns the Table constructed from the specified polynomial.
func MakeTable(poly uint32) *Table {
	t := new(Table);
	for i := 0; i < 256; i++ {
		crc := uint32(i);
		for j := 0; j < 8; j++ {
			if crc&1 == 1 {
				crc = (crc>>1) ^ poly;
			} else {
				crc >>= 1;
			}
		}
		t[i] = crc;
	}
	return t;
}

// IEEETable is the table for the IEEE polynomial.
var IEEETable = MakeTable(IEEE);

// digest represents the partial evaluation of a checksum.
type digest struct {
	crc uint32;
	tab *Table;
}

// New creates a new Hash computing the CRC-32 checksum
// using the polynomial represented by the Table.
func New(tab *Table) hash.Hash32 {
	return &digest{0, tab};
}

// NewIEEE creates a new Hash computing the CRC-32 checksum
// using the IEEE polynomial.
func NewIEEE() hash.Hash32 {
	return New(IEEETable);
}

func (d *digest) Size() int {
	return Size;
}

func (d *digest) Reset() {
	d.crc = 0;
}

func update(crc uint32, tab *Table, p []byte) uint32 {
	crc ^= 0xFFFFFFFF;
	for i := 0; i < len(p); i++ {
		crc = tab[byte(crc) ^ p[i]] ^ (crc >> 8);
	}
	crc ^= 0xFFFFFFFF;
	return crc;
}

func (d *digest) Write(p []byte) (n int, err os.Error) {
	d.crc = update(d.crc, d.tab, p);
	return len(p), nil;
}

func (d *digest) Sum32() uint32 {
	return d.crc
}

func (d *digest) Sum() []byte {
	p := make([]byte, 4);
	s := d.Sum32();
	p[0] = byte(s>>24);
	p[1] = byte(s>>16);
	p[2] = byte(s>>8);
	p[3] = byte(s);
	return p;
}

// Checksum returns the CRC-32 checksum of data
// using the polynomial represented by the Table.
func Checksum(data []byte, tab *Table) uint32 {
	return update(0, tab, data);
}

// ChecksumIEEE returns the CRC-32 checksum of data
// using the IEEE polynomial.
func ChecksumIEEE(data []byte) uint32 {
	return update(0, IEEETable, data);
}
<commit_msg>I guess I forgot there was a unary ^ operator.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This package implements the 32-bit cyclic redundancy check, or CRC-32, checksum.
// See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for information.
package crc32

import (
	"hash";
	"os";
)

// The size of a CRC-32 checksum in bytes.
const Size = 4;

// Predefined polynomials.
const (
	// Far and away the most common CRC-32 polynomial.
	// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, mpeg-2, ...
	IEEE = 0xedb88320;

	// Castagnoli's polynomial, used in iSCSI.
	// Has better error detection characteristics than IEEE.
	// http://dx.doi.org/10.1109/26.231911
	Castagnoli = 0x82f63b78;

	// Koopman's polynomial.
	// Also has better error detection characteristics than IEEE.
	// http://dx.doi.org/10.1109/DSN.2002.1028931
	Koopman = 0xeb31d82e;
)

// Table is a 256-word table representing the polynomial for efficient processing.
type Table [256]uint32

// MakeTable returns the Table constructed from the specified polynomial.
func MakeTable(poly uint32) *Table {
	t := new(Table);
	for i := 0; i < 256; i++ {
		crc := uint32(i);
		for j := 0; j < 8; j++ {
			if crc&1 == 1 {
				crc = (crc>>1) ^ poly;
			} else {
				crc >>= 1;
			}
		}
		t[i] = crc;
	}
	return t;
}

// IEEETable is the table for the IEEE polynomial.
var IEEETable = MakeTable(IEEE);

// digest represents the partial evaluation of a checksum.
type digest struct {
	crc uint32;
	tab *Table;
}

// New creates a new Hash computing the CRC-32 checksum
// using the polynomial represented by the Table.
func New(tab *Table) hash.Hash32 {
	return &digest{0, tab};
}

// NewIEEE creates a new Hash computing the CRC-32 checksum
// using the IEEE polynomial.
func NewIEEE() hash.Hash32 {
	return New(IEEETable);
}

func (d *digest) Size() int {
	return Size;
}

func (d *digest) Reset() {
	d.crc = 0;
}

func update(crc uint32, tab *Table, p []byte) uint32 {
	crc = ^crc;
	for i := 0; i < len(p); i++ {
		crc = tab[byte(crc) ^ p[i]] ^ (crc >> 8);
	}
	return ^crc;
}

func (d *digest) Write(p []byte) (n int, err os.Error) {
	d.crc = update(d.crc, d.tab, p);
	return len(p), nil;
}

func (d *digest) Sum32() uint32 {
	return d.crc
}

func (d *digest) Sum() []byte {
	p := make([]byte, 4);
	s := d.Sum32();
	p[0] = byte(s>>24);
	p[1] = byte(s>>16);
	p[2] = byte(s>>8);
	p[3] = byte(s);
	return p;
}

// Checksum returns the CRC-32 checksum of data
// using the polynomial represented by the Table.
func Checksum(data []byte, tab *Table) uint32 {
	return update(0, tab, data);
}

// ChecksumIEEE returns the CRC-32 checksum of data
// using the IEEE polynomial.
func ChecksumIEEE(data []byte) uint32 {
	return update(0, IEEETable, data);
}
<|endoftext|>


<commit_before>package http

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/cloudevents/conformance/pkg/event"
)

func addHeader(req *http.Request, key, value string) {
	value = strings.TrimSpace(value)
	if value != "" {
		req.Header.Add(key, value)
	}
}

func EventToRequest(url string, event event.Event) (*http.Request, error) {

	req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(event.Data)))
	if err != nil {
		return nil, err
	}

	// CloudEvents attributes.
	addHeader(req, "ce-specversion", event.Attributes.SpecVersion)
	addHeader(req, "ce-type", event.Attributes.Type)
	addHeader(req, "ce-time", event.Attributes.Time)
	addHeader(req, "ce-id", event.Attributes.ID)
	addHeader(req, "ce-source", event.Attributes.Source)
	addHeader(req, "ce-subject", event.Attributes.Subject)
	addHeader(req, "ce-schemaurl", event.Attributes.SchemaURL)
	addHeader(req, "Content-Type", event.Attributes.DataContentType)
	addHeader(req, "ce-datacontentencoding", event.Attributes.DataContentEncoding)

	// CloudEvents attribute extensions.
	for k, v := range event.Attributes.Extensions {
		addHeader(req, "ce-"+k, v)
	}

	// Transport extensions.
	for k, v := range event.TransportExtensions {
		addHeader(req, k, v)
	}

	return req, nil
}

func RequestToEvent(req *http.Request) (*event.Event, error) {
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}
	_ = body

	event := &event.Event{
		Data: string(body),
	}

	// CloudEvents attributes.
	event.Attributes.SpecVersion = req.Header.Get("ce-specversion")
	req.Header.Del("ce-specversion")
	event.Attributes.Type = req.Header.Get("ce-type")
	req.Header.Del("ce-type")
	event.Attributes.Time = req.Header.Get("ce-time")
	req.Header.Del("ce-time")
	event.Attributes.ID = req.Header.Get("ce-id")
	req.Header.Del("ce-id")
	event.Attributes.Source = req.Header.Get("ce-source")
	req.Header.Del("ce-source")
	event.Attributes.Subject = req.Header.Get("ce-subject")
	req.Header.Del("ce-subject")
	event.Attributes.SchemaURL = req.Header.Get("ce-schemaurl")
	req.Header.Del("ce-schemaurl")
	event.Attributes.DataContentType = req.Header.Get("Content-Type")
	req.Header.Del("Content-Type")
	event.Attributes.DataContentEncoding = req.Header.Get("ce-datacontentencoding")
	req.Header.Del("ce-datacontentencoding")

	// CloudEvents attribute extensions.
	event.Attributes.Extensions = make(map[string]string)
	for k, _ := range req.Header {
		if strings.HasPrefix(strings.ToLower(k), "ce-") {
			event.Attributes.Extensions[k] = req.Header.Get(k)
			req.Header.Del(k)
		}
	}

	// Transport extensions.
	event.TransportExtensions = make(map[string]string)
	for k, _ := range req.Header {
		event.TransportExtensions[k] = req.Header.Get(k)
		req.Header.Del(k)
	}

	return event, nil
}

func Do(req *http.Request) error {
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return fmt.Errorf("expected 200 level response, got %s", resp.Status)
	}

	// TODO might want something from resp.
	return nil
}
<commit_msg>need to trim off ce- from header keys. (#9)<commit_after>package http

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/cloudevents/conformance/pkg/event"
)

func addHeader(req *http.Request, key, value string) {
	value = strings.TrimSpace(value)
	if value != "" {
		req.Header.Add(key, value)
	}
}

func EventToRequest(url string, event event.Event) (*http.Request, error) {

	req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(event.Data)))
	if err != nil {
		return nil, err
	}

	// CloudEvents attributes.
	addHeader(req, "ce-specversion", event.Attributes.SpecVersion)
	addHeader(req, "ce-type", event.Attributes.Type)
	addHeader(req, "ce-time", event.Attributes.Time)
	addHeader(req, "ce-id", event.Attributes.ID)
	addHeader(req, "ce-source", event.Attributes.Source)
	addHeader(req, "ce-subject", event.Attributes.Subject)
	addHeader(req, "ce-schemaurl", event.Attributes.SchemaURL)
	addHeader(req, "Content-Type", event.Attributes.DataContentType)
	addHeader(req, "ce-datacontentencoding", event.Attributes.DataContentEncoding)

	// CloudEvents attribute extensions.
	for k, v := range event.Attributes.Extensions {
		addHeader(req, "ce-"+k, v)
	}

	// Transport extensions.
	for k, v := range event.TransportExtensions {
		addHeader(req, k, v)
	}

	return req, nil
}

func RequestToEvent(req *http.Request) (*event.Event, error) {
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}
	_ = body

	event := &event.Event{
		Data: string(body),
	}

	// CloudEvents attributes.
	event.Attributes.SpecVersion = req.Header.Get("ce-specversion")
	req.Header.Del("ce-specversion")
	event.Attributes.Type = req.Header.Get("ce-type")
	req.Header.Del("ce-type")
	event.Attributes.Time = req.Header.Get("ce-time")
	req.Header.Del("ce-time")
	event.Attributes.ID = req.Header.Get("ce-id")
	req.Header.Del("ce-id")
	event.Attributes.Source = req.Header.Get("ce-source")
	req.Header.Del("ce-source")
	event.Attributes.Subject = req.Header.Get("ce-subject")
	req.Header.Del("ce-subject")
	event.Attributes.SchemaURL = req.Header.Get("ce-schemaurl")
	req.Header.Del("ce-schemaurl")
	event.Attributes.DataContentType = req.Header.Get("Content-Type")
	req.Header.Del("Content-Type")
	event.Attributes.DataContentEncoding = req.Header.Get("ce-datacontentencoding")
	req.Header.Del("ce-datacontentencoding")

	// CloudEvents attribute extensions.
	event.Attributes.Extensions = make(map[string]string)
	for k, _ := range req.Header {
		if strings.HasPrefix(strings.ToLower(k), "ce-") {
			event.Attributes.Extensions[k[len("ce-"):]] = req.Header.Get(k)
			req.Header.Del(k)
		}
	}

	// Transport extensions.
	event.TransportExtensions = make(map[string]string)
	for k, _ := range req.Header {
		event.TransportExtensions[k] = req.Header.Get(k)
		req.Header.Del(k)
	}

	return event, nil
}

func Do(req *http.Request) error {
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return fmt.Errorf("expected 200 level response, got %s", resp.Status)
	}

	// TODO might want something from resp.
	return nil
}
<|endoftext|>


<commit_before>package kube

import (
	"fmt"

	"k8s.io/api/extensions/v1beta1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	"github.com/jetstack-experimental/navigator/pkg/apis/navigator"
)

var thirdPartyResource = &v1beta1.ThirdPartyResource{
	ObjectMeta: metav1.ObjectMeta{
		Name: "elasticsearch-cluster." + navigator.GroupName,
	},
	Description: "A specification of an Elasticsearch cluster",
	Versions: []v1beta1.APIVersion{
		{
			Name: "v1alpha1",
		},
	},
}

// Config will return a rest.Config for communicating with the Kubernetes API server.
// If apiServerHost is specified, a config without authentication that is configured
// to talk to the apiServerHost URL will be returned. Else, the in-cluster config will be loaded,
// and failing this, the config will be loaded from the users local kubeconfig directory
func Config(apiServerHost string) (*rest.Config, error) {
	var err error
	var cfg *rest.Config

	if len(apiServerHost) > 0 {
		cfg = new(rest.Config)
		cfg.Host = apiServerHost
	} else if cfg, err = rest.InClusterConfig(); err != nil {
		apiCfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()

		if err != nil {
			return nil, fmt.Errorf("error loading cluster config: %s", err.Error())
		}

		cfg, err = clientcmd.NewDefaultClientConfig(*apiCfg, &clientcmd.ConfigOverrides{}).ClientConfig()

		if err != nil {
			return nil, fmt.Errorf("error loading cluster client config: %s", err.Error())
		}
	}

	return cfg, nil
}

// EnsureTPR will ensure that the appropriate ThirdPartyResources exist in
// the target Kubernetes cluster
func EnsureTPR(cl *kubernetes.Clientset) error {
	_, err := cl.Extensions().ThirdPartyResources().Create(thirdPartyResource)

	if err != nil {
		if !errors.IsAlreadyExists(err) {
			return err
		}
	}

	return nil
}
<commit_msg>Remove old functions<commit_after>package kube

import (
	"fmt"

	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

// Config will return a rest.Config for communicating with the Kubernetes API server.
// If apiServerHost is specified, a config without authentication that is configured
// to talk to the apiServerHost URL will be returned. Else, the in-cluster config will be loaded,
// and failing this, the config will be loaded from the users local kubeconfig directory
func Config(apiServerHost string) (*rest.Config, error) {
	var err error
	var cfg *rest.Config

	if len(apiServerHost) > 0 {
		cfg = new(rest.Config)
		cfg.Host = apiServerHost
	} else if cfg, err = rest.InClusterConfig(); err != nil {
		apiCfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()

		if err != nil {
			return nil, fmt.Errorf("error loading cluster config: %s", err.Error())
		}

		cfg, err = clientcmd.NewDefaultClientConfig(*apiCfg, &clientcmd.ConfigOverrides{}).ClientConfig()

		if err != nil {
			return nil, fmt.Errorf("error loading cluster client config: %s", err.Error())
		}
	}

	return cfg, nil
}
<|endoftext|>