<commit_before>/*
Copyright 2019 The Kubernetes 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 testutil

import (
	"io"

	"github.com/prometheus/client_golang/prometheus/testutil"

	"k8s.io/component-base/metrics"
)

// GatherAndCompare gathers all metrics from the provided Gatherer and compares
// it to an expected output read from the provided Reader in the Prometheus text
// exposition format. If any metricNames are provided, only metrics with those
// names are compared.
func GatherAndCompare(g metrics.Gatherer, expected io.Reader, metricNames ...string) error {
	return testutil.GatherAndCompare(g, expected, metricNames...)
}
<commit_msg>Introduce CollectAndCompare to testutils<commit_after>/*
Copyright 2019 The Kubernetes 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 testutil

import (
	"io"

	"github.com/prometheus/client_golang/prometheus/testutil"

	"k8s.io/component-base/metrics"
)

// CollectAndCompare registers the provided Collector with a newly created
// pedantic Registry. It then does the same as GatherAndCompare, gathering the
// metrics from the pedantic Registry.
func CollectAndCompare(c metrics.Collector, expected io.Reader, metricNames ...string) error {
	return testutil.CollectAndCompare(c, expected, metricNames...)
}

// GatherAndCompare gathers all metrics from the provided Gatherer and compares
// it to an expected output read from the provided Reader in the Prometheus text
// exposition format. If any metricNames are provided, only metrics with those
// names are compared.
func GatherAndCompare(g metrics.Gatherer, expected io.Reader, metricNames ...string) error {
	return testutil.GatherAndCompare(g, expected, metricNames...)
}
<|endoftext|>


<commit_before>package application

import (
	"bytes"
	"crypto/md5"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
)

func TestRegistration(t *testing.T) {
	server := httptest.NewServer(GetRouter(true))
	defer server.Close()

	file, err := ioutil.TempFile("", "")
	if err != nil {
		t.Fatal(err)
	}
	db, err := gorm.Open("sqlite3", file.Name())
	db.AutoMigrate(&User{})
	Gorm = db

	data := []byte("_123_")
	authKey := fmt.Sprintf("%x", md5.Sum(data))
	jsonBytes, _ := json.Marshal(AuthRequestPart{
		AuthKey: authKey,
		ExtID:   123,
		SysID:   "VK",
	})
	reader := bytes.NewReader(jsonBytes)

	resp, err := http.Post(fmt.Sprint(server.URL, "/ReqEnter"), "application/json", reader)
	if err != nil {
		t.Fatal(err)
	}
	decoder := json.NewDecoder(resp.Body)
	var response enterResponse
	err = decoder.Decode(response)
	if err != nil {
		t.Fatal(err)
	}
	t.Fatal(response)
}
<commit_msg>tested<commit_after>package application

import (
	"bytes"
	"crypto/md5"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
)

func TestRegistration(t *testing.T) {
	server := httptest.NewServer(GetRouter(true))
	defer server.Close()

	file, err := ioutil.TempFile("", "")
	if err != nil {
		t.Fatal(err)
	}
	db, err := gorm.Open("sqlite3", file.Name())
	db.AutoMigrate(&User{})
	Gorm = db

	data := []byte("_123_")
	authKey := fmt.Sprintf("%x", md5.Sum(data))
	jsonBytes, _ := json.Marshal(AuthRequestPart{
		AuthKey: authKey,
		ExtID:   123,
		SysID:   "VK",
	})
	reader := bytes.NewReader(jsonBytes)

	resp, err := http.Post(fmt.Sprint(server.URL, "/ReqEnter"), "application/json", reader)
	if err != nil {
		t.Fatal(err)
	}
	decoder := json.NewDecoder(resp.Body)
	var response enterResponse
	err = decoder.Decode(&response)
	if err != nil {
		t.Fatal(err)
	}
	if response.FirstGame != 1 {
		t.Fatalf("first game expected, got %+v", response)
	}
}
<|endoftext|>


<commit_before>package routes

import (
	"net/http"
	"time"

	"github.com/trackit/trackit/db"
	"github.com/trackit/trackit/models"
	"github.com/trackit/trackit/routes"
	"github.com/trackit/trackit/users"
)

type response struct {
	Results []result `json:"results"`
}

type result struct {
	ReportDate string `json:"reportDate"`
	Tags       string `json:"tags"`
}

func routeGetMostUsedTags(r *http.Request, a routes.Arguments) (int, interface{}) {
	u := a[users.AuthenticatedUser].(users.User)

	dateBegin := a[mostUsedTagsQueryArgs[0]].(time.Time)
	dateEnd := a[mostUsedTagsQueryArgs[1]].(time.Time).Add(time.Hour*time.Duration(23) + time.Minute*time.Duration(59) + time.Second*time.Duration(59))

	dbRes, err := models.MostUsedTagsByAwsAccountIDInRange(db.Db, u.Id, dateBegin, dateEnd)
	if err != nil {
		return 500, nil
	}

	res := response{}
	for _, entry := range dbRes {
		res.Results = append(res.Results, result{
			ReportDate: entry.ReportDate.String(),
			Tags:       entry.Tags,
		})
	}

	return 200, res
}
<commit_msg>Improved response format for get most used tags route<commit_after>package routes

import (
	"encoding/json"
	"net/http"
	"time"

	"github.com/trackit/trackit/db"
	"github.com/trackit/trackit/models"
	"github.com/trackit/trackit/routes"
	"github.com/trackit/trackit/users"
)

func routeGetMostUsedTags(r *http.Request, a routes.Arguments) (int, interface{}) {
	u := a[users.AuthenticatedUser].(users.User)

	dateBegin := a[mostUsedTagsQueryArgs[0]].(time.Time)
	dateEnd := a[mostUsedTagsQueryArgs[1]].(time.Time).Add(time.Hour*time.Duration(23) + time.Minute*time.Duration(59) + time.Second*time.Duration(59))

	dbRes, err := models.MostUsedTagsByAwsAccountIDInRange(db.Db, u.Id, dateBegin, dateEnd)
	if err != nil {
		return 500, nil
	}

	res := map[string]interface{}{}
	for _, entry := range dbRes {
		tagsList := []string{}
		err = json.Unmarshal([]byte(entry.Tags), &tagsList)
		if err != nil {
			continue
		}

		res[entry.ReportDate.String()] = tagsList
	}

	return 200, res
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes 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 main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"time"

	"k8s.io/api/admissionregistration/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"

	"github.com/golang/glog"
)

const (
	webhookConfigName = "vpa-webhook-config"
)

// get a clientset with in-cluster config.
func getClient() *kubernetes.Clientset {
	config, err := rest.InClusterConfig()
	if err != nil {
		glog.Fatal(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		glog.Fatal(err)
	}
	return clientset
}

// retrieve the CA cert that will signed the cert used by the
// "GenericAdmissionWebhook" plugin admission controller.
func getAPIServerCert(clientset *kubernetes.Clientset) []byte {
	c, err := clientset.CoreV1().ConfigMaps("kube-system").Get("extension-apiserver-authentication", metav1.GetOptions{})
	if err != nil {
		glog.Fatal(err)
	}

	pem, ok := c.Data["requestheader-client-ca-file"]
	if !ok {
		glog.Fatalf(fmt.Sprintf("cannot find the ca.crt in the configmap, configMap.Data is %#v", c.Data))
	}
	glog.V(4).Info("client-ca-file=", pem)
	return []byte(pem)
}

func configTLS(clientset *kubernetes.Clientset, serverCert, serverKey []byte) *tls.Config {
	cert := getAPIServerCert(clientset)
	apiserverCA := x509.NewCertPool()
	apiserverCA.AppendCertsFromPEM(cert)

	sCert, err := tls.X509KeyPair(serverCert, serverKey)
	if err != nil {
		glog.Fatal(err)
	}
	return &tls.Config{
		Certificates: []tls.Certificate{sCert},
		ClientCAs:    apiserverCA,
		// Consider changing to tls.RequireAndVerifyClientCert.
		ClientAuth: tls.NoClientCert,
	}
}

// register this webhook admission controller with the kube-apiserver
// by creating MutatingWebhookConfiguration.
func selfRegistration(clientset *kubernetes.Clientset, caCert []byte) {
	time.Sleep(10 * time.Second)
	client := clientset.AdmissionregistrationV1beta1().MutatingWebhookConfigurations()
	_, err := client.Get(webhookConfigName, metav1.GetOptions{})
	if err == nil {
		if err2 := client.Delete(webhookConfigName, nil); err2 != nil {
			glog.Fatal(err2)
		}
	}
	webhookConfig := &v1beta1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: webhookConfigName,
		},
		Webhooks: []v1beta1.Webhook{
			{
				Name: "vpa.k8s.io",
				Rules: []v1beta1.RuleWithOperations{
					{
						Operations: []v1beta1.OperationType{v1beta1.Create, v1beta1.Update},
						Rule: v1beta1.Rule{
							APIGroups:   []string{""},
							APIVersions: []string{"v1"},
							Resources:   []string{"pods"},
						},
					},
					{
						Operations: []v1beta1.OperationType{v1beta1.Create, v1beta1.Update},
						Rule: v1beta1.Rule{
							APIGroups:   []string{"poc.autoscaling.k8s.io"},
							APIVersions: []string{"v1alpha1"},
							Resources:   []string{"verticalpodautoscalers"},
						},
					}},
				ClientConfig: v1beta1.WebhookClientConfig{
					Service: &v1beta1.ServiceReference{
						Namespace: "kube-system",
						Name:      "vpa-webhook",
					},
					CABundle: caCert,
				},
			},
		},
	}
	if _, err := client.Create(webhookConfig); err != nil {
		glog.Fatal(err)
	} else {
		glog.V(3).Info("Self registration as MutatingWebhook succeeded.")
	}
}
<commit_msg>Don't review Pod Update event<commit_after>/*
Copyright 2018 The Kubernetes 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 main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"time"

	"k8s.io/api/admissionregistration/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"

	"github.com/golang/glog"
)

const (
	webhookConfigName = "vpa-webhook-config"
)

// get a clientset with in-cluster config.
func getClient() *kubernetes.Clientset {
	config, err := rest.InClusterConfig()
	if err != nil {
		glog.Fatal(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		glog.Fatal(err)
	}
	return clientset
}

// retrieve the CA cert that will signed the cert used by the
// "GenericAdmissionWebhook" plugin admission controller.
func getAPIServerCert(clientset *kubernetes.Clientset) []byte {
	c, err := clientset.CoreV1().ConfigMaps("kube-system").Get("extension-apiserver-authentication", metav1.GetOptions{})
	if err != nil {
		glog.Fatal(err)
	}

	pem, ok := c.Data["requestheader-client-ca-file"]
	if !ok {
		glog.Fatalf(fmt.Sprintf("cannot find the ca.crt in the configmap, configMap.Data is %#v", c.Data))
	}
	glog.V(4).Info("client-ca-file=", pem)
	return []byte(pem)
}

func configTLS(clientset *kubernetes.Clientset, serverCert, serverKey []byte) *tls.Config {
	cert := getAPIServerCert(clientset)
	apiserverCA := x509.NewCertPool()
	apiserverCA.AppendCertsFromPEM(cert)

	sCert, err := tls.X509KeyPair(serverCert, serverKey)
	if err != nil {
		glog.Fatal(err)
	}
	return &tls.Config{
		Certificates: []tls.Certificate{sCert},
		ClientCAs:    apiserverCA,
		// Consider changing to tls.RequireAndVerifyClientCert.
		ClientAuth: tls.NoClientCert,
	}
}

// register this webhook admission controller with the kube-apiserver
// by creating MutatingWebhookConfiguration.
func selfRegistration(clientset *kubernetes.Clientset, caCert []byte) {
	time.Sleep(10 * time.Second)
	client := clientset.AdmissionregistrationV1beta1().MutatingWebhookConfigurations()
	_, err := client.Get(webhookConfigName, metav1.GetOptions{})
	if err == nil {
		if err2 := client.Delete(webhookConfigName, nil); err2 != nil {
			glog.Fatal(err2)
		}
	}
	webhookConfig := &v1beta1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: webhookConfigName,
		},
		Webhooks: []v1beta1.Webhook{
			{
				Name: "vpa.k8s.io",
				Rules: []v1beta1.RuleWithOperations{
					{
						Operations: []v1beta1.OperationType{v1beta1.Create},
						Rule: v1beta1.Rule{
							APIGroups:   []string{""},
							APIVersions: []string{"v1"},
							Resources:   []string{"pods"},
						},
					},
					{
						Operations: []v1beta1.OperationType{v1beta1.Create, v1beta1.Update},
						Rule: v1beta1.Rule{
							APIGroups:   []string{"poc.autoscaling.k8s.io"},
							APIVersions: []string{"v1alpha1"},
							Resources:   []string{"verticalpodautoscalers"},
						},
					}},
				ClientConfig: v1beta1.WebhookClientConfig{
					Service: &v1beta1.ServiceReference{
						Namespace: "kube-system",
						Name:      "vpa-webhook",
					},
					CABundle: caCert,
				},
			},
		},
	}
	if _, err := client.Create(webhookConfig); err != nil {
		glog.Fatal(err)
	} else {
		glog.V(3).Info("Self registration as MutatingWebhook succeeded.")
	}
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 config

import (
	"path/filepath"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/tools/go/analysis/analysistest"
)

func TestReadConfigs(t *testing.T) {
	tests := []struct {
		desc  string
		files map[string]string // fake workspace files
		want  *Config
	}{
		{
			desc: "file with empty definitions",
			files: map[string]string{
				"file.json": `
				{}
				`,
			},
			want: &Config{},
		},
		{
			desc: "file with unknown field",
			files: map[string]string{
				"file.json": `
				{
					"unknown": 1
				}
				`,
			},
			want: &Config{},
		},
		{
			desc: "file with banned import",
			files: map[string]string{
				"file.json": `
				{
					"imports": [{
						"name": "legacyconversions",
						"msg": "Sample message",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
			},
			want: &Config{Imports: []BannedApi{
				{
					Name: "legacyconversions",
					Msg:  "Sample message",
					Exemptions: []Exemption{
						{
							Justification: "My justification",
							AllowedDir:    "subdirs/vetted/...",
						},
					},
				}},
			},
		},
		{
			desc: "multiple files with imports",
			files: map[string]string{
				"file1.json": `
				{
					"imports": [{
						"name": "import1",
						"msg": "msg1"
					}]
				}
				`,
				"file2.json": `
				{
					"imports": [{
						"name": "import2",
						"msg": "msg2"
					}]
				}
				`,
			},
			want: &Config{Imports: []BannedApi{
				{Name: "import1", Msg: "msg1"}, {Name: "import2", Msg: "msg2"},
			}},
		},
		{
			desc: "file with banned function",
			files: map[string]string{
				"file.json": `
				{
					"functions": [{
						"name": "safehttp.NewServeMuxConfig",
						"msg": "Sample message",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
			},
			want: &Config{Functions: []BannedApi{{
				Name: "safehttp.NewServeMuxConfig",
				Msg:  "Sample message",
				Exemptions: []Exemption{
					{
						Justification: "My justification",
						AllowedDir:    "subdirs/vetted/...",
					},
				},
			}}},
		},
		{
			desc: "multiple files with functions",
			files: map[string]string{
				"file1.json": `
				{
					"functions": [{
						"name": "function1",
						"msg": "msg1"
					}]
				}
				`,
				"file2.json": `
				{
					"functions": [{
						"name": "function2",
						"msg": "msg2"
					}]
				}
				`,
			},
			want: &Config{Functions: []BannedApi{
				{Name: "function1", Msg: "msg1"}, {Name: "function2", Msg: "msg2"},
			}},
		},
		{
			desc: "duplicate definitions",
			files: map[string]string{
				"file1.json": `
				{
					"functions": [{
						"name": "function",
						"msg": "Banned by team x",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
				"file2.json": `
				{
					"functions": [{
						"name": "function",
						"msg": "Banned by team y",
						"exemptions": [{
							"justification": "#yolo",
							"allowedDir": "otherdir/legacy/..."
						}]
					}]
				}
				`,
			},
			want: &Config{
				Functions: []BannedApi{
					{
						Name: "function",
						Msg:  "Banned by team x",
						Exemptions: []Exemption{
							{
								Justification: "My justification",
								AllowedDir:    "subdirs/vetted/...",
							},
						},
					},
					{
						Name: "function",
						Msg:  "Banned by team y",
						Exemptions: []Exemption{
							{
								Justification: "#yolo",
								AllowedDir:    "otherdir/legacy/...",
							},
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			dir, cleanup, err := analysistest.WriteFiles(test.files)
			if err != nil {
				t.Fatalf("WriteFiles() returned err: %v", err)
			}
			defer cleanup()
			var files []string
			for f := range test.files {
				path := filepath.Join(dir, "src", f)
				files = append(files, path)
			}

			cfg, err := ReadConfigs(files)

			if err != nil {
				t.Errorf("ReadConfigs() got err: %v want: nil", err)
			}
			if diff := cmp.Diff(cfg, test.want, cmpopts.SortSlices(bannedApiCmp)); diff != "" {
				t.Errorf("config mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

var bannedApiCmp = func(b1, b2 BannedApi) bool { return b1.Msg < b2.Msg }

func TestConfigErrors(t *testing.T) {
	tests := []struct {
		desc     string
		files    map[string]string // fake workspace files
		fileName string            // file name to read
	}{
		{
			desc:     "file does not exist",
			files:    map[string]string{},
			fileName: "nonexistent",
		},
		{
			desc: "file is a directory",
			files: map[string]string{
				"dir/file.json": ``,
			},
			fileName: "dir",
		},
		{
			desc: "file has invalid contents",
			files: map[string]string{
				"file.json": `
				{"imports":"this should be an object"}
				`,
			},
			fileName: "file.json",
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			dir, cleanup, err := analysistest.WriteFiles(test.files)
			if err != nil {
				t.Fatalf("WriteFiles() got err: %v", err)
			}
			defer cleanup()

			file := filepath.Join(dir, "src", test.fileName)
			cfg, err := ReadConfigs([]string{file})

			if cfg != nil {
				t.Errorf("ReadConfigs(%q) got %v, wanted nil", cfg, test.fileName)
			}
			if err == nil {
				t.Errorf("ReadBannedImports(%q) succeeded but wanted error", test.fileName)
			}
		})
	}
}
<commit_msg>Lint fixes.<commit_after>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 config

import (
	"path/filepath"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/tools/go/analysis/analysistest"
)

func TestReadConfigs(t *testing.T) {
	tests := []struct {
		desc  string
		files map[string]string
		want  *Config
	}{
		{
			desc: "file with empty definitions",
			files: map[string]string{
				"file.json": `
				{}
				`,
			},
			want: &Config{},
		},
		{
			desc: "file with unknown field",
			files: map[string]string{
				"file.json": `
				{
					"unknown": 1
				}
				`,
			},
			want: &Config{},
		},
		{
			desc: "file with banned import",
			files: map[string]string{
				"file.json": `
				{
					"imports": [{
						"name": "legacyconversions",
						"msg": "Sample message",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
			},
			want: &Config{Imports: []BannedApi{
				{
					Name: "legacyconversions",
					Msg:  "Sample message",
					Exemptions: []Exemption{
						{
							Justification: "My justification",
							AllowedDir:    "subdirs/vetted/...",
						},
					},
				}},
			},
		},
		{
			desc: "multiple files with imports",
			files: map[string]string{
				"file1.json": `
				{
					"imports": [{
						"name": "import1",
						"msg": "msg1"
					}]
				}
				`,
				"file2.json": `
				{
					"imports": [{
						"name": "import2",
						"msg": "msg2"
					}]
				}
				`,
			},
			want: &Config{Imports: []BannedApi{
				{Name: "import1", Msg: "msg1"}, {Name: "import2", Msg: "msg2"},
			}},
		},
		{
			desc: "file with banned function",
			files: map[string]string{
				"file.json": `
				{
					"functions": [{
						"name": "safehttp.NewServeMuxConfig",
						"msg": "Sample message",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
			},
			want: &Config{Functions: []BannedApi{{
				Name: "safehttp.NewServeMuxConfig",
				Msg:  "Sample message",
				Exemptions: []Exemption{
					{
						Justification: "My justification",
						AllowedDir:    "subdirs/vetted/...",
					},
				},
			}}},
		},
		{
			desc: "multiple files with functions",
			files: map[string]string{
				"file1.json": `
				{
					"functions": [{
						"name": "function1",
						"msg": "msg1"
					}]
				}
				`,
				"file2.json": `
				{
					"functions": [{
						"name": "function2",
						"msg": "msg2"
					}]
				}
				`,
			},
			want: &Config{Functions: []BannedApi{
				{Name: "function1", Msg: "msg1"}, {Name: "function2", Msg: "msg2"},
			}},
		},
		{
			desc: "duplicate definitions",
			files: map[string]string{
				"file1.json": `
				{
					"functions": [{
						"name": "function",
						"msg": "Banned by team x",
						"exemptions": [{
							"justification": "My justification",
							"allowedDir": "subdirs/vetted/..."
						}]
					}]
				}
				`,
				"file2.json": `
				{
					"functions": [{
						"name": "function",
						"msg": "Banned by team y",
						"exemptions": [{
							"justification": "#yolo",
							"allowedDir": "otherdir/legacy/..."
						}]
					}]
				}
				`,
			},
			want: &Config{
				Functions: []BannedApi{
					{
						Name: "function",
						Msg:  "Banned by team x",
						Exemptions: []Exemption{
							{
								Justification: "My justification",
								AllowedDir:    "subdirs/vetted/...",
							},
						},
					},
					{
						Name: "function",
						Msg:  "Banned by team y",
						Exemptions: []Exemption{
							{
								Justification: "#yolo",
								AllowedDir:    "otherdir/legacy/...",
							},
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			dir, cleanup, err := analysistest.WriteFiles(test.files)
			if err != nil {
				t.Fatalf("WriteFiles() returned err: %v", err)
			}
			defer cleanup()
			var files []string
			for f := range test.files {
				path := filepath.Join(dir, "src", f)
				files = append(files, path)
			}

			cfg, err := ReadConfigs(files)

			if err != nil {
				t.Errorf("ReadConfigs() got err: %v want: nil", err)
			}
			if diff := cmp.Diff(cfg, test.want, cmpopts.SortSlices(bannedApiCmp)); diff != "" {
				t.Errorf("config mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

var bannedApiCmp = func(b1, b2 BannedApi) bool { return b1.Msg < b2.Msg }

func TestConfigErrors(t *testing.T) {
	tests := []struct {
		desc     string
		files    map[string]string
		fileName string
	}{
		{
			desc:     "file does not exist",
			files:    map[string]string{},
			fileName: "nonexistent",
		},
		{
			desc: "file is a directory",
			files: map[string]string{
				"dir/file.json": ``,
			},
			fileName: "dir",
		},
		{
			desc: "file has invalid contents",
			files: map[string]string{
				"file.json": `
				{"imports":"this should be an object"}
				`,
			},
			fileName: "file.json",
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			dir, cleanup, err := analysistest.WriteFiles(test.files)
			if err != nil {
				t.Fatalf("WriteFiles() got err: %v", err)
			}
			defer cleanup()

			file := filepath.Join(dir, "src", test.fileName)
			cfg, err := ReadConfigs([]string{file})

			if cfg != nil {
				t.Errorf("ReadConfigs() got %v, wanted nil", cfg)
			}
			if err == nil {
				t.Errorf("ReadConfigs() got %v, wanted error", cfg)
			}
		})
	}
}
<|endoftext|>


<commit_before>package http

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/ansel1/merry"
	uuid "github.com/satori/go.uuid"

	"github.com/go-graphite/carbonapi/carbonapipb"
	"github.com/go-graphite/carbonapi/cmd/carbonapi/config"
	utilctx "github.com/go-graphite/carbonapi/util/ctx"
	"github.com/go-graphite/carbonapi/zipper/types"
	"github.com/lomik/zapwriter"
	"go.uber.org/zap"
)

func tagHandler(w http.ResponseWriter, r *http.Request) {
	t0 := time.Now()
	uuid := uuid.NewV4()

	// TODO: Migrate to context.WithTimeout
	ctx := r.Context()
	requestHeaders := utilctx.GetLogHeaders(ctx)
	username, _, _ := r.BasicAuth()

	logger := zapwriter.Logger("tag").With(
		zap.String("carbonapi_uuid", uuid.String()),
		zap.String("username", username),
		zap.Any("request_headers", requestHeaders),
	)

	srcIP, srcPort := splitRemoteAddr(r.RemoteAddr)

	accessLogger := zapwriter.Logger("access")
	var accessLogDetails = &carbonapipb.AccessLogDetails{
		Handler:        "tags",
		Username:       username,
		CarbonapiUUID:  uuid.String(),
		URL:            r.URL.Path,
		PeerIP:         srcIP,
		PeerPort:       srcPort,
		Host:           r.Host,
		Referer:        r.Referer(),
		URI:            r.RequestURI,
		RequestHeaders: requestHeaders,
	}

	logAsError := false
	defer func() {
		deferredAccessLogging(accessLogger, accessLogDetails, t0, logAsError)
	}()

	err := r.ParseForm()
	if err != nil {
		logAsError = true
		w.Header().Set("Content-Type", contentTypeJSON)
		_, _ = w.Write([]byte{'[', ']'})
		return
	}

	prettyStr := r.FormValue("pretty")
	limit := int64(-1)
	limitStr := r.FormValue("limit")
	if limitStr != "" {
		limit, err = strconv.ParseInt(limitStr, 10, 64)
		if err != nil {
			logger.Debug("error parsing limit, ignoring",
				zap.String("limit", r.FormValue("limit")),
				zap.Error(err),
			)
			limit = -1
		}
	}

	q := r.URL.Query()
	q.Del("pretty")
	rawQuery := q.Encode()

	// TODO(civil): Implement caching
	var res []string
	if strings.HasSuffix(r.URL.Path, "tags") || strings.HasSuffix(r.URL.Path, "tags/") {
		res, err = config.Config.ZipperInstance.TagNames(ctx, rawQuery, limit)
	} else if strings.HasSuffix(r.URL.Path, "values") || strings.HasSuffix(r.URL.Path, "values/") {
		res, err = config.Config.ZipperInstance.TagValues(ctx, rawQuery, limit)
	} else {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		accessLogDetails.HTTPCode = http.StatusNotFound
		return
	}

	// TODO(civil): Implement stats
	if err != nil && !merry.Is(err, types.ErrNoMetricsFetched) && !merry.Is(err, types.ErrNonFatalErrors) {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		accessLogDetails.HTTPCode = http.StatusInternalServerError
		accessLogDetails.Reason = err.Error()
		logAsError = true
		return
	}

	var b []byte
	if prettyStr == "1" {
		b, err = json.MarshalIndent(res, "", "\t")
	} else {
		b, err = json.Marshal(res)
	}

	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		accessLogDetails.HTTPCode = http.StatusInternalServerError
		accessLogDetails.Reason = err.Error()
		logAsError = true
		return
	}

	w.Header().Set("Content-Type", contentTypeJSON)
	w.Header().Set(ctxHeaderUUID, uuid.String())
	_, _ = w.Write(b)
	accessLogDetails.Runtime = time.Since(t0).Seconds()
	accessLogDetails.HTTPCode = http.StatusOK
}
<commit_msg>tags: pass carbonapi uuid for autocomplete handler<commit_after>package http

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/ansel1/merry"
	uuid "github.com/satori/go.uuid"

	"github.com/go-graphite/carbonapi/carbonapipb"
	"github.com/go-graphite/carbonapi/cmd/carbonapi/config"
	utilctx "github.com/go-graphite/carbonapi/util/ctx"
	"github.com/go-graphite/carbonapi/zipper/types"
	"github.com/lomik/zapwriter"
	"go.uber.org/zap"
)

func tagHandler(w http.ResponseWriter, r *http.Request) {
	t0 := time.Now()
	uuid := uuid.NewV4()

	// TODO: Migrate to context.WithTimeout
	ctx := utilctx.SetUUID(r.Context(), uuid.String())
	requestHeaders := utilctx.GetLogHeaders(ctx)
	username, _, _ := r.BasicAuth()

	logger := zapwriter.Logger("tag").With(
		zap.String("carbonapi_uuid", uuid.String()),
		zap.String("username", username),
		zap.Any("request_headers", requestHeaders),
	)

	srcIP, srcPort := splitRemoteAddr(r.RemoteAddr)

	accessLogger := zapwriter.Logger("access")
	var accessLogDetails = &carbonapipb.AccessLogDetails{
		Handler:        "tags",
		Username:       username,
		CarbonapiUUID:  uuid.String(),
		URL:            r.URL.Path,
		PeerIP:         srcIP,
		PeerPort:       srcPort,
		Host:           r.Host,
		Referer:        r.Referer(),
		URI:            r.RequestURI,
		RequestHeaders: requestHeaders,
	}

	logAsError := false
	defer func() {
		deferredAccessLogging(accessLogger, accessLogDetails, t0, logAsError)
	}()

	err := r.ParseForm()
	if err != nil {
		logAsError = true
		w.Header().Set("Content-Type", contentTypeJSON)
		_, _ = w.Write([]byte{'[', ']'})
		return
	}

	prettyStr := r.FormValue("pretty")
	limit := int64(-1)
	limitStr := r.FormValue("limit")
	if limitStr != "" {
		limit, err = strconv.ParseInt(limitStr, 10, 64)
		if err != nil {
			logger.Debug("error parsing limit, ignoring",
				zap.String("limit", r.FormValue("limit")),
				zap.Error(err),
			)
			limit = -1
		}
	}

	q := r.URL.Query()
	q.Del("pretty")
	rawQuery := q.Encode()

	// TODO(civil): Implement caching
	var res []string
	if strings.HasSuffix(r.URL.Path, "tags") || strings.HasSuffix(r.URL.Path, "tags/") {
		res, err = config.Config.ZipperInstance.TagNames(ctx, rawQuery, limit)
	} else if strings.HasSuffix(r.URL.Path, "values") || strings.HasSuffix(r.URL.Path, "values/") {
		res, err = config.Config.ZipperInstance.TagValues(ctx, rawQuery, limit)
	} else {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		accessLogDetails.HTTPCode = http.StatusNotFound
		return
	}

	// TODO(civil): Implement stats
	if err != nil && !merry.Is(err, types.ErrNoMetricsFetched) && !merry.Is(err, types.ErrNonFatalErrors) {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		accessLogDetails.HTTPCode = http.StatusInternalServerError
		accessLogDetails.Reason = err.Error()
		logAsError = true
		return
	}

	var b []byte
	if prettyStr == "1" {
		b, err = json.MarshalIndent(res, "", "\t")
	} else {
		b, err = json.Marshal(res)
	}

	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		accessLogDetails.HTTPCode = http.StatusInternalServerError
		accessLogDetails.Reason = err.Error()
		logAsError = true
		return
	}

	w.Header().Set("Content-Type", contentTypeJSON)
	w.Header().Set(ctxHeaderUUID, uuid.String())
	_, _ = w.Write(b)
	accessLogDetails.Runtime = time.Since(t0).Seconds()
	accessLogDetails.HTTPCode = http.StatusOK
}
<|endoftext|>


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

package integration_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"testing"

	"github.com/googlecloudplatform/gcsfuse/internal/canned"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

func TestMountHelper(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type MountHelperTest struct {
	// Path to the mount(8) helper binary.
	helperPath string

	// A temporary directory into which a file system may be mounted. Removed in
	// TearDown.
	dir string
}

var _ SetUpInterface = &MountHelperTest{}
var _ TearDownInterface = &MountHelperTest{}

func init() { RegisterTestSuite(&MountHelperTest{}) }

func (t *MountHelperTest) SetUp(_ *TestInfo) {
	var err error

	// Set up the appropriate helper path.
	switch runtime.GOOS {
	case "darwin":
		t.helperPath = path.Join(gBuildDir, "sbin/mount_gcsfuse")

	case "linux":
		t.helperPath = path.Join(gBuildDir, "sbin/mount.gcsfuse")

	default:
		AddFailure("Don't know how to deal with OS: %q", runtime.GOOS)
		AbortTest()
	}

	// Set up the temporary directory.
	t.dir, err = ioutil.TempDir("", "mount_helper_test")
	AssertEq(nil, err)
}

func (t *MountHelperTest) TearDown() {
	err := os.Remove(t.dir)
	AssertEq(nil, err)
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *MountHelperTest) BadUsage() {
	testCases := []struct {
		args           []string
		expectedOutput string
	}{
		// Too few args
		0: {
			[]string{canned.FakeBucketName},
			"two positional arguments",
		},

		// Too many args
		1: {
			[]string{canned.FakeBucketName, "a", "b"},
			"Unexpected arg 3",
		},

		// Trailing -o
		2: {
			[]string{canned.FakeBucketName, "a", "-o"},
			"Unexpected -o",
		},
	}

	// Run each test case.
	for i, tc := range testCases {
		cmd := exec.Command(t.helperPath)
		cmd.Args = append(cmd.Args, tc.args...)

		output, err := cmd.CombinedOutput()
		ExpectThat(err, Error(HasSubstr("exit status")), "case %d", i)
		ExpectThat(string(output), MatchesRegexp(tc.expectedOutput), "case %d", i)
	}
}

func (t *MountHelperTest) SuccessfulMount() {
	AssertTrue(false, "TODO")
}

func (t *MountHelperTest) ReadOnlyMode() {
	AssertTrue(false, "TODO")
}

func (t *MountHelperTest) ExtraneousOptions() {
	AssertTrue(false, "TODO")
}

func (t *MountHelperTest) FuseSubtype() {
	AssertTrue(false, "TODO")
}
<commit_msg>MountHelperTest.SuccessfulMount<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package integration_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"testing"

	"github.com/googlecloudplatform/gcsfuse/internal/canned"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

func TestMountHelper(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type MountHelperTest struct {
	// Path to the mount(8) helper binary.
	helperPath string

	// A temporary directory into which a file system may be mounted. Removed in
	// TearDown.
	dir string
}

var _ SetUpInterface = &MountHelperTest{}
var _ TearDownInterface = &MountHelperTest{}

func init() { RegisterTestSuite(&MountHelperTest{}) }

func (t *MountHelperTest) SetUp(_ *TestInfo) {
	var err error

	// Set up the appropriate helper path.
	switch runtime.GOOS {
	case "darwin":
		t.helperPath = path.Join(gBuildDir, "sbin/mount_gcsfuse")

	case "linux":
		t.helperPath = path.Join(gBuildDir, "sbin/mount.gcsfuse")

	default:
		AddFailure("Don't know how to deal with OS: %q", runtime.GOOS)
		AbortTest()
	}

	// Set up the temporary directory.
	t.dir, err = ioutil.TempDir("", "mount_helper_test")
	AssertEq(nil, err)
}

func (t *MountHelperTest) TearDown() {
	err := os.Remove(t.dir)
	AssertEq(nil, err)
}

func (t *MountHelperTest) mount(args []string) (err error) {
	cmd := exec.Command(t.helperPath)
	cmd.Args = append(cmd.Args, args...)
	cmd.Env = []string{
		fmt.Sprintf("PATH=%s", path.Join(gBuildDir, "bin")),
	}

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

	return
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *MountHelperTest) BadUsage() {
	testCases := []struct {
		args           []string
		expectedOutput string
	}{
		// Too few args
		0: {
			[]string{canned.FakeBucketName},
			"two positional arguments",
		},

		// Too many args
		1: {
			[]string{canned.FakeBucketName, "a", "b"},
			"Unexpected arg 3",
		},

		// Trailing -o
		2: {
			[]string{canned.FakeBucketName, "a", "-o"},
			"Unexpected -o",
		},
	}

	// Run each test case.
	for i, tc := range testCases {
		cmd := exec.Command(t.helperPath)
		cmd.Args = append(cmd.Args, tc.args...)
		cmd.Env = []string{}

		output, err := cmd.CombinedOutput()
		ExpectThat(err, Error(HasSubstr("exit status")), "case %d", i)
		ExpectThat(string(output), MatchesRegexp(tc.expectedOutput), "case %d", i)
	}
}

func (t *MountHelperTest) SuccessfulMount() {
	var err error
	var fi os.FileInfo

	// Mount.
	args := []string{canned.FakeBucketName, t.dir}

	err = t.mount(args)
	AssertEq(nil, err)
	defer unmount(t.dir)

	// Check that the file system is available.
	fi, err = os.Lstat(path.Join(t.dir, canned.TopLevelFile))
	AssertEq(nil, err)
	ExpectEq(os.FileMode(0644), fi.Mode())
	ExpectEq(len(canned.TopLevelFile_Contents), fi.Size())
}

func (t *MountHelperTest) ReadOnlyMode() {
	AssertTrue(false, "TODO")
}

func (t *MountHelperTest) ExtraneousOptions() {
	AssertTrue(false, "TODO")
}

func (t *MountHelperTest) FuseSubtype() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package v7

import (
	"code.cloudfoundry.org/cli/actor/actionerror"
	"code.cloudfoundry.org/cli/actor/sharedaction"
	"code.cloudfoundry.org/cli/actor/v7action"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/flag"
	"code.cloudfoundry.org/cli/command/v7/shared"
)

//go:generate counterfeiter . CreateRouteActor

type CreateRouteActor interface {
	CreateRoute(spaceName, domainName, hostname string) (v7action.Warnings, error)
}

type CreateRouteCommand struct {
	RequiredArgs    flag.Domain `positional-args:"yes"`
	usage           interface{} `usage:"CF_NAME create-route DOMAIN [--hostname HOSTNAME] [--path PATH]\n\nEXAMPLES:\n   CF_NAME create-route example.com                              # example.com\n   CF_NAME create-route example.com --hostname myapp            # myapp.example.com\n   CF_NAME create-route example.com --hostname myapp --path foo # myapp.example.com/foo"`
	Hostname        string      `long:"hostname" short:"n" description:"Hostname for the HTTP route (required for shared domains)"`
	Path            string      `long:"path" description:"Path for the HTTP route"`
	relatedCommands interface{} `related_commands:"check-route, domains, map-route, routes, unmap route"`

	UI          command.UI
	Config      command.Config
	Actor       CreateRouteActor
	SharedActor command.SharedActor
}

func (cmd *CreateRouteCommand) Setup(config command.Config, ui command.UI) error {
	cmd.UI = ui
	cmd.Config = config
	sharedActor := sharedaction.NewActor(config)
	cmd.SharedActor = sharedActor

	ccClient, uaaClient, err := shared.NewClients(config, ui, true, "")
	if err != nil {
		return err
	}
	cmd.Actor = v7action.NewActor(ccClient, config, sharedActor, uaaClient)
	return nil
}

func (cmd CreateRouteCommand) Execute(args []string) error {
	err := cmd.SharedActor.CheckTarget(true, true)
	if err != nil {
		return err
	}

	user, err := cmd.Config.CurrentUser()
	if err != nil {
		return err
	}

	domain := cmd.RequiredArgs.Domain
	hostname := cmd.Hostname
	spaceName := cmd.Config.TargetedSpace().Name
	orgName := cmd.Config.TargetedOrganization().Name
	fqdn := ""
	if hostname != "" {
		fqdn += hostname + "."
	}
	fqdn += domain

	cmd.UI.DisplayTextWithFlavor("Creating route {{.FQDN}} for org {{.Organization}} / space {{.Space}} as {{.User}}...",
		map[string]interface{}{
			"FQDN":         fqdn,
			"User":         user.Name,
			"Space":        spaceName,
			"Organization": orgName,
		})

	warnings, err := cmd.Actor.CreateRoute(spaceName, domain, hostname)

	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		if _, ok := err.(actionerror.RouteAlreadyExistsError); ok {
			cmd.UI.DisplayText(err.Error())
			cmd.UI.DisplayOK()
			return nil
		}
		return err
	}

	cmd.UI.DisplayText("Route {{.FQDN}} has been created.",
		map[string]interface{}{
			"FQDN": fqdn,
		})

	cmd.UI.DisplayOK()
	return nil
}
<commit_msg>Fix spacing issue in help text for create route command<commit_after>package v7

import (
	"code.cloudfoundry.org/cli/actor/actionerror"
	"code.cloudfoundry.org/cli/actor/sharedaction"
	"code.cloudfoundry.org/cli/actor/v7action"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/flag"
	"code.cloudfoundry.org/cli/command/v7/shared"
)

//go:generate counterfeiter . CreateRouteActor

type CreateRouteActor interface {
	CreateRoute(spaceName, domainName, hostname string) (v7action.Warnings, error)
}

type CreateRouteCommand struct {
	RequiredArgs    flag.Domain `positional-args:"yes"`
	usage           interface{} `usage:"CF_NAME create-route DOMAIN [--hostname HOSTNAME] [--path PATH]\n\nEXAMPLES:\n   CF_NAME create-route example.com                             # example.com\n   CF_NAME create-route example.com --hostname myapp            # myapp.example.com\n   CF_NAME create-route example.com --hostname myapp --path foo # myapp.example.com/foo"`
	Hostname        string      `long:"hostname" short:"n" description:"Hostname for the HTTP route (required for shared domains)"`
	Path            string      `long:"path" description:"Path for the HTTP route"`
	relatedCommands interface{} `related_commands:"check-route, domains, map-route, routes, unmap route"`

	UI          command.UI
	Config      command.Config
	Actor       CreateRouteActor
	SharedActor command.SharedActor
}

func (cmd *CreateRouteCommand) Setup(config command.Config, ui command.UI) error {
	cmd.UI = ui
	cmd.Config = config
	sharedActor := sharedaction.NewActor(config)
	cmd.SharedActor = sharedActor

	ccClient, uaaClient, err := shared.NewClients(config, ui, true, "")
	if err != nil {
		return err
	}
	cmd.Actor = v7action.NewActor(ccClient, config, sharedActor, uaaClient)
	return nil
}

func (cmd CreateRouteCommand) Execute(args []string) error {
	err := cmd.SharedActor.CheckTarget(true, true)
	if err != nil {
		return err
	}

	user, err := cmd.Config.CurrentUser()
	if err != nil {
		return err
	}

	domain := cmd.RequiredArgs.Domain
	hostname := cmd.Hostname
	spaceName := cmd.Config.TargetedSpace().Name
	orgName := cmd.Config.TargetedOrganization().Name
	fqdn := ""
	if hostname != "" {
		fqdn += hostname + "."
	}
	fqdn += domain

	cmd.UI.DisplayTextWithFlavor("Creating route {{.FQDN}} for org {{.Organization}} / space {{.Space}} as {{.User}}...",
		map[string]interface{}{
			"FQDN":         fqdn,
			"User":         user.Name,
			"Space":        spaceName,
			"Organization": orgName,
		})

	warnings, err := cmd.Actor.CreateRoute(spaceName, domain, hostname)

	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		if _, ok := err.(actionerror.RouteAlreadyExistsError); ok {
			cmd.UI.DisplayText(err.Error())
			cmd.UI.DisplayOK()
			return nil
		}
		return err
	}

	cmd.UI.DisplayText("Route {{.FQDN}} has been created.",
		map[string]interface{}{
			"FQDN": fqdn,
		})

	cmd.UI.DisplayOK()
	return nil
}
<|endoftext|>


<commit_before>package activity

import (
	"fmt"
	"log"

	"github.com/awslabs/aws-sdk-go/gen/swf"
	"github.com/juju/errors"
	"github.com/sclasen/swfsm/fsm"
	"github.com/sclasen/swfsm/poller"
	. "github.com/sclasen/swfsm/sugar"
)

type SWFOps interface {
	RecordActivityTaskHeartbeat(req *swf.RecordActivityTaskHeartbeatInput) (resp *swf.ActivityTaskStatus, err error)
	RespondActivityTaskCanceled(req *swf.RespondActivityTaskCanceledInput) (err error)
	RespondActivityTaskCompleted(req *swf.RespondActivityTaskCompletedInput) (err error)
	RespondActivityTaskFailed(req *swf.RespondActivityTaskFailedInput) (err error)
	PollForActivityTask(req *swf.PollForActivityTaskInput) (resp *swf.ActivityTask, err error)
}

type ActivityWorker struct {
	Serializer fsm.StateSerializer
	// Domain of the workflow associated with the FSM.
	Domain string
	// TaskList that the underlying poller will poll for decision tasks.
	TaskList string
	// Identity used in PollForActivityTaskRequests, can be empty.
	Identity string
	// Client used to make SWF api requests.
	SWF SWFOps
	// Type Info for handled activities
	handlers map[string]*ActivityHandler
	// ShutdownManager
	ShutdownManager *poller.ShutdownManager
	// ActivityTaskDispatcher
	ActivityTaskDispatcher ActivityTaskDispatcher
	// ActivityInterceptor
	ActivityInterceptor ActivityInterceptor
    // allow panics in activities rather than recovering and failing the activity, useful for testing
    AllowPanics bool
}

func (a *ActivityWorker) AddHandler(handler *ActivityHandler) {
	if a.handlers == nil {
		a.handlers = map[string]*ActivityHandler{}
	}
	a.handlers[handler.Activity] = handler
}

func (a *ActivityWorker) Init() {
	if a.Serializer == nil {
		a.Serializer = fsm.JSONStateSerializer{}
	}

	if a.ActivityInterceptor == nil {
		a.ActivityInterceptor = &FuncInterceptor{}
	}

	if a.ActivityTaskDispatcher == nil {
		a.ActivityTaskDispatcher = &CallingGoroutineDispatcher{}
	}

	if a.ShutdownManager == nil {
		a.ShutdownManager = poller.NewShutdownManager()
	}
}

func (a *ActivityWorker) Start() {
	a.Init()
	poller := poller.NewActivityTaskPoller(a.SWF, a.Domain, a.Identity, a.TaskList)
	go poller.PollUntilShutdownBy(a.ShutdownManager, fmt.Sprintf("%s-poller", a.Identity), a.dispatchTask)
}

func (a *ActivityWorker) dispatchTask(activityTask *swf.ActivityTask) {
    if a.AllowPanics {
        a.ActivityTaskDispatcher.DispatchTask(activityTask, a.handleActivityTask)
    } else {
        a.ActivityTaskDispatcher.DispatchTask(activityTask, a.handleWithRecovery(a.handleActivityTask))
    }
}

func (a *ActivityWorker) handleActivityTask(activityTask *swf.ActivityTask) {
	a.ActivityInterceptor.BeforeTask(activityTask)
	handler := a.handlers[*activityTask.ActivityType.Name]
	if handler != nil {
		var deserialized interface{}
		if activityTask.Input != nil {
			deserialized = handler.ZeroInput()
			err := a.Serializer.Deserialize(*activityTask.Input, deserialized)
			if err != nil {
				a.ActivityInterceptor.AfterTaskFailed(activityTask, err)
				a.fail(activityTask, err)
				return
			}
		} else {
			deserialized = nil
		}

		result, err := handler.HandlerFunc(activityTask, deserialized)
		if err != nil {
			a.ActivityInterceptor.AfterTaskFailed(activityTask, err)
			a.fail(activityTask, err)
		} else {
			if result == nil {
				a.ActivityInterceptor.AfterTaskComplete(activityTask, "")
			} else {
				a.ActivityInterceptor.AfterTaskComplete(activityTask, result)
				switch t := result.(type) {
				case string:
					a.done(activityTask, t)
				default:
					serialized, err := a.Serializer.Serialize(result)
					if err != nil {
						a.fail(activityTask, err)
					} else {
						a.done(activityTask, serialized)
					}
				}
			}
		}
	} else {
		//fail
		err := errors.NewErr("no handler for activity: %s", activityTask.ActivityType.Name)
		a.ActivityInterceptor.AfterTaskFailed(activityTask, &err)
		a.fail(activityTask, &err)
	}
}

func (h *ActivityWorker) fail(resp *swf.ActivityTask, err error) {
	log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, err.Error())
	failErr := h.SWF.RespondActivityTaskFailed(&swf.RespondActivityTaskFailedInput{
		TaskToken: resp.TaskToken,
		Reason:    S(err.Error()),
		Details:   S(err.Error()),
	})
	if failErr != nil {
		log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=failed-response-fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, failErr.Error())
	}
}

func (h *ActivityWorker) done(resp *swf.ActivityTask, result string) {
	log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=done", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID)

	completeErr := h.SWF.RespondActivityTaskCompleted(&swf.RespondActivityTaskCompletedInput{
		TaskToken: resp.TaskToken,
		Result:    S(result),
	})
	if completeErr != nil {
		log.Printf("workflow-id=%s  activity-id=%s activity-id=%s at=completed-response-fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, completeErr.Error())
	}
}

func (h *ActivityWorker) handleWithRecovery(handler func(*swf.ActivityTask)) func(*swf.ActivityTask) {
	return func(resp *swf.ActivityTask) {
		defer func() {
			var anErr error
			if r := recover(); r != nil {
				if err, ok := r.(error); ok && err != nil {
					anErr = err
				} else {
					anErr = errors.New("panic in activity with nil error")
				}
				log.Printf("component=activity at=error error=activity-panic-recovery msg=%s", r)
				h.fail(resp, anErr)
			}
		}()
		handler(resp)

	}
}
<commit_msg>debug output<commit_after>package activity

import (
	"fmt"
	"log"

	"github.com/awslabs/aws-sdk-go/gen/swf"
	"github.com/juju/errors"
	"github.com/sclasen/swfsm/fsm"
	"github.com/sclasen/swfsm/poller"
	. "github.com/sclasen/swfsm/sugar"
)

type SWFOps interface {
	RecordActivityTaskHeartbeat(req *swf.RecordActivityTaskHeartbeatInput) (resp *swf.ActivityTaskStatus, err error)
	RespondActivityTaskCanceled(req *swf.RespondActivityTaskCanceledInput) (err error)
	RespondActivityTaskCompleted(req *swf.RespondActivityTaskCompletedInput) (err error)
	RespondActivityTaskFailed(req *swf.RespondActivityTaskFailedInput) (err error)
	PollForActivityTask(req *swf.PollForActivityTaskInput) (resp *swf.ActivityTask, err error)
}

type ActivityWorker struct {
	Serializer fsm.StateSerializer
	// Domain of the workflow associated with the FSM.
	Domain string
	// TaskList that the underlying poller will poll for decision tasks.
	TaskList string
	// Identity used in PollForActivityTaskRequests, can be empty.
	Identity string
	// Client used to make SWF api requests.
	SWF SWFOps
	// Type Info for handled activities
	handlers map[string]*ActivityHandler
	// ShutdownManager
	ShutdownManager *poller.ShutdownManager
	// ActivityTaskDispatcher
	ActivityTaskDispatcher ActivityTaskDispatcher
	// ActivityInterceptor
	ActivityInterceptor ActivityInterceptor
    // allow panics in activities rather than recovering and failing the activity, useful for testing
    AllowPanics bool
}

func (a *ActivityWorker) AddHandler(handler *ActivityHandler) {
	if a.handlers == nil {
		a.handlers = map[string]*ActivityHandler{}
	}
	a.handlers[handler.Activity] = handler
}

func (a *ActivityWorker) Init() {
	if a.Serializer == nil {
		a.Serializer = fsm.JSONStateSerializer{}
	}

	if a.ActivityInterceptor == nil {
		a.ActivityInterceptor = &FuncInterceptor{}
	}

	if a.ActivityTaskDispatcher == nil {
		a.ActivityTaskDispatcher = &CallingGoroutineDispatcher{}
	}

	if a.ShutdownManager == nil {
		a.ShutdownManager = poller.NewShutdownManager()
	}
}

func (a *ActivityWorker) Start() {
	a.Init()
	poller := poller.NewActivityTaskPoller(a.SWF, a.Domain, a.Identity, a.TaskList)
	go poller.PollUntilShutdownBy(a.ShutdownManager, fmt.Sprintf("%s-poller", a.Identity), a.dispatchTask)
}

func (a *ActivityWorker) dispatchTask(activityTask *swf.ActivityTask) {
    if a.AllowPanics {
        a.ActivityTaskDispatcher.DispatchTask(activityTask, a.handleActivityTask)
    } else {
        a.ActivityTaskDispatcher.DispatchTask(activityTask, a.handleWithRecovery(a.handleActivityTask))
    }
}

func (a *ActivityWorker) handleActivityTask(activityTask *swf.ActivityTask) {
	a.ActivityInterceptor.BeforeTask(activityTask)
	handler := a.handlers[*activityTask.ActivityType.Name]
	if handler != nil {
		var deserialized interface{}
		if activityTask.Input != nil {
			deserialized = handler.ZeroInput()
			err := a.Serializer.Deserialize(*activityTask.Input, deserialized)
			if err != nil {
				a.ActivityInterceptor.AfterTaskFailed(activityTask, err)
				a.fail(activityTask, err)
				return
			}
		} else {
			deserialized = nil
		}

        log.Printf("at=handleActivityTask task=%+v input=%+v", activityTask, deserialized)
		result, err := handler.HandlerFunc(activityTask, deserialized)
		if err != nil {
			a.ActivityInterceptor.AfterTaskFailed(activityTask, err)
			a.fail(activityTask, err)
		} else {
			if result == nil {
				a.ActivityInterceptor.AfterTaskComplete(activityTask, "")
			} else {
				a.ActivityInterceptor.AfterTaskComplete(activityTask, result)
				switch t := result.(type) {
				case string:
					a.done(activityTask, t)
				default:
					serialized, err := a.Serializer.Serialize(result)
					if err != nil {
						a.fail(activityTask, err)
					} else {
						a.done(activityTask, serialized)
					}
				}
			}
		}
	} else {
		//fail
		err := errors.NewErr("no handler for activity: %s", activityTask.ActivityType.Name)
		a.ActivityInterceptor.AfterTaskFailed(activityTask, &err)
		a.fail(activityTask, &err)
	}
}

func (h *ActivityWorker) fail(resp *swf.ActivityTask, err error) {
	log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, err.Error())
	failErr := h.SWF.RespondActivityTaskFailed(&swf.RespondActivityTaskFailedInput{
		TaskToken: resp.TaskToken,
		Reason:    S(err.Error()),
		Details:   S(err.Error()),
	})
	if failErr != nil {
		log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=failed-response-fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, failErr.Error())
	}
}

func (h *ActivityWorker) done(resp *swf.ActivityTask, result string) {
	log.Printf("workflow-id=%s activity-id=%s activity-id=%s at=done", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID)

	completeErr := h.SWF.RespondActivityTaskCompleted(&swf.RespondActivityTaskCompletedInput{
		TaskToken: resp.TaskToken,
		Result:    S(result),
	})
	if completeErr != nil {
		log.Printf("workflow-id=%s  activity-id=%s activity-id=%s at=completed-response-fail error=%s ", *resp.WorkflowExecution.WorkflowID, *resp.ActivityType.Name, *resp.ActivityID, completeErr.Error())
	}
}

func (h *ActivityWorker) handleWithRecovery(handler func(*swf.ActivityTask)) func(*swf.ActivityTask) {
	return func(resp *swf.ActivityTask) {
		defer func() {
			var anErr error
			if r := recover(); r != nil {
				if err, ok := r.(error); ok && err != nil {
					anErr = err
				} else {
					anErr = errors.New("panic in activity with nil error")
				}
				log.Printf("component=activity at=error error=activity-panic-recovery msg=%s", r)
				h.fail(resp, anErr)
			}
		}()
		handler(resp)

	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strings"

	"github.com/appc/spec/discovery"
)

var (
	cmdDiscover = &Command{
		Name:        "discover",
		Description: "Discover the download URLs for an app",
		Summary:     "Discover the download URLs for one or more app container images",
		Usage:       "APP...",
		Run:         runDiscover,
	}
)

func init() {
	cmdDiscover.Flags.BoolVar(&transportFlags.Insecure, "insecure", false,
		"Allow insecure non-TLS downloads over http")
}

func runDiscover(args []string) (exit int) {
	if len(args) < 1 {
		stderr("discover: at least one name required")
	}

	for _, name := range args {
		app, err := discovery.NewAppFromString(name)
		if err != nil {
			stderr("%s: %s", name, err)
			return 1
		}
		eps, attempts, err := discovery.DiscoverEndpoints(*app, transportFlags.Insecure)
		if err != nil {
			stderr("error fetching %s: %s", name, err)
			return 1
		}
		for _, a := range attempts {
			fmt.Printf("discover walk: prefix: %s error: %v\n", a.Prefix, a.Error)
		}
		for _, aciEndpoint := range eps.ACIEndpoints {
			fmt.Printf("ACI: %s, Sig: %s\n", aciEndpoint.ACI, aciEndpoint.Sig)
		}
		if len(eps.Keys) > 0 {
			fmt.Println("Keys: " + strings.Join(eps.Keys, ","))
		}
	}

	return
}
<commit_msg>actool: default os and arch to GOOS and GOARCH<commit_after>package main

import (
	"fmt"
	"runtime"
	"strings"

	"github.com/appc/spec/discovery"
)

var (
	cmdDiscover = &Command{
		Name:        "discover",
		Description: "Discover the download URLs for an app",
		Summary:     "Discover the download URLs for one or more app container images",
		Usage:       "APP...",
		Run:         runDiscover,
	}
)

func init() {
	cmdDiscover.Flags.BoolVar(&transportFlags.Insecure, "insecure", false,
		"Allow insecure non-TLS downloads over http")
}

func runDiscover(args []string) (exit int) {
	if len(args) < 1 {
		stderr("discover: at least one name required")
	}

	for _, name := range args {
		app, err := discovery.NewAppFromString(name)
		if app.Labels["os"] == "" {
			app.Labels["os"] = runtime.GOOS
		}
		if app.Labels["arch"] == "" {
			app.Labels["arch"] = runtime.GOARCH
		}
		if err != nil {
			stderr("%s: %s", name, err)
			return 1
		}
		eps, attempts, err := discovery.DiscoverEndpoints(*app, transportFlags.Insecure)
		if err != nil {
			stderr("error fetching %s: %s", name, err)
			return 1
		}
		for _, a := range attempts {
			fmt.Printf("discover walk: prefix: %s error: %v\n", a.Prefix, a.Error)
		}
		for _, aciEndpoint := range eps.ACIEndpoints {
			fmt.Printf("ACI: %s, Sig: %s\n", aciEndpoint.ACI, aciEndpoint.Sig)
		}
		if len(eps.Keys) > 0 {
			fmt.Println("Keys: " + strings.Join(eps.Keys, ","))
		}
	}

	return
}
<|endoftext|>


<commit_before>package packet

import (
	"fmt"
	"big"
	"crypto/openpgp/error"
	"crypto/rsa"
	"crypto/sha1"
	"io"
	"os"
)

func readHeader(r io.Reader) (tag uint8, length uint64, err os.Error) {
	var buf [4]byte
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	if buf[0] & 0x80 == 0 {
		err = error.StructuralError("tag byte does not have MSB set")
		return
	}
	if buf[0] & 0x40 == 0 {
		// Old format packet
		tag = (buf[0] & 0x3f) >> 2
		lengthType := buf[0] & 3
		if lengthType == 3 {
			err = error.Unsupported("indeterminate length packet")
			return
		}
		lengthBytes := 1 << lengthType
		_, err = io.ReadFull(r, buf[0:lengthBytes])
		if err != nil {
			return
		}
		for i := 0; i < lengthBytes; i++ {
			length <<= 8
			length |= uint64(buf[i])
		}
		return
	}

	// New format packet
	tag = buf[0] & 0x3f
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	switch {
		case buf[0] < 192:
			length = uint64(buf[0])
		case buf[0] < 224:
			length = uint64(buf[0] - 192) << 8
			_, err = io.ReadFull(r, buf[0:1])
			if err != nil {
				return
			}
			length += uint64(buf[0]) + 192
		case buf[0] < 255:
			err = error.Unsupported("chunked packet")
		default:
			_, err := io.ReadFull(r, buf[0:4])
			if err != nil {
				return
			}
			length = uint64(buf[0]) << 24 |
				 uint64(buf[1]) << 16 |
				 uint64(buf[2]) << 8 |
				 uint64(buf[3])
	}
	return
}

type Packet interface {
	Type() string
}

func ReadPacket(r io.Reader) (p Packet, err os.Error) {
	tag, length, err := readHeader(r)
	limitReader := io.LimitReader(r, int64(length))
	switch tag {
		case 2:
			p, err = readSignaturePacket(limitReader)
		case 6:
			p, err = readPublicKeyPacket(limitReader, uint16(length))
		default:
			err = error.Unsupported("unknown packet type")
	}
	return
}

type SignatureType uint8
type PublicKeyAlgorithm uint8
type HashFunction uint8

const (
	SigTypeBinary SignatureType = 0
	SigTypeText SignatureType = 1
	// Many other types omitted
)

const (
	// RFC 4880, section 9.1
	PubKeyAlgoRSA PublicKeyAlgorithm = 1
	PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
	PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
	PubKeyAlgoElgamal PublicKeyAlgorithm = 16
	PubKeyAlgoDSA PublicKeyAlgorithm = 17
)

const (
	// RFC 4880, section 9.4
	HashFuncSHA1 = 2
)

type SignaturePacket struct {
	SigType SignatureType
	PubKeyAlgo PublicKeyAlgorithm
	Hash HashFunction
	HashSuffix []byte
	HashTag [2]byte
	CreationTime uint32
	Signature []byte
}

func (s SignaturePacket) Type() string {
	return "signature"
}

func readSignaturePacket(r io.Reader) (sig SignaturePacket, err os.Error) {
	// RFC 4880, section 5.2.3
	var buf [5]byte
	_, err = io.ReadFull(r, buf[:1])
	if err != nil {
		return
	}
	if buf[0] != 4 {
		err = error.Unsupported("signature packet version")
		return
	}

	_, err = io.ReadFull(r, buf[:5])
	if err != nil {
		return
	}
	sig.SigType = SignatureType(buf[0])
	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
	switch sig.PubKeyAlgo {
		case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		default:
			err = error.Unsupported("public key algorithm")
			return
	}
	sig.Hash = HashFunction(buf[2])
	hashedSubpacketsLength := int(buf[3]) << 8 | int(buf[4])
	l := 6 + hashedSubpacketsLength
	sig.HashSuffix = make([]byte, l + 6)
	sig.HashSuffix[0] = 4
	copy(sig.HashSuffix[1:], buf[:5])
	hashedSubpackets := sig.HashSuffix[6:l]
	_, err = io.ReadFull(r, hashedSubpackets)
	if err != nil {
		return
	}
	// See RFC 4880, section 5.2.4
	trailer := sig.HashSuffix[l:]
	trailer[0] = 4
	trailer[1] = 0xff
	trailer[2] = uint8(l >> 24)
	trailer[3] = uint8(l >> 16)
	trailer[4] = uint8(l >> 8)
	trailer[5] = uint8(l)

	err = parseSignatureSubpackets(&sig, hashedSubpackets, true)
	if err != nil {
		return
	}

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}
	unhashedSubpacketsLength := int(buf[0]) << 8 | int(buf[1])
	unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
	_, err = io.ReadFull(r, unhashedSubpackets)
	if err != nil {
		return
	}
	err = parseSignatureSubpackets(&sig, unhashedSubpackets, false)
	if err != nil {
		return
	}

	_, err = io.ReadFull(r, sig.HashTag[:2])
	if err != nil {
		return
	}

	// We have already checked that the public key algorithm is RSA.
	sig.Signature, _, err = readMPI(r)
	return
}

func readMPI(r io.Reader) (mpi []byte, hdr [2]byte, err os.Error) {
	_, err = io.ReadFull(r, hdr[0:])
	if err != nil {
		return
	}
	numBits := int(hdr[0]) << 8 | int(hdr[1])
	numBytes := (numBits + 7) / 8
	mpi = make([]byte, numBytes)
	_, err = io.ReadFull(r, mpi)
	return
}

func parseSignatureSubpackets(sig *SignaturePacket, subpackets []byte, isHashed bool) (err os.Error) {
	for len(subpackets) > 0 {
		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
		if err != nil {
			return
		}
	}

	if sig.CreationTime == 0 {
		err = error.StructuralError("no creation time in signature")
	}

	return
}

func parseSignatureSubpacket(sig *SignaturePacket, subpacket []byte, isHashed bool) (rest []byte, err os.Error) {
	// RFC 4880, section 5.2.3.1
	var length uint32
	switch {
		case subpacket[0] < 192:
			length = uint32(subpacket[0])
			subpacket = subpacket[1:]
		case subpacket[0] < 255:
			if len(subpacket) < 2 {
				goto Truncated
			}
			length = uint32(subpacket[0] - 192) << 8 + uint32(subpacket[1]) + 192
			subpacket = subpacket[2:]
		default:
			if len(subpacket) < 5 {
				goto Truncated
			}
			length = uint32(subpacket[1]) << 24 |
				 uint32(subpacket[2]) << 16 |
				 uint32(subpacket[3]) << 8 |
				 uint32(subpacket[4])
			subpacket = subpacket[5:]
	}
	if length < uint32(len(subpacket)) {
		goto Truncated
	}
	rest = subpacket[length:]
	subpacket = subpacket[:length]
	if len(subpacket) == 0 {
		err = error.StructuralError("zero length signature subpacket")
		return
	}
	packetType := subpacket[0] & 0x7f
	isCritial := subpacket[0] & 0x80 == 0x80
	subpacket = subpacket[1:]
	switch packetType {
		case 2:
			if !isHashed {
				err = error.StructuralError("signature creation time in non-hashed area")
				return
			}
			if len(subpacket) != 4 {
				err = error.StructuralError("signature creation time not four bytes")
				return
			}
			sig.CreationTime = uint32(subpacket[0]) << 24 |
					   uint32(subpacket[1]) << 16 |
					   uint32(subpacket[2]) << 8 |
					   uint32(subpacket[3])
		default:
			if isCritial {
				err = error.Unsupported("unknown critical signature subpacket")
				return
			}
	}
	return

 Truncated:
	err = error.StructuralError("signature subpacket truncated")
	return
}

type PublicKeyPacket struct {
	CreationTime uint32
	PubKeyAlgo   PublicKeyAlgorithm
	PublicKey    rsa.PublicKey
	Fingerprint  []byte
}

func (pk PublicKeyPacket) Type() string {
	return "public key"
}

func (pk PublicKeyPacket) FingerprintString() string {
	return fmt.Sprintf("%X", pk.Fingerprint)
}

func (pk PublicKeyPacket) KeyIdString() string {
	return fmt.Sprintf("%X", pk.Fingerprint[len(pk.Fingerprint)-4:])
}

func readPublicKeyPacket(r io.Reader, length uint16) (pk PublicKeyPacket, err os.Error) {
	// RFC 4880, section 5.5.2
	var buf [6]byte
	_, err = io.ReadFull(r, buf[0:])
	if err != nil {
		return
	}
	if buf[0] != 4 {
		err = error.Unsupported("public key version")
	}

	// RFC 4880, section 12.2
	fprint := sha1.New()
	fprint.Write([]byte{'\x99', uint8(length >> 8), uint8(length)})
	fprint.Write(buf[0:6]) // version, timestamp, algorithm

	pk.CreationTime = uint32(buf[1]) << 24 |
			  uint32(buf[2]) << 16 |
			  uint32(buf[3]) << 8 |
			  uint32(buf[4])
	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
	switch pk.PubKeyAlgo {
		case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
		default:
			err = error.Unsupported("public key type")
			return
	}

	nBytes, mpiHdr, err := readMPI(r)
	if err != nil {
		return
	}
	fprint.Write(mpiHdr[:])
	fprint.Write(nBytes)

	eBytes, mpiHdr, err := readMPI(r)
	if err != nil {
		return
	}
	fprint.Write(mpiHdr[:])
	fprint.Write(eBytes)

	if len(eBytes) > 3 {
		err = error.Unsupported("large public exponent")
		return
	}
	pk.PublicKey.E = 0
	for i := 0; i < len(eBytes); i++ {
		pk.PublicKey.E <<= 8
		pk.PublicKey.E |= int(eBytes[i])
	}
	pk.PublicKey.N = (new(big.Int)).SetBytes(nBytes)
	pk.Fingerprint = fprint.Sum()
	return
}
<commit_msg>complain more clearly when DSA public keys are read.<commit_after>package packet

import (
	"fmt"
	"big"
	"crypto/openpgp/error"
	"crypto/rsa"
	"crypto/sha1"
	"io"
	"os"
)

func readHeader(r io.Reader) (tag uint8, length uint64, err os.Error) {
	var buf [4]byte
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	if buf[0] & 0x80 == 0 {
		err = error.StructuralError("tag byte does not have MSB set")
		return
	}
	if buf[0] & 0x40 == 0 {
		// Old format packet
		tag = (buf[0] & 0x3f) >> 2
		lengthType := buf[0] & 3
		if lengthType == 3 {
			err = error.Unsupported("indeterminate length packet")
			return
		}
		lengthBytes := 1 << lengthType
		_, err = io.ReadFull(r, buf[0:lengthBytes])
		if err != nil {
			return
		}
		for i := 0; i < lengthBytes; i++ {
			length <<= 8
			length |= uint64(buf[i])
		}
		return
	}

	// New format packet
	tag = buf[0] & 0x3f
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	switch {
		case buf[0] < 192:
			length = uint64(buf[0])
		case buf[0] < 224:
			length = uint64(buf[0] - 192) << 8
			_, err = io.ReadFull(r, buf[0:1])
			if err != nil {
				return
			}
			length += uint64(buf[0]) + 192
		case buf[0] < 255:
			err = error.Unsupported("chunked packet")
		default:
			_, err := io.ReadFull(r, buf[0:4])
			if err != nil {
				return
			}
			length = uint64(buf[0]) << 24 |
				 uint64(buf[1]) << 16 |
				 uint64(buf[2]) << 8 |
				 uint64(buf[3])
	}
	return
}

type Packet interface {
	Type() string
}

func ReadPacket(r io.Reader) (p Packet, err os.Error) {
	tag, length, err := readHeader(r)
	limitReader := io.LimitReader(r, int64(length))
	switch tag {
		case 2:
			p, err = readSignaturePacket(limitReader)
		case 6:
			p, err = readPublicKeyPacket(limitReader, uint16(length))
		default:
			err = error.Unsupported("unknown packet type")
	}
	return
}

type SignatureType uint8
type PublicKeyAlgorithm uint8
type HashFunction uint8

const (
	SigTypeBinary SignatureType = 0
	SigTypeText SignatureType = 1
	// Many other types omitted
)

const (
	// RFC 4880, section 9.1
	PubKeyAlgoRSA PublicKeyAlgorithm = 1
	PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
	PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
	PubKeyAlgoElgamal PublicKeyAlgorithm = 16
	PubKeyAlgoDSA PublicKeyAlgorithm = 17
)

const (
	// RFC 4880, section 9.4
	HashFuncSHA1 = 2
)

type SignaturePacket struct {
	SigType SignatureType
	PubKeyAlgo PublicKeyAlgorithm
	Hash HashFunction
	HashSuffix []byte
	HashTag [2]byte
	CreationTime uint32
	Signature []byte
}

func (s SignaturePacket) Type() string {
	return "signature"
}

func readSignaturePacket(r io.Reader) (sig SignaturePacket, err os.Error) {
	// RFC 4880, section 5.2.3
	var buf [5]byte
	_, err = io.ReadFull(r, buf[:1])
	if err != nil {
		return
	}
	if buf[0] != 4 {
		err = error.Unsupported("signature packet version")
		return
	}

	_, err = io.ReadFull(r, buf[:5])
	if err != nil {
		return
	}
	sig.SigType = SignatureType(buf[0])
	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
	switch sig.PubKeyAlgo {
		case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		default:
			err = error.Unsupported("public key algorithm")
			return
	}
	sig.Hash = HashFunction(buf[2])
	hashedSubpacketsLength := int(buf[3]) << 8 | int(buf[4])
	l := 6 + hashedSubpacketsLength
	sig.HashSuffix = make([]byte, l + 6)
	sig.HashSuffix[0] = 4
	copy(sig.HashSuffix[1:], buf[:5])
	hashedSubpackets := sig.HashSuffix[6:l]
	_, err = io.ReadFull(r, hashedSubpackets)
	if err != nil {
		return
	}
	// See RFC 4880, section 5.2.4
	trailer := sig.HashSuffix[l:]
	trailer[0] = 4
	trailer[1] = 0xff
	trailer[2] = uint8(l >> 24)
	trailer[3] = uint8(l >> 16)
	trailer[4] = uint8(l >> 8)
	trailer[5] = uint8(l)

	err = parseSignatureSubpackets(&sig, hashedSubpackets, true)
	if err != nil {
		return
	}

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}
	unhashedSubpacketsLength := int(buf[0]) << 8 | int(buf[1])
	unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
	_, err = io.ReadFull(r, unhashedSubpackets)
	if err != nil {
		return
	}
	err = parseSignatureSubpackets(&sig, unhashedSubpackets, false)
	if err != nil {
		return
	}

	_, err = io.ReadFull(r, sig.HashTag[:2])
	if err != nil {
		return
	}

	// We have already checked that the public key algorithm is RSA.
	sig.Signature, _, err = readMPI(r)
	return
}

func readMPI(r io.Reader) (mpi []byte, hdr [2]byte, err os.Error) {
	_, err = io.ReadFull(r, hdr[0:])
	if err != nil {
		return
	}
	numBits := int(hdr[0]) << 8 | int(hdr[1])
	numBytes := (numBits + 7) / 8
	mpi = make([]byte, numBytes)
	_, err = io.ReadFull(r, mpi)
	return
}

func parseSignatureSubpackets(sig *SignaturePacket, subpackets []byte, isHashed bool) (err os.Error) {
	for len(subpackets) > 0 {
		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
		if err != nil {
			return
		}
	}

	if sig.CreationTime == 0 {
		err = error.StructuralError("no creation time in signature")
	}

	return
}

func parseSignatureSubpacket(sig *SignaturePacket, subpacket []byte, isHashed bool) (rest []byte, err os.Error) {
	// RFC 4880, section 5.2.3.1
	var length uint32
	switch {
		case subpacket[0] < 192:
			length = uint32(subpacket[0])
			subpacket = subpacket[1:]
		case subpacket[0] < 255:
			if len(subpacket) < 2 {
				goto Truncated
			}
			length = uint32(subpacket[0] - 192) << 8 + uint32(subpacket[1]) + 192
			subpacket = subpacket[2:]
		default:
			if len(subpacket) < 5 {
				goto Truncated
			}
			length = uint32(subpacket[1]) << 24 |
				 uint32(subpacket[2]) << 16 |
				 uint32(subpacket[3]) << 8 |
				 uint32(subpacket[4])
			subpacket = subpacket[5:]
	}
	if length < uint32(len(subpacket)) {
		goto Truncated
	}
	rest = subpacket[length:]
	subpacket = subpacket[:length]
	if len(subpacket) == 0 {
		err = error.StructuralError("zero length signature subpacket")
		return
	}
	packetType := subpacket[0] & 0x7f
	isCritial := subpacket[0] & 0x80 == 0x80
	subpacket = subpacket[1:]
	switch packetType {
		case 2:
			if !isHashed {
				err = error.StructuralError("signature creation time in non-hashed area")
				return
			}
			if len(subpacket) != 4 {
				err = error.StructuralError("signature creation time not four bytes")
				return
			}
			sig.CreationTime = uint32(subpacket[0]) << 24 |
					   uint32(subpacket[1]) << 16 |
					   uint32(subpacket[2]) << 8 |
					   uint32(subpacket[3])
		default:
			if isCritial {
				err = error.Unsupported("unknown critical signature subpacket")
				return
			}
	}
	return

 Truncated:
	err = error.StructuralError("signature subpacket truncated")
	return
}

type PublicKeyPacket struct {
	CreationTime uint32
	PubKeyAlgo   PublicKeyAlgorithm
	PublicKey    rsa.PublicKey
	Fingerprint  []byte
}

func (pk PublicKeyPacket) Type() string {
	return "public key"
}

func (pk PublicKeyPacket) FingerprintString() string {
	return fmt.Sprintf("%X", pk.Fingerprint)
}

func (pk PublicKeyPacket) KeyIdString() string {
	return fmt.Sprintf("%X", pk.Fingerprint[len(pk.Fingerprint)-4:])
}

func readPublicKeyPacket(r io.Reader, length uint16) (pk PublicKeyPacket, err os.Error) {
	// RFC 4880, section 5.5.2
	var buf [6]byte
	_, err = io.ReadFull(r, buf[0:])
	if err != nil {
		return
	}
	if buf[0] != 4 {
		err = error.Unsupported("public key version")
	}

	// RFC 4880, section 12.2
	fprint := sha1.New()
	fprint.Write([]byte{'\x99', uint8(length >> 8), uint8(length)})
	fprint.Write(buf[0:6]) // version, timestamp, algorithm

	pk.CreationTime = uint32(buf[1]) << 24 |
			  uint32(buf[2]) << 16 |
			  uint32(buf[3]) << 8 |
			  uint32(buf[4])
	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
	switch pk.PubKeyAlgo {
		case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
			// good.
		case PubKeyAlgoDSA:
			err = error.Unsupported("DSA public key type")
			return
		default:
			err = error.Unsupported(fmt.Sprintf("public key type (%d)", pk.PubKeyAlgo))
			return
	}

	nBytes, mpiHdr, err := readMPI(r)
	if err != nil {
		return
	}
	fprint.Write(mpiHdr[:])
	fprint.Write(nBytes)

	eBytes, mpiHdr, err := readMPI(r)
	if err != nil {
		return
	}
	fprint.Write(mpiHdr[:])
	fprint.Write(eBytes)

	if len(eBytes) > 3 {
		err = error.Unsupported("large public exponent")
		return
	}
	pk.PublicKey.E = 0
	for i := 0; i < len(eBytes); i++ {
		pk.PublicKey.E <<= 8
		pk.PublicKey.E |= int(eBytes[i])
	}
	pk.PublicKey.N = (new(big.Int)).SetBytes(nBytes)
	pk.Fingerprint = fprint.Sum()
	return
}
<|endoftext|>


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

package tls

import (
	"crypto/x509"
	"runtime"
	"testing"
)

var tlsServers = []string{
	"google.com",
	"github.com",
	"twitter.com",
}

func TestOSCertBundles(t *testing.T) {
	if testing.Short() {
		t.Logf("skipping certificate tests in short mode")
		return
	}

	for _, addr := range tlsServers {
		conn, err := Dial("tcp", addr+":443", &Config{ServerName: addr})
		if err != nil {
			t.Errorf("unable to verify %v: %v", addr, err)
			continue
		}
		err = conn.Close()
		if err != nil {
			t.Error(err)
		}
	}
}

func TestCertHostnameVerifyWindows(t *testing.T) {
	if runtime.GOOS != "windows" {
		return
	}

	if testing.Short() {
		t.Logf("skipping certificate tests in short mode")
		return
	}

	for _, addr := range tlsServers {
		cfg := &Config{ServerName: "example.com"}
		conn, err := Dial("tcp", addr+":443", cfg)
		if err == nil {
			conn.Close()
			t.Errorf("should fail to verify for example.com: %v", addr)
			continue
		}
		_, ok := err.(x509.HostnameError)
		if !ok {
			t.Errorf("error type mismatch, got: %v", err)
		}
	}
}
<commit_msg>crypto/tls: remove flakey tests<commit_after><|endoftext|>


<commit_before>package neoutils

import (
	"fmt"
	"net/http"

	"github.com/jmcvetta/neoism"
)

type ConnectionConfig struct {
	// BatchSize controls how and whether to batch multiple requests to
	// CypherQuery into a single batch. BatchSize 0 disables this behaviour.
	// Values >0 indicate the largest preferred batch size.  Actual sizes
	// may be larger because values from a single call will never be split.
	BatchSize     int
	Transactional bool
	HTTPClient    *http.Client
}

func DefaultConnectionConfig() *ConnectionConfig {
	return &ConnectionConfig{
		BatchSize:     1024,
		Transactional: true,
		HTTPClient: &http.Client{
			Transport: &http.Transport{
				MaxIdleConnsPerHost: 100,
			},
		},
	}
}

func Connect(neoURL string, conf *ConnectionConfig) (NeoConnection, error) {
	if conf == nil {
		conf = DefaultConnectionConfig()
	}

	db, err := neoism.Connect(neoURL)
	if err != nil {
		return nil, err
	}

	if conf.HTTPClient != nil {
		db.Session.Client = conf.HTTPClient
	}

	var cr CypherRunner = db
	if conf.Transactional {
		cr = TransactionalCypherRunner{db}
	} else {
		cr = db
	}

	if conf.BatchSize > 0 {
		cr = NewBatchCypherRunner(cr, conf.BatchSize)
	}

	ie := &defaultIndexEnsurer{db}

	return &DefaultNeoConnection{neoURL, cr, ie, db}, nil
}

type DefaultNeoConnection struct {
	dbURL string
	cr    CypherRunner
	ie    IndexEnsurer

	db *neoism.Database
}

func (c *DefaultNeoConnection) CypherBatch(cypher []*neoism.CypherQuery) error {
	return c.cr.CypherBatch(cypher)

}

func (c *DefaultNeoConnection) EnsureConstraints(constraints map[string]string) error {
	return c.ie.EnsureConstraints(constraints)
}

func (c *DefaultNeoConnection) EnsureIndexes(indexes map[string]string) error {
	return c.ie.EnsureIndexes(indexes)
}

func (c *DefaultNeoConnection) String() string {
	return fmt.Sprintf("DefaultNeoConnection(%s)", c.dbURL)
}

var _ NeoConnection = (*DefaultNeoConnection)(nil) //{}

type defaultIndexEnsurer struct {
	db *neoism.Database
}

func (ie *defaultIndexEnsurer) EnsureIndexes(indexes map[string]string) error {
	return EnsureIndexes(ie.db, indexes)
}

func (ie *defaultIndexEnsurer) EnsureConstraints(constraints map[string]string) error {
	return EnsureConstraints(ie.db, constraints)
}
<commit_msg>Added documentation in ConnectionConfig<commit_after>package neoutils

import (
	"fmt"
	"net/http"

	"github.com/jmcvetta/neoism"
)

type ConnectionConfig struct {
	// BatchSize controls how and whether to batch multiple requests to
	// CypherQuery into a single batch. BatchSize 0 disables this behaviour.
	// Values >0 indicate the largest preferred batch size.  Actual sizes
	// may be larger because values from a single call will never be split.
	BatchSize int
	// Transactional indicates that the connection should use the
	// transactional endpoints in the neo4j REST API.
	Transactional bool
	// Optionally a custom http.Client can be supplied
	HTTPClient *http.Client
}

func DefaultConnectionConfig() *ConnectionConfig {
	return &ConnectionConfig{
		BatchSize:     1024,
		Transactional: true,
		HTTPClient: &http.Client{
			Transport: &http.Transport{
				MaxIdleConnsPerHost: 100,
			},
		},
	}
}

func Connect(neoURL string, conf *ConnectionConfig) (NeoConnection, error) {
	if conf == nil {
		conf = DefaultConnectionConfig()
	}

	db, err := neoism.Connect(neoURL)
	if err != nil {
		return nil, err
	}

	if conf.HTTPClient != nil {
		db.Session.Client = conf.HTTPClient
	}

	var cr CypherRunner = db
	if conf.Transactional {
		cr = TransactionalCypherRunner{db}
	} else {
		cr = db
	}

	if conf.BatchSize > 0 {
		cr = NewBatchCypherRunner(cr, conf.BatchSize)
	}

	ie := &defaultIndexEnsurer{db}

	return &DefaultNeoConnection{neoURL, cr, ie, db}, nil
}

type DefaultNeoConnection struct {
	dbURL string
	cr    CypherRunner
	ie    IndexEnsurer

	db *neoism.Database
}

func (c *DefaultNeoConnection) CypherBatch(cypher []*neoism.CypherQuery) error {
	return c.cr.CypherBatch(cypher)

}

func (c *DefaultNeoConnection) EnsureConstraints(constraints map[string]string) error {
	return c.ie.EnsureConstraints(constraints)
}

func (c *DefaultNeoConnection) EnsureIndexes(indexes map[string]string) error {
	return c.ie.EnsureIndexes(indexes)
}

func (c *DefaultNeoConnection) String() string {
	return fmt.Sprintf("DefaultNeoConnection(%s)", c.dbURL)
}

var _ NeoConnection = (*DefaultNeoConnection)(nil) //{}

type defaultIndexEnsurer struct {
	db *neoism.Database
}

func (ie *defaultIndexEnsurer) EnsureIndexes(indexes map[string]string) error {
	return EnsureIndexes(ie.db, indexes)
}

func (ie *defaultIndexEnsurer) EnsureConstraints(constraints map[string]string) error {
	return EnsureConstraints(ie.db, constraints)
}
<|endoftext|>


<commit_before>package apiserver

import (
	"context"
	"fmt"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"
	exutil "github.com/openshift/origin/test/extended/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/test/e2e/framework"
)

var _ = g.Describe("[Conformance][sig-api-machinery][Feature:APIServer] local kubeconfig", func() {
	defer g.GinkgoRecover()
	oc := exutil.NewCLI("apiserver")

	for _, kubeconfig := range []string{
		"localhost.kubeconfig",
		"lb-ext.kubeconfig",
		"lb-int.kubeconfig",
		"localhost-recovery.kubeconfig",
	} {
		g.It(fmt.Sprintf("%q should be present on all masters and work", kubeconfig), func() {
			masterNodes, err := oc.AdminKubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
				LabelSelector: `node-role.kubernetes.io/master`,
			})
			o.Expect(err).NotTo(o.HaveOccurred())
			framework.Logf("Discovered %d master nodes.", len(masterNodes.Items))
			o.Expect(masterNodes.Items).NotTo(o.HaveLen(0))
			for _, master := range masterNodes.Items {
				g.By("Testing master node " + master.Name)
				kubeconfigPath := "/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/" + kubeconfig
				framework.Logf("Verifying kubeconfig %q on master %s", master.Name)
				out, err := oc.AsAdmin().Run("debug").Args("node/"+master.Name, "--image=docker.io/library/centos:latest", "--", "chroot", "/host", "/bin/bash", "-euxo", "pipefail", "-c", fmt.Sprintf(`oc --kubeconfig "%s" get namespace kube-system`, kubeconfigPath)).Output()
				o.Expect(err).NotTo(o.HaveOccurred())
				framework.Logf(out)
			}
		})
	}
})
<commit_msg>Bug 1882454: test/apiserver: replace centos by ubi<commit_after>package apiserver

import (
	"context"
	"fmt"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"
	exutil "github.com/openshift/origin/test/extended/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/test/e2e/framework"
)

var _ = g.Describe("[Conformance][sig-api-machinery][Feature:APIServer] local kubeconfig", func() {
	defer g.GinkgoRecover()
	oc := exutil.NewCLI("apiserver")

	for _, kubeconfig := range []string{
		"localhost.kubeconfig",
		"lb-ext.kubeconfig",
		"lb-int.kubeconfig",
		"localhost-recovery.kubeconfig",
	} {
		g.It(fmt.Sprintf("%q should be present on all masters and work", kubeconfig), func() {
			masterNodes, err := oc.AdminKubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
				LabelSelector: `node-role.kubernetes.io/master`,
			})
			o.Expect(err).NotTo(o.HaveOccurred())
			framework.Logf("Discovered %d master nodes.", len(masterNodes.Items))
			o.Expect(masterNodes.Items).NotTo(o.HaveLen(0))
			for _, master := range masterNodes.Items {
				g.By("Testing master node " + master.Name)
				kubeconfigPath := "/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/" + kubeconfig
				framework.Logf("Verifying kubeconfig %q on master %s", master.Name)
				out, err := oc.AsAdmin().Run("debug").Args("node/"+master.Name, "--image=registry.access.redhat.com/ubi8/ubi-minimal:latest", "--", "chroot", "/host", "/bin/bash", "-euxo", "pipefail", "-c", fmt.Sprintf(`oc --kubeconfig "%s" get namespace kube-system`, kubeconfigPath)).Output()
				o.Expect(err).NotTo(o.HaveOccurred())
				framework.Logf(out)
			}
		})
	}
})
<|endoftext|>


<commit_before>/*
   Copyright 2015 Cesanta Software Ltd.

   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

       https://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 server

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"io/ioutil"
	"strings"

	"github.com/cesanta/docker_auth/auth_server/authn"
	"github.com/cesanta/docker_auth/auth_server/authz"
	"github.com/docker/libtrust"
	yaml "gopkg.in/yaml.v2"
)

type Config struct {
	Server     ServerConfig                   `yaml:"server"`
	Token      TokenConfig                    `yaml:"token"`
	Users      map[string]*authn.Requirements `yaml:"users,omitempty"`
	GoogleAuth *authn.GoogleAuthConfig        `yaml:"google_auth,omitempty"`
	LDAPAuth   *authn.LDAPAuthConfig          `yaml:"ldap_auth,omitempty"`
	MongoAuth  *authn.MongoAuthConfig         `yaml:"mongo_auth,omitempty"`
	ACL        authz.ACL                      `yaml:"acl"`
	ACLMongo   *authz.ACLMongoConfig          `yaml:"acl_mongo"`
}

type ServerConfig struct {
	ListenAddress string `yaml:"addr,omitempty"`
	CertFile      string `yaml:"certificate,omitempty"`
	KeyFile       string `yaml:"key,omitempty"`

	publicKey  libtrust.PublicKey
	privateKey libtrust.PrivateKey
}

type TokenConfig struct {
	Issuer     string `yaml:"issuer,omitempty"`
	CertFile   string `yaml:"certificate,omitempty"`
	KeyFile    string `yaml:"key,omitempty"`
	Expiration int64  `yaml:"expiration,omitempty"`

	publicKey  libtrust.PublicKey
	privateKey libtrust.PrivateKey
}

func validate(c *Config) error {
	if c.Server.ListenAddress == "" {
		return errors.New("server.addr is required")
	}

	if c.Token.Issuer == "" {
		return errors.New("token.issuer is required")
	}
	if c.Token.Expiration <= 0 {
		return fmt.Errorf("expiration must be positive, got %d", c.Token.Expiration)
	}
	if c.Users == nil && c.GoogleAuth == nil && c.LDAPAuth == nil && c.MongoAuth == nil {
		return errors.New("no auth methods are configured, this is probably a mistake. Use an empty user map if you really want to deny everyone.")
	}
	if c.MongoAuth != nil {
		if err := c.MongoAuth.Validate("mongo_auth"); err != nil {
			return err
		}
	}
	if gac := c.GoogleAuth; gac != nil {
		if gac.ClientSecretFile != "" {
			contents, err := ioutil.ReadFile(gac.ClientSecretFile)
			if err != nil {
				return fmt.Errorf("could not read %s: %s", gac.ClientSecretFile, err)
			}
			gac.ClientSecret = strings.TrimSpace(string(contents))
		}
		if gac.ClientId == "" || gac.ClientSecret == "" || gac.TokenDB == "" {
			return errors.New("google_auth.{client_id,client_secret,token_db} are required.")
		}
		if gac.HTTPTimeout <= 0 {
			gac.HTTPTimeout = 10
		}
	}
	if c.ACL == nil && c.ACLMongo == nil {
		return errors.New("ACL is empty, this is probably a mistake. Use an empty list if you really want to deny all actions")
	}
	if c.ACLMongo != nil {
		if err := c.ACLMongo.Validate("acl_mongo"); err != nil {
			return err
		}
	}
	return nil
}

func loadCertAndKey(certFile, keyFile string) (pk libtrust.PublicKey, prk libtrust.PrivateKey, err error) {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return
	}
	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		return
	}
	pk, err = libtrust.FromCryptoPublicKey(x509Cert.PublicKey)
	if err != nil {
		return
	}
	prk, err = libtrust.FromCryptoPrivateKey(cert.PrivateKey)
	return
}

func LoadConfig(fileName string) (*Config, error) {
	contents, err := ioutil.ReadFile(fileName)
	if err != nil {
		return nil, fmt.Errorf("could not read %s: %s", fileName, err)
	}
	c := &Config{}
	if err = yaml.Unmarshal(contents, c); err != nil {
		return nil, fmt.Errorf("could not parse config: %s", err)
	}
	if err = validate(c); err != nil {
		return nil, fmt.Errorf("invalid config: %s", err)
	}
	serverConfigured := false
	if c.Server.CertFile != "" || c.Server.KeyFile != "" {
		// Check for partial configuration.
		if c.Server.CertFile == "" || c.Server.KeyFile == "" {
			return nil, fmt.Errorf("failed to load server cert and key: both were not provided")
		}
		c.Server.publicKey, c.Server.privateKey, err = loadCertAndKey(c.Server.CertFile, c.Server.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("failed to load server cert and key: %s", err)
		}
		serverConfigured = true
	}
	tokenConfigured := false
	if c.Token.CertFile != "" || c.Token.KeyFile != "" {
		// Check for partial configuration.
		if c.Token.CertFile == "" || c.Token.KeyFile == "" {
			return nil, fmt.Errorf("failed to load token cert and key: both were not provided")
		}
		c.Token.publicKey, c.Token.privateKey, err = loadCertAndKey(c.Token.CertFile, c.Token.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("failed to load token cert and key: %s", err)
		}
		tokenConfigured = true
	}

	if serverConfigured && !tokenConfigured {
		c.Token.publicKey, c.Token.privateKey = c.Server.publicKey, c.Server.privateKey
		tokenConfigured = true
	}

	if !tokenConfigured {
		return nil, fmt.Errorf("failed to load token cert and key: none provided")
	}
	return c, nil
}
<commit_msg>Make ACLMongo omitempty for serialization<commit_after>/*
   Copyright 2015 Cesanta Software Ltd.

   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

       https://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 server

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"io/ioutil"
	"strings"

	"github.com/cesanta/docker_auth/auth_server/authn"
	"github.com/cesanta/docker_auth/auth_server/authz"
	"github.com/docker/libtrust"
	yaml "gopkg.in/yaml.v2"
)

type Config struct {
	Server     ServerConfig                   `yaml:"server"`
	Token      TokenConfig                    `yaml:"token"`
	Users      map[string]*authn.Requirements `yaml:"users,omitempty"`
	GoogleAuth *authn.GoogleAuthConfig        `yaml:"google_auth,omitempty"`
	LDAPAuth   *authn.LDAPAuthConfig          `yaml:"ldap_auth,omitempty"`
	MongoAuth  *authn.MongoAuthConfig         `yaml:"mongo_auth,omitempty"`
	ACL        authz.ACL                      `yaml:"acl"`
	ACLMongo   *authz.ACLMongoConfig          `yaml:"acl_mongo,omitempty"`
}

type ServerConfig struct {
	ListenAddress string `yaml:"addr,omitempty"`
	CertFile      string `yaml:"certificate,omitempty"`
	KeyFile       string `yaml:"key,omitempty"`

	publicKey  libtrust.PublicKey
	privateKey libtrust.PrivateKey
}

type TokenConfig struct {
	Issuer     string `yaml:"issuer,omitempty"`
	CertFile   string `yaml:"certificate,omitempty"`
	KeyFile    string `yaml:"key,omitempty"`
	Expiration int64  `yaml:"expiration,omitempty"`

	publicKey  libtrust.PublicKey
	privateKey libtrust.PrivateKey
}

func validate(c *Config) error {
	if c.Server.ListenAddress == "" {
		return errors.New("server.addr is required")
	}

	if c.Token.Issuer == "" {
		return errors.New("token.issuer is required")
	}
	if c.Token.Expiration <= 0 {
		return fmt.Errorf("expiration must be positive, got %d", c.Token.Expiration)
	}
	if c.Users == nil && c.GoogleAuth == nil && c.LDAPAuth == nil && c.MongoAuth == nil {
		return errors.New("no auth methods are configured, this is probably a mistake. Use an empty user map if you really want to deny everyone.")
	}
	if c.MongoAuth != nil {
		if err := c.MongoAuth.Validate("mongo_auth"); err != nil {
			return err
		}
	}
	if gac := c.GoogleAuth; gac != nil {
		if gac.ClientSecretFile != "" {
			contents, err := ioutil.ReadFile(gac.ClientSecretFile)
			if err != nil {
				return fmt.Errorf("could not read %s: %s", gac.ClientSecretFile, err)
			}
			gac.ClientSecret = strings.TrimSpace(string(contents))
		}
		if gac.ClientId == "" || gac.ClientSecret == "" || gac.TokenDB == "" {
			return errors.New("google_auth.{client_id,client_secret,token_db} are required.")
		}
		if gac.HTTPTimeout <= 0 {
			gac.HTTPTimeout = 10
		}
	}
	if c.ACL == nil && c.ACLMongo == nil {
		return errors.New("ACL is empty, this is probably a mistake. Use an empty list if you really want to deny all actions")
	}
	if c.ACLMongo != nil {
		if err := c.ACLMongo.Validate("acl_mongo"); err != nil {
			return err
		}
	}
	return nil
}

func loadCertAndKey(certFile, keyFile string) (pk libtrust.PublicKey, prk libtrust.PrivateKey, err error) {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return
	}
	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		return
	}
	pk, err = libtrust.FromCryptoPublicKey(x509Cert.PublicKey)
	if err != nil {
		return
	}
	prk, err = libtrust.FromCryptoPrivateKey(cert.PrivateKey)
	return
}

func LoadConfig(fileName string) (*Config, error) {
	contents, err := ioutil.ReadFile(fileName)
	if err != nil {
		return nil, fmt.Errorf("could not read %s: %s", fileName, err)
	}
	c := &Config{}
	if err = yaml.Unmarshal(contents, c); err != nil {
		return nil, fmt.Errorf("could not parse config: %s", err)
	}
	if err = validate(c); err != nil {
		return nil, fmt.Errorf("invalid config: %s", err)
	}
	serverConfigured := false
	if c.Server.CertFile != "" || c.Server.KeyFile != "" {
		// Check for partial configuration.
		if c.Server.CertFile == "" || c.Server.KeyFile == "" {
			return nil, fmt.Errorf("failed to load server cert and key: both were not provided")
		}
		c.Server.publicKey, c.Server.privateKey, err = loadCertAndKey(c.Server.CertFile, c.Server.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("failed to load server cert and key: %s", err)
		}
		serverConfigured = true
	}
	tokenConfigured := false
	if c.Token.CertFile != "" || c.Token.KeyFile != "" {
		// Check for partial configuration.
		if c.Token.CertFile == "" || c.Token.KeyFile == "" {
			return nil, fmt.Errorf("failed to load token cert and key: both were not provided")
		}
		c.Token.publicKey, c.Token.privateKey, err = loadCertAndKey(c.Token.CertFile, c.Token.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("failed to load token cert and key: %s", err)
		}
		tokenConfigured = true
	}

	if serverConfigured && !tokenConfigured {
		c.Token.publicKey, c.Token.privateKey = c.Server.publicKey, c.Server.privateKey
		tokenConfigured = true
	}

	if !tokenConfigured {
		return nil, fmt.Errorf("failed to load token cert and key: none provided")
	}
	return c, nil
}
<|endoftext|>