<commit_before>package main

import (
	"os"
	"fmt"
	"crypto/sha256"
	"flag"
	"log"
	"encoding/hex"
)

const (
	BLOCK_SIZE = 1024
	BUFFER_SIZE = 1024 * BLOCK_SIZE
	HASH_SIZE = sha256.Size
)

var (
	inputFileName = flag.String("i", "", "Specify the input file name.")
	outputFileName = flag.String("o", "", "Specify the output file name.")
)

func EncodeAndHash(inputFileName, outputFileName string) ([]byte, error) {
	file, err := os.Open(inputFileName)
	if err != nil {
		return nil, fmt.Errorf("Open input file %s failed with:%v\n", inputFileName, err)
	}

	defer file.Close()

	desFile, err := os.Create(outputFileName)
	if err != nil {
		return nil, fmt.Errorf("Create output file %s failed with: %v\n", outputFileName, err)
	}

	defer  desFile.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		return nil, fmt.Errorf("Get file state failed with: %v\n", err)
	}

	srcLen := fileInfo.Size()
	blockSize := srcLen % BLOCK_SIZE
	bufferSize := BUFFER_SIZE + blockSize
	if srcLen < bufferSize {
		bufferSize = srcLen
	}

	// move pointer to the end
	_, err = file.Seek(-bufferSize, 2)
	if err != nil {
		return nil, fmt.Errorf("Seek file failed with: %v\n", err)
	}
	dataBuff := make([]byte, bufferSize)
	desBuff := make([]byte, (bufferSize-blockSize)/BLOCK_SIZE * (BLOCK_SIZE+HASH_SIZE) + blockSize)
	var hashValue []byte = nil

	if blockSize == 0 {
		blockSize = BLOCK_SIZE
	}

	for {
		readedBytes, err := file.Read(dataBuff)
		if err != nil {
			return nil, fmt.Errorf("Read file failed with: %v\n", err)
		} else if readedBytes != len(dataBuff) {
			return nil, fmt.Errorf("Readed bytes is not enough: %d < %d\n", readedBytes, len(dataBuff))
		}
		//process dataBuff
		hashValue = processBlocks(dataBuff, desBuff, hashValue, blockSize)
		blockSize = BLOCK_SIZE
		bufferSize = BUFFER_SIZE

		srcLen -= (int64)(readedBytes)

		//write to dist file
		_, err = desFile.Seek((srcLen/BLOCK_SIZE)*(BLOCK_SIZE+HASH_SIZE), 0)
		if err != nil {
			return nil, fmt.Errorf("Seek dst file failed with: %v\n", err)
		}

		writedBytes, err := desFile.Write(desBuff)
		if err != nil || writedBytes < len(desBuff) {
			return nil, fmt.Errorf("Write to dst file failed with: %v. Or written bytes are not enough: %d < %d\n", err, writedBytes, len(desBuff))
		}

		//read next buffer
		if srcLen <= 0 {
			break
		} else if srcLen < bufferSize {
			bufferSize = srcLen
		}
		dataBuff = dataBuff[:bufferSize]

		_, err = file.Seek(-(int64)(readedBytes)-bufferSize, 1)
		if err != nil {
			return nil, fmt.Errorf("Seek file failed with: %v\n", err)
		}
	}

	return hashValue, nil
}

func DecodeAndVerify(inputFileName string, h0 []byte) error {
	return nil
}

func processBlocks(srcBuff, desBuff, hashValue []byte, blockSize int64) []byte {
//	log.Print(srcBuff, desBuff, hashValue, blockSize)
//	log.Print("len srcBuff=", len(srcBuff), "len desBuff=", len(desBuff))
	srcLen := (int64)(len(srcBuff))
//	log.Print("srcLen=",srcLen)
	desOffset := (srcLen-blockSize)/BLOCK_SIZE * (BLOCK_SIZE+HASH_SIZE)
//	log.Print("desOffset=",desOffset)
	if hashValue == nil {
		desBuff = desBuff[:desOffset+blockSize]
	} else {
		desBuff = desBuff[:desOffset+blockSize+HASH_SIZE]
	}
	for i:=srcLen-blockSize; i>=0; i-=BLOCK_SIZE {
//		log.Print("i=",i,",desOffset=",desOffset)
		copy(desBuff[desOffset:desOffset+blockSize], srcBuff[i:i+blockSize])
		if hashValue != nil {
			copy(desBuff[desOffset+blockSize:desOffset+blockSize+HASH_SIZE],hashValue)
			res := sha256.Sum256(desBuff[desOffset:desOffset+blockSize+HASH_SIZE])
			hashValue = res[:]
//			log.Print("desBuff=", desBuff[desOffset:desOffset+blockSize+HASH_SIZE], "len=", len(desBuff[desOffset:desOffset+blockSize+HASH_SIZE]))
//			log.Print("hashValue=",hashValue)
		} else {
			res := sha256.Sum256(desBuff[desOffset:desOffset+blockSize])
			hashValue = res[:]
//			log.Print("desBuff=", desBuff[desOffset:desOffset+blockSize], "len=", len(desBuff[desOffset:desOffset+blockSize]))
//			log.Print("hashValue=",hashValue)
		}

		desOffset -= (BLOCK_SIZE+HASH_SIZE)
		blockSize = BLOCK_SIZE
	}

	return hashValue
}

func main() {
	flag.Parse()

	if *inputFileName == "" || *outputFileName == "" {
		fmt.Printf("%s <-i input file name> <-o output file name>\n", os.Args[0])
		flag.PrintDefaults()
		return
	}

	hashValue, err := EncodeAndHash(*inputFileName, *outputFileName)
	if err != nil {
		log.Print(err)
	} else {
		log.Print(hex.EncodeToString(hashValue))
	}
}
<commit_msg>week3完成验证部分，并修复了bug。<commit_after>package main

import (
	"os"
	"fmt"
	"crypto/sha256"
	"flag"
	"log"
	"encoding/hex"
	"io"
	"math"
)

const (
	BUFFER_BLOCKS = 1024
	BLOCK_SIZE = 1024
	HASH_SIZE = sha256.Size
	HASHED_BLOCK_SIZE = BLOCK_SIZE + HASH_SIZE

	BUFFER_SIZE = BUFFER_BLOCKS * BLOCK_SIZE
)

var (
	inputFileName = flag.String("i", "", "Specify the input file name.")
	outputFileName = flag.String("o", "", "Specify the output file name.")
	verifyFlag = flag.String("v", "", "Hash0 value in hex")
)

func EncodeAndHash(inputFileName, outputFileName string) ([]byte, error) {
	file, err := os.Open(inputFileName)
	if err != nil {
		return nil, fmt.Errorf("Open input file %s failed with:%v\n", inputFileName, err)
	}

	defer file.Close()

	desFile, err := os.Create(outputFileName)
	if err != nil {
		return nil, fmt.Errorf("Create output file %s failed with: %v\n", outputFileName, err)
	}

	defer  desFile.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		return nil, fmt.Errorf("Get file state failed with: %v\n", err)
	}

	srcLen := fileInfo.Size()
	blockSize := srcLen % BLOCK_SIZE
	bufferSize := BUFFER_SIZE + blockSize
	if srcLen < bufferSize {
		bufferSize = srcLen
	}

	// move pointer to the end
	_, err = file.Seek(-bufferSize, 2)
	if err != nil {
		return nil, fmt.Errorf("Seek file failed with: %v\n", err)
	}
	dataBuff := make([]byte, bufferSize)
	desBuff := make([]byte, (bufferSize-blockSize)/BLOCK_SIZE * (BLOCK_SIZE+HASH_SIZE) + blockSize)
	var hashValue []byte = nil

	if blockSize == 0 {
		blockSize = BLOCK_SIZE
	}

	for {
		readedBytes, err := file.Read(dataBuff)
		if err != nil {
			return nil, fmt.Errorf("Read file failed with: %v\n", err)
		} else if readedBytes != len(dataBuff) {
			return nil, fmt.Errorf("Readed bytes is not enough: %d < %d\n", readedBytes, len(dataBuff))
		}
		//process dataBuff
		hashValue = processBlocks(dataBuff, &desBuff, hashValue, blockSize)
		blockSize = BLOCK_SIZE
		bufferSize = BUFFER_SIZE

		srcLen -= (int64)(readedBytes)

		//write to dist file
		_, err = desFile.Seek((srcLen/BLOCK_SIZE)*(BLOCK_SIZE+HASH_SIZE), 0)
	//	log.Printf("Seek pos:%d, desBuff len:%d\ndes Buff:%v\n", (srcLen/BLOCK_SIZE)*(BLOCK_SIZE+HASH_SIZE),
	//	len(desBuff), desBuff)
		if err != nil {
			return nil, fmt.Errorf("Seek dst file failed with: %v\n", err)
		}

		writedBytes, err := desFile.Write(desBuff)
		if err != nil || writedBytes < len(desBuff) {
			return nil, fmt.Errorf("Write to dst file failed with: %v. Or written bytes are not enough: %d < %d\n", err, writedBytes, len(desBuff))
		}

		//read next buffer
		if srcLen <= 0 {
			break
		} else if srcLen < bufferSize {
			bufferSize = srcLen
		}
		dataBuff = dataBuff[:bufferSize]

		_, err = file.Seek(-(int64)(readedBytes)-bufferSize, 1)
		if err != nil {
			return nil, fmt.Errorf("Seek file failed with: %v\n", err)
		}
	}

	return hashValue, nil
}

func DecodeAndVerify(inputFileName, outputFileName string, hashValue *[HASH_SIZE]byte) error {
	file, err := os.Open(inputFileName)
	if err != nil {
		return fmt.Errorf("Open input file %s failed with:%v\n", inputFileName, err)
	}

	defer file.Close()

	desFile, err := os.Create(outputFileName)
	if err != nil {
		return fmt.Errorf("Create output file %s failed with: %v\n", outputFileName, err)
	}

	defer desFile.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		return fmt.Errorf("Get file state failed with: %v\n", err)
	}

	srcLen := fileInfo.Size()
	srcBlocks := int64(math.Ceil(float64(srcLen) / HASHED_BLOCK_SIZE))

	var bufferBlocks int64 = BUFFER_BLOCKS
	if bufferBlocks > srcBlocks {
		bufferBlocks = srcBlocks
	}

	srcBuff := make([]byte, HASHED_BLOCK_SIZE * bufferBlocks)
	desBuff := make([]byte, BLOCK_SIZE * bufferBlocks)

	var blockIndex int = 0
	for {
		readCount, err := file.Read(srcBuff)
		if err != nil {
			if err == io.EOF && readCount == 0 {
				// read finished
				return nil
			} else {
				return fmt.Errorf("Read from input file failed with: %v\n", err)
			}
		} else if readCount < len(srcBuff) {
			if srcLen >= int64(len(srcBuff)) {
				return fmt.Errorf("Not enough bytes read from file: %d < %d\n", readCount, len(srcBuff))
			} else if int64(readCount) == srcLen {
				srcBuff = srcBuff[:readCount]
			} else {
				return fmt.Errorf("Not enough bytes read from file: %d < %d\n", readCount, srcLen)
			}
		}

		srcLen -= int64(readCount)
		err = verifyBlocks(srcBuff, &desBuff, hashValue, &blockIndex)
		if err != nil {
			return err
		}

		writeCount, err := desFile.Write(desBuff)
		if err != nil || writeCount != len(desBuff) {
			return fmt.Errorf("Write to dst file failed with: %v. Or written bytes are not enough: %d < %d\n", err, writeCount, len(desBuff))
		}
	}
}

func verifyBlocks(srcBuff []byte, desBuff *[]byte, hashValue *[HASH_SIZE]byte, blockIndex *int) error {
	remainedSize := len(srcBuff)
	i := 0
	j := 0
	var verifyBlockSize int
	var lastBlock bool
	for remainedSize > 0 {
		if remainedSize >= HASHED_BLOCK_SIZE {
			verifyBlockSize = HASHED_BLOCK_SIZE
			lastBlock = false
		} else {
			verifyBlockSize = remainedSize
			lastBlock = true
		}

		if sha256.Sum256(srcBuff[i:i+verifyBlockSize]) == *hashValue {
			if lastBlock {
				copy((*desBuff)[j:j+verifyBlockSize], srcBuff[i:i+verifyBlockSize])
				j += verifyBlockSize
			} else {
				copy((*desBuff)[j:j+BLOCK_SIZE], srcBuff[i:i+BLOCK_SIZE])
				copy((*hashValue)[:], srcBuff[i+BLOCK_SIZE:i+HASHED_BLOCK_SIZE])
				j += BLOCK_SIZE
			}

			*blockIndex ++
			remainedSize -= verifyBlockSize
		} else {
			return fmt.Errorf("Verify failed at block index %d\n", *blockIndex)
		}

		i += HASHED_BLOCK_SIZE
	}

	*desBuff = (*desBuff)[:j]

	return nil
}

func processBlocks(srcBuff []byte, desBuff *[]byte, hashValue []byte, blockSize int64) []byte {
//	log.Print(srcBuff, desBuff, hashValue, blockSize)
//	log.Print("len srcBuff=", len(srcBuff), "len desBuff=", len(desBuff))
	srcLen := (int64)(len(srcBuff))
//	log.Print("srcLen=",srcLen)
	desOffset := (srcLen-blockSize)/BLOCK_SIZE * (BLOCK_SIZE+HASH_SIZE)
//	log.Print("desOffset=",desOffset)
	if hashValue == nil {
		*desBuff = (*desBuff)[:desOffset+blockSize]
	} else {
		*desBuff = (*desBuff)[:desOffset+blockSize+HASH_SIZE]
	}
	for i:=srcLen-blockSize; i>=0; i-=BLOCK_SIZE {
//		log.Print("i=",i,",desOffset=",desOffset)
		copy((*desBuff)[desOffset:desOffset+blockSize], srcBuff[i:i+blockSize])
		if hashValue != nil {
			copy((*desBuff)[desOffset+blockSize:desOffset+blockSize+HASH_SIZE],hashValue)
			res := sha256.Sum256((*desBuff)[desOffset:desOffset+blockSize+HASH_SIZE])
			hashValue = res[:]
//			log.Print("desBuff=", desBuff[desOffset:desOffset+blockSize+HASH_SIZE], "len=", len(desBuff[desOffset:desOffset+blockSize+HASH_SIZE]))
//			log.Print("hashValue=",hashValue)
		} else {
			res := sha256.Sum256((*desBuff)[desOffset:desOffset+blockSize])
			hashValue = res[:]
//			log.Print("desBuff=", desBuff[desOffset:desOffset+blockSize], "len=", len(desBuff[desOffset:desOffset+blockSize]))
//			log.Print("hashValue=",hashValue)
		}

		desOffset -= (BLOCK_SIZE+HASH_SIZE)
		blockSize = BLOCK_SIZE
	}

	return hashValue
}

func main() {
	flag.Parse()

	if *inputFileName == "" || *outputFileName == "" {
		fmt.Printf("%s <-i input file name> <-o output file name> [-v hash value]\n", os.Args[0])
		flag.PrintDefaults()
		return
	}

	bVerify := false

	for _,v := range os.Args {
		if v == "-v" {
			bVerify = true
		}
	}

	var hashValue0 [HASH_SIZE]byte

	if bVerify {
		if *verifyFlag != "" {
			hexValue, err := hex.DecodeString(*verifyFlag)
			if err != nil {
				fmt.Printf("Decodex hex string %s failed with: %v\n", *verifyFlag, err)
				return
			} else if len(hexValue) != HASH_SIZE {
				fmt.Printf("The length of hash value is not %d\n", HASH_SIZE)
				return
			}

			copy(hashValue0[:], hexValue)
			bVerify = true
		} else {
			fmt.Print("Hash value can not be empty.\n")
			return
		}
	}

	if bVerify {
		err := DecodeAndVerify(*inputFileName, *outputFileName, &hashValue0)
		if err != nil {
			log.Print(err)
		} else {
			log.Print("Verify and decode succeeded.\n")
		}
	} else {
		hashValue, err := EncodeAndHash(*inputFileName, *outputFileName)
		if err != nil {
			log.Print(err)
		} else {
			log.Print(hex.EncodeToString(hashValue))
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package build

import (
	pathpkg "path"
	"path/filepath"
	"strings"
	"unicode"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
)

// An Instance describes the collection of files, and its imports, necessary
// to build a CUE instance.
//
// A typical way to create an Instance is to use the loader package.
type Instance struct {
	ctxt *Context

	BuildFiles    []*File // files to be inclduded in the build
	IgnoredFiles  []*File // files excluded for this build
	OrphanedFiles []*File // recognized file formats not part of any build
	InvalidFiles  []*File // could not parse these files
	UnknownFiles  []*File // unknown file types

	// Files contains the AST for all files part of this instance.
	// TODO: the intent is to deprecate this in favor of BuildFiles.
	Files []*ast.File

	loadFunc LoadFunc
	done     bool

	// Scope is another instance that may be used to resolve any unresolved
	// reference of this instance. For instance, tool and test instances
	// may refer to top-level fields in their package scope.
	Scope *Instance

	// PkgName is the name specified in the package clause.
	PkgName string
	hasName bool

	// ImportPath returns the unique path to identify an imported instance.
	//
	// Instances created with NewInstance do not have an import path.
	ImportPath string

	// Imports lists the instances of all direct imports of this instance.
	Imports []*Instance

	// The Err for loading this package or nil on success. This does not
	// include any errors of dependencies. Incomplete will be set if there
	// were any errors in dependencies.
	Err errors.Error

	// Incomplete reports whether any dependencies had an error.
	Incomplete bool

	parent *Instance // TODO: for cycle detection

	// The following fields are for informative purposes and are not used by
	// the cue package to create an instance.

	// ImportComment is the path in the import comment on the package statement.
	ImportComment string

	// DisplayPath is a user-friendly version of the package or import path.
	DisplayPath string

	// Dir is the package directory. Note that a package may also include files
	// from ancestor directories, up to the module file.
	Dir string

	// Module defines the module name of a package. It must be defined if
	// the packages within the directory structure of the module are to be
	// imported by other packages, including those within the module.
	Module string

	// Root is the root of the directory hierarchy, it may be "" if this an
	// instance has no imports.
	// If Module != "", this corresponds to the module root.
	// Root/pkg is the directory that holds third-party packages.
	Root string // root directory of hierarchy ("" if unknown)

	// AllTags are the build tags that can influence file selection in this
	// directory.
	AllTags []string

	Standard bool // Is a builtin package
	User     bool // True if package was created from individual files.

	// Deprecated: use BuildFiles
	CUEFiles []string // .cue source files
	// Deprecated: use BuildFiles and OrphanedFiles
	DataFiles []string // recognized data files (.json, .yaml, etc.)

	// The intent is to also deprecate the following fields in favor of
	// IgnoredFiles and UnknownFiles.
	TestCUEFiles    []string // .cue test files (_test.cue)
	ToolCUEFiles    []string // .cue tool files (_tool.cue)
	IgnoredCUEFiles []string // .cue source files ignored for this build
	InvalidCUEFiles []string // .cue source files with detected problems (parse error, wrong package name, and so on)

	// Dependencies
	ImportPaths []string
	ImportPos   map[string][]token.Pos // line information for Imports

	Deps       []string
	DepsErrors []error
	Match      []string
}

// Dependencies reports all Instances on which this instance depends.
func (inst *Instance) Dependencies() []*Instance {
	// TODO: as cyclic dependencies are not allowed, we could just not check.
	// Do for safety now and remove later if needed.
	return appendDependencies(nil, inst, map[*Instance]bool{})
}

func appendDependencies(a []*Instance, inst *Instance, done map[*Instance]bool) []*Instance {
	for _, d := range inst.Imports {
		if done[d] {
			continue
		}
		a = append(a, d)
		done[d] = true
		a = appendDependencies(a, d, done)
	}
	return a
}

// Abs converts relative path used in the one of the file fields to an
// absolute one.
func (inst *Instance) Abs(path string) string {
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(inst.Root, path)
}

func (inst *Instance) setPkg(pkg string) bool {
	if !inst.hasName {
		inst.hasName = true
		inst.PkgName = pkg
		return true
	}
	return false
}

// ReportError reports an error processing this instance.
func (inst *Instance) ReportError(err errors.Error) {
	inst.Err = errors.Append(inst.Err, err)
}

// Context defines the build context for this instance. All files defined
// in Syntax as well as all imported instances must be created using the
// same build context.
func (inst *Instance) Context() *Context {
	return inst.ctxt
}

func (inst *Instance) parse(name string, src interface{}) (*ast.File, error) {
	if inst.ctxt != nil && inst.ctxt.parseFunc != nil {
		return inst.ctxt.parseFunc(name, src)
	}
	return parser.ParseFile(name, src, parser.ParseComments)
}

// LookupImport defines a mapping from an ImportSpec's ImportPath to Instance.
func (inst *Instance) LookupImport(path string) *Instance {
	path = inst.expandPath(path)
	for _, inst := range inst.Imports {
		if inst.ImportPath == path {
			return inst
		}
	}
	return nil
}

func (inst *Instance) addImport(imp *Instance) {
	for _, inst := range inst.Imports {
		if inst.ImportPath == imp.ImportPath {
			if inst != imp {
				panic("import added multiple times with different instances")
			}
			return
		}
	}
	inst.Imports = append(inst.Imports, imp)
}

// AddFile adds the file with the given name to the list of files for this
// instance. The file may be loaded from the cache of the instance's context.
// It does not process the file's imports. The package name of the file must
// match the package name of the instance.
func (inst *Instance) AddFile(filename string, src interface{}) error {
	file, err := inst.parse(filename, src)
	if err != nil {
		// should always be an errors.List, but just in case.
		err := errors.Promote(err, "error adding file")
		inst.ReportError(err)
		return err
	}

	return inst.AddSyntax(file)
}

// AddSyntax adds the given file to list of files for this instance. The package
// name of the file must match the package name of the instance.
func (inst *Instance) AddSyntax(file *ast.File) errors.Error {
	astutil.Resolve(file, func(pos token.Pos, msg string, args ...interface{}) {
		inst.Err = errors.Append(inst.Err, errors.Newf(pos, msg, args...))
	})
	_, pkg, pos := internal.PackageInfo(file)
	if pkg != "" && pkg != "_" && !inst.setPkg(pkg) && pkg != inst.PkgName {
		err := errors.Newf(pos,
			"package name %q conflicts with previous package name %q",
			pkg, inst.PkgName)
		inst.ReportError(err)
		return err
	}
	inst.Files = append(inst.Files, file)
	return nil
}

func (inst *Instance) expandPath(path string) string {
	isLocal := IsLocalImport(path)
	if isLocal {
		path = dirToImportPath(filepath.Join(inst.Dir, path))
	}
	return path
}

// dirToImportPath returns the pseudo-import path we use for a package
// outside the CUE path. It begins with _/ and then contains the full path
// to the directory. If the package lives in c:\home\gopher\my\pkg then
// the pseudo-import path is _/c_/home/gopher/my/pkg.
// Using a pseudo-import path like this makes the ./ imports no longer
// a special case, so that all the code to deal with ordinary imports works
// automatically.
func dirToImportPath(dir string) string {
	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
}

func makeImportValid(r rune) rune {
	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
		return '_'
	}
	return r
}

// IsLocalImport reports whether the import path is
// a local import path, like ".", "..", "./foo", or "../foo".
func IsLocalImport(path string) bool {
	return path == "." || path == ".." ||
		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
}
<commit_msg>cue/build: fix typo reference to cue/load package<commit_after>// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package build

import (
	pathpkg "path"
	"path/filepath"
	"strings"
	"unicode"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
)

// An Instance describes the collection of files, and its imports, necessary
// to build a CUE instance.
//
// A typical way to create an Instance is to use the cue/load package.
type Instance struct {
	ctxt *Context

	BuildFiles    []*File // files to be inclduded in the build
	IgnoredFiles  []*File // files excluded for this build
	OrphanedFiles []*File // recognized file formats not part of any build
	InvalidFiles  []*File // could not parse these files
	UnknownFiles  []*File // unknown file types

	// Files contains the AST for all files part of this instance.
	// TODO: the intent is to deprecate this in favor of BuildFiles.
	Files []*ast.File

	loadFunc LoadFunc
	done     bool

	// Scope is another instance that may be used to resolve any unresolved
	// reference of this instance. For instance, tool and test instances
	// may refer to top-level fields in their package scope.
	Scope *Instance

	// PkgName is the name specified in the package clause.
	PkgName string
	hasName bool

	// ImportPath returns the unique path to identify an imported instance.
	//
	// Instances created with NewInstance do not have an import path.
	ImportPath string

	// Imports lists the instances of all direct imports of this instance.
	Imports []*Instance

	// The Err for loading this package or nil on success. This does not
	// include any errors of dependencies. Incomplete will be set if there
	// were any errors in dependencies.
	Err errors.Error

	// Incomplete reports whether any dependencies had an error.
	Incomplete bool

	parent *Instance // TODO: for cycle detection

	// The following fields are for informative purposes and are not used by
	// the cue package to create an instance.

	// ImportComment is the path in the import comment on the package statement.
	ImportComment string

	// DisplayPath is a user-friendly version of the package or import path.
	DisplayPath string

	// Dir is the package directory. Note that a package may also include files
	// from ancestor directories, up to the module file.
	Dir string

	// Module defines the module name of a package. It must be defined if
	// the packages within the directory structure of the module are to be
	// imported by other packages, including those within the module.
	Module string

	// Root is the root of the directory hierarchy, it may be "" if this an
	// instance has no imports.
	// If Module != "", this corresponds to the module root.
	// Root/pkg is the directory that holds third-party packages.
	Root string // root directory of hierarchy ("" if unknown)

	// AllTags are the build tags that can influence file selection in this
	// directory.
	AllTags []string

	Standard bool // Is a builtin package
	User     bool // True if package was created from individual files.

	// Deprecated: use BuildFiles
	CUEFiles []string // .cue source files
	// Deprecated: use BuildFiles and OrphanedFiles
	DataFiles []string // recognized data files (.json, .yaml, etc.)

	// The intent is to also deprecate the following fields in favor of
	// IgnoredFiles and UnknownFiles.
	TestCUEFiles    []string // .cue test files (_test.cue)
	ToolCUEFiles    []string // .cue tool files (_tool.cue)
	IgnoredCUEFiles []string // .cue source files ignored for this build
	InvalidCUEFiles []string // .cue source files with detected problems (parse error, wrong package name, and so on)

	// Dependencies
	ImportPaths []string
	ImportPos   map[string][]token.Pos // line information for Imports

	Deps       []string
	DepsErrors []error
	Match      []string
}

// Dependencies reports all Instances on which this instance depends.
func (inst *Instance) Dependencies() []*Instance {
	// TODO: as cyclic dependencies are not allowed, we could just not check.
	// Do for safety now and remove later if needed.
	return appendDependencies(nil, inst, map[*Instance]bool{})
}

func appendDependencies(a []*Instance, inst *Instance, done map[*Instance]bool) []*Instance {
	for _, d := range inst.Imports {
		if done[d] {
			continue
		}
		a = append(a, d)
		done[d] = true
		a = appendDependencies(a, d, done)
	}
	return a
}

// Abs converts relative path used in the one of the file fields to an
// absolute one.
func (inst *Instance) Abs(path string) string {
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(inst.Root, path)
}

func (inst *Instance) setPkg(pkg string) bool {
	if !inst.hasName {
		inst.hasName = true
		inst.PkgName = pkg
		return true
	}
	return false
}

// ReportError reports an error processing this instance.
func (inst *Instance) ReportError(err errors.Error) {
	inst.Err = errors.Append(inst.Err, err)
}

// Context defines the build context for this instance. All files defined
// in Syntax as well as all imported instances must be created using the
// same build context.
func (inst *Instance) Context() *Context {
	return inst.ctxt
}

func (inst *Instance) parse(name string, src interface{}) (*ast.File, error) {
	if inst.ctxt != nil && inst.ctxt.parseFunc != nil {
		return inst.ctxt.parseFunc(name, src)
	}
	return parser.ParseFile(name, src, parser.ParseComments)
}

// LookupImport defines a mapping from an ImportSpec's ImportPath to Instance.
func (inst *Instance) LookupImport(path string) *Instance {
	path = inst.expandPath(path)
	for _, inst := range inst.Imports {
		if inst.ImportPath == path {
			return inst
		}
	}
	return nil
}

func (inst *Instance) addImport(imp *Instance) {
	for _, inst := range inst.Imports {
		if inst.ImportPath == imp.ImportPath {
			if inst != imp {
				panic("import added multiple times with different instances")
			}
			return
		}
	}
	inst.Imports = append(inst.Imports, imp)
}

// AddFile adds the file with the given name to the list of files for this
// instance. The file may be loaded from the cache of the instance's context.
// It does not process the file's imports. The package name of the file must
// match the package name of the instance.
func (inst *Instance) AddFile(filename string, src interface{}) error {
	file, err := inst.parse(filename, src)
	if err != nil {
		// should always be an errors.List, but just in case.
		err := errors.Promote(err, "error adding file")
		inst.ReportError(err)
		return err
	}

	return inst.AddSyntax(file)
}

// AddSyntax adds the given file to list of files for this instance. The package
// name of the file must match the package name of the instance.
func (inst *Instance) AddSyntax(file *ast.File) errors.Error {
	astutil.Resolve(file, func(pos token.Pos, msg string, args ...interface{}) {
		inst.Err = errors.Append(inst.Err, errors.Newf(pos, msg, args...))
	})
	_, pkg, pos := internal.PackageInfo(file)
	if pkg != "" && pkg != "_" && !inst.setPkg(pkg) && pkg != inst.PkgName {
		err := errors.Newf(pos,
			"package name %q conflicts with previous package name %q",
			pkg, inst.PkgName)
		inst.ReportError(err)
		return err
	}
	inst.Files = append(inst.Files, file)
	return nil
}

func (inst *Instance) expandPath(path string) string {
	isLocal := IsLocalImport(path)
	if isLocal {
		path = dirToImportPath(filepath.Join(inst.Dir, path))
	}
	return path
}

// dirToImportPath returns the pseudo-import path we use for a package
// outside the CUE path. It begins with _/ and then contains the full path
// to the directory. If the package lives in c:\home\gopher\my\pkg then
// the pseudo-import path is _/c_/home/gopher/my/pkg.
// Using a pseudo-import path like this makes the ./ imports no longer
// a special case, so that all the code to deal with ordinary imports works
// automatically.
func dirToImportPath(dir string) string {
	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
}

func makeImportValid(r rune) rune {
	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
		return '_'
	}
	return r
}

// IsLocalImport reports whether the import path is
// a local import path, like ".", "..", "./foo", or "../foo".
func IsLocalImport(path string) bool {
	return path == "." || path == ".." ||
		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
}
<|endoftext|>


<commit_before>package image_ecosystem

import (
	"context"
	"fmt"
	"strings"
	"time"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/util/wait"
	e2e "k8s.io/kubernetes/test/e2e/framework"

	exutil "github.com/openshift/origin/test/extended/util"
)

var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy for openshift perl image", func() {
	defer g.GinkgoRecover()
	var (
		appSource     = exutil.FixturePath("testdata", "image_ecosystem", "perl-hotdeploy")
		perlTemplate  = exutil.FixturePath("testdata", "image_ecosystem", "perl-hotdeploy", "perl.json")
		oc            = exutil.NewCLI("s2i-perl")
		modifyCommand = []string{"sed", "-ie", `s/initial value/modified value/`, "lib/My/Test.pm"}
		dcName        = "perl"
		rcNameOne     = fmt.Sprintf("%s-1", dcName)
		rcNameTwo     = fmt.Sprintf("%s-2", dcName)
		dcLabelOne    = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameOne))
		dcLabelTwo    = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameTwo))
	)

	g.Context("", func() {
		g.JustBeforeEach(func() {
			exutil.PreTestDump()
		})

		g.AfterEach(func() {
			if g.CurrentGinkgoTestDescription().Failed {
				exutil.DumpPodStates(oc)
				exutil.DumpPodLogsStartingWith("", oc)
			}
		})

		g.Describe("hot deploy test", func() {
			g.It("should work", func() {

				exutil.WaitForOpenShiftNamespaceImageStreams(oc)
				g.By(fmt.Sprintf("calling oc new-app -f %q", perlTemplate))
				err := oc.Run("new-app").Args("-f", perlTemplate, "-e", "HTTPD_START_SERVERS=1", "-e", "HTTPD_MAX_SPARE_SERVERS=1", "-e", "HTTPD_MAX_REQUEST_WORKERS=1").Execute()
				o.Expect(err).NotTo(o.HaveOccurred())

				br, err := exutil.StartBuildAndWait(oc, "perl", fmt.Sprintf("--from-dir=%s", appSource))
				o.Expect(err).NotTo(o.HaveOccurred())
				br.AssertSuccess()

				g.By("waiting for build to finish")
				err = exutil.WaitForABuild(oc.BuildClient().BuildV1().Builds(oc.Namespace()), rcNameOne, nil, nil, nil)
				if err != nil {
					exutil.DumpBuildLogs(dcName, oc)
				}
				o.Expect(err).NotTo(o.HaveOccurred())

				err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 1, true, oc)
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("waiting for endpoint")
				err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName)
				o.Expect(err).NotTo(o.HaveOccurred())
				oldEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{})
				o.Expect(err).NotTo(o.HaveOccurred())

				checkPage := func(expected string, dcLabel labels.Selector) {
					_, err := exutil.WaitForPods(oc.KubeClient().CoreV1().Pods(oc.Namespace()), dcLabel, exutil.CheckPodIsRunning, 1, 4*time.Minute)
					o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred())
					result, err := CheckPageContains(oc, dcName, "", expected)
					o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred())
					o.ExpectWithOffset(1, result).To(o.BeTrue())
				}

				checkPage("initial value", dcLabelOne)

				g.By("modifying the source code with disabled hot deploy")
				err = RunInPodContainer(oc, dcLabelOne, modifyCommand)
				o.Expect(err).NotTo(o.HaveOccurred())
				checkPage("initial value", dcLabelOne)

				g.By("turning on hot-deploy")
				err = oc.Run("set", "env").Args("dc", dcName, "PERL_APACHE2_RELOAD=true").Execute()
				o.Expect(err).NotTo(o.HaveOccurred())
				err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 2, true, oc)
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("waiting for a new endpoint")
				err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName)
				o.Expect(err).NotTo(o.HaveOccurred())

				// Ran into an issue where we'd try to hit the endpoint before it was updated, resulting in
				// request timeouts against the previous pod's ip.  So make sure the endpoint is pointing to the
				// new pod before hitting it.
				err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) {
					newEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{})
					if err != nil {
						return false, err
					}
					if !strings.Contains(newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) {
						e2e.Logf("waiting on endpoint address ref %s to contain %s", newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo)
						return false, nil
					}
					e2e.Logf("old endpoint was %#v, new endpoint is %#v", oldEndpoint, newEndpoint)
					return true, nil
				})
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("modifying the source code with enabled hot deploy")
				checkPage("initial value", dcLabelTwo)
				err = RunInPodContainer(oc, dcLabelTwo, modifyCommand)
				o.Expect(err).NotTo(o.HaveOccurred())
				checkPage("modified value", dcLabelTwo)
			})
		})

	})
})
<commit_msg>Skipping test Hot deploy for openshift perl image for ARM64<commit_after>package image_ecosystem

import (
	"context"
	"fmt"
	"strings"
	"time"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/util/wait"
	e2e "k8s.io/kubernetes/test/e2e/framework"

	exutil "github.com/openshift/origin/test/extended/util"
)

func archHasModPerl(oc *exutil.CLI) bool {
	workerNodes, err := oc.AsAdmin().KubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{LabelSelector: "node-role.kubernetes.io/worker"})
	if err != nil {
		e2e.Logf("problem getting nodes for arch check: %s", err)
	}
	for _, node := range workerNodes.Items {
		switch node.Status.NodeInfo.Architecture {
		case "amd64":
			return true
		case "ppc64le":
			return true
		case "s390x":
			return true
		default:
		}
	}
	return false
}

var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy for openshift perl image", func() {
	defer g.GinkgoRecover()
	var (
		appSource     = exutil.FixturePath("testdata", "image_ecosystem", "perl-hotdeploy")
		perlTemplate  = exutil.FixturePath("testdata", "image_ecosystem", "perl-hotdeploy", "perl.json")
		oc            = exutil.NewCLI("s2i-perl")
		modifyCommand = []string{"sed", "-ie", `s/initial value/modified value/`, "lib/My/Test.pm"}
		dcName        = "perl"
		rcNameOne     = fmt.Sprintf("%s-1", dcName)
		rcNameTwo     = fmt.Sprintf("%s-2", dcName)
		dcLabelOne    = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameOne))
		dcLabelTwo    = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameTwo))
	)

	g.Context("", func() {
		g.JustBeforeEach(func() {
			exutil.PreTestDump()
		})

		g.AfterEach(func() {
			if g.CurrentGinkgoTestDescription().Failed {
				exutil.DumpPodStates(oc)
				exutil.DumpPodLogsStartingWith("", oc)
			}
		})

		g.Describe("hot deploy test", func() {
			g.It("should work", func() {
				// This image-ecosystem test fails on ARM because it depends on behaviour specific to mod_perl,
				// which is only included in the RHSCL (RHEL 7) perl images which are not available on ARM.
				if !archHasModPerl(oc) {
					g.Skip("mod_perl based builder image is not available on arm64")
				}
				exutil.WaitForOpenShiftNamespaceImageStreams(oc)
				g.By(fmt.Sprintf("calling oc new-app -f %q", perlTemplate))
				err := oc.Run("new-app").Args("-f", perlTemplate, "-e", "HTTPD_START_SERVERS=1", "-e", "HTTPD_MAX_SPARE_SERVERS=1", "-e", "HTTPD_MAX_REQUEST_WORKERS=1").Execute()
				o.Expect(err).NotTo(o.HaveOccurred())

				br, err := exutil.StartBuildAndWait(oc, "perl", fmt.Sprintf("--from-dir=%s", appSource))
				o.Expect(err).NotTo(o.HaveOccurred())
				br.AssertSuccess()

				g.By("waiting for build to finish")
				err = exutil.WaitForABuild(oc.BuildClient().BuildV1().Builds(oc.Namespace()), rcNameOne, nil, nil, nil)
				if err != nil {
					exutil.DumpBuildLogs(dcName, oc)
				}
				o.Expect(err).NotTo(o.HaveOccurred())

				err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 1, true, oc)
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("waiting for endpoint")
				err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName)
				o.Expect(err).NotTo(o.HaveOccurred())
				oldEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{})
				o.Expect(err).NotTo(o.HaveOccurred())

				checkPage := func(expected string, dcLabel labels.Selector) {
					_, err := exutil.WaitForPods(oc.KubeClient().CoreV1().Pods(oc.Namespace()), dcLabel, exutil.CheckPodIsRunning, 1, 4*time.Minute)
					o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred())
					result, err := CheckPageContains(oc, dcName, "", expected)
					o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred())
					o.ExpectWithOffset(1, result).To(o.BeTrue())
				}

				checkPage("initial value", dcLabelOne)

				g.By("modifying the source code with disabled hot deploy")
				err = RunInPodContainer(oc, dcLabelOne, modifyCommand)
				o.Expect(err).NotTo(o.HaveOccurred())
				checkPage("initial value", dcLabelOne)

				g.By("turning on hot-deploy")
				err = oc.Run("set", "env").Args("dc", dcName, "PERL_APACHE2_RELOAD=true").Execute()
				o.Expect(err).NotTo(o.HaveOccurred())
				err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 2, true, oc)
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("waiting for a new endpoint")
				err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName)
				o.Expect(err).NotTo(o.HaveOccurred())

				// Ran into an issue where we'd try to hit the endpoint before it was updated, resulting in
				// request timeouts against the previous pod's ip.  So make sure the endpoint is pointing to the
				// new pod before hitting it.
				err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) {
					newEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{})
					if err != nil {
						return false, err
					}
					if !strings.Contains(newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) {
						e2e.Logf("waiting on endpoint address ref %s to contain %s", newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo)
						return false, nil
					}
					e2e.Logf("old endpoint was %#v, new endpoint is %#v", oldEndpoint, newEndpoint)
					return true, nil
				})
				o.Expect(err).NotTo(o.HaveOccurred())

				g.By("modifying the source code with enabled hot deploy")
				checkPage("initial value", dcLabelTwo)
				err = RunInPodContainer(oc, dcLabelTwo, modifyCommand)
				o.Expect(err).NotTo(o.HaveOccurred())
				checkPage("modified value", dcLabelTwo)
			})
		})

	})
})
<|endoftext|>


<commit_before>package networking

import (
	"context"
	"fmt"
	"strings"
	"time"

	exutil "github.com/openshift/origin/test/extended/util"
	networkingv1 "k8s.io/api/networking/v1"

	kapiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	e2e "k8s.io/kubernetes/test/e2e/framework"
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
	psapi "k8s.io/pod-security-admission/api"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	maxPokeRetrys = 15
	retryInterval = 1 * time.Second
)

var _ = Describe("[sig-network][Feature:Network Policy Audit logging]", func() {
	var oc *exutil.CLI
	var ns []string
	var auditOut string
	// this hook must be registered before the framework namespace teardown
	// hook
	AfterEach(func() {
		if CurrentGinkgoTestDescription().Failed {
			// If test fails dump test pods logs
			exutil.DumpPodLogsStartingWithInNamespace("acl-logging", ns[0], oc.AsAdmin())
			exutil.DumpPodLogsStartingWithInNamespace("acl-logging", ns[1], oc.AsAdmin())
			// Dump what audit logs looked like if test failed
			e2e.Logf("Audit logs are incorrect:\n %v", auditOut)
		}
	})

	oc = exutil.NewCLIWithPodSecurityLevel("acl-logging", psapi.LevelBaseline)

	// The OVNKubernetes subnet plugin should allow acl_logging for network policy.
	// For Openshift SDN and third party plugins, the behavior is unspecified and we should not run either test.
	InOVNKubernetesContext(
		func() {
			f := oc.KubeFramework()
			It("should ensure acl logs are created and correct", func() {
				ns = append(ns, f.Namespace.Name)
				makeNamespaceScheduleToAllNodes(f)
				makeNamespaceACLLoggingEnabled(oc)

				nsNoACLLog := oc.SetupProject()
				By("making namespace " + nsNoACLLog + " with acl-logging disabled")
				ns = append(ns, nsNoACLLog)

				testACLLogging(f, oc, ns, auditOut)
			})
		},
	)
})

func makeNamespaceACLLoggingEnabled(oc *exutil.CLI) {
	nsName := oc.Namespace()

	By("setting the k8s.ovn.org/acl-logging annotation for the namespace: " + nsName)
	ns, err := oc.AdminKubeClient().CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
	expectNoError(err)

	if ns.Annotations == nil {
		ns.Annotations = make(map[string]string, 1)
	}
	ns.Annotations["k8s.ovn.org/acl-logging"] = `{ "deny": "alert", "allow": "alert" }`
	_, err = oc.AdminKubeClient().CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{})
	expectNoError(err)
}

// Test the Network policy audit logging feature
func testACLLogging(f *e2e.Framework, oc *exutil.CLI, ns []string, auditOut string) {
	// We launch 3 pods total; pod[0] and pod[1] will end up on node[0] in ns "acl-logging-on" , and pod[2]
	// will end up on node[1] in ns "acl-logging off", to know which acl-logging container to look in
	var nodes [2]*kapiv1.Node
	var pods [3]string
	var ips []string
	var err error
	var ipv6 bool

	nodes[0], nodes[1], err = findAppropriateNodes(f, DIFFERENT_NODE)
	expectNoError(err)

	By("making two pods in the acl-logging-on namespace and one in the acl-logging-off namespace")
	// make the first two pods in ns acl-logging-on on node[0] and the other in acl-logging-off on node[1]
	for i := range pods {
		pods[i] = fmt.Sprintf("acl-logging-%d", i+1)
		testPod := e2epod.NewAgnhostPod(ns[i/2], pods[i], nil, nil, nil, "netexec", "--http-port=80", "--udp-port=90")
		testPod.Spec.NodeName = nodes[i/2].Name
		_, err := f.ClientSet.CoreV1().Pods(ns[i/2]).Create(context.TODO(), testPod, metav1.CreateOptions{})
		expectNoError(err)
	}

	// make sure pods come up
	for i := range pods {
		tempIp, err := waitForACLLoggingPod(f, ns[i/2], pods[i])
		expectNoError(err)

		ips = append(ips, tempIp)
	}

	// Check if pods are have ipv6 addr
	if isIpv6(ips) {
		ipv6 = true
	}

	By("making \"default deny\" and \"allow from same namespace\" network policies")
	// a make network policy that allows ingress only from the same ns "acl-logging-on"
	_, err = makeFromSameNSPolicy(f, ns[0])
	expectNoError(err)

	By("sending traffic between acl-logging test pods and analyzing the audit logs")
	var errAllow error
	var errDeny error
	var podOut string
	allowReady := false
	denyReady := false
	allowLogFound := false
	denyLogFound := false

	// Retry here in the case where OVN acls have not been programmed yet
	for i := 1; i < maxPokeRetrys; i++ {
		// Ping pod[0] from pod[1] which should succeed since it's in the same namespace with out == ip[0]
		// Should hit the `allow-same-namespace` networkpolicy and have a response of pod[1]'s IP
		e2e.Logf("Poke pod %s from pod %s", pods[0], pods[1])
		podOut, errAllow = pokePod(oc, pods[1], ns[0], ips[0], ipv6)
		if errAllow == nil && strings.Contains(podOut, ips[1]) {
			e2e.Logf("Poke succeeded on try: %v", i)
			allowReady = true
		}
		// Ping pod[0] from pod[2] which should not succeed since it's in a different namespace
		// Should hit the all-deny policy
		e2e.Logf("Poke pod %s from pod %s", pods[0], pods[2])
		_, errDeny = pokePod(oc, pods[2], ns[1], ips[0], ipv6)
		if errDeny != nil {
			e2e.Logf("Poke failed successfully on try: %v", i)
			denyReady = true
		}

		time.Sleep(retryInterval)

		e2e.Logf("collecting the audit logs with 'oc adm node-logs' for node: %s", nodes[0].Name)
		// Ensure audit logs are there and that `oc adm node-logs` command adequately collects them
		auditOut, _, err = oc.AsAdmin().Run("adm").Args("node-logs", "--since=10s", nodes[0].Name, "--path=/ovn/acl-audit-log.log").Outputs()
		expectNoError(err)

		e2e.Logf("verifying the audit logs from node %s have the correct name and action", nodes[0].Name)
		allowLogFound, denyLogFound = verifyAuditLogs(auditOut, ns, ips, ipv6)

		// break if traffic flowed as expected and audit logs were correctly formed
		if allowReady && denyReady && allowLogFound && denyLogFound {
			break
		}

	}

	// Fail if allowed traffic was blocked
	expectNoError(errAllow)
	// Fail if allow curl response does not contain correct Ip
	if !strings.Contains(podOut, ips[1]) {
		expectNoError(fmt.Errorf("Incorrect Pod was poked, it's IP is %s", ips[1]))
	}
	// Fail if denied traffic was allowed
	expectError(errDeny)

	// Fail if correctly formed allow log was never found
	By("ensuring the correct allow log is found")
	Expect(allowLogFound).Should(Equal(true))
	// Fail if correctly formed deny log was never found
	By("ensuring the correct deny log is found")
	Expect(denyLogFound).Should(Equal(true))
}

func pokePod(oc *exutil.CLI, srcPodName string, srcNamespace string, dstPodIP string, ipv6 bool) (string, error) {
	var url = strings.Join([]string{dstPodIP, "/clientip"}, "")

	if ipv6 {
		url = strings.Join([]string{"[", dstPodIP, "]", "/clientip"}, "")
	}

	out, _, err := oc.AsAdmin().Run("exec").Args(srcPodName, "-n", srcNamespace, "--", "curl", "-m", "1", url).Outputs()
	return out, err
}

func verifyAuditLogs(out string, ns []string, ips []string, ipv6 bool) (bool, bool) {
	ipMatchSrc := "nw_src="
	ipMatchDst := "nw_dst="
	allowLogFound := false
	denyLogFound := false

	if ipv6 {
		ipMatchSrc = "ipv6_src="
		ipMatchDst = "ipv6_dst="
	}

	e2e.Logf("Ensuring the audit log contains: '%s_allow-from-same-ns_0\", verdict=allow' AND '%s' AND '%s'", ns[0], ipMatchSrc+ips[1], ipMatchDst+ips[0])
	e2e.Logf("Ensuring the audit log contains: '%s_allow-from-same-ns\", verdict=drop' AND '%s' AND '%s'", ns[0], ipMatchSrc+ips[2], ipMatchDst+ips[0])
	// Ensure the ACL audit logs are correct
	for _, logLine := range strings.Split(out, "\n") {
		if strings.Contains(logLine, ns[0]+"_allow-from-same-ns_0\", verdict=allow") && strings.Contains(logLine, ipMatchSrc+ips[1]) &&
			strings.Contains(logLine, ipMatchDst+ips[0]) {
			allowLogFound = true
			continue
		}
		if (strings.Contains(logLine, ns[0]+"_allow-from-same-ns\", verdict=drop") && strings.Contains(logLine, ipMatchSrc+ips[2]) ||
			strings.Contains(logLine, ns[0]+"_ingressDefaultDeny\", verdict=drop") && strings.Contains(logLine, ipMatchSrc+ips[2])) &&
			strings.Contains(logLine, ipMatchDst+ips[0]) {
			denyLogFound = true
			continue
		}

	}

	return allowLogFound, denyLogFound
}

func waitForACLLoggingPod(f *e2e.Framework, namespace string, podName string) (string, error) {
	var podIP string
	err := e2epod.WaitForPodCondition(f.ClientSet, namespace, podName, "running", podStartTimeout, func(pod *kapiv1.Pod) (bool, error) {
		podIP = pod.Status.PodIP
		return (podIP != "" && pod.Status.Phase != kapiv1.PodPending), nil
	})
	return podIP, err
}

func makeDenyAllPolicy(f *e2e.Framework, ns string) (*networkingv1.NetworkPolicy, error) {

	policy := &networkingv1.NetworkPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Name: "default-deny-all",
		},
		Spec: networkingv1.NetworkPolicySpec{
			PodSelector: metav1.LabelSelector{},
			PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress},
			Ingress:     []networkingv1.NetworkPolicyIngressRule{},
			Egress:      []networkingv1.NetworkPolicyEgressRule{},
		},
	}

	policy, err := f.ClientSet.NetworkingV1().NetworkPolicies(ns).Create(context.TODO(), policy, metav1.CreateOptions{})

	return policy, err
}

func makeFromSameNSPolicy(f *e2e.Framework, ns string) (*networkingv1.NetworkPolicy, error) {

	policy := &networkingv1.NetworkPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Name: "allow-from-same-ns",
		},
		Spec: networkingv1.NetworkPolicySpec{
			PodSelector: metav1.LabelSelector{},
			PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
			Ingress: []networkingv1.NetworkPolicyIngressRule{{
				From: []networkingv1.NetworkPolicyPeer{{
					PodSelector: &metav1.LabelSelector{},
				}},
			}},
		},
	}

	policy, err := f.ClientSet.NetworkingV1().NetworkPolicies(ns).Create(context.TODO(), policy, metav1.CreateOptions{})

	return policy, err
}
<commit_msg>networking/acl: properly dump found audit logs in case of a failure<commit_after>package networking

import (
	"context"
	"fmt"
	"strings"
	"time"

	exutil "github.com/openshift/origin/test/extended/util"
	networkingv1 "k8s.io/api/networking/v1"

	kapiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	e2e "k8s.io/kubernetes/test/e2e/framework"
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
	psapi "k8s.io/pod-security-admission/api"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	maxPokeRetrys = 15
	retryInterval = 1 * time.Second
)

var _ = Describe("[sig-network][Feature:Network Policy Audit logging]", func() {
	var oc *exutil.CLI
	var ns []string
	// this hook must be registered before the framework namespace teardown
	// hook
	AfterEach(func() {
		if CurrentGinkgoTestDescription().Failed {
			// If test fails dump test pods logs
			exutil.DumpPodLogsStartingWithInNamespace("acl-logging", ns[0], oc.AsAdmin())
			exutil.DumpPodLogsStartingWithInNamespace("acl-logging", ns[1], oc.AsAdmin())
		}
	})

	oc = exutil.NewCLIWithPodSecurityLevel("acl-logging", psapi.LevelBaseline)

	// The OVNKubernetes subnet plugin should allow acl_logging for network policy.
	// For Openshift SDN and third party plugins, the behavior is unspecified and we should not run either test.
	InOVNKubernetesContext(
		func() {
			f := oc.KubeFramework()
			It("should ensure acl logs are created and correct", func() {
				ns = append(ns, f.Namespace.Name)
				makeNamespaceScheduleToAllNodes(f)
				makeNamespaceACLLoggingEnabled(oc)

				nsNoACLLog := oc.SetupProject()
				By("making namespace " + nsNoACLLog + " with acl-logging disabled")
				ns = append(ns, nsNoACLLog)

				testACLLogging(f, oc, ns)
			})
		},
	)
})

func makeNamespaceACLLoggingEnabled(oc *exutil.CLI) {
	nsName := oc.Namespace()

	By("setting the k8s.ovn.org/acl-logging annotation for the namespace: " + nsName)
	ns, err := oc.AdminKubeClient().CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
	expectNoError(err)

	if ns.Annotations == nil {
		ns.Annotations = make(map[string]string, 1)
	}
	ns.Annotations["k8s.ovn.org/acl-logging"] = `{ "deny": "alert", "allow": "alert" }`
	_, err = oc.AdminKubeClient().CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{})
	expectNoError(err)
}

// Test the Network policy audit logging feature
func testACLLogging(f *e2e.Framework, oc *exutil.CLI, ns []string) {
	// We launch 3 pods total; pod[0] and pod[1] will end up on node[0] in ns "acl-logging-on" , and pod[2]
	// will end up on node[1] in ns "acl-logging off", to know which acl-logging container to look in
	var nodes [2]*kapiv1.Node
	var pods [3]string
	var ips []string
	var err error
	var ipv6 bool

	nodes[0], nodes[1], err = findAppropriateNodes(f, DIFFERENT_NODE)
	expectNoError(err)

	By("making two pods in the acl-logging-on namespace and one in the acl-logging-off namespace")
	// make the first two pods in ns acl-logging-on on node[0] and the other in acl-logging-off on node[1]
	for i := range pods {
		pods[i] = fmt.Sprintf("acl-logging-%d", i+1)
		testPod := e2epod.NewAgnhostPod(ns[i/2], pods[i], nil, nil, nil, "netexec", "--http-port=80", "--udp-port=90")
		testPod.Spec.NodeName = nodes[i/2].Name
		_, err := f.ClientSet.CoreV1().Pods(ns[i/2]).Create(context.TODO(), testPod, metav1.CreateOptions{})
		expectNoError(err)
	}

	// make sure pods come up
	for i := range pods {
		tempIp, err := waitForACLLoggingPod(f, ns[i/2], pods[i])
		expectNoError(err)

		ips = append(ips, tempIp)
	}

	// Check if pods are have ipv6 addr
	if isIpv6(ips) {
		ipv6 = true
	}

	By("making \"default deny\" and \"allow from same namespace\" network policies")
	// a make network policy that allows ingress only from the same ns "acl-logging-on"
	_, err = makeFromSameNSPolicy(f, ns[0])
	expectNoError(err)

	By("sending traffic between acl-logging test pods and analyzing the audit logs")
	var errAllow error
	var errDeny error
	var podOut string
	var auditOut string
	allowReady := false
	denyReady := false
	allowLogFound := false
	denyLogFound := false

	// Retry here in the case where OVN acls have not been programmed yet
	for i := 1; i < maxPokeRetrys; i++ {
		// Ping pod[0] from pod[1] which should succeed since it's in the same namespace with out == ip[0]
		// Should hit the `allow-same-namespace` networkpolicy and have a response of pod[1]'s IP
		e2e.Logf("Poke pod %s from pod %s", pods[0], pods[1])
		podOut, errAllow = pokePod(oc, pods[1], ns[0], ips[0], ipv6)
		if errAllow == nil && strings.Contains(podOut, ips[1]) {
			e2e.Logf("Poke succeeded on try: %v", i)
			allowReady = true
		}
		// Ping pod[0] from pod[2] which should not succeed since it's in a different namespace
		// Should hit the all-deny policy
		e2e.Logf("Poke pod %s from pod %s", pods[0], pods[2])
		_, errDeny = pokePod(oc, pods[2], ns[1], ips[0], ipv6)
		if errDeny != nil {
			e2e.Logf("Poke failed successfully on try: %v", i)
			denyReady = true
		}

		time.Sleep(retryInterval)

		e2e.Logf("collecting the audit logs with 'oc adm node-logs' for node: %s", nodes[0].Name)
		// Ensure audit logs are there and that `oc adm node-logs` command adequately collects them
		auditOut, _, err = oc.AsAdmin().Run("adm").Args("node-logs", "--since=10s", nodes[0].Name, "--path=/ovn/acl-audit-log.log").Outputs()
		expectNoError(err)

		e2e.Logf("verifying the audit logs from node %s have the correct name and action", nodes[0].Name)
		allowLogFound, denyLogFound = verifyAuditLogs(auditOut, ns, ips, ipv6)

		// break if traffic flowed as expected and audit logs were correctly formed
		if allowReady && denyReady && allowLogFound && denyLogFound {
			break
		}

	}

	// Fail if allowed traffic was blocked
	expectNoError(errAllow)
	// Fail if allow curl response does not contain correct Ip
	if !strings.Contains(podOut, ips[1]) {
		expectNoError(fmt.Errorf("Incorrect Pod was poked, it's IP is %s", ips[1]))
	}
	// Fail if denied traffic was allowed
	expectError(errDeny)

	// Fail if correctly formed allow log was never found
	By("ensuring the correct allow log is found")
	Expect(allowLogFound).Should(Equal(true), "allow log not found in the logs\n%s", auditOut)
	// Fail if correctly formed deny log was never found
	By("ensuring the correct deny log is found")
	Expect(denyLogFound).Should(Equal(true), "deny log not found in the logs:\n%s", auditOut)
}

func pokePod(oc *exutil.CLI, srcPodName string, srcNamespace string, dstPodIP string, ipv6 bool) (string, error) {
	var url = strings.Join([]string{dstPodIP, "/clientip"}, "")

	if ipv6 {
		url = strings.Join([]string{"[", dstPodIP, "]", "/clientip"}, "")
	}

	out, _, err := oc.AsAdmin().Run("exec").Args(srcPodName, "-n", srcNamespace, "--", "curl", "-m", "1", url).Outputs()
	return out, err
}

func verifyAuditLogs(out string, ns []string, ips []string, ipv6 bool) (bool, bool) {
	ipMatchSrc := "nw_src="
	ipMatchDst := "nw_dst="
	allowLogFound := false
	denyLogFound := false

	if ipv6 {
		ipMatchSrc = "ipv6_src="
		ipMatchDst = "ipv6_dst="
	}

	e2e.Logf("Ensuring the audit log contains: '%s_allow-from-same-ns_0\", verdict=allow' AND '%s' AND '%s'", ns[0], ipMatchSrc+ips[1], ipMatchDst+ips[0])
	e2e.Logf("Ensuring the audit log contains: '%s_allow-from-same-ns\", verdict=drop' AND '%s' AND '%s'", ns[0], ipMatchSrc+ips[2], ipMatchDst+ips[0])
	// Ensure the ACL audit logs are correct
	for _, logLine := range strings.Split(out, "\n") {
		if strings.Contains(logLine, ns[0]+"_allow-from-same-ns_0\", verdict=allow") && strings.Contains(logLine, ipMatchSrc+ips[1]) &&
			strings.Contains(logLine, ipMatchDst+ips[0]) {
			allowLogFound = true
			continue
		}
		if (strings.Contains(logLine, ns[0]+"_allow-from-same-ns\", verdict=drop") && strings.Contains(logLine, ipMatchSrc+ips[2]) ||
			strings.Contains(logLine, ns[0]+"_ingressDefaultDeny\", verdict=drop") && strings.Contains(logLine, ipMatchSrc+ips[2])) &&
			strings.Contains(logLine, ipMatchDst+ips[0]) {
			denyLogFound = true
			continue
		}

	}

	return allowLogFound, denyLogFound
}

func waitForACLLoggingPod(f *e2e.Framework, namespace string, podName string) (string, error) {
	var podIP string
	err := e2epod.WaitForPodCondition(f.ClientSet, namespace, podName, "running", podStartTimeout, func(pod *kapiv1.Pod) (bool, error) {
		podIP = pod.Status.PodIP
		return (podIP != "" && pod.Status.Phase != kapiv1.PodPending), nil
	})
	return podIP, err
}

func makeDenyAllPolicy(f *e2e.Framework, ns string) (*networkingv1.NetworkPolicy, error) {

	policy := &networkingv1.NetworkPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Name: "default-deny-all",
		},
		Spec: networkingv1.NetworkPolicySpec{
			PodSelector: metav1.LabelSelector{},
			PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress},
			Ingress:     []networkingv1.NetworkPolicyIngressRule{},
			Egress:      []networkingv1.NetworkPolicyEgressRule{},
		},
	}

	policy, err := f.ClientSet.NetworkingV1().NetworkPolicies(ns).Create(context.TODO(), policy, metav1.CreateOptions{})

	return policy, err
}

func makeFromSameNSPolicy(f *e2e.Framework, ns string) (*networkingv1.NetworkPolicy, error) {

	policy := &networkingv1.NetworkPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Name: "allow-from-same-ns",
		},
		Spec: networkingv1.NetworkPolicySpec{
			PodSelector: metav1.LabelSelector{},
			PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
			Ingress: []networkingv1.NetworkPolicyIngressRule{{
				From: []networkingv1.NetworkPolicyPeer{{
					PodSelector: &metav1.LabelSelector{},
				}},
			}},
		},
	}

	policy, err := f.ClientSet.NetworkingV1().NetworkPolicies(ns).Create(context.TODO(), policy, metav1.CreateOptions{})

	return policy, err
}
<|endoftext|>


<commit_before>// Copyright 2015 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 integration_test

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"testing"
)

// A directory containing outputs created by build_gcsfuse, set up and deleted
// in TestMain.
var gBuildDir string

func TestMain(m *testing.M) {
	flag.Parse()

	// Set up a directory into which we will build.
	gBuildDir, err := ioutil.TempDir("", "gcsfuse_integration_tests")
	if err != nil {
		log.Fatalf("TempDir: %v", err)
		return
	}

	// Build into that directory.
	err = buildGcsfuse(gBuildDir)
	if err != nil {
		log.Fatalf("buildGcsfuse: %v", err)
		return
	}

	// Run tests.
	code := m.Run()

	// Clean up and exit.
	os.RemoveAll(gBuildDir)
	os.Exit(code)
}

// Build bin/gcsfuse, sbin/mount_gcsfuse, etc. into the supplied directory.
func buildGcsfuse(dstDir string) (err error) {
	// Ensure we have a copy of build_gcsfuse sitting around.
	var toolPath string
	{
		var toolDir string
		toolDir, err = ioutil.TempDir("", "gcsfuse_integration_tests")
		if err != nil {
			err = fmt.Errorf("TempDir: %v", err)
			return
		}

		defer os.RemoveAll(toolDir)

		toolPath = path.Join(toolDir, "build_gcsfuse")
		log.Printf("Building build_gcsfuse at %s", toolPath)

		err = buildBuildGcsfuse(toolPath)
		if err != nil {
			err = fmt.Errorf("buildBuildGcsfuse: %v", err)
			return
		}
	}

	// Use it to perform a build.
	log.Printf("Building gcsfuse into %s", dstDir)

	{
		cmd := exec.Command(
			toolPath,
			srcDir,
			dstDir,
			"fake_version",
		)

		var output []byte
		output, err = cmd.CombinedOutput()
		if err != nil {
			err = fmt.Errorf("build_gcsfuse: %v\nOutput:\n%s", err, output)
			return
		}
	}

	return
}

// Build the build_gcsfuse tool, writing the binary to the supplied path.
func buildBuildGcsfuse(dst string) (err error) {
	err = errors.New("TODO")
	return
}
<commit_msg>Find the gcsfuse sources.<commit_after>// Copyright 2015 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 integration_test

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"testing"
)

// A directory containing outputs created by build_gcsfuse, set up and deleted
// in TestMain.
var gBuildDir string

func TestMain(m *testing.M) {
	flag.Parse()

	// Set up a directory into which we will build.
	gBuildDir, err := ioutil.TempDir("", "gcsfuse_integration_tests")
	if err != nil {
		log.Fatalf("TempDir: %v", err)
		return
	}

	// Build into that directory.
	err = buildGcsfuse(gBuildDir)
	if err != nil {
		log.Fatalf("buildGcsfuse: %v", err)
		return
	}

	// Run tests.
	code := m.Run()

	// Clean up and exit.
	os.RemoveAll(gBuildDir)
	os.Exit(code)
}

// Build bin/gcsfuse, sbin/mount_gcsfuse, etc. into the supplied directory.
func buildGcsfuse(dstDir string) (err error) {
	// Ensure we have a copy of build_gcsfuse sitting around.
	var toolPath string
	{
		var toolDir string
		toolDir, err = ioutil.TempDir("", "gcsfuse_integration_tests")
		if err != nil {
			err = fmt.Errorf("TempDir: %v", err)
			return
		}

		defer os.RemoveAll(toolDir)

		toolPath = path.Join(toolDir, "build_gcsfuse")
		log.Printf("Building build_gcsfuse at %s", toolPath)

		err = buildBuildGcsfuse(toolPath)
		if err != nil {
			err = fmt.Errorf("buildBuildGcsfuse: %v", err)
			return
		}
	}

	// Figure out where we can find the source code for gcsfuse.
	var srcDir string
	{
		var pkg *build.Package
		pkg, err = build.Import(
			"github.com/googlecloudplatform/gcsfuse",
			"",
			build.FindOnly)

		if err != nil {
			err = fmt.Errorf("build.Import: %v", err)
			return
		}

		srcDir = pkg.Dir
	}

	// Use build_gcsfuse to perform a build.
	log.Printf("Building gcsfuse into %s", dstDir)

	{
		cmd := exec.Command(
			toolPath,
			srcDir,
			dstDir,
			"fake_version",
		)

		var output []byte
		output, err = cmd.CombinedOutput()
		if err != nil {
			err = fmt.Errorf("build_gcsfuse: %v\nOutput:\n%s", err, output)
			return
		}
	}

	return
}

// Build the build_gcsfuse tool, writing the binary to the supplied path.
func buildBuildGcsfuse(dst string) (err error) {
	err = errors.New("TODO")
	return
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/coreos/go-iptables/iptables"
	"github.com/spf13/cobra"
	"k8s.io/client-go/kubernetes"
	coreapi "k8s.io/client-go/pkg/api/v1"
	extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/pkg/fields"
	"k8s.io/client-go/pkg/runtime"
	"k8s.io/client-go/pkg/util/wait"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/cache"

	"github.com/weaveworks/weave/common"
	"github.com/weaveworks/weave/npc"
	"github.com/weaveworks/weave/npc/ipset"
	"github.com/weaveworks/weave/npc/metrics"
	"github.com/weaveworks/weave/npc/ulogd"
)

var (
	version     = "unreleased"
	metricsAddr string
	logLevel    string
	allowMcast  bool
	nodeName    string
)

func handleError(err error) { common.CheckFatal(err) }

func makeController(getter cache.Getter, resource string,
	objType runtime.Object, handlers cache.ResourceEventHandlerFuncs) *cache.Controller {
	listWatch := cache.NewListWatchFromClient(getter, resource, "", fields.Everything())
	_, controller := cache.NewInformer(listWatch, objType, 0, handlers)
	return controller
}

func resetIPTables(ipt *iptables.IPTables) error {
	// Flush chains first so there are no refs to extant ipsets
	if err := ipt.ClearChain(npc.TableFilter, npc.IngressChain); err != nil {
		return err
	}

	if err := ipt.ClearChain(npc.TableFilter, npc.DefaultChain); err != nil {
		return err
	}

	if err := ipt.ClearChain(npc.TableFilter, npc.MainChain); err != nil {
		return err
	}

	return nil
}

func resetIPSets(ips ipset.Interface) error {
	// Remove ipsets prefixed `weave-` only

	sets, err := ips.List(npc.IpsetNamePrefix)
	if err != nil {
		common.Log.Errorf("Failed to retrieve list of ipsets")
		return err
	}

	common.Log.Debugf("Got list of ipsets: %v", sets)

	// Must remove references to ipsets by other ipsets before they're destroyed
	for _, s := range sets {
		common.Log.Debugf("Flushing ipset '%s'", string(s))
		if err := ips.Flush(s); err != nil {
			common.Log.Errorf("Failed to flush ipset '%s'", string(s))
			return err
		}
	}

	for _, s := range sets {
		common.Log.Debugf("Destroying ipset '%s'", string(s))
		if err := ips.Destroy(s); err != nil {
			common.Log.Errorf("Failed to destroy ipset '%s'", string(s))
			return err
		}
	}

	return nil
}

func createBaseRules(ipt *iptables.IPTables, ips ipset.Interface) error {
	// Configure main chain static rules
	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
		return err
	}

	if allowMcast {
		if err := ipt.Append(npc.TableFilter, npc.MainChain,
			"-d", "224.0.0.0/4", "-j", "ACCEPT"); err != nil {
			return err
		}
	}

	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "NEW", "-j", string(npc.DefaultChain)); err != nil {
		return err
	}

	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "NEW", "-j", string(npc.IngressChain)); err != nil {
		return err
	}

	// If the destination address is not any of the local pods, let it through
	if err := ips.Create(npc.LocalIpset, ipset.HashIP); err != nil {
		return err
	}
	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "set", "--match-set", npc.LocalIpset, "src",
		"-m", "set", "!", "--match-set", npc.LocalIpset, "dst", "-j", "ACCEPT"); err != nil {
		return err
	}

	return nil
}

func root(cmd *cobra.Command, args []string) {
	common.SetLogLevel(logLevel)
	if nodeName == "" {
		// HOSTNAME is set by Kubernetes for pods in the host network namespace
		nodeName = os.Getenv("HOSTNAME")
	}
	if nodeName == "" {
		common.Log.Fatalf("Must set node name via --node-name or $HOSTNAME")
	}
	common.Log.Infof("Starting Weaveworks NPC %s; node name %q", version, nodeName)

	if err := metrics.Start(metricsAddr); err != nil {
		common.Log.Fatalf("Failed to start metrics: %v", err)
	}

	if err := ulogd.Start(); err != nil {
		common.Log.Fatalf("Failed to start ulogd: %v", err)
	}

	config, err := rest.InClusterConfig()
	handleError(err)

	client, err := kubernetes.NewForConfig(config)
	handleError(err)

	ipt, err := iptables.New()
	handleError(err)

	ips := ipset.New(common.LogLogger())

	handleError(resetIPTables(ipt))
	handleError(resetIPSets(ips))
	handleError(createBaseRules(ipt, ips))

	npc := npc.New(nodeName, ipt, ips)

	nsController := makeController(client.Core().RESTClient(), "namespaces", &coreapi.Namespace{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddNamespace(obj.(*coreapi.Namespace)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *coreapi.Namespace:
					handleError(npc.DeleteNamespace(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeleteNamespace(obj.Obj.(*coreapi.Namespace)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdateNamespace(old.(*coreapi.Namespace), new.(*coreapi.Namespace)))
			}})

	podController := makeController(client.Core().RESTClient(), "pods", &coreapi.Pod{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddPod(obj.(*coreapi.Pod)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *coreapi.Pod:
					handleError(npc.DeletePod(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeletePod(obj.Obj.(*coreapi.Pod)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdatePod(old.(*coreapi.Pod), new.(*coreapi.Pod)))
			}})

	npController := makeController(client.Extensions().RESTClient(), "networkpolicies", &extnapi.NetworkPolicy{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddNetworkPolicy(obj.(*extnapi.NetworkPolicy)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *extnapi.NetworkPolicy:
					handleError(npc.DeleteNetworkPolicy(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeleteNetworkPolicy(obj.Obj.(*extnapi.NetworkPolicy)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdateNetworkPolicy(old.(*extnapi.NetworkPolicy), new.(*extnapi.NetworkPolicy)))
			}})

	go nsController.Run(wait.NeverStop)
	go podController.Run(wait.NeverStop)
	go npController.Run(wait.NeverStop)

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
	common.Log.Fatalf("Exiting: %v", <-signals)
}

func main() {
	rootCmd := &cobra.Command{
		Use:   "weave-npc",
		Short: "Weaveworks Kubernetes Network Policy Controller",
		Run:   root}

	rootCmd.PersistentFlags().StringVar(&metricsAddr, "metrics-addr", ":6781", "metrics server bind address")
	rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "debug", "logging level (debug, info, warning, error)")
	rootCmd.PersistentFlags().BoolVar(&allowMcast, "allow-mcast", true, "allow all multicast traffic")
	rootCmd.PersistentFlags().StringVar(&nodeName, "node-name", "", "only generate rules that apply to this node")

	handleError(rootCmd.Execute())
}
<commit_msg>Allow any non-local traffic onto the weave bridge<commit_after>package main

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/coreos/go-iptables/iptables"
	"github.com/spf13/cobra"
	"k8s.io/client-go/kubernetes"
	coreapi "k8s.io/client-go/pkg/api/v1"
	extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/pkg/fields"
	"k8s.io/client-go/pkg/runtime"
	"k8s.io/client-go/pkg/util/wait"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/cache"

	"github.com/weaveworks/weave/common"
	"github.com/weaveworks/weave/npc"
	"github.com/weaveworks/weave/npc/ipset"
	"github.com/weaveworks/weave/npc/metrics"
	"github.com/weaveworks/weave/npc/ulogd"
)

var (
	version     = "unreleased"
	metricsAddr string
	logLevel    string
	allowMcast  bool
	nodeName    string
)

func handleError(err error) { common.CheckFatal(err) }

func makeController(getter cache.Getter, resource string,
	objType runtime.Object, handlers cache.ResourceEventHandlerFuncs) *cache.Controller {
	listWatch := cache.NewListWatchFromClient(getter, resource, "", fields.Everything())
	_, controller := cache.NewInformer(listWatch, objType, 0, handlers)
	return controller
}

func resetIPTables(ipt *iptables.IPTables) error {
	// Flush chains first so there are no refs to extant ipsets
	if err := ipt.ClearChain(npc.TableFilter, npc.IngressChain); err != nil {
		return err
	}

	if err := ipt.ClearChain(npc.TableFilter, npc.DefaultChain); err != nil {
		return err
	}

	if err := ipt.ClearChain(npc.TableFilter, npc.MainChain); err != nil {
		return err
	}

	return nil
}

func resetIPSets(ips ipset.Interface) error {
	// Remove ipsets prefixed `weave-` only

	sets, err := ips.List(npc.IpsetNamePrefix)
	if err != nil {
		common.Log.Errorf("Failed to retrieve list of ipsets")
		return err
	}

	common.Log.Debugf("Got list of ipsets: %v", sets)

	// Must remove references to ipsets by other ipsets before they're destroyed
	for _, s := range sets {
		common.Log.Debugf("Flushing ipset '%s'", string(s))
		if err := ips.Flush(s); err != nil {
			common.Log.Errorf("Failed to flush ipset '%s'", string(s))
			return err
		}
	}

	for _, s := range sets {
		common.Log.Debugf("Destroying ipset '%s'", string(s))
		if err := ips.Destroy(s); err != nil {
			common.Log.Errorf("Failed to destroy ipset '%s'", string(s))
			return err
		}
	}

	return nil
}

func createBaseRules(ipt *iptables.IPTables, ips ipset.Interface) error {
	// Configure main chain static rules
	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
		return err
	}

	if allowMcast {
		if err := ipt.Append(npc.TableFilter, npc.MainChain,
			"-d", "224.0.0.0/4", "-j", "ACCEPT"); err != nil {
			return err
		}
	}

	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "NEW", "-j", string(npc.DefaultChain)); err != nil {
		return err
	}

	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "state", "--state", "NEW", "-j", string(npc.IngressChain)); err != nil {
		return err
	}

	// If the destination address is not any of the local pods, let it through
	if err := ips.Create(npc.LocalIpset, ipset.HashIP); err != nil {
		return err
	}
	if err := ipt.Append(npc.TableFilter, npc.MainChain,
		"-m", "set", "!", "--match-set", npc.LocalIpset, "dst", "-j", "ACCEPT"); err != nil {
		return err
	}

	return nil
}

func root(cmd *cobra.Command, args []string) {
	common.SetLogLevel(logLevel)
	if nodeName == "" {
		// HOSTNAME is set by Kubernetes for pods in the host network namespace
		nodeName = os.Getenv("HOSTNAME")
	}
	if nodeName == "" {
		common.Log.Fatalf("Must set node name via --node-name or $HOSTNAME")
	}
	common.Log.Infof("Starting Weaveworks NPC %s; node name %q", version, nodeName)

	if err := metrics.Start(metricsAddr); err != nil {
		common.Log.Fatalf("Failed to start metrics: %v", err)
	}

	if err := ulogd.Start(); err != nil {
		common.Log.Fatalf("Failed to start ulogd: %v", err)
	}

	config, err := rest.InClusterConfig()
	handleError(err)

	client, err := kubernetes.NewForConfig(config)
	handleError(err)

	ipt, err := iptables.New()
	handleError(err)

	ips := ipset.New(common.LogLogger())

	handleError(resetIPTables(ipt))
	handleError(resetIPSets(ips))
	handleError(createBaseRules(ipt, ips))

	npc := npc.New(nodeName, ipt, ips)

	nsController := makeController(client.Core().RESTClient(), "namespaces", &coreapi.Namespace{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddNamespace(obj.(*coreapi.Namespace)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *coreapi.Namespace:
					handleError(npc.DeleteNamespace(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeleteNamespace(obj.Obj.(*coreapi.Namespace)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdateNamespace(old.(*coreapi.Namespace), new.(*coreapi.Namespace)))
			}})

	podController := makeController(client.Core().RESTClient(), "pods", &coreapi.Pod{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddPod(obj.(*coreapi.Pod)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *coreapi.Pod:
					handleError(npc.DeletePod(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeletePod(obj.Obj.(*coreapi.Pod)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdatePod(old.(*coreapi.Pod), new.(*coreapi.Pod)))
			}})

	npController := makeController(client.Extensions().RESTClient(), "networkpolicies", &extnapi.NetworkPolicy{},
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				handleError(npc.AddNetworkPolicy(obj.(*extnapi.NetworkPolicy)))
			},
			DeleteFunc: func(obj interface{}) {
				switch obj := obj.(type) {
				case *extnapi.NetworkPolicy:
					handleError(npc.DeleteNetworkPolicy(obj))
				case cache.DeletedFinalStateUnknown:
					// We know this object has gone away, but its final state is no longer
					// available from the API server. Instead we use the last copy of it
					// that we have, which is good enough for our cleanup.
					handleError(npc.DeleteNetworkPolicy(obj.Obj.(*extnapi.NetworkPolicy)))
				}
			},
			UpdateFunc: func(old, new interface{}) {
				handleError(npc.UpdateNetworkPolicy(old.(*extnapi.NetworkPolicy), new.(*extnapi.NetworkPolicy)))
			}})

	go nsController.Run(wait.NeverStop)
	go podController.Run(wait.NeverStop)
	go npController.Run(wait.NeverStop)

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
	common.Log.Fatalf("Exiting: %v", <-signals)
}

func main() {
	rootCmd := &cobra.Command{
		Use:   "weave-npc",
		Short: "Weaveworks Kubernetes Network Policy Controller",
		Run:   root}

	rootCmd.PersistentFlags().StringVar(&metricsAddr, "metrics-addr", ":6781", "metrics server bind address")
	rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "debug", "logging level (debug, info, warning, error)")
	rootCmd.PersistentFlags().BoolVar(&allowMcast, "allow-mcast", true, "allow all multicast traffic")
	rootCmd.PersistentFlags().StringVar(&nodeName, "node-name", "", "only generate rules that apply to this node")

	handleError(rootCmd.Execute())
}
<|endoftext|>


<commit_before>package integration

import (
	"testing"

	kapierror "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/sets"

	authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
	authorizationclient "github.com/openshift/origin/pkg/authorization/generated/internalclientset"
	imageclient "github.com/openshift/origin/pkg/image/generated/internalclientset"
	"github.com/openshift/origin/pkg/oc/lib/tokencmd"
	templateclient "github.com/openshift/origin/pkg/template/generated/internalclientset"
	testutil "github.com/openshift/origin/test/util"
	testserver "github.com/openshift/origin/test/util/server"
)

func TestBootstrapPolicyAuthenticatedUsersAgainstOpenshiftNamespace(t *testing.T) {
	masterConfig, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	defer testserver.CleanupMasterEtcd(t, masterConfig)

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	valerieClientConfig := *clusterAdminClientConfig
	valerieClientConfig.Username = ""
	valerieClientConfig.Password = ""
	valerieClientConfig.BearerToken = ""
	valerieClientConfig.CertFile = ""
	valerieClientConfig.KeyFile = ""
	valerieClientConfig.CertData = nil
	valerieClientConfig.KeyData = nil

	accessToken, err := tokencmd.RequestToken(&valerieClientConfig, nil, "valerie", "security!")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	valerieClientConfig.BearerToken = accessToken
	valerieTemplateClient := templateclient.NewForConfigOrDie(&valerieClientConfig).Template()
	valerieImageClient := imageclient.NewForConfigOrDie(&valerieClientConfig).Image()

	openshiftSharedResourcesNamespace := "openshift"

	if _, err := valerieTemplateClient.Templates(openshiftSharedResourcesNamespace).List(metav1.ListOptions{}); err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if _, err := valerieTemplateClient.Templates(metav1.NamespaceDefault).List(metav1.ListOptions{}); err == nil || !kapierror.IsForbidden(err) {
		t.Errorf("unexpected error: %v", err)
	}

	if _, err := valerieImageClient.ImageStreams(openshiftSharedResourcesNamespace).List(metav1.ListOptions{}); err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if _, err := valerieImageClient.ImageStreams(metav1.NamespaceDefault).List(metav1.ListOptions{}); err == nil || !kapierror.IsForbidden(err) {
		t.Errorf("unexpected error: %v", err)
	}

	if _, err := valerieImageClient.ImageStreamTags(openshiftSharedResourcesNamespace).Get("name:tag", metav1.GetOptions{}); !kapierror.IsNotFound(err) {
		t.Errorf("unexpected error: %v", err)
	}
	if _, err := valerieImageClient.ImageStreamTags(metav1.NamespaceDefault).Get("name:tag", metav1.GetOptions{}); err == nil || !kapierror.IsForbidden(err) {
		t.Errorf("unexpected error: %v", err)
	}
}

func TestBootstrapPolicySelfSubjectAccessReviews(t *testing.T) {
	masterConfig, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	defer testserver.CleanupMasterEtcd(t, masterConfig)

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	valerieKubeClient, valerieClientConfig, err := testutil.GetClientForUser(clusterAdminClientConfig, "valerie")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	valerieAuthorizationClient := authorizationclient.NewForConfigOrDie(valerieClientConfig).Authorization()

	askCanICreatePolicyBindings := &authorizationapi.LocalSubjectAccessReview{
		Action: authorizationapi.Action{Verb: "create", Resource: "policybindings"},
	}
	subjectAccessReviewTest{
		description:       "can I get a subjectaccessreview on myself even if I have no rights to do it generally",
		localInterface:    valerieAuthorizationClient.LocalSubjectAccessReviews("openshift"),
		localReview:       askCanICreatePolicyBindings,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		response: authorizationapi.SubjectAccessReviewResponse{
			Allowed:   false,
			Reason:    ``,
			Namespace: "openshift",
		},
	}.run(t)

	askCanClusterAdminsCreateProject := &authorizationapi.LocalSubjectAccessReview{
		Groups: sets.NewString("system:cluster-admins"),
		Action: authorizationapi.Action{Verb: "create", Resource: "projects"},
	}
	subjectAccessReviewTest{
		description:       "I shouldn't be allowed to ask whether someone else can perform an action",
		localInterface:    valerieAuthorizationClient.LocalSubjectAccessReviews("openshift"),
		localReview:       askCanClusterAdminsCreateProject,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		kubeNamespace:     "openshift",
		err:               `localsubjectaccessreviews.authorization.openshift.io is forbidden: User "valerie" cannot create resource "localsubjectaccessreviews" in API group "authorization.openshift.io" in the namespace "openshift"`,
		kubeErr:           `localsubjectaccessreviews.authorization.k8s.io is forbidden: User "valerie" cannot create resource "localsubjectaccessreviews" in API group "authorization.k8s.io" in the namespace "openshift"`,
	}.run(t)

}

func TestSelfSubjectAccessReviewsNonExistingNamespace(t *testing.T) {
	masterConfig, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	defer testserver.CleanupMasterEtcd(t, masterConfig)

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	valerieKubeClient, valerieClientConfig, err := testutil.GetClientForUser(clusterAdminClientConfig, "valerie")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// ensure that a SAR for a non-exisitng namespace gives a SAR response and not a
	// namespace doesn't exist response from admisison.
	askCanICreatePodsInNonExistingNamespace := &authorizationapi.LocalSubjectAccessReview{
		Action: authorizationapi.Action{Namespace: "foo", Verb: "create", Resource: "pods"},
	}
	subjectAccessReviewTest{
		description:       "ensure SAR for non-existing namespace does not leak namespace info",
		localInterface:    authorizationclient.NewForConfigOrDie(valerieClientConfig).Authorization().LocalSubjectAccessReviews("foo"),
		localReview:       askCanICreatePodsInNonExistingNamespace,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		response: authorizationapi.SubjectAccessReviewResponse{
			Allowed:   false,
			Reason:    ``,
			Namespace: "foo",
		},
	}.run(t)
}
<commit_msg>remove test for non-standard configuration mechanism<commit_after>package integration

import (
	"testing"

	"k8s.io/apimachinery/pkg/util/sets"

	authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
	authorizationclient "github.com/openshift/origin/pkg/authorization/generated/internalclientset"
	testutil "github.com/openshift/origin/test/util"
	testserver "github.com/openshift/origin/test/util/server"
)

func TestBootstrapPolicySelfSubjectAccessReviews(t *testing.T) {
	masterConfig, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	defer testserver.CleanupMasterEtcd(t, masterConfig)

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	valerieKubeClient, valerieClientConfig, err := testutil.GetClientForUser(clusterAdminClientConfig, "valerie")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	valerieAuthorizationClient := authorizationclient.NewForConfigOrDie(valerieClientConfig).Authorization()

	askCanICreatePolicyBindings := &authorizationapi.LocalSubjectAccessReview{
		Action: authorizationapi.Action{Verb: "create", Resource: "policybindings"},
	}
	subjectAccessReviewTest{
		description:       "can I get a subjectaccessreview on myself even if I have no rights to do it generally",
		localInterface:    valerieAuthorizationClient.LocalSubjectAccessReviews("openshift"),
		localReview:       askCanICreatePolicyBindings,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		response: authorizationapi.SubjectAccessReviewResponse{
			Allowed:   false,
			Reason:    ``,
			Namespace: "openshift",
		},
	}.run(t)

	askCanClusterAdminsCreateProject := &authorizationapi.LocalSubjectAccessReview{
		Groups: sets.NewString("system:cluster-admins"),
		Action: authorizationapi.Action{Verb: "create", Resource: "projects"},
	}
	subjectAccessReviewTest{
		description:       "I shouldn't be allowed to ask whether someone else can perform an action",
		localInterface:    valerieAuthorizationClient.LocalSubjectAccessReviews("openshift"),
		localReview:       askCanClusterAdminsCreateProject,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		kubeNamespace:     "openshift",
		err:               `localsubjectaccessreviews.authorization.openshift.io is forbidden: User "valerie" cannot create resource "localsubjectaccessreviews" in API group "authorization.openshift.io" in the namespace "openshift"`,
		kubeErr:           `localsubjectaccessreviews.authorization.k8s.io is forbidden: User "valerie" cannot create resource "localsubjectaccessreviews" in API group "authorization.k8s.io" in the namespace "openshift"`,
	}.run(t)

}

func TestSelfSubjectAccessReviewsNonExistingNamespace(t *testing.T) {
	masterConfig, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	defer testserver.CleanupMasterEtcd(t, masterConfig)

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	valerieKubeClient, valerieClientConfig, err := testutil.GetClientForUser(clusterAdminClientConfig, "valerie")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// ensure that a SAR for a non-exisitng namespace gives a SAR response and not a
	// namespace doesn't exist response from admisison.
	askCanICreatePodsInNonExistingNamespace := &authorizationapi.LocalSubjectAccessReview{
		Action: authorizationapi.Action{Namespace: "foo", Verb: "create", Resource: "pods"},
	}
	subjectAccessReviewTest{
		description:       "ensure SAR for non-existing namespace does not leak namespace info",
		localInterface:    authorizationclient.NewForConfigOrDie(valerieClientConfig).Authorization().LocalSubjectAccessReviews("foo"),
		localReview:       askCanICreatePodsInNonExistingNamespace,
		kubeAuthInterface: valerieKubeClient.AuthorizationV1(),
		response: authorizationapi.SubjectAccessReviewResponse{
			Allowed:   false,
			Reason:    ``,
			Namespace: "foo",
		},
	}.run(t)
}
<|endoftext|>


<commit_before><commit_msg>fix error logging<commit_after><|endoftext|>


<commit_before>/**
 * Copyright 2015 @ z3q.net.
 * name : message_result
 * author : jarryliu
 * date : -- :
 * description :
 * history :
 */
package dto

type (
	//操作消息结果
	MessageResult struct {
		Result  bool   `json:"result"`
		Message string `json:"message"`
		Tag     int    `json:"tag"`
	}

	// 站内信
	SiteMessage struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 消息类型
		Type int `db:"msg_type"`
		// 消息用途
		UseFor       int `db:"use_for"`
		SenderUserId int
		SenderName   string
		// 是否只能阅读
		Readonly int `db:"read_only"`
		// 创建时间
		CreateTime int64 `db:"create_time"`
		// 数据
		Data interface{}
		// 接收者编号
		ToId int `db:"to_id"`
		// 接收者角色
		ToRole int `db:"to_role"`
		// 是否阅读
		HasRead int `db:"has_read"`
		// 阅读时间
		ReadTime int64 `db:"read_time"`
	}

	// 商品查询复合信息
	GoodsComplex struct {
		GoodsId int    `db:"id"`
		ItemId  int    `db:"item_id"`
		MchId   int    `db:"mch_id"`
		MchName string `db:"mch_name"`
	}

	PagedMemberAfterSalesOrder struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 订单编号
		OrderNo int `db:"order_id"`
		// 运营商编号
		VendorId int `db:"vendor_id"`
		// 运营商名称
		VendorName string `db:"vendor_name"`
		// 类型，退货、换货、维修
		Type       int `db:"type"`
		SkuId      int
		GoodsTitle string
		GoodsImage string
		// 退货的商品项编号
		SnapshotId int `db:"snap_id"`
		// 商品数量
		Quantity int `db:"quantity"`
		// 售后单状态
		State int `db:"state"`
		// 提交时间
		CreateTime int64 `db:"create_time"`
		// 更新时间
		UpdateTime int64 `db:"update_time"`
		// 订单状态
		StateText string `db:"-"`
	}

	// 分页商户售后单
	PagedVendorAfterSalesOrder struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 订单编号
		OrderNo int `db:"order_id"`
		// 会员编号
		BuyerId int `db:"vendor_id"`
		// 会员名称
		BuyerName string `db:"buyer_name"`
		// 类型，退货、换货、维修
		Type       int `db:"type"`
		SkuId      int
		GoodsTitle string
		GoodsImage string
		// 退货的商品项编号
		SnapshotId int `db:"snap_id"`
		// 商品数量
		Quantity int `db:"quantity"`
		// 售后单状态
		State int `db:"state"`
		// 提交时间
		CreateTime int64 `db:"create_time"`
		// 更新时间
		UpdateTime int64 `db:"update_time"`
		// 订单状态
		StateText string `db:"-"`
	}

	// 店铺收藏
	PagedShopFav struct {
		Id         int    `db:"id"`
		ShopId     int    `db:"shop_id"`
		ShopName   string `db:"shop_name"`
		MchId      int    `db:"mch_id"`
		Logo       string `db:"logo"`
		UpdateTime int64  `db:"update_time"`
	}

	// 商品收藏
	PagedGoodsFav struct {
		Id         int    `db:"id"`
		SkuId      int    `db:"sku_id"`
		GoodsName  string `db:"goods_name"`
		Image      string `db:"image"`
		OnShelves  int    `db:"on_shelves"`
		StockNum   int    `db:"stock_num"`
		SalePrice  string `db:"sale_price"`
		UpdateTime int64  `db:"update_time"`
	}
	// 分类
	Category struct {
		Id    int
		Name  string
		Icon  string
		Url   string
		Level int
		Child []Category
	}
	ListOnlineShop struct {
		Id         int    `db:"sp.id"`
		Name       string `db:"sp.name"`
		Alias      string `db:"alias"`
		Host       string `db:"ol.host"`
		Logo       string `db:"logo"`
		CreateTime int64  `db:"sp.create_time" json:"-"`
	}
)
<commit_msg>core/dto/dto.go<commit_after>/**
 * Copyright 2015 @ z3q.net.
 * name : message_result
 * author : jarryliu
 * date : -- :
 * description :
 * history :
 */
package dto

type (
	//操作消息结果
	MessageResult struct {
		Result  bool   `json:"result"`
		Message string `json:"message"`
		Tag     int    `json:"tag"`
	}

	// 站内信
	SiteMessage struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 消息类型
		Type int `db:"msg_type"`
		// 消息用途
		UseFor       int `db:"use_for"`
		SenderUserId int
		SenderName   string
		// 是否只能阅读
		Readonly int `db:"read_only"`
		// 创建时间
		CreateTime int64 `db:"create_time"`
		// 数据
		Data interface{}
		// 接收者编号
		ToId int `db:"to_id"`
		// 接收者角色
		ToRole int `db:"to_role"`
		// 是否阅读
		HasRead int `db:"has_read"`
		// 阅读时间
		ReadTime int64 `db:"read_time"`
	}

	// 商品查询复合信息
	GoodsComplex struct {
		GoodsId int    `db:"id"`
		ItemId  int    `db:"item_id"`
		MchId   int    `db:"mch_id"`
		MchName string `db:"mch_name"`
	}

	PagedMemberAfterSalesOrder struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 订单编号
		OrderNo int `db:"order_id"`
		// 运营商编号
		VendorId int `db:"vendor_id"`
		// 运营商名称
		VendorName string `db:"vendor_name"`
		// 类型，退货、换货、维修
		Type       int `db:"type"`
		SkuId      int
		GoodsTitle string
		GoodsImage string
		// 退货的商品项编号
		SnapshotId int `db:"snap_id"`
		// 商品数量
		Quantity int `db:"quantity"`
		// 售后单状态
		State int `db:"state"`
		// 提交时间
		CreateTime int64 `db:"create_time"`
		// 更新时间
		UpdateTime int64 `db:"update_time"`
		// 订单状态
		StateText string `db:"-"`
	}

	// 分页商户售后单
	PagedVendorAfterSalesOrder struct {
		// 编号
		Id int `db:"id" pk:"yes" auto:"yes"`
		// 订单编号
		OrderNo string `db:"order_id"`
		// 会员编号
		BuyerId int `db:"vendor_id"`
		// 会员名称
		BuyerName string `db:"buyer_name"`
		// 类型，退货、换货、维修
		Type       int `db:"type"`
		SkuId      int
		GoodsTitle string
		GoodsImage string
		// 退货的商品项编号
		SnapshotId int `db:"snap_id"`
		// 商品数量
		Quantity int `db:"quantity"`
		// 售后单状态
		State int `db:"state"`
		// 提交时间
		CreateTime int64 `db:"create_time"`
		// 更新时间
		UpdateTime int64 `db:"update_time"`
		// 订单状态
		StateText string `db:"-"`
	}

	// 店铺收藏
	PagedShopFav struct {
		Id         int    `db:"id"`
		ShopId     int    `db:"shop_id"`
		ShopName   string `db:"shop_name"`
		MchId      int    `db:"mch_id"`
		Logo       string `db:"logo"`
		UpdateTime int64  `db:"update_time"`
	}

	// 商品收藏
	PagedGoodsFav struct {
		Id         int    `db:"id"`
		SkuId      int    `db:"sku_id"`
		GoodsName  string `db:"goods_name"`
		Image      string `db:"image"`
		OnShelves  int    `db:"on_shelves"`
		StockNum   int    `db:"stock_num"`
		SalePrice  string `db:"sale_price"`
		UpdateTime int64  `db:"update_time"`
	}
	// 分类
	Category struct {
		Id    int
		Name  string
		Icon  string
		Url   string
		Level int
		Child []Category
	}
	ListOnlineShop struct {
		Id         int    `db:"sp.id"`
		Name       string `db:"sp.name"`
		Alias      string `db:"alias"`
		Host       string `db:"ol.host"`
		Logo       string `db:"logo"`
		CreateTime int64  `db:"sp.create_time" json:"-"`
	}
)
<|endoftext|>