func setupRunOnceDurationTest(t *testing.T, pluginConfig *pluginapi.RunOnceDurationConfig, nsAnnotations map[string]string) kclient.Interface { masterConfig, err := testserver.DefaultMasterOptions() if err != nil { t.Fatalf("error creating config: %v", err) } plugins := append([]string{"RunOnceDuration"}, kubemaster.AdmissionPlugins...) masterConfig.KubernetesMasterConfig.AdmissionConfig.PluginOrderOverride = plugins masterConfig.KubernetesMasterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "RunOnceDuration": { Configuration: runtime.EmbeddedObject{ Object: pluginConfig, }, }, } kubeConfigFile, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("error starting server: %v", err) } kubeClient, err := testutil.GetClusterAdminKubeClient(kubeConfigFile) if err != nil { t.Fatalf("error getting client: %v", err) } ns := &kapi.Namespace{} ns.Name = testutil.Namespace() ns.Annotations = nsAnnotations _, err = kubeClient.Namespaces().Create(ns) if err != nil { t.Fatalf("error creating namespace: %v", err) } if err := testserver.WaitForServiceAccounts(kubeClient, testutil.Namespace(), []string{bootstrappolicy.DefaultServiceAccountName}); err != nil { t.Errorf("unexpected error: %v", err) } return kubeClient }
func setupClusterResourceOverrideTest(t *testing.T, pluginConfig *overrideapi.ClusterResourceOverrideConfig) kclient.Interface { masterConfig, err := testserver.DefaultMasterOptions() checkErr(t, err) // fill in possibly-empty config values if masterConfig.KubernetesMasterConfig == nil { masterConfig.KubernetesMasterConfig = &api.KubernetesMasterConfig{} } kubeMaster := masterConfig.KubernetesMasterConfig if kubeMaster.AdmissionConfig.PluginConfig == nil { kubeMaster.AdmissionConfig.PluginConfig = map[string]api.AdmissionPluginConfig{} } // set our config as desired kubeMaster.AdmissionConfig.PluginConfig[overrideapi.PluginName] = api.AdmissionPluginConfig{Configuration: pluginConfig} // start up a server and return useful clients to that server clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig) checkErr(t, err) clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) checkErr(t, err) clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) checkErr(t, err) // need to create a project and return client for project admin clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) checkErr(t, err) _, err = testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, testutil.Namespace(), "peon") checkErr(t, err) checkErr(t, testserver.WaitForServiceAccounts(clusterAdminKubeClient, testutil.Namespace(), []string{bootstrappolicy.DefaultServiceAccountName})) return clusterAdminKubeClient }
func removeBuildStrategyRoleResources(t *testing.T, clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) { // remove resources from role so that certain build strategies are forbidden for _, role := range []string{bootstrappolicy.BuildStrategyCustomRoleName, bootstrappolicy.BuildStrategyDockerRoleName, bootstrappolicy.BuildStrategySourceRoleName, bootstrappolicy.BuildStrategyJenkinsPipelineRoleName} { options := &policy.RoleModificationOptions{ RoleNamespace: "", RoleName: role, RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient), Groups: []string{"system:authenticated"}, } if err := options.RemoveRole(); err != nil { t.Fatalf("unexpected error: %v", err) } } if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.DockerBuildResource), false); err != nil { t.Fatal(err) } if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.SourceBuildResource), false); err != nil { t.Fatal(err) } if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.CustomBuildResource), false); err != nil { t.Fatal(err) } if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.JenkinsPipelineBuildResource), false); err != nil { t.Fatal(err) } }
func setupRunOnceDurationTest(t *testing.T, pluginConfig *pluginapi.RunOnceDurationConfig, nsAnnotations map[string]string) kclient.Interface { testutil.RequireEtcd(t) masterConfig, err := testserver.DefaultMasterOptions() if err != nil { t.Fatalf("error creating config: %v", err) } masterConfig.KubernetesMasterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "RunOnceDuration": { Configuration: pluginConfig, }, } kubeConfigFile, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("error starting server: %v", err) } kubeClient, err := testutil.GetClusterAdminKubeClient(kubeConfigFile) if err != nil { t.Fatalf("error getting client: %v", err) } ns := &kapi.Namespace{} ns.Name = testutil.Namespace() ns.Annotations = nsAnnotations _, err = kubeClient.Namespaces().Create(ns) if err != nil { t.Fatalf("error creating namespace: %v", err) } if err := testserver.WaitForPodCreationServiceAccounts(kubeClient, testutil.Namespace()); err != nil { t.Errorf("unexpected error: %v", err) } return kubeClient }
func TestSimpleImageChangeBuildTriggerFromImageStreamTagCustomWithConfigChange(t *testing.T) { defer testutil.DumpEtcdOnFailure(t) projectAdminClient, _ := setup(t) clusterAdminClient, err := testutil.GetClusterAdminClient(testutil.GetBaseDir() + "/openshift.local.config/master/admin.kubeconfig") if err != nil { t.Fatalf("unexpected error: %v", err) } clusterRoleBindingAccessor := policy.NewClusterRoleBindingAccessor(clusterAdminClient) subjects := []kapi.ObjectReference{ { Kind: authorizationapi.SystemGroupKind, Name: bootstrappolicy.AuthenticatedGroup, }, } options := policy.RoleModificationOptions{ RoleNamespace: testutil.Namespace(), RoleName: bootstrappolicy.BuildStrategyCustomRoleName, RoleBindingAccessor: clusterRoleBindingAccessor, Subjects: subjects, } options.AddRole() if err := testutil.WaitForPolicyUpdate(projectAdminClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.CustomBuildResource), true); err != nil { t.Fatal(err) } imageStream := mockImageStream2(tag) imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag) strategy := customStrategy("ImageStreamTag", streamName+":"+tag) config := imageChangeBuildConfigWithConfigChange("custom-imagestreamtag", strategy) runTest(t, "SimpleImageChangeBuildTriggerFromImageStreamTagCustom", projectAdminClient, imageStream, imageStreamMapping, config, tag) }
func setupImageStreamAdmissionTest(t *testing.T) (*kclient.Client, *client.Client) { testutil.RequireEtcd(t) _, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI() if err != nil { t.Fatalf("unexpected error: %v", err) } kClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } client, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } for { _, err = client.ImageStreams(testutil.Namespace()).Create(newImageStreamWithSpecTags("src", nil)) t.Logf("initing: %v", err) if err != nil { if errForbiddenWithRetry(err) { t.Logf("waiting for limit ranger to catch up: %v", err) continue } t.Fatalf("err: %#v", err) } break } return kClient, client }
func TestImageStreamDelete(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() if err := clusterAdminClient.ImageStreams(testutil.Namespace()).Delete(stream.Name); err == nil || !errors.IsNotFound(err) { t.Fatalf("Unxpected non-error or type: %v", err) } actual, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if err := clusterAdminClient.ImageStreams(testutil.Namespace()).Delete(actual.Name); err != nil { t.Fatalf("Unxpected error: %v", err) } }
func setupImageStreamAdmissionTest(t *testing.T) (*kclient.Client, *client.Client) { testutil.RequireEtcd(t) _, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI() if err != nil { t.Fatalf("unexpected error: %v", err) } kClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } client, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } _, err = client.ImageStreams(testutil.Namespace()).Create(&imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: "src", }, }) if err != nil { t.Fatal(err) } return kClient, client }
func runBuildConfigChangeControllerTest(t *testing.T, clusterAdminClient *client.Client, clusterAdminKubeClient *kclient.Client) { config := configChangeBuildConfig() created, err := clusterAdminClient.BuildConfigs(testutil.Namespace()).Create(config) if err != nil { t.Fatalf("Couldn't create BuildConfig: %v", err) } watch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } defer watch.Stop() watch2, err := clusterAdminClient.BuildConfigs(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to BuildConfigs %v", err) } defer watch2.Stop() // wait for initial build event event := waitForWatch(t, "config change initial build added", watch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } event = waitForWatch(t, "config change config updated", watch2) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } if bc := event.Object.(*buildapi.BuildConfig); bc.Status.LastVersion == 0 { t.Fatalf("expected build config lastversion to be greater than zero after build") } }
func TestImageStreamList(t *testing.T) { testutil.RequireEtcd(t) defer testutil.DumpEtcdOnFailure(t) _, clusterAdminKubeConfig, err := testserver.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } builds, err := clusterAdminClient.ImageStreams(testutil.Namespace()).List(kapi.ListOptions{}) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(builds.Items) != 0 { t.Errorf("Expected no builds, got %#v", builds.Items) } }
func setupBuildStrategyTest(t *testing.T) (clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) { namespace := testutil.Namespace() _, clusterAdminKubeConfig, err := testserver.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err = testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } projectAdminClient, err = testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, namespace, "harold") if err != nil { t.Fatalf("unexpected error: %v", err) } projectEditorClient, _, _, err = testutil.GetClientForUser(*clusterAdminClientConfig, "joe") if err != nil { t.Fatalf("unexpected error: %v", err) } addJoe := &policy.RoleModificationOptions{ RoleNamespace: "", RoleName: bootstrappolicy.EditRoleName, RoleBindingAccessor: policy.NewLocalRoleBindingAccessor(namespace, projectAdminClient), Users: []string{"joe"}, } if err := addJoe.AddRole(); err != nil { t.Fatalf("unexpected error: %v", err) } if err := testutil.WaitForPolicyUpdate(projectEditorClient, namespace, "create", authorizationapi.DockerBuildResource, true); err != nil { t.Fatalf(err.Error()) } // Create builder image stream and tag imageStream := &imageapi.ImageStream{} imageStream.Name = "builderimage" _, err = clusterAdminClient.ImageStreams(testutil.Namespace()).Create(imageStream) if err != nil { t.Fatalf("Couldn't create ImageStream: %v", err) } // Create image stream mapping imageStreamMapping := &imageapi.ImageStreamMapping{} imageStreamMapping.Name = "builderimage" imageStreamMapping.Tag = "latest" imageStreamMapping.Image.Name = "image-id" imageStreamMapping.Image.DockerImageReference = "test/builderimage:latest" err = clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(imageStreamMapping) if err != nil { t.Fatalf("Couldn't create ImageStreamMapping: %v", err) } return }
func TestClusterResourceOverridePluginWithLimits(t *testing.T) { defer testutil.DumpEtcdOnFailure(t) config := &overrideapi.ClusterResourceOverrideConfig{ LimitCPUToMemoryPercent: 100, CPURequestToLimitPercent: 50, MemoryRequestToLimitPercent: 50, } kubeClientset := setupClusterResourceOverrideTest(t, config) podHandler := kubeClientset.Core().Pods(testutil.Namespace()) limitHandler := kubeClientset.Core().LimitRanges(testutil.Namespace()) // test with limits object with defaults; // I wanted to test with a limits object without defaults to see limits forbid an empty resource spec, // but found that if defaults aren't set in the limit object, something still fills them in. // note: defaults are only used when quantities are *missing*, not when they are 0 limitItem := kapi.LimitRangeItem{ Type: kapi.LimitTypeContainer, Max: testResourceList("2Gi", "2"), Min: testResourceList("128Mi", "200m"), Default: testResourceList("512Mi", "500m"), // note: auto-filled from max if we set that; DefaultRequest: testResourceList("128Mi", "200m"), // filled from max if set, or min if that is set MaxLimitRequestRatio: kapi.ResourceList{}, } limit := &kapi.LimitRange{ ObjectMeta: kapi.ObjectMeta{Name: "limit"}, Spec: kapi.LimitRangeSpec{Limits: []kapi.LimitRangeItem{limitItem}}, } _, err := limitHandler.Create(limit) if err != nil { t.Fatal(err) } podCreated, err := podHandler.Create(testClusterResourceOverridePod("limit-with-default", "", "1")) if err != nil { t.Fatal(err) } if memory := podCreated.Spec.Containers[0].Resources.Limits.Memory(); memory.Cmp(resource.MustParse("512Mi")) != 0 { t.Errorf("limit-with-default: Memory limit did not match default 512Mi: %v", memory) } if memory := podCreated.Spec.Containers[0].Resources.Requests.Memory(); memory.Cmp(resource.MustParse("256Mi")) != 0 { t.Errorf("limit-with-default: Memory req did not match expected 256Mi: %v", memory) } if cpu := podCreated.Spec.Containers[0].Resources.Limits.Cpu(); cpu.Cmp(resource.MustParse("500m")) != 0 { t.Errorf("limit-with-default: CPU limit did not match expected 500 mcore: %v", cpu) } if cpu := podCreated.Spec.Containers[0].Resources.Requests.Cpu(); cpu.Cmp(resource.MustParse("250m")) != 0 { t.Errorf("limit-with-default: CPU req did not match expected 250 mcore: %v", cpu) } // set it up so that the overrides create resources that fail validation _, err = podHandler.Create(testClusterResourceOverridePod("limit-with-default-fail", "128Mi", "1")) if err == nil { t.Errorf("limit-with-default-fail: expected to be forbidden") } else if !apierrors.IsForbidden(err) { t.Errorf("limit-with-default-fail: unexpected error: %v", err) } }
func TestTriggers_manual(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestDeployOpenshift(t) defer openshift.Close() config := deploytest.OkDeploymentConfig(0) config.Namespace = testutil.Namespace() config.Triggers = []deployapi.DeploymentTriggerPolicy{ { Type: deployapi.DeploymentTriggerManual, }, } dc, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Create(config) if err != nil { t.Fatalf("Couldn't create DeploymentConfig: %v %#v", err, config) } watch, err := openshift.KubeClient.ReplicationControllers(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), dc.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Deployments: %v", err) } defer watch.Stop() retryErr := kclient.RetryOnConflict(wait.Backoff{Steps: maxUpdateRetries}, func() error { config, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Generate(config.Name) if err != nil { return err } if config.LatestVersion != 1 { t.Fatalf("Generated deployment should have version 1: %#v", config) } t.Logf("config(1): %#v", config) updatedConfig, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Update(config) if err != nil { return err } t.Logf("config(2): %#v", updatedConfig) return nil }) if retryErr != nil { t.Fatal(err) } event := <-watch.ResultChan() if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } deployment := event.Object.(*kapi.ReplicationController) if e, a := config.Name, deployutil.DeploymentConfigNameFor(deployment); e != a { t.Fatalf("Expected deployment annotated with deploymentConfig '%s', got '%s'", e, a) } if e, a := 1, deployutil.DeploymentVersionFor(deployment); e != a { t.Fatalf("Deployment annotation version does not match: %#v", deployment) } }
func TestPolicyBasedRestrictionOfBuildConfigCreateAndInstantiateByStrategy(t *testing.T) { defer testutil.DumpEtcdOnFailure(t) clusterAdminClient, projectAdminClient, projectEditorClient := setupBuildStrategyTest(t, true) clients := map[string]*client.Client{"admin": projectAdminClient, "editor": projectEditorClient} buildConfigs := map[string]*buildapi.BuildConfig{} // by default admins and editors can create all type of buildconfigs for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { var err error if buildConfigs[string(strategy)+clientType], err = createBuildConfig(t, client.BuildConfigs(testutil.Namespace()), strategy); err != nil { t.Errorf("unexpected error for strategy %s and client %s: %v", strategy, clientType, err) } } } // by default admins and editors can instantiate build configs for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := instantiateBuildConfig(t, client.BuildConfigs(testutil.Namespace()), buildConfigs[string(strategy)+clientType]); err != nil { t.Errorf("unexpected instantiate error for strategy %s and client %s: %v", strategy, clientType, err) } } } removeBuildStrategyRoleResources(t, clusterAdminClient, projectAdminClient, projectEditorClient) // make sure buildconfigs are rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := createBuildConfig(t, client.BuildConfigs(testutil.Namespace()), strategy); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } // make sure buildconfig updates are rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := updateBuildConfig(t, client.BuildConfigs(testutil.Namespace()), buildConfigs[string(strategy)+clientType]); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } // make sure instantiate is rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := instantiateBuildConfig(t, client.BuildConfigs(testutil.Namespace()), buildConfigs[string(strategy)+clientType]); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } }
func TestWebhookGitHubPing(t *testing.T) { testutil.RequireEtcd(t) _, clusterAdminKubeConfig, err := testserver.StartTestMaster() if err != nil { t.Fatalf("unable to start master: %v", err) } kubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unable to get kubeClient: %v", err) } osClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unable to get osClient: %v", err) } kubeClient.Namespaces().Create(&kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{Name: testutil.Namespace()}, }) // create buildconfig buildConfig := mockBuildConfigImageParms("originalImage", "imageStream", "validTag") if _, err := osClient.BuildConfigs(testutil.Namespace()).Create(buildConfig); err != nil { t.Fatalf("Unexpected error: %v", err) } watch, err := osClient.Builds(testutil.Namespace()).Watch(kapi.ListOptions{}) if err != nil { t.Fatalf("Couldn't subscribe to builds: %v", err) } defer watch.Stop() for _, s := range []string{ "/oapi/v1/namespaces/" + testutil.Namespace() + "/buildconfigs/pushbuild/webhooks/secret101/github", } { // trigger build event sending push notification clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } postFile(kubeClient.RESTClient.Client, "ping", "pingevent.json", clusterAdminClientConfig.Host+s, http.StatusOK, t) // TODO: improve negative testing timer := time.NewTimer(time.Second / 2) select { case <-timer.C: // nothing should happen case event := <-watch.ResultChan(): build := event.Object.(*buildapi.Build) t.Fatalf("Unexpected build created: %#v", build) } } }
func TestPolicyBasedRestrictionOfBuildCreateAndCloneByStrategy(t *testing.T) { clusterAdminClient, projectAdminClient, projectEditorClient := setupBuildStrategyTest(t) clients := map[string]*client.Client{"admin": projectAdminClient, "editor": projectEditorClient} builds := map[string]*buildapi.Build{} // Create builds to setup test for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { var err error if builds[string(strategy)+clientType], err = createBuild(t, client.Builds(testutil.Namespace()), strategy); err != nil { t.Errorf("unexpected error for strategy %s and client %s: %v", strategy, clientType, err) } } } // by default amdins and editors can clone builds for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := cloneBuild(t, client.Builds(testutil.Namespace()), builds[string(strategy)+clientType]); err != nil { t.Errorf("unexpected clone error for strategy %s and client %s: %v", strategy, clientType, err) } } } removeBuildStrategyRoleResources(t, clusterAdminClient, projectAdminClient, projectEditorClient) // make sure builds are rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := createBuild(t, client.Builds(testutil.Namespace()), strategy); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } // make sure build updates are rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := updateBuild(t, client.Builds(testutil.Namespace()), builds[string(strategy)+clientType]); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } // make sure clone is rejected for _, strategy := range buildStrategyTypes() { for clientType, client := range clients { if _, err := cloneBuild(t, client.Builds(testutil.Namespace()), builds[string(strategy)+clientType]); !kapierror.IsForbidden(err) { t.Errorf("expected forbidden for strategy %s and client %s: got %v", strategy, clientType, err) } } } }
func removeBuildStrategyRoleResources(t *testing.T, clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) { // remove resources from role so that certain build strategies are forbidden removeBuildStrategyPrivileges(t, clusterAdminClient.ClusterRoles(), bootstrappolicy.EditRoleName) if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", authorizationapi.DockerBuildResource, false); err != nil { t.Error(err) } removeBuildStrategyPrivileges(t, clusterAdminClient.ClusterRoles(), bootstrappolicy.AdminRoleName) if err := testutil.WaitForPolicyUpdate(projectAdminClient, testutil.Namespace(), "create", authorizationapi.DockerBuildResource, false); err != nil { t.Error(err) } }
func setupUserPodNodeConstraintsTest(t *testing.T, pluginConfig *pluginapi.PodNodeConstraintsConfig, user string) (*client.Client, *kclientset.Clientset) { testutil.RequireEtcd(t) masterConfig, err := testserver.DefaultMasterOptions() if err != nil { t.Fatalf("error creating config: %v", err) } cfg := map[string]configapi.AdmissionPluginConfig{ "PodNodeConstraints": { Configuration: pluginConfig, }, } masterConfig.AdmissionConfig.PluginConfig = cfg masterConfig.KubernetesMasterConfig.AdmissionConfig.PluginConfig = cfg kubeConfigFile, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("error starting server: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(kubeConfigFile) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(kubeConfigFile) if err != nil { t.Fatalf("unexpected error: %v", err) } userClient, userkubeClientset, _, err := testutil.GetClientForUser(*clusterAdminClientConfig, user) if err != nil { t.Fatalf("error getting user/kube client: %v", err) } kubeClientset, err := testutil.GetClusterAdminKubeClient(kubeConfigFile) if err != nil { t.Fatalf("error getting kube client: %v", err) } ns := &kapi.Namespace{} ns.Name = testutil.Namespace() _, err = kubeClientset.Core().Namespaces().Create(ns) if err != nil { t.Fatalf("error creating namespace: %v", err) } if err := testserver.WaitForServiceAccounts(kubeClientset, testutil.Namespace(), []string{bootstrappolicy.DefaultServiceAccountName}); err != nil { t.Fatalf("unexpected error: %v", err) } addUser := &policy.RoleModificationOptions{ RoleNamespace: ns.Name, RoleName: bootstrappolicy.AdminRoleName, RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient), Users: []string{user}, } if err := addUser.AddRole(); err != nil { t.Fatalf("unexpected error: %v", err) } return userClient, userkubeClientset }
func runBuildRunningPodDeleteTest(t *testing.T, clusterAdminClient *client.Client, clusterAdminKubeClient *kclient.Client) { buildWatch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } defer buildWatch.Stop() created, err := clusterAdminClient.Builds(testutil.Namespace()).Create(mockBuild()) if err != nil { t.Fatalf("Couldn't create Build: %v", err) } podWatch, err := clusterAdminKubeClient.Pods(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Pods %v", err) } defer podWatch.Stop() // wait for initial build event from the creation of the imagerepo with tag latest event := waitForWatch(t, "initial build added", buildWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild := event.Object.(*buildapi.Build) // initial pod creation for build event = waitForWatch(t, "build pod created", podWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } event = waitForWatch(t, "build updated to pending", buildWatch) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) if newBuild.Status.Phase != buildapi.BuildPhasePending { t.Fatalf("expected build status to be marked pending, but was marked %s", newBuild.Status.Phase) } clusterAdminKubeClient.Pods(testutil.Namespace()).Delete(buildutil.GetBuildPodName(newBuild), kapi.NewDeleteOptions(0)) event = waitForWatch(t, "build updated to error", buildWatch) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) if newBuild.Status.Phase != buildapi.BuildPhaseError { t.Fatalf("expected build status to be marked error, but was marked %s", newBuild.Status.Phase) } }
func TestDeleteBuild(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() build := mockBuild() actual, err := openshift.Client.Builds(testutil.Namespace()).Create(build) if err != nil { t.Fatalf("Unexpected error: %v", err) } if err := openshift.Client.Builds(testutil.Namespace()).Delete(actual.Name); err != nil { t.Fatalf("Unxpected error: %v", err) } }
func TestAlwaysPullImagesOn(t *testing.T) { testutil.RequireEtcd(t) defer testutil.DumpEtcdOnFailure(t) masterConfig, err := testserver.DefaultMasterOptions() if err != nil { t.Fatalf("error creating config: %v", err) } masterConfig.KubernetesMasterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "AlwaysPullImages": { Configuration: &configapi.DefaultAdmissionConfig{}, }, } kubeConfigFile, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("error starting server: %v", err) } kubeClientset, err := testutil.GetClusterAdminKubeClient(kubeConfigFile) if err != nil { t.Fatalf("error getting client: %v", err) } ns := &kapi.Namespace{} ns.Name = testutil.Namespace() _, err = kubeClientset.Core().Namespaces().Create(ns) if err != nil { t.Fatalf("error creating namespace: %v", err) } if err := testserver.WaitForPodCreationServiceAccounts(kubeClientset, testutil.Namespace()); err != nil { t.Fatalf("error getting client config: %v", err) } testPod := &kapi.Pod{} testPod.GenerateName = "test" testPod.Spec.Containers = []kapi.Container{ { Name: "container", Image: "openshift/origin-pod:notlatest", ImagePullPolicy: kapi.PullNever, }, } actualPod, err := kubeClientset.Core().Pods(testutil.Namespace()).Create(testPod) if err != nil { t.Fatalf("unexpected error: %v", err) } if actualPod.Spec.Containers[0].ImagePullPolicy != kapi.PullAlways { t.Errorf("expected %v, got %v", kapi.PullAlways, actualPod.Spec.Containers[0].ImagePullPolicy) } }
func setupBuildControllerTest(counts controllerCount, t *testing.T) (*client.Client, *kclientset.Clientset) { testutil.RequireEtcd(t) master, clusterAdminKubeConfig, err := testserver.StartTestMaster() if err != nil { t.Fatal(err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatal(err) } clusterAdminKubeClientset, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Fatal(err) } _, err = clusterAdminKubeClientset.Core().Namespaces().Create(&kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{Name: testutil.Namespace()}, }) if err != nil { t.Fatal(err) } if err := testserver.WaitForServiceAccounts(clusterAdminKubeClientset, testutil.Namespace(), []string{bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DefaultServiceAccountName}); err != nil { t.Fatalf("unexpected error: %v", err) } openshiftConfig, err := origin.BuildMasterConfig(*master) if err != nil { t.Fatal(err) } // Get the build controller clients, since those rely on service account tokens // We don't want to proceed with the rest of the test until those are available openshiftConfig.BuildControllerClients() for i := 0; i < counts.BuildControllers; i++ { openshiftConfig.RunBuildController(openshiftConfig.Informers) } for i := 0; i < counts.BuildPodControllers; i++ { openshiftConfig.RunBuildPodController() } for i := 0; i < counts.ImageChangeControllers; i++ { openshiftConfig.RunBuildImageChangeTriggerController() } for i := 0; i < counts.ConfigChangeControllers; i++ { openshiftConfig.RunBuildConfigChangeController() } return clusterAdminClient, clusterAdminKubeClientset }
// testPodNodeConstraintsObjectCreationWithPodTemplate attempts to create different object types that contain pod templates // using the passed in nodeName and nodeSelector. It will use the expectError flag to determine if an error should be returned or not func testPodNodeConstraintsObjectCreationWithPodTemplate(t *testing.T, name string, kclientset kclientset.Interface, client client.Interface, nodeName string, nodeSelector map[string]string, expectError bool) { checkForbiddenErr := func(objType string, err error) { if err == nil && expectError { t.Errorf("%s (%s): expected forbidden error but did not receive one", name, objType) return } if err != nil && !expectError { t.Errorf("%s (%s): got error but did not expect one: %v", name, objType, err) return } if err != nil && expectError && !kapierrors.IsForbidden(err) { t.Errorf("%s (%s): did not get an expected forbidden error: %v", name, objType, err) return } } // Pod pod := testPodNodeConstraintsPod(nodeName, nodeSelector) _, err := kclientset.Core().Pods(testutil.Namespace()).Create(pod) checkForbiddenErr("pod", err) // ReplicationController rc := testPodNodeConstraintsReplicationController(nodeName, nodeSelector) _, err = kclientset.Core().ReplicationControllers(testutil.Namespace()).Create(rc) checkForbiddenErr("rc", err) // TODO: Enable when the deployments endpoint is supported in Origin // Deployment // d := testPodNodeConstraintsDeployment(nodeName, nodeSelector) // _, err = kclientset.Extensions().Deployments(testutil.Namespace()).Create(d) // checkForbiddenErr("deployment", err) // ReplicaSet rs := testPodNodeConstraintsReplicaSet(nodeName, nodeSelector) _, err = kclientset.Extensions().ReplicaSets(testutil.Namespace()).Create(rs) checkForbiddenErr("replicaset", err) // Job job := testPodNodeConstraintsJob(nodeName, nodeSelector) _, err = kclientset.Batch().Jobs(testutil.Namespace()).Create(job) checkForbiddenErr("job", err) // DeploymentConfig dc := testPodNodeConstraintsDeploymentConfig(nodeName, nodeSelector) _, err = client.DeploymentConfigs(testutil.Namespace()).Create(dc) checkForbiddenErr("dc", err) }
func imageChangeBuildConfig(name string, strategy buildapi.BuildStrategy) *buildapi.BuildConfig { return &buildapi.BuildConfig{ ObjectMeta: kapi.ObjectMeta{ Name: name, Namespace: testutil.Namespace(), Labels: map[string]string{"testlabel": "testvalue"}, }, Spec: buildapi.BuildConfigSpec{ BuildSpec: buildapi.BuildSpec{ Source: buildapi.BuildSource{ Type: "Git", Git: &buildapi.GitBuildSource{ URI: "git://github.com/openshift/ruby-hello-world.git", }, ContextDir: "contextimage", }, Strategy: strategy, Output: buildapi.BuildOutput{ To: &kapi.ObjectReference{ Kind: "ImageStreamTag", Name: "test-image-trigger-repo:outputtag", }, }, }, Triggers: []buildapi.BuildTriggerPolicy{ { Type: buildapi.ImageChangeBuildTriggerType, ImageChange: &buildapi.ImageChangeTrigger{}, }, }, }, } }
func TestClusterResourceOverridePluginWithNoLimits(t *testing.T) { defer testutil.DumpEtcdOnFailure(t) config := &overrideapi.ClusterResourceOverrideConfig{ LimitCPUToMemoryPercent: 100, CPURequestToLimitPercent: 50, MemoryRequestToLimitPercent: 50, } kubeClientset := setupClusterResourceOverrideTest(t, config) podHandler := kubeClientset.Core().Pods(testutil.Namespace()) // test with no limits object present podCreated, err := podHandler.Create(testClusterResourceOverridePod("limitless", "2Gi", "1")) if err != nil { t.Fatal(err) } if memory := podCreated.Spec.Containers[0].Resources.Requests.Memory(); memory.Cmp(resource.MustParse("1Gi")) != 0 { t.Errorf("limitlesspod: Memory did not match expected 1Gi: %#v", memory) } if cpu := podCreated.Spec.Containers[0].Resources.Limits.Cpu(); cpu.Cmp(resource.MustParse("2")) != 0 { t.Errorf("limitlesspod: CPU limit did not match expected 2 core: %#v", cpu) } if cpu := podCreated.Spec.Containers[0].Resources.Requests.Cpu(); cpu.Cmp(resource.MustParse("1")) != 0 { t.Errorf("limitlesspod: CPU req did not match expected 1 core: %#v", cpu) } }
func TestImageStreamCreate(t *testing.T) { testutil.RequireEtcd(t) defer testutil.DumpEtcdOnFailure(t) _, clusterAdminKubeConfig, err := testserver.StartTestMasterAPI() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() if _, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(&imageapi.ImageStream{}); err == nil || !errors.IsInvalid(err) { t.Fatalf("Unexpected error: %v", err) } expected, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if expected.Name == "" { t.Errorf("Unexpected empty image Name %v", expected) } actual, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(stream.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %s", diff.ObjectDiff(expected, actual)) } streams, err := clusterAdminClient.ImageStreams(testutil.Namespace()).List(kapi.ListOptions{}) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(streams.Items) != 1 { t.Errorf("Expected one image, got %#v", streams.Items) } }
func TestImageStreamCreate(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() if _, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(&imageapi.ImageStream{}); err == nil || !errors.IsInvalid(err) { t.Fatalf("Unexpected error: %v", err) } expected, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if expected.Name == "" { t.Errorf("Unexpected empty image Name %v", expected) } actual, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(stream.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %s", util.ObjectDiff(expected, actual)) } streams, err := clusterAdminClient.ImageStreams(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(streams.Items) != 1 { t.Errorf("Expected one image, got %#v", streams.Items) } }
func TestUpdateBuildConfig(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfig := mockBuildConfig() actual, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig) if err != nil { t.Fatalf("Unexpected error: %v", err) } actual, err = openshift.Client.BuildConfigs(testutil.Namespace()).Get(actual.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if _, err := openshift.Client.BuildConfigs(testutil.Namespace()).Update(actual); err != nil { t.Fatalf("Unexpected error: %v", err) } }
func runBuildDeleteTest(t *testing.T, clusterAdminClient *client.Client, clusterAdminKubeClient *kclient.Client) { buildWatch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } defer buildWatch.Stop() created, err := clusterAdminClient.Builds(testutil.Namespace()).Create(mockBuild()) if err != nil { t.Fatalf("Couldn't create Build: %v", err) } podWatch, err := clusterAdminKubeClient.Pods(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Pods %v", err) } defer podWatch.Stop() // wait for initial build event from the creation of the imagerepo with tag latest event := waitForWatch(t, "initial build added", buildWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild := event.Object.(*buildapi.Build) // initial pod creation for build event = waitForWatch(t, "build pod created", podWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } clusterAdminClient.Builds(testutil.Namespace()).Delete(newBuild.Name) event = waitForWatchType(t, "pod deleted due to build deleted", podWatch, watchapi.Deleted) if e, a := watchapi.Deleted, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } pod := event.Object.(*kapi.Pod) if expected := buildutil.GetBuildPodName(newBuild); pod.Name != expected { t.Fatalf("Expected pod %s to be deleted, but pod %s was deleted", expected, pod.Name) } }
func configChangeBuildConfig() *buildapi.BuildConfig { bc := &buildapi.BuildConfig{} bc.Name = "testcfgbc" bc.Namespace = testutil.Namespace() bc.Spec.Source.Git = &buildapi.GitBuildSource{} bc.Spec.Source.Git.URI = "git://github.com/openshift/ruby-hello-world.git" bc.Spec.Strategy.DockerStrategy = &buildapi.DockerBuildStrategy{} configChangeTrigger := buildapi.BuildTriggerPolicy{Type: buildapi.ConfigChangeBuildTriggerType} bc.Spec.Triggers = append(bc.Spec.Triggers, configChangeTrigger) return bc }