Beispiel #1
0
func TestTemplateTransformationFromConfig(t *testing.T) {
	osMux := http.NewServeMux()
	server := httptest.NewServer(osMux)
	defer server.Close()

	osClient := osclient.NewOrDie(&kclient.Config{Host: server.URL, GroupVersion: &latest.Version})

	storage := map[string]rest.Storage{
		"processedTemplates": templateregistry.NewREST(),
	}
	for k, v := range storage {
		delete(storage, k)
		storage[strings.ToLower(k)] = v
	}

	interfaces, _ := latest.InterfacesFor(latest.Version)
	handlerContainer := master.NewHandlerContainer(osMux)
	version := apiserver.APIGroupVersion{
		Root:         "/oapi",
		GroupVersion: latest.Version,

		Mapper: latest.RESTMapper,

		Storage: storage,
		Codec:   interfaces.Codec,

		Creater:   kapi.Scheme,
		Typer:     kapi.Scheme,
		Convertor: kapi.Scheme,
		Linker:    interfaces.MetadataAccessor,

		Admit:   admit.NewAlwaysAdmit(),
		Context: kapi.NewRequestContextMapper(),
	}
	if err := version.InstallREST(handlerContainer); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	walkJSONFiles("fixtures", func(name, path string, data []byte) {
		template, err := interfaces.Codec.Decode(data)
		if err != nil {
			t.Errorf("%q: unexpected error: %v", path, err)
			return
		}
		config, err := osClient.TemplateConfigs("default").Create(template.(*templateapi.Template))
		if err != nil {
			t.Errorf("%q: unexpected error: %v", path, err)
			return
		}
		if len(config.Objects) == 0 {
			t.Errorf("%q: no items in config object", path)
			return
		}
		t.Logf("tested %q", path)
	})
}
// NewFakeFactory returns a new fake OpenShift factory
func NewFakeFactory(namespace string, fake *kclient.FakeRESTClient) (*Factory, *testFactory, runtime.Codec) {
	kf, t, codec := newFakeKubeFactory()

	t.Namespace = namespace

	// Create an OpenShift client and inject it into the client cache
	osClient := client.NewOrDie(t.ClientConfig)
	fake.Codec = codec
	osClient.Client = fake
	clients := &clientCache{
		clients:       map[string]*client.Client{"v1": osClient},
		defaultConfig: &kclient.Config{},
	}

	// Override here any other function we need

	return &Factory{
		Factory:               kf,
		OpenShiftClientConfig: &fakeClientConfig{},
		clients:               clients,
	}, t, codec
}
func NewTestDeployOpenshift(t *testing.T) *testDeployOpenshift {
	t.Logf("Starting test openshift")

	openshift := &testDeployOpenshift{
		stop: make(chan struct{}),
	}

	openshift.lock.Lock()
	defer openshift.lock.Unlock()

	etcdClient := testutil.NewEtcdClient()
	etcdHelper, _ := master.NewEtcdHelper(etcdClient, latest.Version, etcdtest.PathPrefix())

	osMux := http.NewServeMux()
	openshift.server = httptest.NewServer(osMux)

	kubeClient := client.NewOrDie(&client.Config{Host: openshift.server.URL, Version: klatest.Version})
	osClient := osclient.NewOrDie(&client.Config{Host: openshift.server.URL, Version: latest.Version})

	openshift.Client = osClient
	openshift.KubeClient = kubeClient

	kubeletClient, err := kclient.NewKubeletClient(&kclient.KubeletConfig{Port: 10250})
	if err != nil {
		t.Fatalf("Unable to configure Kubelet client: %v", err)
	}

	handlerContainer := master.NewHandlerContainer(osMux)

	_ = master.New(&master.Config{
		EtcdHelper:       etcdHelper,
		KubeletClient:    kubeletClient,
		APIPrefix:        "/api",
		AdmissionControl: admit.NewAlwaysAdmit(),
		RestfulContainer: handlerContainer,
		DisableV1:        false,
	})

	interfaces, _ := latest.InterfacesFor(latest.Version)

	imageStorage := imageetcd.NewREST(etcdHelper)
	imageRegistry := image.NewRegistry(imageStorage)

	imageStreamStorage, imageStreamStatus := imagestreametcd.NewREST(
		etcdHelper,
		imagestream.DefaultRegistryFunc(func() (string, bool) {
			return "registry:3000", true
		}),
		&fakeSubjectAccessReviewRegistry{},
	)
	imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatus)

	imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry)

	imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry)
	//imageStreamImageRegistry := imagestreamimage.NewRegistry(imageStreamImageStorage)

	imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry)
	//imageStreamTagRegistry := imagestreamtag.NewRegistry(imageStreamTagStorage)

	deployConfigStorage := deployconfigetcd.NewStorage(etcdHelper)
	deployConfigRegistry := deployconfigregistry.NewRegistry(deployConfigStorage)

	deployConfigGenerator := &deployconfiggenerator.DeploymentConfigGenerator{
		Client: deployconfiggenerator.Client{
			DCFn:   deployConfigRegistry.GetDeploymentConfig,
			ISFn:   imageStreamRegistry.GetImageStream,
			LISFn2: imageStreamRegistry.ListImageStreams,
		},
	}

	storage := map[string]rest.Storage{
		"images":                    imageStorage,
		"imageStreams":              imageStreamStorage,
		"imageStreamImages":         imageStreamImageStorage,
		"imageStreamMappings":       imageStreamMappingStorage,
		"imageStreamTags":           imageStreamTagStorage,
		"deploymentConfigs":         deployConfigStorage,
		"generateDeploymentConfigs": deployconfiggenerator.NewREST(deployConfigGenerator, latest.Codec),
	}
	for k, v := range storage {
		storage[strings.ToLower(k)] = v
	}

	version := &apiserver.APIGroupVersion{
		Root:    "/oapi",
		Version: "v1",

		Storage: storage,
		Codec:   latest.Codec,

		Mapper: latest.RESTMapper,

		Creater:   kapi.Scheme,
		Typer:     kapi.Scheme,
		Convertor: kapi.Scheme,
		Linker:    interfaces.MetadataAccessor,

		Admit:   admit.NewAlwaysAdmit(),
		Context: kapi.NewRequestContextMapper(),
	}
	if err := version.InstallREST(handlerContainer); err != nil {
		t.Fatalf("unable to install REST: %v", err)
	}

	dccFactory := deployconfigcontroller.DeploymentConfigControllerFactory{
		Client:     osClient,
		KubeClient: kubeClient,
		Codec:      latest.Codec,
	}
	dccFactory.Create().Run()

	cccFactory := configchangecontroller.DeploymentConfigChangeControllerFactory{
		Client:     osClient,
		KubeClient: kubeClient,
		Codec:      latest.Codec,
	}
	cccFactory.Create().Run()

	iccFactory := imagechangecontroller.ImageChangeControllerFactory{
		Client: osClient,
	}
	iccFactory.Create().Run()

	return openshift
}
func NewTestBuildOpenshift(t *testing.T) *testBuildOpenshift {
	openshift := &testBuildOpenshift{
		stop: make(chan struct{}),
	}

	openshift.lock.Lock()
	defer openshift.lock.Unlock()
	etcdClient := testutil.NewEtcdClient()
	etcdHelper, _ := master.NewEtcdHelper(etcdClient, latest.Version, etcdtest.PathPrefix())

	osMux := http.NewServeMux()
	openshift.server = httptest.NewServer(osMux)

	kubeClient := client.NewOrDie(&client.Config{Host: openshift.server.URL, Version: klatest.Version})
	osClient := osclient.NewOrDie(&client.Config{Host: openshift.server.URL, Version: latest.Version})

	openshift.Client = osClient
	openshift.KubeClient = kubeClient

	kubeletClient, err := kclient.NewKubeletClient(&kclient.KubeletConfig{Port: 10250})
	if err != nil {
		t.Fatalf("Unable to configure Kubelet client: %v", err)
	}

	handlerContainer := master.NewHandlerContainer(osMux)

	_ = master.New(&master.Config{
		EtcdHelper:       etcdHelper,
		KubeletClient:    kubeletClient,
		APIPrefix:        "/api",
		AdmissionControl: admit.NewAlwaysAdmit(),
		RestfulContainer: handlerContainer,
		DisableV1:        false,
	})

	interfaces, _ := latest.InterfacesFor(latest.Version)

	buildStorage := buildetcd.NewStorage(etcdHelper)
	buildRegistry := buildregistry.NewRegistry(buildStorage)
	buildConfigStorage := buildconfigetcd.NewStorage(etcdHelper)
	buildConfigRegistry := buildconfigregistry.NewRegistry(buildConfigStorage)

	imageStorage := imageetcd.NewREST(etcdHelper)
	imageRegistry := image.NewRegistry(imageStorage)

	imageStreamStorage, imageStreamStatus := imagestreametcd.NewREST(
		etcdHelper,
		imagestream.DefaultRegistryFunc(func() (string, bool) {
			return "registry:3000", true
		}),
		&fakeSubjectAccessReviewRegistry{},
	)
	imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatus)

	imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry)
	imageStreamImageRegistry := imagestreamimage.NewRegistry(imageStreamImageStorage)

	imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry)
	imageStreamTagRegistry := imagestreamtag.NewRegistry(imageStreamTagStorage)

	buildGenerator := &buildgenerator.BuildGenerator{
		Client: buildgenerator.Client{
			GetBuildConfigFunc:      buildConfigRegistry.GetBuildConfig,
			UpdateBuildConfigFunc:   buildConfigRegistry.UpdateBuildConfig,
			GetBuildFunc:            buildRegistry.GetBuild,
			CreateBuildFunc:         buildRegistry.CreateBuild,
			GetImageStreamFunc:      imageStreamRegistry.GetImageStream,
			GetImageStreamImageFunc: imageStreamImageRegistry.GetImageStreamImage,
			GetImageStreamTagFunc:   imageStreamTagRegistry.GetImageStreamTag,
		},
	}

	buildConfigWebHooks := buildconfigregistry.NewWebHookREST(
		buildConfigRegistry,
		buildclient.NewOSClientBuildConfigInstantiatorClient(osClient),
		map[string]webhook.Plugin{
			"generic": generic.New(),
			"github":  github.New(),
		},
	)

	storage := map[string]rest.Storage{
		"builds":                   buildStorage,
		"buildConfigs":             buildConfigStorage,
		"buildConfigs/webhooks":    buildConfigWebHooks,
		"builds/clone":             buildclonestorage.NewStorage(buildGenerator),
		"buildConfigs/instantiate": buildinstantiatestorage.NewStorage(buildGenerator),
		"imageStreams":             imageStreamStorage,
		"imageStreams/status":      imageStreamStatus,
		"imageStreamTags":          imageStreamTagStorage,
		"imageStreamImages":        imageStreamImageStorage,
	}
	for k, v := range storage {
		storage[strings.ToLower(k)] = v
	}

	version := &apiserver.APIGroupVersion{
		Root:    "/oapi",
		Version: "v1",

		Storage: storage,
		Codec:   latest.Codec,

		Mapper: latest.RESTMapper,

		Creater:   kapi.Scheme,
		Typer:     kapi.Scheme,
		Convertor: kapi.Scheme,
		Linker:    interfaces.MetadataAccessor,

		Admit:   admit.NewAlwaysAdmit(),
		Context: kapi.NewRequestContextMapper(),
	}
	if err := version.InstallREST(handlerContainer); err != nil {
		t.Fatalf("unable to install REST: %v", err)
	}

	bcFactory := buildcontrollerfactory.BuildControllerFactory{
		OSClient:     osClient,
		KubeClient:   kubeClient,
		BuildUpdater: buildclient.NewOSClientBuildClient(osClient),
		DockerBuildStrategy: &buildstrategy.DockerBuildStrategy{
			Image: "test-docker-builder",
			Codec: latest.Codec,
		},
		SourceBuildStrategy: &buildstrategy.SourceBuildStrategy{
			Image:                "test-sti-builder",
			TempDirectoryCreator: buildstrategy.STITempDirectoryCreator,
			Codec:                latest.Codec,
		},
		Stop: openshift.stop,
	}

	bcFactory.Create().Run()

	bpcFactory := buildcontrollerfactory.BuildPodControllerFactory{
		OSClient:     osClient,
		KubeClient:   kubeClient,
		BuildUpdater: buildclient.NewOSClientBuildClient(osClient),
		Stop:         openshift.stop,
	}

	bpcFactory.Create().Run()

	return openshift
}
func TestOAuthCertFallback(t *testing.T) {

	var (
		invalidToken = "invalid"
		noToken      = ""

		invalidCert = restclient.TLSClientConfig{
		// We have to generate this dynamically in order to have an invalid cert signed by a signer with the same name as the valid CA
		// CertData: ...,
		// KeyData:  ...,
		}
		noCert = restclient.TLSClientConfig{}

		tokenUser = "******"
		certUser  = "******"

		unauthorizedError = "the server has asked for the client to provide credentials (get users ~)"
		anonymousError    = `User "system:anonymous" cannot get users at the cluster scope`
	)

	testutil.RequireEtcd(t)
	// Build master config
	masterOptions, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Start server
	clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterOptions)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	adminConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	validCert := adminConfig.TLSClientConfig

	validToken, err := tokencmd.RequestToken(adminConfig, nil, tokenUser, "pass")
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	if len(validToken) == 0 {
		t.Fatalf("Expected valid token, got none")
	}

	// make a client cert signed by a fake CA with the same name as the real CA.
	// this is needed to get the go client to actually send the cert to the server,
	// since the server advertises the signer name it requires
	fakecadir, err := ioutil.TempDir("", "fakeca")
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	defer os.RemoveAll(fakecadir)
	cacerts, err := util.CertificatesFromFile(masterOptions.ServingInfo.ClientCA)
	if err != nil || len(cacerts) != 1 {
		t.Fatalf("Unexpected error or number of certs: %v, %d", err, len(cacerts))
	}
	fakeca, err := (&admin.CreateSignerCertOptions{
		CertFile:   path.Join(fakecadir, "fakeca.crt"),
		KeyFile:    path.Join(fakecadir, "fakeca.key"),
		SerialFile: path.Join(fakecadir, "fakeca.serial"),
		Name:       cacerts[0].Subject.CommonName,
		Output:     ioutil.Discard,
		Overwrite:  true,
	}).CreateSignerCert()
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	clientCertConfig, err := fakeca.MakeClientCertificate(
		path.Join(fakecadir, "fakeclient.crt"),
		path.Join(fakecadir, "fakeclient.key"),
		&user.DefaultInfo{Name: "fakeuser"},
	)
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	invalidCert.CertData, invalidCert.KeyData, err = clientCertConfig.GetPEMBytes()
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	for k, test := range map[string]struct {
		token         string
		cert          restclient.TLSClientConfig
		expectedUser  string
		errorExpected bool
		errorString   string
	}{
		"valid token, valid cert": {
			token:        validToken,
			cert:         validCert,
			expectedUser: tokenUser,
		},
		"valid token, invalid cert": {
			token:        validToken,
			cert:         invalidCert,
			expectedUser: tokenUser,
		},
		"valid token, no cert": {
			token:        validToken,
			cert:         noCert,
			expectedUser: tokenUser,
		},
		"invalid token, valid cert": {
			token:         invalidToken,
			cert:          validCert,
			errorExpected: true,
			errorString:   unauthorizedError,
		},
		"invalid token, invalid cert": {
			token:         invalidToken,
			cert:          invalidCert,
			errorExpected: true,
			errorString:   unauthorizedError,
		},
		"invalid token, no cert": {
			token:         invalidToken,
			cert:          noCert,
			errorExpected: true,
			errorString:   unauthorizedError,
		},
		"no token, valid cert": {
			token:        noToken,
			cert:         validCert,
			expectedUser: certUser,
		},
		"no token, invalid cert": {
			token:         noToken,
			cert:          invalidCert,
			errorExpected: true,
			errorString:   unauthorizedError,
		},
		"no token, no cert": {
			token:         noToken,
			cert:          noCert,
			errorExpected: true,
			errorString:   anonymousError,
		},
	} {
		config := *adminConfig
		config.BearerToken = test.token
		config.TLSClientConfig = test.cert
		config.CAData = adminConfig.CAData

		client := oclient.NewOrDie(&config)

		user, err := client.Users().Get("~")

		if user.Name != test.expectedUser {
			t.Errorf("%s: unexpected user %q", k, user.Name)
		}

		if test.errorExpected {
			if err == nil {
				t.Errorf("%s: expected error but got nil", k)
			} else if err.Error() != test.errorString {
				t.Errorf("%s: unexpected error string %q", k, err.Error())
			}
		} else {
			if err != nil {
				t.Errorf("%s: unexpected error %q", k, err.Error())
			}
		}
	}

}