<commit_before>/*
Copyright 2020 The Knative 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 ingress

import (
	"strings"
	"testing"

	"knative.dev/networking/test"
)

var istioStableTests = map[string]func(t *testing.T){
	"basics":                       TestBasics,
	"basics/http2":                 TestBasicsHTTP2,
	"headers/pre-split":            TestPreSplitSetHeaders,
	"headers/post-split":           TestPostSplitSetHeaders,
	"dispatch/path":                TestPath,
	"dispatch/percentage":          TestPercentage,
	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
	"dispatch/rule":                TestRule,
	"hosts/multiple":               TestMultipleHosts,
	"timeout":                      TestTimeout,
	"websocket":                    TestWebsocket,
	"websocket/split":              TestWebsocketSplit,
	"grpc":                         TestGRPC,
	"grpc/split":                   TestGRPCSplit,
}

var contourStableTests = map[string]func(t *testing.T){
	"basics": TestBasics,
}

var stableTests = map[string]func(t *testing.T){
	"basics":                       TestBasics,
	"basics/http2":                 TestBasicsHTTP2,
	"headers/pre-split":            TestPreSplitSetHeaders,
	"headers/post-split":           TestPostSplitSetHeaders,
	"dispatch/path":                TestPath,
	"dispatch/percentage":          TestPercentage,
	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
	"dispatch/rule":                TestRule,
	"hosts/multiple":               TestMultipleHosts,
	"timeout":                      TestTimeout,
	"websocket":                    TestWebsocket,
	"websocket/split":              TestWebsocketSplit,
	"grpc":                         TestGRPC,
	"grpc/split":                   TestGRPCSplit,
	/*
		"headers/probe":                TestProbeHeaders,
		"retry":                        TestRetry,
		"tls":                          TestIngressTLS,
		"update":                       TestUpdate,
		"visibility":                   TestVisibility,
		"visibility/split":             TestVisibilitySplit,
		"visibility/path":              TestVisibilityPath,
		"ingressclass":                 TestIngressClass,
	*/
}

var contourBetaTests = map[string]func(t *testing.T){}

var istioBetaTests = map[string]func(t *testing.T){
	"headers/tags": TestTagHeaders,
	"host-rewrite": TestRewriteHost,
}

var betaTests = map[string]func(t *testing.T){
	// Add your conformance test for beta features
	"headers/tags": TestTagHeaders,
	"host-rewrite": TestRewriteHost,
}

var alphaTests = map[string]func(t *testing.T){
	// Add your conformance test for alpha features
}

// RunConformance will run ingress conformance tests
//
// Depending on the options it may test alpha and beta features
func RunConformance(t *testing.T) {

	var stables map[string]func(t *testing.T)
	var betas map[string]func(t *testing.T)
	switch test.NetworkingFlags.IngressClass {
	case "istio":
		stables = istioStableTests
		betas = istioBetaTests
	case "contour":
		stables = contourStableTests
		betas = contourBetaTests
	default:
		stables = stableTests
		betas = betaTests
	}

	for name, test := range stables {
		t.Run(name, test)
	}

	skipTests := skipTests()

	// TODO(dprotaso) we'll need something more robust
	// in the long term that lets downstream
	// implementations to better select which tests
	// should be run -  selection across various
	// dimensions
	// ie. state - alpha, beta, ga
	// ie. requirement - must, should, may
	if test.NetworkingFlags.EnableBetaFeatures {
		for name, test := range betas {
			if _, ok := skipTests[name]; ok {
				t.Run(name, skipFunc)
				continue
			}
			t.Run(name, test)
		}
	}

	if test.NetworkingFlags.EnableAlphaFeatures {
		for name, test := range alphaTests {
			if _, ok := skipTests[name]; ok {
				t.Run(name, skipFunc)
				continue
			}
			t.Run(name, test)
		}
	}
}

var skipFunc = func(t *testing.T) {
	t.Skip("Skipping the test in skip-test flag")
}

func skipTests() map[string]struct{} {
	skipArray := strings.Split(test.NetworkingFlags.SkipTests, ",")
	skipMap := make(map[string]struct{}, len(skipArray))
	for _, name := range skipArray {
		skipMap[name] = struct{}{}
	}
	return skipMap
}
<commit_msg>Add contour tests (#39)<commit_after>/*
Copyright 2020 The Knative 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 ingress

import (
	"strings"
	"testing"

	"knative.dev/networking/test"
)

var istioStableTests = map[string]func(t *testing.T){
	"basics":                       TestBasics,
	"basics/http2":                 TestBasicsHTTP2,
	"headers/pre-split":            TestPreSplitSetHeaders,
	"headers/post-split":           TestPostSplitSetHeaders,
	"dispatch/path":                TestPath,
	"dispatch/percentage":          TestPercentage,
	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
	"dispatch/rule":                TestRule,
	"hosts/multiple":               TestMultipleHosts,
	"timeout":                      TestTimeout,
	"websocket":                    TestWebsocket,
	"websocket/split":              TestWebsocketSplit,
	"grpc":                         TestGRPC,
	"grpc/split":                   TestGRPCSplit,
}

var contourStableTests = map[string]func(t *testing.T){
	"basics":                       TestBasics,
	"headers/pre-split":            TestPreSplitSetHeaders,
	"headers/post-split":           TestPostSplitSetHeaders,
	"dispatch/path":                TestPath,
	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
	"dispatch/rule":                TestRule,
	"hosts/multiple":               TestMultipleHosts,
	"timeout":                      TestTimeout,
}

var stableTests = map[string]func(t *testing.T){
	"basics":                       TestBasics,
	"basics/http2":                 TestBasicsHTTP2,
	"headers/pre-split":            TestPreSplitSetHeaders,
	"headers/post-split":           TestPostSplitSetHeaders,
	"dispatch/path":                TestPath,
	"dispatch/percentage":          TestPercentage,
	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
	"dispatch/rule":                TestRule,
	"hosts/multiple":               TestMultipleHosts,
	"timeout":                      TestTimeout,
	"websocket":                    TestWebsocket,
	"websocket/split":              TestWebsocketSplit,
	"grpc":                         TestGRPC,
	"grpc/split":                   TestGRPCSplit,
	/*
		"headers/probe":                TestProbeHeaders,
		"retry":                        TestRetry,
		"tls":                          TestIngressTLS,
		"update":                       TestUpdate,
		"visibility":                   TestVisibility,
		"visibility/split":             TestVisibilitySplit,
		"visibility/path":              TestVisibilityPath,
		"ingressclass":                 TestIngressClass,
	*/
}

var contourBetaTests = map[string]func(t *testing.T){}

var istioBetaTests = map[string]func(t *testing.T){
	"headers/tags": TestTagHeaders,
	"host-rewrite": TestRewriteHost,
}

var betaTests = map[string]func(t *testing.T){
	// Add your conformance test for beta features
	"headers/tags": TestTagHeaders,
	"host-rewrite": TestRewriteHost,
}

var alphaTests = map[string]func(t *testing.T){
	// Add your conformance test for alpha features
}

// RunConformance will run ingress conformance tests
//
// Depending on the options it may test alpha and beta features
func RunConformance(t *testing.T) {

	var stables map[string]func(t *testing.T)
	var betas map[string]func(t *testing.T)
	switch test.NetworkingFlags.IngressClass {
	case "istio":
		stables = istioStableTests
		betas = istioBetaTests
	case "contour":
		stables = contourStableTests
		betas = contourBetaTests
	default:
		stables = stableTests
		betas = betaTests
	}

	for name, test := range stables {
		t.Run(name, test)
	}

	skipTests := skipTests()

	// TODO(dprotaso) we'll need something more robust
	// in the long term that lets downstream
	// implementations to better select which tests
	// should be run -  selection across various
	// dimensions
	// ie. state - alpha, beta, ga
	// ie. requirement - must, should, may
	if test.NetworkingFlags.EnableBetaFeatures {
		for name, test := range betas {
			if _, ok := skipTests[name]; ok {
				t.Run(name, skipFunc)
				continue
			}
			t.Run(name, test)
		}
	}

	if test.NetworkingFlags.EnableAlphaFeatures {
		for name, test := range alphaTests {
			if _, ok := skipTests[name]; ok {
				t.Run(name, skipFunc)
				continue
			}
			t.Run(name, test)
		}
	}
}

var skipFunc = func(t *testing.T) {
	t.Skip("Skipping the test in skip-test flag")
}

func skipTests() map[string]struct{} {
	skipArray := strings.Split(test.NetworkingFlags.SkipTests, ",")
	skipMap := make(map[string]struct{}, len(skipArray))
	for _, name := range skipArray {
		skipMap[name] = struct{}{}
	}
	return skipMap
}
<|endoftext|>


<commit_before>/*
 *    Copyright (C) 2014 Michael Wendland
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Michael Wendland <michiwend@michiwend.com>
 */

// hellobee dummy module for beehive
package hellobee

import (
	"github.com/muesli/beehive/app"
	"github.com/muesli/beehive/modules"
)

type HelloBee struct {
	some_flag string
}

func (mod *HelloBee) Name() string {
	return "hellobee"
}

func (mod *HelloBee) Description() string {
	return "A 'Hello World' module for beehive"
}

func (mod *HelloBee) Events() []modules.EventDescriptor {
	events := []modules.EventDescriptor{}
	return events
}

func (mod *HelloBee) Actions() []modules.ActionDescriptor {
	actions := []modules.ActionDescriptor{}
	return actions
}

func (mod *HelloBee) Run(eventChan chan modules.Event) {
	helloEvent := modules.Event{
		Namespace: mod.Name(),
		Name:      "Say Hello",
		Options:   []modules.Placeholder{},
	}

	eventChan <- helloEvent
}

func (mod *HelloBee) Action(action modules.Action) []modules.Placeholder {
	return []modules.Placeholder{}
}

func init() {
	hello := HelloBee{}

	app.AddFlags([]app.CliFlag{
		app.CliFlag{&hello.some_flag, "foo", "default value", "some option"},
	})

	modules.RegisterModule(&hello)
}
<commit_msg>* Comment out fake event being sent for now.<commit_after>/*
 *    Copyright (C) 2014 Michael Wendland
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Michael Wendland <michiwend@michiwend.com>
 */

// hellobee dummy module for beehive
package hellobee

import (
	"github.com/muesli/beehive/app"
	"github.com/muesli/beehive/modules"
)

type HelloBee struct {
	some_flag string
}

func (mod *HelloBee) Name() string {
	return "hellobee"
}

func (mod *HelloBee) Description() string {
	return "A 'Hello World' module for beehive"
}

func (mod *HelloBee) Events() []modules.EventDescriptor {
	events := []modules.EventDescriptor{}
	return events
}

func (mod *HelloBee) Actions() []modules.ActionDescriptor {
	actions := []modules.ActionDescriptor{}
	return actions
}

func (mod *HelloBee) Run(eventChan chan modules.Event) {
/*	helloEvent := modules.Event{
		Namespace: mod.Name(),
		Name:      "Say Hello",
		Options:   []modules.Placeholder{},
	}

	eventChan <- helloEvent*/
}

func (mod *HelloBee) Action(action modules.Action) []modules.Placeholder {
	return []modules.Placeholder{}
}

func init() {
	hello := HelloBee{}

	app.AddFlags([]app.CliFlag{
		app.CliFlag{&hello.some_flag, "foo", "default value", "some option"},
	})

	modules.RegisterModule(&hello)
}
<|endoftext|>


<commit_before>package bloom_filter

import (
	"math"
)

type BloomFilter struct {
	Capacity    int
	Probability float64
	size        int
	hashTable   []int
	hashesNum   int
}

func NewBloomFilter(probability float64, capacity int) *BloomFilter {
	bloomFilter := new(BloomFilter)
	bloomFilter.Probability = probability
	bloomFilter.Capacity = capacity

	bloomFilter.size = int(math.Ceil(
		(float64(capacity) * math.Log(probability)) / math.Log(1/math.Pow(2, math.Log(2))),
	))

	bloomFilter.hashTable = make([]int, bloomFilter.size)
	bloomFilter.hashesNum = int(math.Round(math.Log(2) * float64(bloomFilter.size/capacity)))

	return bloomFilter
}

func (b *BloomFilter) hashFunc(key string, seed int) int {
	h := 0
	for _, char := range key {
		h += int(char) + seed
	}
	return h % b.size
}

func (b *BloomFilter) Add(key string) {
	for seed := 1; seed <= b.hashesNum+1; seed++ {
		b.hashTable[b.hashFunc(key, seed)] = 1
	}
}

func (b *BloomFilter) Check(key string) bool {
	for seed := 1; seed <= b.hashesNum+1; seed++ {
		if b.hashTable[b.hashFunc(key, seed)] == 0 {
			return false
		}
	}

	return true
}

func (b *BloomFilter) GetSize() int {
	return b.size
}
<commit_msg>Added GetCapacity method to a BloomFilter data structure<commit_after>package bloom_filter

import (
	"math"
)

type BloomFilter struct {
	Capacity    int
	Probability float64
	size        int
	hashTable   []int
	hashesNum   int
}

func NewBloomFilter(probability float64, capacity int) *BloomFilter {
	bloomFilter := new(BloomFilter)
	bloomFilter.Probability = probability
	bloomFilter.Capacity = capacity

	bloomFilter.size = int(math.Ceil(
		(float64(capacity) * math.Log(probability)) / math.Log(1/math.Pow(2, math.Log(2))),
	))

	bloomFilter.hashTable = make([]int, bloomFilter.size)
	bloomFilter.hashesNum = int(math.Round(math.Log(2) * float64(bloomFilter.size/capacity)))

	return bloomFilter
}

func (b *BloomFilter) hashFunc(key string, seed int) int {
	h := 0
	for _, char := range key {
		h += int(char) + seed
	}
	return h % b.size
}

func (b *BloomFilter) Add(key string) {
	for seed := 1; seed <= b.hashesNum+1; seed++ {
		b.hashTable[b.hashFunc(key, seed)] = 1
	}
}

func (b *BloomFilter) Check(key string) bool {
	for seed := 1; seed <= b.hashesNum+1; seed++ {
		if b.hashTable[b.hashFunc(key, seed)] == 0 {
			return false
		}
	}

	return true
}

func (b *BloomFilter) GetSize() int {
	return b.size
}

func (b *BloomFilter) GetCapacity() int {
	return b.Capacity
}
<|endoftext|>


<commit_before>// Copyright 2016 ego 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 core

import (
	"sync"

	"github.com/go-ego/riot/types"
)

var (
	// DocInfoGroup 文档信息 [shard][id]info
	DocInfoGroup         = make(map[int]*types.DocInfosShard)
	docInfosGroupRWMutex sync.RWMutex
)

// AddDocInfosShard add document infos shard
func AddDocInfosShard(shard int) {
	docInfosGroupRWMutex.Lock()
	defer docInfosGroupRWMutex.Unlock()
	if _, found := DocInfoGroup[shard]; !found {
		DocInfoGroup[shard] = &types.DocInfosShard{
			DocInfos: make(map[uint64]*types.DocInfo),
		}
	}
}

// AddDocInfo add documents info
func AddDocInfo(shard int, docId uint64, docinfo *types.DocInfo) {
	docInfosGroupRWMutex.Lock()
	defer docInfosGroupRWMutex.Unlock()
	if _, ok := DocInfoGroup[shard]; !ok {
		DocInfoGroup[shard] = &types.DocInfosShard{
			DocInfos: make(map[uint64]*types.DocInfo),
		}
	}
	DocInfoGroup[shard].DocInfos[docId] = docinfo
	DocInfoGroup[shard].NumDocs++
}

// IsDocExist doc is exist
func IsDocExist(docId uint64) bool {
	docInfosGroupRWMutex.RLock()
	defer docInfosGroupRWMutex.RUnlock()
	for _, docInfosShard := range DocInfoGroup {
		_, found := docInfosShard.DocInfos[docId]
		if found {
			return true
		}
	}
	return false
}

var (
	// InvertedIndexGroup 反向索引表([shard][关键词]反向索引表)
	InvertedIndexGroup        = make(map[int]*types.InvertedIndexShard)
	invertedIndexGroupRWMutex sync.RWMutex
)

// AddInvertedIndexShard add inverted index shard
func AddInvertedIndexShard(shard int) {
	invertedIndexGroupRWMutex.Lock()
	defer invertedIndexGroupRWMutex.Unlock()
	if _, found := InvertedIndexGroup[shard]; !found {
		InvertedIndexGroup[shard] = &types.InvertedIndexShard{
			InvertedIndex: make(map[string]*types.KeywordIndices),
		}
	}
}

// AddKeywordIndices  add keyword indices
func AddKeywordIndices(shard int, keyword string, keywordIndices *types.KeywordIndices) {
	invertedIndexGroupRWMutex.Lock()
	defer invertedIndexGroupRWMutex.Unlock()
	if _, ok := InvertedIndexGroup[shard]; !ok {
		InvertedIndexGroup[shard] = &types.InvertedIndexShard{
			InvertedIndex: make(map[string]*types.KeywordIndices),
		}
	}
	InvertedIndexGroup[shard].InvertedIndex[keyword] = keywordIndices
	InvertedIndexGroup[shard].TotalTokenLen++
}
<commit_msg>update core data code<commit_after>// Copyright 2016 ego 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 core

import (
	"sync"

	"github.com/go-ego/riot/types"
)

var (
	// DocInfoGroup 文档信息 [shard][id]info
	DocInfoGroup         = make(map[int]*types.DocInfosShard)
	docInfosGroupRWMutex sync.RWMutex
)

// AddDocInfosShard add document infos shard
func AddDocInfosShard(shard int) {
	docInfosGroupRWMutex.Lock()
	defer docInfosGroupRWMutex.Unlock()
	if _, found := DocInfoGroup[shard]; !found {
		DocInfoGroup[shard] = &types.DocInfosShard{
			DocInfos: make(map[string]*types.DocInfo),
		}
	}
}

// AddDocInfo add documents info
func AddDocInfo(shard int, docId string, docinfo *types.DocInfo) {
	docInfosGroupRWMutex.Lock()
	defer docInfosGroupRWMutex.Unlock()
	if _, ok := DocInfoGroup[shard]; !ok {
		DocInfoGroup[shard] = &types.DocInfosShard{
			DocInfos: make(map[string]*types.DocInfo),
		}
	}

	DocInfoGroup[shard].DocInfos[docId] = docinfo
	DocInfoGroup[shard].NumDocs++
}

// IsDocExist doc is exist
func IsDocExist(docId string) bool {
	docInfosGroupRWMutex.RLock()
	defer docInfosGroupRWMutex.RUnlock()
	for _, docInfosShard := range DocInfoGroup {
		_, found := docInfosShard.DocInfos[docId]
		if found {
			return true
		}
	}
	return false
}

var (
	// InvertedIndexGroup 反向索引表([shard][关键词]反向索引表)
	InvertedIndexGroup        = make(map[int]*types.InvertedIndexShard)
	invertedIndexGroupRWMutex sync.RWMutex
)

// AddInvertedIndexShard add inverted index shard
func AddInvertedIndexShard(shard int) {
	invertedIndexGroupRWMutex.Lock()
	defer invertedIndexGroupRWMutex.Unlock()
	if _, found := InvertedIndexGroup[shard]; !found {
		InvertedIndexGroup[shard] = &types.InvertedIndexShard{
			InvertedIndex: make(map[string]*types.KeywordIndices),
		}
	}
}

// AddKeywordIndices  add keyword indices
func AddKeywordIndices(shard int, keyword string, keywordIndices *types.KeywordIndices) {
	invertedIndexGroupRWMutex.Lock()
	defer invertedIndexGroupRWMutex.Unlock()
	if _, ok := InvertedIndexGroup[shard]; !ok {
		InvertedIndexGroup[shard] = &types.InvertedIndexShard{
			InvertedIndex: make(map[string]*types.KeywordIndices),
		}
	}
	InvertedIndexGroup[shard].InvertedIndex[keyword] = keywordIndices
	InvertedIndexGroup[shard].TotalTokenLen++
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kyma 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 function

import (
	"context"
	"fmt"
	"os"
	"reflect"
	"strings"

	servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1"
	runtimev1alpha1 "github.com/kyma-incubator/runtime/pkg/apis/runtime/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/handler"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
	"sigs.k8s.io/controller-runtime/pkg/source"

	runtimeUtil "github.com/kyma-incubator/runtime/pkg/utils"
)

var log = logf.Log.WithName("controller")

// Add creates a new Function Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
	return add(mgr, newReconciler(mgr))
}

// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
	return &ReconcileFunction{Client: mgr.GetClient(), scheme: mgr.GetScheme()}
}

// add adds a new Controller to mgr with r as the reconcile.Reconciler
func add(mgr manager.Manager, r reconcile.Reconciler) error {
	// Create a new controller
	c, err := controller.New("function-controller", mgr, controller.Options{Reconciler: r})
	if err != nil {
		return err
	}

	// Watch for changes to Function
	err = c.Watch(&source.Kind{Type: &runtimev1alpha1.Function{}}, &handler.EnqueueRequestForObject{})
	if err != nil {
		return err
	}

	// TODO(user): Modify this to be the types you create
	// Uncomment watch a Deployment created by Function - change this for objects you create
	// err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, &handler.EnqueueRequestForOwner{
	// 	IsController: true,
	// 	OwnerType:    &runtimev1alpha1.Function{},
	// })
	// if err != nil {
	// 	return err
	// }

	return nil
}

var _ reconcile.Reconciler = &ReconcileFunction{}

// ReconcileFunction reconciles a Function object
type ReconcileFunction struct {
	client.Client
	scheme *runtime.Scheme
}

// Reconcile reads that state of the cluster for a Function object and makes changes based on the state read
// and what is in the Function.Spec
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=runtime.kyma-project.io,resources=functions,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=runtime.kyma-project.io,resources=functions/status,verbs=get;update;patch
func (r *ReconcileFunction) Reconcile(request reconcile.Request) (reconcile.Result, error) {

	fnConfigName := "fn-config"
	fnConfigNamespace := "default"
	fnConfigNameEnv := os.Getenv("CONTROLLER_CONFIGMAP")
	fnConfigNamespaceEnv := os.Getenv("CONTROLLER_CONFIGMAP_NS")

	if len(fnConfigNameEnv) > 0 {
		fnConfigName = fnConfigNameEnv
	}

	if len(fnConfigNamespaceEnv) > 0 {
		fnConfigNamespace = fnConfigNamespaceEnv
	}
	fnConfig := &corev1.ConfigMap{}
	err := r.Get(context.TODO(), types.NamespacedName{Name: fnConfigName, Namespace: fnConfigNamespace}, fnConfig)

	if err != nil {
		log.Error(err, "Unable to read Function controller config: %v from Namespace: %v", fnConfigName, fnConfigNamespace)
		return reconcile.Result{},
	}

	rnInfo, err := runtimeUtil.New(fnConfig)
	if err != nil {
		fmt.Printf("Error in reading ConfigMap: %v", err)
		return reconcile.Result{}, err
	}
	// Fetch the Function instance
	fn := &runtimev1alpha1.Function{}
	err = r.Get(context.TODO(), request.NamespacedName, fn)
	if err != nil {
		if errors.IsNotFound(err) {
			// Object not found, return.  Created objects are automatically garbage collected.
			// For additional cleanup logic use finalizers.
			return reconcile.Result{}, nil
		}
		// Error reading the object - requeue the request.
		return reconcile.Result{}, err
	}
	data := make(map[string]string)
	data["handler"] = "handler.main"
	data["handler.js"] = fn.Spec.Function
	if len(strings.Trim(fn.Spec.Deps, " ")) == 0 {
		data["package.json"] = "{}"
	} else {
		data["package.json"] = fn.Spec.Deps
	}

	// Managing a ConfigMap
	deployCm := &corev1.ConfigMap{
		ObjectMeta: metav1.ObjectMeta{
			Labels:    fn.Labels,
			Namespace: fn.Namespace,
			Name:      fn.Name,
		},
		Data: data,
	}
	if err := controllerutil.SetControllerReference(fn, deployCm, r.scheme); err != nil {
		return reconcile.Result{}, err
	}

	foundCm := &corev1.ConfigMap{}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployCm.Name, Namespace: deployCm.Namespace}, foundCm)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Creating ConfigMap", "namespace", deployCm.Namespace, "name", deployCm.Name)
		err = r.Create(context.TODO(), deployCm)
		if err != nil {
			return reconcile.Result{}, err
		}
	} else if err != nil {
		return reconcile.Result{}, err
	}

	if !reflect.DeepEqual(deployCm.Data, foundCm.Data) {
		foundCm.Data = deployCm.Data
		log.Info("Updating ConfigMap", "namespace", deployCm.Namespace, "name", deployCm.Name)
		err = r.Update(context.TODO(), foundCm)
		if err != nil {
			return reconcile.Result{}, err
		}
	}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployCm.Name, Namespace: deployCm.Namespace}, foundCm)
	if err != nil {
		log.Error(err, "namespace", deployCm.Namespace, "name", deployCm.Name)
	}
	cmVersion := foundCm.GetObjectMeta().GetResourceVersion()
	log.Info("Configmap version", "version", cmVersion)
	// Managing a resource of type Service.serving.knative.dev

	dockerRegistry := rnInfo.RegistryInfo
	imageName := fmt.Sprintf("%s/%s-%s:%s", dockerRegistry, fn.Namespace, fn.Name, cmVersion)
	log.Info("image name", "name:", imageName)
	deployService := &servingv1alpha1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Labels:    fn.Labels,
			Namespace: fn.Namespace,
			Name:      fn.Name,
		},
		Spec: runtimeUtil.GetServiceSpec(imageName, *fn, rnInfo),
	}

	if err := controllerutil.SetControllerReference(fn, deployService, r.scheme); err != nil {
		return reconcile.Result{}, err
	}

	foundService := &servingv1alpha1.Service{}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployService.Name, Namespace: deployService.Namespace}, foundService)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Creating Service", "namespace", deployService.Namespace, "name", deployService.Name)
		err = r.Create(context.TODO(), deployService)
		if err != nil {
			return reconcile.Result{}, err
		}
	} else if err != nil {
		fmt.Printf("Error while creating: %v", err)
		return reconcile.Result{}, err
	}

	if !reflect.DeepEqual(deployService.Spec, foundService.Spec) {
		foundService.Spec = deployService.Spec
		log.Info("Updating Service", "namespace", deployService.Namespace, "name", deployService.Name)
		err = r.Update(context.TODO(), foundService)
		if err != nil {
			return reconcile.Result{}, err
		}
	}

	return reconcile.Result{}, nil

}
<commit_msg>return error<commit_after>/*
Copyright 2019 The Kyma 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 function

import (
	"context"
	"fmt"
	"os"
	"reflect"
	"strings"

	servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1"
	runtimev1alpha1 "github.com/kyma-incubator/runtime/pkg/apis/runtime/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/handler"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
	"sigs.k8s.io/controller-runtime/pkg/source"

	runtimeUtil "github.com/kyma-incubator/runtime/pkg/utils"
)

var log = logf.Log.WithName("controller")

// Add creates a new Function Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
	return add(mgr, newReconciler(mgr))
}

// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
	return &ReconcileFunction{Client: mgr.GetClient(), scheme: mgr.GetScheme()}
}

// add adds a new Controller to mgr with r as the reconcile.Reconciler
func add(mgr manager.Manager, r reconcile.Reconciler) error {
	// Create a new controller
	c, err := controller.New("function-controller", mgr, controller.Options{Reconciler: r})
	if err != nil {
		return err
	}

	// Watch for changes to Function
	err = c.Watch(&source.Kind{Type: &runtimev1alpha1.Function{}}, &handler.EnqueueRequestForObject{})
	if err != nil {
		return err
	}

	// TODO(user): Modify this to be the types you create
	// Uncomment watch a Deployment created by Function - change this for objects you create
	// err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, &handler.EnqueueRequestForOwner{
	// 	IsController: true,
	// 	OwnerType:    &runtimev1alpha1.Function{},
	// })
	// if err != nil {
	// 	return err
	// }

	return nil
}

var _ reconcile.Reconciler = &ReconcileFunction{}

// ReconcileFunction reconciles a Function object
type ReconcileFunction struct {
	client.Client
	scheme *runtime.Scheme
}

// Reconcile reads that state of the cluster for a Function object and makes changes based on the state read
// and what is in the Function.Spec
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=runtime.kyma-project.io,resources=functions,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=runtime.kyma-project.io,resources=functions/status,verbs=get;update;patch
func (r *ReconcileFunction) Reconcile(request reconcile.Request) (reconcile.Result, error) {

	fnConfigName := "fn-config"
	fnConfigNamespace := "default"
	fnConfigNameEnv := os.Getenv("CONTROLLER_CONFIGMAP")
	fnConfigNamespaceEnv := os.Getenv("CONTROLLER_CONFIGMAP_NS")

	if len(fnConfigNameEnv) > 0 {
		fnConfigName = fnConfigNameEnv
	}

	if len(fnConfigNamespaceEnv) > 0 {
		fnConfigNamespace = fnConfigNamespaceEnv
	}
	fnConfig := &corev1.ConfigMap{}
	err := r.Get(context.TODO(), types.NamespacedName{Name: fnConfigName, Namespace: fnConfigNamespace}, fnConfig)

	if err != nil {
		log.Error(err, "Unable to read Function controller config: %v from Namespace: %v", fnConfigName, fnConfigNamespace)
		return reconcile.Result{}, err
	}

	rnInfo, err := runtimeUtil.New(fnConfig)
	if err != nil {
		fmt.Printf("Error in reading ConfigMap: %v", err)
		return reconcile.Result{}, err
	}
	// Fetch the Function instance
	fn := &runtimev1alpha1.Function{}
	err = r.Get(context.TODO(), request.NamespacedName, fn)
	if err != nil {
		if errors.IsNotFound(err) {
			// Object not found, return.  Created objects are automatically garbage collected.
			// For additional cleanup logic use finalizers.
			return reconcile.Result{}, nil
		}
		// Error reading the object - requeue the request.
		return reconcile.Result{}, err
	}
	data := make(map[string]string)
	data["handler"] = "handler.main"
	data["handler.js"] = fn.Spec.Function
	if len(strings.Trim(fn.Spec.Deps, " ")) == 0 {
		data["package.json"] = "{}"
	} else {
		data["package.json"] = fn.Spec.Deps
	}

	// Managing a ConfigMap
	deployCm := &corev1.ConfigMap{
		ObjectMeta: metav1.ObjectMeta{
			Labels:    fn.Labels,
			Namespace: fn.Namespace,
			Name:      fn.Name,
		},
		Data: data,
	}
	if err := controllerutil.SetControllerReference(fn, deployCm, r.scheme); err != nil {
		return reconcile.Result{}, err
	}

	foundCm := &corev1.ConfigMap{}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployCm.Name, Namespace: deployCm.Namespace}, foundCm)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Creating ConfigMap", "namespace", deployCm.Namespace, "name", deployCm.Name)
		err = r.Create(context.TODO(), deployCm)
		if err != nil {
			return reconcile.Result{}, err
		}
	} else if err != nil {
		return reconcile.Result{}, err
	}

	if !reflect.DeepEqual(deployCm.Data, foundCm.Data) {
		foundCm.Data = deployCm.Data
		log.Info("Updating ConfigMap", "namespace", deployCm.Namespace, "name", deployCm.Name)
		err = r.Update(context.TODO(), foundCm)
		if err != nil {
			return reconcile.Result{}, err
		}
	}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployCm.Name, Namespace: deployCm.Namespace}, foundCm)
	if err != nil {
		log.Error(err, "namespace", deployCm.Namespace, "name", deployCm.Name)
	}
	cmVersion := foundCm.GetObjectMeta().GetResourceVersion()
	log.Info("Configmap version", "version", cmVersion)
	// Managing a resource of type Service.serving.knative.dev

	dockerRegistry := rnInfo.RegistryInfo
	imageName := fmt.Sprintf("%s/%s-%s:%s", dockerRegistry, fn.Namespace, fn.Name, cmVersion)
	log.Info("image name", "name:", imageName)
	deployService := &servingv1alpha1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Labels:    fn.Labels,
			Namespace: fn.Namespace,
			Name:      fn.Name,
		},
		Spec: runtimeUtil.GetServiceSpec(imageName, *fn, rnInfo),
	}

	if err := controllerutil.SetControllerReference(fn, deployService, r.scheme); err != nil {
		return reconcile.Result{}, err
	}

	foundService := &servingv1alpha1.Service{}
	err = r.Get(context.TODO(), types.NamespacedName{Name: deployService.Name, Namespace: deployService.Namespace}, foundService)
	if err != nil && errors.IsNotFound(err) {
		log.Info("Creating Service", "namespace", deployService.Namespace, "name", deployService.Name)
		err = r.Create(context.TODO(), deployService)
		if err != nil {
			return reconcile.Result{}, err
		}
	} else if err != nil {
		fmt.Printf("Error while creating: %v", err)
		return reconcile.Result{}, err
	}

	if !reflect.DeepEqual(deployService.Spec, foundService.Spec) {
		foundService.Spec = deployService.Spec
		log.Info("Updating Service", "namespace", deployService.Namespace, "name", deployService.Name)
		err = r.Update(context.TODO(), foundService)
		if err != nil {
			return reconcile.Result{}, err
		}
	}

	return reconcile.Result{}, nil

}
<|endoftext|>


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

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"

	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)

var filterImplC string = `
struct icmp_t {
  unsigned char type;
  unsigned char code;
  unsigned short checksum;
} BPF_PACKET_HEADER;

BPF_TABLE("hash", u32, u32, endpoints, 1024);

struct match {
  u16 sport;
  u16 dport;
  u8 proto;
  u8 direction;
};
BPF_TABLE("hash", struct match, int, rules, 1024);

static int handle_tx(void *skb, struct metadata *md) {
  u8 *cursor = 0;
  struct match m = {};
  int ret = RX_DROP;
  u32 dst_tag = 0, src_tag = 0;
  if (md->data[0].type == 1)
    src_tag = md->data[0].value;

  ethernet: {
    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
    u16 ethertype = ethernet->type;
    switch (ethertype) {
    case ETH_P_IP: goto ip;
    case ETH_P_IPV6: goto ip6;
    case ETH_P_ARP: goto arp;
    default: goto DONE;
    }
  }

  ip: {
    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
    u32 dst_ip = ip->dst;
    m.proto = ip->nextp;

    u32 *tag = endpoints.lookup(&dst_ip);
    if (!tag)
      goto DONE;
    dst_tag = *tag;
    switch (m.proto) {
      case 1: goto icmp;
      case 6: goto tcp;
      case 17: goto udp;
      default: goto DONE;
    }
  }

  ip6: {
    goto DONE;
  }

  icmp: {
    struct icmp_t *icmp = cursor_advance(cursor, sizeof(*icmp));
    goto EOP;
  }

  tcp: {
    struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
    m.dport = tcp->dst_port;
    m.sport = tcp->src_port;
    goto EOP;
  }

  udp: {
    struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
    m.dport = udp->dport;
    m.sport = udp->sport;
    goto EOP;
  }

  arp: {
    return RX_OK;
  }

EOP: ;
  struct match m1 = {m.sport, m.dport, m.proto, 0};
  int *result = rules.lookup(&m1);
  if (result) {
    ret = *result;
    goto DONE;
  }
  struct match m2 = {m.sport, 0, m.proto, 2};
  result = rules.lookup(&m2);
  if (result) {
    ret = *result;
    goto DONE;
  }
  struct match m3 = {0, m.dport, m.proto, 1};
  result = rules.lookup(&m3);
  if (result) {
    ret = *result;
    goto DONE;
  }

DONE:
  return ret;
}

static int handle_rx(void *skb, struct metadata *md) {
  u8 *cursor = 0;
  u32 src_tag = 0;
  int ret = RX_OK;

  ethernet: {
    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
    u16 ethertype = ethernet->type;
    switch (ethertype) {
    case ETH_P_IP: goto ip;
    case ETH_P_IPV6: goto ip6;
    case ETH_P_ARP: goto arp;
    default: goto DONE;
    }
  }

  ip: {
    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
    u32 src_ip = ip->src;

    u32 *tag = endpoints.lookup(&src_ip);
    if (!tag)
      goto DONE;
    src_tag = *tag;
    goto DONE;
  }

  ip6: {
    goto DONE;
  }

  arp: {
    goto DONE;
  }

DONE:
  if (src_tag != 0) {
    md->data[0].type = 1;
    md->data[0].value = src_tag;
  }

  return ret;
}
`

type moduleEntry struct {
	Id          string                 `json:"id"`
	ModuleType  string                 `json:"module_type"`
	DisplayName string                 `json:"display_name"`
	Perm        string                 `json:"permissions"`
	Config      map[string]interface{} `json:"config"`
}

type tableEntry struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

type Dataplane struct {
	client  *http.Client
	baseUrl string
	id      string
	db      *sqlx.DB
}

func NewDataplane(sqlUrl string) *Dataplane {
	client := &http.Client{}
	d := &Dataplane{
		client: client,
		db:     sqlx.MustConnect("sqlite3", sqlUrl),
	}
	d.db.Exec(`
CREATE TABLE endpoints (
	ip CHAR(50)     PRIMARY KEY NOT NULL,
	tenant CHAR(40) NOT NULL,
	epg CHAR(40)    NOT NULL
);
`)
	return d
}

func (d *Dataplane) postObject(url string, requestObj interface{}, responseObj interface{}) (err error) {
	b, err := json.Marshal(requestObj)
	if err != nil {
		return
	}
	Debug.Printf("Uploading GBP dataplane code to %s\n", d.baseUrl)
	resp, err := d.client.Post(d.baseUrl+url, "application/json", bytes.NewReader(b))
	if err != nil {
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		var body []byte
		if body, err = ioutil.ReadAll(resp.Body); err != nil {
			Error.Print(string(body))
		}
		return fmt.Errorf("module server returned %s", resp.Status)
	}
	if responseObj != nil {
		err = json.NewDecoder(resp.Body).Decode(responseObj)
	}
	return
}

func (d *Dataplane) Init(baseUrl string) error {
	d.baseUrl = baseUrl
	req := map[string]interface{}{
		"module_type":  "bpf",
		"display_name": "gbp",
		"config": map[string]interface{}{
			"code":     filterImplC,
			"handlers": []string{"handle_rx", "handle_tx"},
		},
	}
	var module moduleEntry
	err := d.postObject("/modules/", req, &module)
	if err != nil {
		return err
	}
	d.id = module.Id
	return nil
}

func (d *Dataplane) Id() string {
	return d.id
}

func (d *Dataplane) Close() error {
	return nil
}

func epgToId(epgName string) int {
	// TODO: store in the DB a name->id mapping
	switch epgName {
	case "client":
		return 1
	case "web":
		return 2
	}
	return 0
}

func (d *Dataplane) ParsePolicy(policy *Policy) (err error) {
	Debug.Println("ParsePolicy")
	//consumerId := epgToId(policy.ConsumerEpgId)
	//providerId := epgToId(policy.ProviderEpgId)
	for _, ruleGroupConstrained := range policy.PolicyRuleGroups {
		for _, ruleGroup := range ruleGroupConstrained.PolicyRuleGroups {
			for _, rule := range ruleGroup.ResolvedRules {
				for _, classifier := range rule.Classifiers {
					m := classifier.ToMatch()
					k := fmt.Sprintf("{ %d %d %d %d }", m.SourcePort, m.DestPort, m.Proto, m.Direction)
					v := "2" // drop
					if rule.IsAllow() {
						v = "0"
					}
					Debug.Printf("rule %s %s\n", k, v)
					obj := &tableEntry{Key: k, Value: v}
					err = d.postObject("/modules/"+d.id+"/tables/rules/entries/", obj, nil)
					if err != nil {
						return
					}
				}
			}
		}
	}
	return
}

type EndpointEntry struct {
	Ip     string `db:"ip"`
	Tenant string `db:"tenant"`
	Epg    string `db:"epg"`
}

func (d *Dataplane) Endpoints() <-chan *EndpointEntry {
	ch := make(chan *EndpointEntry)
	rows, err := d.db.Queryx(`SELECT * FROM endpoints`)
	if err != nil {
		return nil
	}
	go func() {
		defer close(ch)
		for rows.Next() {
			var e EndpointEntry
			err = rows.StructScan(&e)
			if err != nil {
				return
			}
			ch <- &e
		}
	}()
	return ch
}

func ipStrToKey(ipStr string) (string, error) {
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return "", fmt.Errorf("ipStrToKey: ipStr is not a valid IP address")
	}
	if ip.To4() != nil {
		return fmt.Sprintf("%d", binary.BigEndian.Uint32(ip.To4())), nil
	}
	return "", fmt.Errorf("ipStrToKey: IPv6 support not implemented")
}
func (d *Dataplane) AddEndpoint(ipStr, tenant, epg string) (err error) {
	ipKey, err := ipStrToKey(ipStr)
	if err != nil {
		return
	}

	tx, err := d.db.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			Info.Printf("AddEndpoint: rolling back %s\n", ipStr)
			tx.Rollback()
		} else {
			err = tx.Commit()
		}
	}()
	_, err = tx.Exec(`INSERT INTO endpoints (ip, tenant, epg) VALUES (?, ?, ?)`, ipStr, tenant, epg)
	if err != nil {
		return
	}
	obj := &tableEntry{
		Key:   ipKey,
		Value: "1",
	}
	err = d.postObject("/modules/"+d.id+"/tables/endpoints/entries/", obj, nil)
	if err != nil {
		return
	}
	return
}

func (d *Dataplane) DeleteEndpoint(ip string) (err error) {
	tx, err := d.db.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			err = tx.Commit()
		}
	}()
	_, err = tx.Exec(`DELETE FROM endpoints WHERE ip=?`, ip)
	if err != nil {
		return
	}
	//err = d.deleteObject("/modules/"+d.id+"/tables/endpoints/entries/"+ip, nil, nil)
	return
}
<commit_msg>Switch to tab formatting for c embedded in .go files<commit_after>// Copyright 2015 PLUMgrid
//
// 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 gbp

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"

	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)

var filterImplC string = `
struct icmp_t {
	unsigned char type;
	unsigned char code;
	unsigned short checksum;
} BPF_PACKET_HEADER;

BPF_TABLE("hash", u32, u32, endpoints, 1024);

struct match {
	u16 sport;
	u16 dport;
	u8 proto;
	u8 direction;
};
BPF_TABLE("hash", struct match, int, rules, 1024);

static int handle_tx(void *skb, struct metadata *md) {
	u8 *cursor = 0;
	struct match m = {};
	int ret = RX_DROP;
	u32 dst_tag = 0, src_tag = 0;
	if (md->data[0].type == 1)
		src_tag = md->data[0].value;

	ethernet: {
		struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
		u16 ethertype = ethernet->type;
		switch (ethertype) {
			case ETH_P_IP: goto ip;
			case ETH_P_IPV6: goto ip6;
			case ETH_P_ARP: goto arp;
			default: goto DONE;
		}
	}

	ip: {
		struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
		u32 dst_ip = ip->dst;
		m.proto = ip->nextp;

		u32 *tag = endpoints.lookup(&dst_ip);
		if (!tag)
			goto DONE;
		dst_tag = *tag;
		switch (m.proto) {
			case 1: goto icmp;
			case 6: goto tcp;
			case 17: goto udp;
			default: goto DONE;
		}
	}

	ip6: {
		goto DONE;
	}

	icmp: {
		struct icmp_t *icmp = cursor_advance(cursor, sizeof(*icmp));
		goto EOP;
	}

	tcp: {
		struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
		m.dport = tcp->dst_port;
		m.sport = tcp->src_port;
		goto EOP;
	}

	udp: {
		struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
		m.dport = udp->dport;
		m.sport = udp->sport;
		goto EOP;
	}

	arp: {
		return RX_OK;
	}

EOP: ;
	struct match m1 = {m.sport, m.dport, m.proto, 0};
	int *result = rules.lookup(&m1);
	if (result) {
		ret = *result;
		goto DONE;
	}
	struct match m2 = {m.sport, 0, m.proto, 2};
	result = rules.lookup(&m2);
	if (result) {
		ret = *result;
		goto DONE;
	}
	struct match m3 = {0, m.dport, m.proto, 1};
	result = rules.lookup(&m3);
	if (result) {
		ret = *result;
		goto DONE;
	}

DONE:
	return ret;
}

static int handle_rx(void *skb, struct metadata *md) {
	u8 *cursor = 0;
	u32 src_tag = 0;
	int ret = RX_OK;

	ethernet: {
		struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
		u16 ethertype = ethernet->type;
		switch (ethertype) {
			case ETH_P_IP: goto ip;
			case ETH_P_IPV6: goto ip6;
			case ETH_P_ARP: goto arp;
			default: goto DONE;
		}
	}

	ip: {
		struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
		u32 src_ip = ip->src;

		u32 *tag = endpoints.lookup(&src_ip);
		if (!tag)
			goto DONE;
		src_tag = *tag;
		goto DONE;
	}

	ip6: {
		goto DONE;
	}

	arp: {
		goto DONE;
	}

DONE:
	if (src_tag != 0) {
		md->data[0].type = 1;
		md->data[0].value = src_tag;
	}

	return ret;
}
`

type moduleEntry struct {
	Id          string                 `json:"id"`
	ModuleType  string                 `json:"module_type"`
	DisplayName string                 `json:"display_name"`
	Perm        string                 `json:"permissions"`
	Config      map[string]interface{} `json:"config"`
}

type tableEntry struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

type Dataplane struct {
	client  *http.Client
	baseUrl string
	id      string
	db      *sqlx.DB
}

func NewDataplane(sqlUrl string) *Dataplane {
	client := &http.Client{}
	d := &Dataplane{
		client: client,
		db:     sqlx.MustConnect("sqlite3", sqlUrl),
	}
	d.db.Exec(`
CREATE TABLE endpoints (
	ip CHAR(50)     PRIMARY KEY NOT NULL,
	tenant CHAR(40) NOT NULL,
	epg CHAR(40)    NOT NULL
);
`)
	return d
}

func (d *Dataplane) postObject(url string, requestObj interface{}, responseObj interface{}) (err error) {
	b, err := json.Marshal(requestObj)
	if err != nil {
		return
	}
	Debug.Printf("Uploading GBP dataplane code to %s\n", d.baseUrl)
	resp, err := d.client.Post(d.baseUrl+url, "application/json", bytes.NewReader(b))
	if err != nil {
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		var body []byte
		if body, err = ioutil.ReadAll(resp.Body); err != nil {
			Error.Print(string(body))
		}
		return fmt.Errorf("module server returned %s", resp.Status)
	}
	if responseObj != nil {
		err = json.NewDecoder(resp.Body).Decode(responseObj)
	}
	return
}

func (d *Dataplane) Init(baseUrl string) error {
	d.baseUrl = baseUrl
	req := map[string]interface{}{
		"module_type":  "bpf",
		"display_name": "gbp",
		"config": map[string]interface{}{
			"code":     filterImplC,
			"handlers": []string{"handle_rx", "handle_tx"},
		},
	}
	var module moduleEntry
	err := d.postObject("/modules/", req, &module)
	if err != nil {
		return err
	}
	d.id = module.Id
	return nil
}

func (d *Dataplane) Id() string {
	return d.id
}

func (d *Dataplane) Close() error {
	return nil
}

func epgToId(epgName string) int {
	// TODO: store in the DB a name->id mapping
	switch epgName {
	case "client":
		return 1
	case "web":
		return 2
	}
	return 0
}

func (d *Dataplane) ParsePolicy(policy *Policy) (err error) {
	Debug.Println("ParsePolicy")
	//consumerId := epgToId(policy.ConsumerEpgId)
	//providerId := epgToId(policy.ProviderEpgId)
	for _, ruleGroupConstrained := range policy.PolicyRuleGroups {
		for _, ruleGroup := range ruleGroupConstrained.PolicyRuleGroups {
			for _, rule := range ruleGroup.ResolvedRules {
				for _, classifier := range rule.Classifiers {
					m := classifier.ToMatch()
					k := fmt.Sprintf("{ %d %d %d %d }", m.SourcePort, m.DestPort, m.Proto, m.Direction)
					v := "2" // drop
					if rule.IsAllow() {
						v = "0"
					}
					Debug.Printf("rule %s %s\n", k, v)
					obj := &tableEntry{Key: k, Value: v}
					err = d.postObject("/modules/"+d.id+"/tables/rules/entries/", obj, nil)
					if err != nil {
						return
					}
				}
			}
		}
	}
	return
}

type EndpointEntry struct {
	Ip     string `db:"ip"`
	Tenant string `db:"tenant"`
	Epg    string `db:"epg"`
}

func (d *Dataplane) Endpoints() <-chan *EndpointEntry {
	ch := make(chan *EndpointEntry)
	rows, err := d.db.Queryx(`SELECT * FROM endpoints`)
	if err != nil {
		return nil
	}
	go func() {
		defer close(ch)
		for rows.Next() {
			var e EndpointEntry
			err = rows.StructScan(&e)
			if err != nil {
				return
			}
			ch <- &e
		}
	}()
	return ch
}

func ipStrToKey(ipStr string) (string, error) {
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return "", fmt.Errorf("ipStrToKey: ipStr is not a valid IP address")
	}
	if ip.To4() != nil {
		return fmt.Sprintf("%d", binary.BigEndian.Uint32(ip.To4())), nil
	}
	return "", fmt.Errorf("ipStrToKey: IPv6 support not implemented")
}
func (d *Dataplane) AddEndpoint(ipStr, tenant, epg string) (err error) {
	ipKey, err := ipStrToKey(ipStr)
	if err != nil {
		return
	}

	tx, err := d.db.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			Info.Printf("AddEndpoint: rolling back %s\n", ipStr)
			tx.Rollback()
		} else {
			err = tx.Commit()
		}
	}()
	_, err = tx.Exec(`INSERT INTO endpoints (ip, tenant, epg) VALUES (?, ?, ?)`, ipStr, tenant, epg)
	if err != nil {
		return
	}
	obj := &tableEntry{
		Key:   ipKey,
		Value: "1",
	}
	err = d.postObject("/modules/"+d.id+"/tables/endpoints/entries/", obj, nil)
	if err != nil {
		return
	}
	return
}

func (d *Dataplane) DeleteEndpoint(ip string) (err error) {
	tx, err := d.db.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			err = tx.Commit()
		}
	}()
	_, err = tx.Exec(`DELETE FROM endpoints WHERE ip=?`, ip)
	if err != nil {
		return
	}
	//err = d.deleteObject("/modules/"+d.id+"/tables/endpoints/entries/"+ip, nil, nil)
	return
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"html/template"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	g "github.com/gogits/git"
	"github.com/lemmi/ghfs"
	"github.com/lemmi/glubcms"
	"github.com/raymondbutcher/tidyhtml"
)

const (
	tmplPath = "templates"
)

func POE(err error, prefix ...interface{}) {
	if err != nil {
		log.Print(prefix...)
		log.Fatal(err)
	}
}

func parseTemplates(fs http.FileSystem) (*template.Template, error) {
	dir, err := fs.Open(tmplPath)
	if err != nil {
		return nil, err
	}
	tmain := template.New("main")
	fis, err := dir.Readdir(-1)
	if err != nil {
		return nil, err
	}
	for _, fi := range fis {
		if !strings.HasSuffix(fi.Name(), ".tmpl") {
			continue
		}
		data, err := fs.Open(filepath.Join(tmplPath, fi.Name()))
		if err != nil {
			return nil, err
		}
		databytes, err := ioutil.ReadAll(data)
		data.Close()
		if err != nil {
			return nil, err
		}

		tname := strings.TrimSuffix(fi.Name(), ".tmpl")
		_, err = tmain.New(tname).Parse(string(databytes))
		if err != nil {
			return nil, err
		}
	}

	return tmain, nil
}

type StaticHandler struct {
	fs http.FileSystem
}

func (sh StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ServeContentFs(w, r, sh.fs)
}
func newStaticHandler(c *g.Commit) (http.Handler, error) {
	stree, err := c.Tree.SubTree("static")
	return http.FileServer(ghfs.FromCommit(c, stree)), err
}

type pageHandler struct {
	c *g.Commit
}

func newPageHandler(c *g.Commit) http.Handler {
	return pageHandler{c}
}
func (h pageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	tmpl := template.Must(parseTemplates(ghfs.FromCommit(h.c)))
	stree, err := h.c.Tree.SubTree("pages")
	POE(err, "Pages")

	p := glubcms.PageFromDir(ghfs.FromCommit(h.c, stree), r.URL.Path)
	buf := bytes.Buffer{}
	if err := tmpl.ExecuteTemplate(&buf, "main", p); err != nil {
		log.Println(err)
		return
	}
	tbuf := bytes.Buffer{}
	if err := tidyhtml.Copy(&tbuf, &buf); err != nil {
		log.Println(err)
		return
	}
	w.Header().Set("Content-Type", "text/html")
	http.ServeContent(w, r, "", h.c.Author.When, bytes.NewReader(tbuf.Bytes()))
}

// func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)
func ServeContentFs(w http.ResponseWriter, req *http.Request, fs http.FileSystem) {
	path := filepath.Clean(req.URL.Path)
	f, err := fs.Open(path)
	if err != nil {
		http.Error(w, path, http.StatusNotFound)
		return
	}
	defer f.Close()
	stat, err := f.Stat()
	if err != nil {
		http.Error(w, path, http.StatusInternalServerError)
		return
	}
	if stat.IsDir() {
		http.Error(w, path, http.StatusForbidden)
		return
	}
	http.ServeContent(w, req, stat.Name(), stat.ModTime(), f)
}

type handler struct {
	prefix string
}

func newHandler(prefix string) handler {
	return handler{
		prefix: prefix,
	}
}

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path, err := filepath.Abs(h.prefix)
	POE(err, "Filepath")

	repo, err := g.OpenRepository(path)
	POE(err, "OpenRepository")

	commit, err := repo.GetCommitOfBranch("master")
	POE(err, "LookupBranch")

	mux := http.NewServeMux()

	staticHandler, err := newStaticHandler(commit)
	POE(err, "StaticHandler")

	mux.Handle("/static/", http.StripPrefix("/static/", staticHandler))
	mux.Handle("/robots.txt", staticHandler)
	mux.Handle("/favicon.ico", staticHandler)
	mux.Handle("/", newPageHandler(commit))
	w.Header().Set("ETag", strings.Trim(commit.Id.String(), "\""))
	w.Header().Set("Cache-Control", "max-age=32")
	mux.ServeHTTP(w, r)
}

func main() {
	prefix := flag.String("prefix", "../example_page", "path to the root dir")
	addr := flag.String("bind", "localhost:8080", "address or path to bind to")
	network := flag.String("net", "tcp", `"tcp", "tcp4", "tcp6", "unix" or "unixpacket"`)
	flag.Parse()
	ln, err := net.Listen(*network, *addr)
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	if strings.HasPrefix(*network, "unix") {
		err = os.Chmod(*addr, 0666)
	}
	if err != nil {
		panic(err)
	}
	log.Fatal(http.Serve(ln, newHandler(*prefix)))
}
<commit_msg>gcserver: use new errors package<commit_after>package main

import (
	"bytes"
	"flag"
	"github.com/pkg/errors"
	"html/template"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	g "github.com/gogits/git"
	"github.com/lemmi/ghfs"
	"github.com/lemmi/glubcms"
	"github.com/raymondbutcher/tidyhtml"
)

const (
	tmplPath = "templates"
)

func POE(err error, prefix ...interface{}) {
	if err != nil {
		log.Print(prefix...)
		log.Fatal(err)
	}
}

func parseTemplates(fs http.FileSystem) (*template.Template, error) {
	dir, err := fs.Open(tmplPath)
	if err != nil {
		return nil, errors.Wrapf(err, "Cannot open directory: %q", tmplPath)
	}
	defer dir.Close()
	tmain := template.New("main")
	fis, err := dir.Readdir(-1)
	if err != nil {
		return nil, errors.Wrapf(err, "Cannot read directory: %q", tmplPath)
	}
	for _, fi := range fis {
		if !strings.HasSuffix(fi.Name(), ".tmpl") {
			continue
		}
		fpath := filepath.Join(tmplPath, fi.Name())
		data, err := fs.Open(fpath)
		if err != nil {
			return nil, errors.Wrapf(err, "Cannot open file: %q", fpath)
		}
		databytes, err := ioutil.ReadAll(data)
		data.Close()
		if err != nil {
			return nil, errors.Wrapf(err, "Cannot read file: %q", fpath)
		}

		tname := strings.TrimSuffix(fi.Name(), ".tmpl")
		_, err = tmain.New(tname).Parse(string(databytes))
		if err != nil {
			return nil, errors.Wrapf(err, "Cannot parse template: %q", fpath)
		}
	}

	return tmain, nil
}

type StaticHandler struct {
	fs http.FileSystem
}

func (sh StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ServeContentFs(w, r, sh.fs)
}
func newStaticHandler(c *g.Commit) (http.Handler, error) {
	stree, err := c.Tree.SubTree("static")
	return http.FileServer(ghfs.FromCommit(c, stree)), err
}

type pageHandler struct {
	c *g.Commit
}

func newPageHandler(c *g.Commit) http.Handler {
	return pageHandler{c}
}
func (h pageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	tmpl := template.Must(parseTemplates(ghfs.FromCommit(h.c)))
	stree, err := h.c.Tree.SubTree("pages")
	POE(err, "Pages")

	p := glubcms.PageFromDir(ghfs.FromCommit(h.c, stree), r.URL.Path)
	buf := bytes.Buffer{}
	if err := tmpl.ExecuteTemplate(&buf, "main", p); err != nil {
		log.Println(errors.Wrapf(err, "template execution failed: %q", r.URL.Path))
		return
	}
	tbuf := bytes.Buffer{}
	if err := tidyhtml.Copy(&tbuf, &buf); err != nil {
		log.Println(errors.Wrapf(err, "tidyhtml failed: %q", r.URL.Path))
		return
	}
	w.Header().Set("Content-Type", "text/html")
	http.ServeContent(w, r, "", h.c.Author.When, bytes.NewReader(tbuf.Bytes()))
}

// func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)
func ServeContentFs(w http.ResponseWriter, req *http.Request, fs http.FileSystem) {
	path := filepath.Clean(req.URL.Path)
	f, err := fs.Open(path)
	if err != nil {
		http.Error(w, path, http.StatusNotFound)
		return
	}
	defer f.Close()
	stat, err := f.Stat()
	if err != nil {
		http.Error(w, path, http.StatusInternalServerError)
		return
	}
	if stat.IsDir() {
		http.Error(w, path, http.StatusForbidden)
		return
	}
	http.ServeContent(w, req, stat.Name(), stat.ModTime(), f)
}

type handler struct {
	prefix string
}

func newHandler(prefix string) handler {
	return handler{
		prefix: prefix,
	}
}

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path, err := filepath.Abs(h.prefix)
	POE(err, "Filepath")

	repo, err := g.OpenRepository(path)
	POE(err, "OpenRepository")

	commit, err := repo.GetCommitOfBranch("master")
	POE(err, "LookupBranch")

	mux := http.NewServeMux()

	staticHandler, err := newStaticHandler(commit)
	POE(err, "StaticHandler")

	mux.Handle("/static/", http.StripPrefix("/static/", staticHandler))
	mux.Handle("/robots.txt", staticHandler)
	mux.Handle("/favicon.ico", staticHandler)
	mux.Handle("/", newPageHandler(commit))
	w.Header().Set("ETag", strings.Trim(commit.Id.String(), "\""))
	w.Header().Set("Cache-Control", "max-age=32")
	mux.ServeHTTP(w, r)
}

func main() {
	prefix := flag.String("prefix", "../example_page", "path to the root dir")
	addr := flag.String("bind", "localhost:8080", "address or path to bind to")
	network := flag.String("net", "tcp", `"tcp", "tcp4", "tcp6", "unix" or "unixpacket"`)
	flag.Parse()
	ln, err := net.Listen(*network, *addr)
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	if strings.HasPrefix(*network, "unix") {
		err = os.Chmod(*addr, 0666)
	}
	if err != nil {
		panic(err)
	}
	log.Fatal(http.Serve(ln, newHandler(*prefix)))
}
<|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 gcsproxy

import (
	"errors"
	"fmt"

	"github.com/googlecloudplatform/gcsfuse/lease"
	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
)

// Given an object record and content that was originally derived from that
// object's contents (and potentially modified):
//
// *   If the content has not been modified, return a nil read proxy and a nil
//     new object.
//
// *   Otherwise, write out a new generation in the bucket (failing with
//     *gcs.PreconditionError if the source generation is no longer current)
//     and return a read proxy for that object's contents.
//
// In the second case, the MutableContent is destroyed. Otherwise, including
// when this function fails, it is guaranteed to still be valid.
func Sync(
	ctx context.Context,
	srcObject *gcs.Object,
	content MutableContent,
	bucket gcs.Bucket) (
	newProxy lease.ReadProxy, newObject *gcs.Object, err error) {
	// Stat the content.
	sr, err := content.Stat()
	if err != nil {
		err = fmt.Errorf("Stat: %v", err)
		return
	}

	err = errors.New("TODO")
	return
}
<commit_msg>Started on Sync.<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 gcsproxy

import (
	"errors"
	"fmt"

	"github.com/googlecloudplatform/gcsfuse/lease"
	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
)

// Given an object record and content that was originally derived from that
// object's contents (and potentially modified):
//
// *   If the content has not been modified, return a nil read proxy and a nil
//     new object.
//
// *   Otherwise, write out a new generation in the bucket (failing with
//     *gcs.PreconditionError if the source generation is no longer current)
//     and return a read proxy for that object's contents.
//
// In the second case, the MutableContent is destroyed. Otherwise, including
// when this function fails, it is guaranteed to still be valid.
func Sync(
	ctx context.Context,
	srcObject *gcs.Object,
	content MutableContent,
	bucket gcs.Bucket) (
	newProxy lease.ReadProxy, newObject *gcs.Object, err error) {
	// Stat the content.
	sr, err := content.Stat(ctx)
	if err != nil {
		err = fmt.Errorf("Stat: %v", err)
		return
	}

	// Make sure the dirty threshold makes sense.
	if sr.DirtyThreshold > int64(srcObject.Size) {
		err = fmt.Errorf(
			"Weird DirtyThreshold field: %d vs. %d",
			sr.DirtyThreshold,
			srcObject.Size)

		return
	}

	// If the content hasn't been dirtied, we're done.
	if sr.DirtyThreshold == int64(srcObject.Size) {
		return
	}

	// Otherwise, we need to create a new generation.
	err = errors.New("TODO")

	return
}
<|endoftext|>


<commit_before>// Copyright 2021 The Knative 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 core

import (
	"github.com/spf13/cobra"
	"knative.dev/kn-plugin-operator/pkg"
	"knative.dev/kn-plugin-operator/pkg/command/configure"
	"knative.dev/kn-plugin-operator/pkg/command/enable"
	"knative.dev/kn-plugin-operator/pkg/command/install"
	"knative.dev/kn-plugin-operator/pkg/command/remove"
	"knative.dev/kn-plugin-operator/pkg/command/uninstall"
)

var cfgFile string

// operationCmd represents the base command when called without any subcommands
func NewOperationCommand() *cobra.Command {
	p := &pkg.OperatorParams{}
	p.Initialize()
	rootCmd := &cobra.Command{
		Use:   "kn operation",
		Short: "A plugin of kn client to operate Knative components",
		Long: `kn operation: a plugin of kn client to operate Knative components.
For example:
kn operation install
kn operation install -c serving
kn operation install -c eventing
`,
	}

	rootCmd.AddCommand(install.NewInstallCommand(p))
	rootCmd.AddCommand(uninstall.NewUninstallCommand(p))
	rootCmd.AddCommand(enable.NewEnableCommand(p))
	rootCmd.AddCommand(configure.NewConfigureCommand(p))
	rootCmd.AddCommand(remove.NewRemoveCommand(p))
	return rootCmd
}
<commit_msg>fix typo in root command display (#202)<commit_after>// Copyright 2021 The Knative 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 core

import (
	"github.com/spf13/cobra"
	"knative.dev/kn-plugin-operator/pkg"
	"knative.dev/kn-plugin-operator/pkg/command/configure"
	"knative.dev/kn-plugin-operator/pkg/command/enable"
	"knative.dev/kn-plugin-operator/pkg/command/install"
	"knative.dev/kn-plugin-operator/pkg/command/remove"
	"knative.dev/kn-plugin-operator/pkg/command/uninstall"
)

var cfgFile string

// operationCmd represents the base command when called without any subcommands
func NewOperationCommand() *cobra.Command {
	p := &pkg.OperatorParams{}
	p.Initialize()
	rootCmd := &cobra.Command{
		Use:   "kn operator",
		Short: "A plugin of kn client to operate Knative components",
		Long: `kn operator: a plugin of kn client to operate Knative components.
For example:
kn operator install
kn operator install -c serving
kn operator install -c eventing
`,
	}

	rootCmd.AddCommand(install.NewInstallCommand(p))
	rootCmd.AddCommand(uninstall.NewUninstallCommand(p))
	rootCmd.AddCommand(enable.NewEnableCommand(p))
	rootCmd.AddCommand(configure.NewConfigureCommand(p))
	rootCmd.AddCommand(remove.NewRemoveCommand(p))
	return rootCmd
}
<|endoftext|>


<commit_before>package core

import (
	"log"
	"testing"
)

func TestFunct(t *testing.T) {
	res := TestFunc()
	log.Println(res)
	//t.Errorf("bang")
}<commit_msg>breaking test<commit_after>package core

import (
	"log"
	"testing"
)

func TestFunct(t *testing.T) {
	res := TestFunc()
	log.Println(res)
	t.Errorf("bang")
}<|endoftext|>


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

package pathutil

import (
	"os"
	"path/filepath"
)

var (
	vcsDirs     = []string{".git", ".svn", ".hg"}
	foundVCSDir bool
)

// FindVCSRoot find package root path from arg path
func FindVCSRoot(basedir string) string {
	foundVCSDir = false

	for {
		filepath.Walk(basedir, findvcsDirWalkFunc)
		if !foundVCSDir {
			basedir = filepath.Dir(basedir)
			continue
		}
		break
	}

	return filepath.Clean(basedir)
}

func findvcsDirWalkFunc(path string, fileInfo os.FileInfo, err error) error {
	if err != nil || fileInfo == nil || fileInfo.IsDir() == false {
		return nil
	}

	for _, d := range vcsDirs {
		_, err := os.Stat(filepath.Join(path, d))
		if err == nil {
			foundVCSDir = true
			break
		}
	}

	return nil
}
<commit_msg>internal/pathutil: remove foundVCSDir global variable on FindVCSRoot<commit_after>// Copyright 2016 The nvim-go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pathutil

import (
	"os"
	"path/filepath"
)

var vcsDirs = []string{".git", ".svn", ".hg"}

// FindVCSRoot find package root path from arg path
func FindVCSRoot(basedir string) string {
	var foundVCSDir bool

	findvcsDirWalkFunc := func(path string, info os.FileInfo, err error) error {
		if err != nil || info == nil || info.IsDir() == false {
			return nil
		}

		for _, d := range vcsDirs {
			_, err := os.Stat(filepath.Join(path, d))
			if err == nil {
				foundVCSDir = true
				break
			}
		}

		return nil
	}

	for {
		filepath.Walk(basedir, findvcsDirWalkFunc)
		if !foundVCSDir {
			basedir = filepath.Dir(basedir)
			continue
		}
		break
	}

	return filepath.Clean(basedir)
}
<|endoftext|>


<commit_before>package main

import "github.com/shirou/gopsutil"

type CPUStat struct {
	old []gopsutil.CPUTimesStat
}

func (s *CPUStat) Emit(emit emitFunc) error {
	stats, err := gopsutil.CPUTimes(false)
	if err != nil {
		return err
	}

	if s.old == nil {
		// First time
		s.old = stats
		return nil
	}

	for i, old := range s.old {
		cur := stats[i]
		user := cur.User - old.User
		nice := cur.Nice - old.Nice
		system := cur.System - old.System
		idle := cur.Idle - old.Idle
		iowait := cur.Iowait - old.Iowait
		irq := cur.Irq - old.Irq
		softirq := cur.Softirq - old.Softirq
		stolen := cur.Stolen - old.Stolen

		total := user + nice + system + idle + iowait + irq + softirq + stolen
		emit("cpu", map[string]interface{}{
			"cpu":     old.CPU,
			"user":    user / total * 100,
			"nice":    nice / total * 100,
			"system":  system / total * 100,
			"idle":    idle / total * 100,
			"iowait":  iowait / total * 100,
			"irq":     irq / total * 100,
			"softirq": softirq / total * 100,
			"stolen":  stolen / total * 100,
		})
	}
	s.old = stats
	return nil
}
<commit_msg>Add cumulative used value to cpu usage<commit_after>package main

import "github.com/shirou/gopsutil"

type CPUStat struct {
	old []gopsutil.CPUTimesStat
}

func (s *CPUStat) Emit(emit emitFunc) error {
	stats, err := gopsutil.CPUTimes(false)
	if err != nil {
		return err
	}

	if s.old == nil {
		// First time
		s.old = stats
		return nil
	}

	for i, old := range s.old {
		cur := stats[i]
		user := cur.User - old.User
		nice := cur.Nice - old.Nice
		system := cur.System - old.System
		idle := cur.Idle - old.Idle
		iowait := cur.Iowait - old.Iowait
		irq := cur.Irq - old.Irq
		softirq := cur.Softirq - old.Softirq
		stolen := cur.Stolen - old.Stolen

		total := user + nice + system + idle + iowait + irq + softirq + stolen
		idle_percent := idle / total * 100
		emit("cpu", map[string]interface{}{
			"cpu":     old.CPU,
			"used":    100 - idle_percent,
			"user":    user / total * 100,
			"nice":    nice / total * 100,
			"system":  system / total * 100,
			"idle":    idle_percent,
			"iowait":  iowait / total * 100,
			"irq":     irq / total * 100,
			"softirq": softirq / total * 100,
			"stolen":  stolen / total * 100,
		})
	}
	s.old = stats
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 The appc 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 lib

import (
	"archive/tar"
	"fmt"
	"os"
	"path/filepath"

	"github.com/appc/acbuild/Godeps/_workspace/src/github.com/appc/spec/aci"
	"github.com/appc/acbuild/Godeps/_workspace/src/github.com/appc/spec/schema/types"

	"github.com/appc/acbuild/util"
)

// Write will produce the resulting ACI from the current build context, saving
// it to the given path, optionally signing it.
func (a *ACBuild) Write(output string, overwrite, sign bool, gpgflags []string) (err error) {
	if err = a.lock(); err != nil {
		return err
	}
	defer func() {
		if err1 := a.unlock(); err == nil {
			err = err1
		}
	}()

	man, err := util.GetManifest(a.CurrentACIPath)
	if err != nil {
		return err
	}

	if man.App != nil && len(man.App.Exec) == 0 {
		fmt.Fprintf(os.Stderr, "warning: exec command was never set.\n")
	}

	if man.Name == types.ACIdentifier(placeholdername) {
		return fmt.Errorf("can't write ACI, name was never set")
	}

	ex, err := util.Exists(output)
	if err != nil {
		return err
	}
	if ex {
		if !overwrite {
			return fmt.Errorf("ACI already exists: %s", output)
		}
		err := os.Remove(output)
		if err != nil {
			return err
		}
	}

	ofile, err := os.OpenFile(output, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}

	aw := aci.NewImageWriter(*man, tar.NewWriter(ofile))

	err = filepath.Walk(a.CurrentACIPath, aci.BuildWalker(a.CurrentACIPath, aw, nil))

	aw.Close()
	ofile.Close()

	if err != nil {
		return err
	}

	if sign {
		err = signACI(output, output+".asc", gpgflags)
		if err != nil {
			os.Remove(output)
			os.Remove(output + ".asc")
			return err
		}
	}

	return nil
}

func signACI(acipath, signaturepath string, flags []string) error {
	if len(flags) == 0 {
		flags = []string{"--armor", "--yes"}
	}
	flags = append(flags, "--output", signaturepath, "--detach-sig", acipath)

	return util.Exec("gpg", flags...)
}
<commit_msg>write: Update to perform overwriting with truncate rather than remove<commit_after>// Copyright 2015 The appc 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 lib

import (
	"archive/tar"
	"fmt"
	"os"
	"path/filepath"

	"github.com/appc/acbuild/Godeps/_workspace/src/github.com/appc/spec/aci"
	"github.com/appc/acbuild/Godeps/_workspace/src/github.com/appc/spec/schema/types"

	"github.com/appc/acbuild/util"
)

// Write will produce the resulting ACI from the current build context, saving
// it to the given path, optionally signing it.
func (a *ACBuild) Write(output string, overwrite, sign bool, gpgflags []string) (err error) {
	if err = a.lock(); err != nil {
		return err
	}
	defer func() {
		if err1 := a.unlock(); err == nil {
			err = err1
		}
	}()

	man, err := util.GetManifest(a.CurrentACIPath)
	if err != nil {
		return err
	}

	if man.App != nil && len(man.App.Exec) == 0 {
		fmt.Fprintf(os.Stderr, "warning: exec command was never set.\n")
	}

	if man.Name == types.ACIdentifier(placeholdername) {
		return fmt.Errorf("can't write ACI, name was never set")
	}

	fileFlags := os.O_CREATE | os.O_WRONLY

	ex, err := util.Exists(output)
	if err != nil {
		return err
	}
	if ex {
		if !overwrite {
			return fmt.Errorf("ACI already exists: %s", output)
		}
		fileFlags |= os.O_TRUNC
	}

	ofile, err := os.OpenFile(output, fileFlags, 0644)
	if err != nil {
		return err
	}

	aw := aci.NewImageWriter(*man, tar.NewWriter(ofile))

	err = filepath.Walk(a.CurrentACIPath, aci.BuildWalker(a.CurrentACIPath, aw, nil))

	aw.Close()
	ofile.Close()

	if err != nil {
		return err
	}

	if sign {
		err = signACI(output, output+".asc", gpgflags)
		if err != nil {
			os.Remove(output)
			os.Remove(output + ".asc")
			return err
		}
	}

	return nil
}

func signACI(acipath, signaturepath string, flags []string) error {
	if len(flags) == 0 {
		flags = []string{"--armor", "--yes"}
	}
	flags = append(flags, "--output", signaturepath, "--detach-sig", acipath)

	return util.Exec("gpg", flags...)
}
<|endoftext|>


<commit_before>// +build linux

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"strings"

	"github.com/openshift/origin/pkg/sdn/plugin/cniserver"

	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
)

type cniPlugin struct {
	socketPath string
}

func NewCNIPlugin(socketPath string) *cniPlugin {
	return &cniPlugin{socketPath: socketPath}
}

// Create and fill a CNIRequest with this plugin's environment and stdin which
// contain the CNI variables and configuration
func newCNIRequest(args *skel.CmdArgs) *cniserver.CNIRequest {
	envMap := make(map[string]string)
	for _, item := range os.Environ() {
		idx := strings.Index(item, "=")
		if idx > 0 {
			envMap[strings.TrimSpace(item[:idx])] = item[idx+1:]
		}
	}

	return &cniserver.CNIRequest{
		Env:    envMap,
		Config: args.StdinData,
	}
}

// Send a CNI request to the CNI server via JSON + HTTP over a root-owned unix socket,
// and return the result
func (p *cniPlugin) doCNI(url string, req *cniserver.CNIRequest) ([]byte, error) {
	data, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal CNI request %v: %v", req, err)
	}

	client := &http.Client{
		Transport: &http.Transport{
			Dial: func(proto, addr string) (net.Conn, error) {
				return net.Dial("unix", p.socketPath)
			},
		},
	}

	resp, err := client.Post(url, "application/json", bytes.NewReader(data))
	if err != nil {
		return nil, fmt.Errorf("failed to send CNI request: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read CNI result: %v", err)
	}

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("CNI request failed with status %v: '%s'", resp.StatusCode, string(body))
	}

	return body, nil
}

// Send the ADD command environment and config to the CNI server, returning
// the IPAM result to the caller
func (p *cniPlugin) CmdAdd(args *skel.CmdArgs) (*types.Result, error) {
	body, err := p.doCNI("http://dummy/", newCNIRequest(args))
	if err != nil {
		return nil, err
	}

	result := &types.Result{}
	if err := json.Unmarshal(body, result); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response '%s': %v", string(body), err)
	}

	return result, nil
}

// Send the ADD command environment and config to the CNI server, printing
// the IPAM result to stdout when called as a CNI plugin
func (p *cniPlugin) skelCmdAdd(args *skel.CmdArgs) error {
	result, err := p.CmdAdd(args)
	if err != nil {
		return err
	}
	return result.Print()
}

// Send the DEL command environment and config to the CNI server
func (p *cniPlugin) CmdDel(args *skel.CmdArgs) error {
	_, err := p.doCNI("http://dummy/", newCNIRequest(args))
	return err
}

func main() {
	p := NewCNIPlugin(cniserver.CNIServerSocketPath)
	skel.PluginMain(p.skelCmdAdd, p.CmdDel)
}
<commit_msg>sdn: update for bumped CNI<commit_after>// +build linux

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"strings"

	"github.com/openshift/origin/pkg/sdn/plugin/cniserver"

	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/containernetworking/cni/pkg/version"
)

type cniPlugin struct {
	socketPath string
}

func NewCNIPlugin(socketPath string) *cniPlugin {
	return &cniPlugin{socketPath: socketPath}
}

// Create and fill a CNIRequest with this plugin's environment and stdin which
// contain the CNI variables and configuration
func newCNIRequest(args *skel.CmdArgs) *cniserver.CNIRequest {
	envMap := make(map[string]string)
	for _, item := range os.Environ() {
		idx := strings.Index(item, "=")
		if idx > 0 {
			envMap[strings.TrimSpace(item[:idx])] = item[idx+1:]
		}
	}

	return &cniserver.CNIRequest{
		Env:    envMap,
		Config: args.StdinData,
	}
}

// Send a CNI request to the CNI server via JSON + HTTP over a root-owned unix socket,
// and return the result
func (p *cniPlugin) doCNI(url string, req *cniserver.CNIRequest) ([]byte, error) {
	data, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal CNI request %v: %v", req, err)
	}

	client := &http.Client{
		Transport: &http.Transport{
			Dial: func(proto, addr string) (net.Conn, error) {
				return net.Dial("unix", p.socketPath)
			},
		},
	}

	resp, err := client.Post(url, "application/json", bytes.NewReader(data))
	if err != nil {
		return nil, fmt.Errorf("failed to send CNI request: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read CNI result: %v", err)
	}

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("CNI request failed with status %v: '%s'", resp.StatusCode, string(body))
	}

	return body, nil
}

// Send the ADD command environment and config to the CNI server, returning
// the IPAM result to the caller
func (p *cniPlugin) CmdAdd(args *skel.CmdArgs) (*types.Result, error) {
	body, err := p.doCNI("http://dummy/", newCNIRequest(args))
	if err != nil {
		return nil, err
	}

	result := &types.Result{}
	if err := json.Unmarshal(body, result); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response '%s': %v", string(body), err)
	}

	return result, nil
}

// Send the ADD command environment and config to the CNI server, printing
// the IPAM result to stdout when called as a CNI plugin
func (p *cniPlugin) skelCmdAdd(args *skel.CmdArgs) error {
	result, err := p.CmdAdd(args)
	if err != nil {
		return err
	}
	return result.Print()
}

// Send the DEL command environment and config to the CNI server
func (p *cniPlugin) CmdDel(args *skel.CmdArgs) error {
	_, err := p.doCNI("http://dummy/", newCNIRequest(args))
	return err
}

func main() {
	p := NewCNIPlugin(cniserver.CNIServerSocketPath)
	skel.PluginMain(p.skelCmdAdd, p.CmdDel, version.Legacy)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

func processFile(writer *bufio.Writer, path string) {
	tag := NewTag(path)
	ext := filepath.Ext(path)
	if ext == ".rake" || filepath.Base(path) == "Rakefile"  {
		ext = ".rb"
	}
	rset := Rules[ext]
	if rset != nil {
		source, err := OpenLineSource(path)
		if err != nil {
			fmt.Println("Error opening file '" + path + "': " + err.Error())
			return
		}
		defer source.Close()
		for {
			line, err := source.ReadLine()
			if err != nil {
				break
			}
			rset.CheckLine(tag, line, source.Loc)
		}
		tag.WriteOn(writer)
	}
}

func walkDir(writer *bufio.Writer, path string, info os.FileInfo, err error) error {
	if info != nil && ! info.IsDir() {
		processFile(writer, path)
	}
	return nil
}

var version = "1.1.0"

func main() {
	var showVersion bool = false
	var showHelp    bool = false

	flag.BoolVar(&showVersion, "v",    false, "Display the version number")
	flag.BoolVar(&showHelp,    "h",    false, "Display help text")
	flag.BoolVar(&showHelp,    "help", false, "Display help text")
	flag.Parse()

	if showVersion {
		fmt.Println(version)
		os.Exit(0)
	}

	if showHelp {
		fmt.Println("Usage: gotags [options] [file...]")
		fmt.Println("")
		fmt.Println("Options are:")
		flag.PrintDefaults()
		os.Exit(0)
	}

	fo, _ := os.Create("TAGS")
	defer fo.Close()

	writer := bufio.NewWriter(fo)
	defer writer.Flush()

	walkFunc := func(path string, info os.FileInfo, err error) error {
		return walkDir(writer, path, info, err)
	}

	var err error = nil

	if len(flag.Args()) == 0 {
		err = filepath.Walk(".", walkFunc)
	} else {
		for _, arg := range flag.Args() {
			err = filepath.Walk(arg, walkFunc)
		}
	}
	if err != nil {
		fmt.Println("Error: " + err.Error())
		os.Exit(-1)
	}
}
<commit_msg>Remove unneeded empty string<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

func processFile(writer *bufio.Writer, path string) {
	tag := NewTag(path)
	ext := filepath.Ext(path)
	if ext == ".rake" || filepath.Base(path) == "Rakefile"  {
		ext = ".rb"
	}
	rset := Rules[ext]
	if rset != nil {
		source, err := OpenLineSource(path)
		if err != nil {
			fmt.Println("Error opening file '" + path + "': " + err.Error())
			return
		}
		defer source.Close()
		for {
			line, err := source.ReadLine()
			if err != nil {
				break
			}
			rset.CheckLine(tag, line, source.Loc)
		}
		tag.WriteOn(writer)
	}
}

func walkDir(writer *bufio.Writer, path string, info os.FileInfo, err error) error {
	if info != nil && ! info.IsDir() {
		processFile(writer, path)
	}
	return nil
}

var version = "1.1.0"

func main() {
	var showVersion bool = false
	var showHelp    bool = false

	flag.BoolVar(&showVersion, "v",    false, "Display the version number")
	flag.BoolVar(&showHelp,    "h",    false, "Display help text")
	flag.BoolVar(&showHelp,    "help", false, "Display help text")
	flag.Parse()

	if showVersion {
		fmt.Println(version)
		os.Exit(0)
	}

	if showHelp {
		fmt.Println("Usage: gotags [options] [file...]")
		fmt.Println()
		fmt.Println("Options are:")
		flag.PrintDefaults()
		os.Exit(0)
	}

	fo, _ := os.Create("TAGS")
	defer fo.Close()

	writer := bufio.NewWriter(fo)
	defer writer.Flush()

	walkFunc := func(path string, info os.FileInfo, err error) error {
		return walkDir(writer, path, info, err)
	}

	var err error = nil

	if len(flag.Args()) == 0 {
		err = filepath.Walk(".", walkFunc)
	} else {
		for _, arg := range flag.Args() {
			err = filepath.Walk(arg, walkFunc)
		}
	}
	if err != nil {
		fmt.Println("Error: " + err.Error())
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package test

import (
	"github.com/ligato/cn-infra/datasync"

	nsmodel "github.com/contiv/vpp/plugins/ksr/model/namespace"
	podmodel "github.com/contiv/vpp/plugins/ksr/model/pod"
	policymodel "github.com/contiv/vpp/plugins/ksr/model/policy"
	"github.com/contiv/vpp/plugins/policy/cache"
)

// MockPolicyCache is mock for PolicyCache that only provides fake implementation
// of LookupPod().
type MockPolicyCache struct {
	pods map[podmodel.ID]*podmodel.Pod
}

// NewMockPolicyCache is a constructor for MockPolicyCache.
func NewMockPolicyCache() *MockPolicyCache {
	return &MockPolicyCache{
		pods: make(map[podmodel.ID]*podmodel.Pod),
	}
}

// AddPodConfig allows to fill the cache with fake pod data.
func (mpc *MockPolicyCache) AddPodConfig(id podmodel.ID, ipAddr string, labels ...*podmodel.Pod_Label) {
	pod := &podmodel.Pod{
		Name:      id.Name,
		Namespace: id.Namespace,
		IpAddress: ipAddr,
	}
	for _, label := range labels {
		pod.Label = append(pod.Label, label)
	}
	mpc.pods[id] = pod
}

// Update is not implemented by the mock.
func (mpc *MockPolicyCache) Update(dataChngEv datasync.ChangeEvent) error {
	return nil
}

// Resync is not implemented by the mock.
func (mpc *MockPolicyCache) Resync(resyncEv datasync.ResyncEvent) error {
	return nil
}

// Watch is not implemented by the mock.
func (mpc *MockPolicyCache) Watch(watcher cache.PolicyCacheWatcher) error {
	return nil
}

// LookupPod return pod config previously added using AddPodConfig.
func (mpc *MockPolicyCache) LookupPod(pod podmodel.ID) (found bool, data *podmodel.Pod) {
	data, found = mpc.pods[pod]
	return found, data
}

// LookupPodsByNSLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByNSLabelSelector(namespace string, podLabelSelector *policymodel.Policy_LabelSelector) (pods []podmodel.ID) {
	return nil
}

// LookupPodsByLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByLabelSelector(podLabelSelector *policymodel.Policy_LabelSelector) (pods []podmodel.ID) {
	return nil
}

// LookupPodsByNamespace is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByNamespace(namespace nsmodel.ID) (pods []podmodel.ID) {
	return nil
}

// ListAllPods is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllPods() (pods []podmodel.ID) {
	return nil
}

// LookupPolicy is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPolicy(policy podmodel.ID) (found bool, data *policymodel.Policy) {
	return false, nil
}

// LookupPoliciesByPod is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPoliciesByPod(pod podmodel.ID) (policies []policymodel.ID) {
	return nil
}

// ListAllPolicies is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllPolicies() (policies []policymodel.ID) {
	return nil
}

// LookupNamespace is not implemented by the mock.
func (mpc *MockPolicyCache) LookupNamespace(namespace nsmodel.ID) (found bool, data *nsmodel.Namespace) {
	return false, data
}

// LookupNamespacesByLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupNamespacesByLabelSelector(nsLabelSelector *policymodel.Policy_LabelSelector) (namespaces []nsmodel.ID) {
	return nil
}

// ListAllNamespaces is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllNamespaces() (namespaces []nsmodel.ID) {
	return nil
}
<commit_msg>Update cache_mock.go<commit_after>package test

import (
	"github.com/ligato/cn-infra/datasync"

	nsmodel "github.com/contiv/vpp/plugins/ksr/model/namespace"
	podmodel "github.com/contiv/vpp/plugins/ksr/model/pod"
	policymodel "github.com/contiv/vpp/plugins/ksr/model/policy"
	"github.com/contiv/vpp/plugins/policy/cache"
)

// MockPolicyCache is mock for PolicyCache that only provides fake implementation
// of LookupPod().
type MockPolicyCache struct {
	pods map[podmodel.ID]*podmodel.Pod
}

// NewMockPolicyCache is a constructor for MockPolicyCache.
func NewMockPolicyCache() *MockPolicyCache {
	return &MockPolicyCache{
		pods: make(map[podmodel.ID]*podmodel.Pod),
	}
}

// AddPodConfig allows to fill the cache with fake pod data.
func (mpc *MockPolicyCache) AddPodConfig(id podmodel.ID, ipAddr string, labels ...*podmodel.Pod_Label) {
	pod := &podmodel.Pod{
		Name:      id.Name,
		Namespace: id.Namespace,
		IpAddress: ipAddr,
	}
	for _, label := range labels {
		pod.Label = append(pod.Label, label)
	}
	mpc.pods[id] = pod
}

// Update is not implemented by the mock.
func (mpc *MockPolicyCache) Update(dataChngEv datasync.ChangeEvent) error {
	return nil
}

// Resync is not implemented by the mock.
func (mpc *MockPolicyCache) Resync(resyncEv datasync.ResyncEvent) error {
	return nil
}

// Watch is not implemented by the mock.
func (mpc *MockPolicyCache) Watch(watcher cache.PolicyCacheWatcher) error {
	return nil
}

// LookupPod return pod config previously added using AddPodConfig.
func (mpc *MockPolicyCache) LookupPod(pod podmodel.ID) (found bool, data *podmodel.Pod) {
	data, found = mpc.pods[pod]
	return found, data
}

// LookupPodsByNSLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByNSLabelSelector(namespace string, podLabelSelector *policymodel.Policy_LabelSelector) (pods []podmodel.ID) {
	return nil
}

// LookupPodsByLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByLabelSelector(podLabelSelector *policymodel.Policy_LabelSelector) (pods []podmodel.ID) {
	return nil
}

// LookupPodsByNamespace is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPodsByNamespace(namespace nsmodel.ID) (pods []podmodel.ID) {
	return nil
}

// ListAllPods is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllPods() (pods []podmodel.ID) {
	return nil
}

// LookupPolicy is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPolicy(policy policymodel.ID) (found bool, data *policymodel.Policy) {
	return false, nil
}

// LookupPoliciesByPod is not implemented by the mock.
func (mpc *MockPolicyCache) LookupPoliciesByPod(pod podmodel.ID) (policies []policymodel.ID) {
	return nil
}

// ListAllPolicies is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllPolicies() (policies []policymodel.ID) {
	return nil
}

// LookupNamespace is not implemented by the mock.
func (mpc *MockPolicyCache) LookupNamespace(namespace nsmodel.ID) (found bool, data *nsmodel.Namespace) {
	return false, data
}

// LookupNamespacesByLabelSelector is not implemented by the mock.
func (mpc *MockPolicyCache) LookupNamespacesByLabelSelector(nsLabelSelector *policymodel.Policy_LabelSelector) (namespaces []nsmodel.ID) {
	return nil
}

// ListAllNamespaces is not implemented by the mock.
func (mpc *MockPolicyCache) ListAllNamespaces() (namespaces []nsmodel.ID) {
	return nil
}
<|endoftext|>