// SetOpenShiftClient sets the passed OpenShift client in the application configuration func (c *AppConfig) SetOpenShiftClient(osclient client.Interface, originNamespace string) { c.osclient = osclient c.originNamespace = originNamespace namespaces := []string{originNamespace} if openshiftNamespace := "openshift"; originNamespace != openshiftNamespace { namespaces = append(namespaces, openshiftNamespace) } c.imageStreamSearcher = app.ImageStreamSearcher{ Client: osclient, ImageStreamImages: osclient, Namespaces: namespaces, } c.imageStreamByAnnotationSearcher = app.NewImageStreamByAnnotationSearcher(osclient, osclient, namespaces) c.templateSearcher = app.TemplateSearcher{ Client: osclient, TemplateConfigsNamespacer: osclient, Namespaces: namespaces, } c.templateFileSearcher = &app.TemplateFileSearcher{ Typer: c.typer, Mapper: c.mapper, ClientMapper: c.clientMapper, Namespace: originNamespace, } }
// SetOpenShiftClient sets the passed OpenShift client in the application configuration func (c *AppConfig) SetOpenShiftClient(osclient client.Interface, OriginNamespace string) { c.OSClient = osclient c.OriginNamespace = OriginNamespace namespaces := []string{OriginNamespace} if openshiftNamespace := "openshift"; OriginNamespace != openshiftNamespace { namespaces = append(namespaces, openshiftNamespace) } c.ImageStreamSearcher = app.ImageStreamSearcher{ Client: osclient, ImageStreamImages: osclient, Namespaces: namespaces, } c.ImageStreamByAnnotationSearcher = app.NewImageStreamByAnnotationSearcher(osclient, osclient, namespaces) c.TemplateSearcher = app.TemplateSearcher{ Client: osclient, TemplateConfigsNamespacer: osclient, Namespaces: namespaces, } c.TemplateFileSearcher = &app.TemplateFileSearcher{ Typer: c.Typer, Mapper: c.Mapper, ClientMapper: c.ClientMapper, Namespace: OriginNamespace, } c.DockerSearcher = app.ImageImportSearcher{ Client: osclient.ImageStreams(OriginNamespace), AllowInsecure: c.InsecureRegistry, Fallback: c.DockerImageSearcher(), } }
// SetOpenShiftClient sets the passed OpenShift client in the application configuration func (c *AppConfig) SetOpenShiftClient(osclient client.Interface, originNamespace string) { c.osclient = osclient c.originNamespace = originNamespace namespaces := []string{originNamespace} if openshiftNamespace := "openshift"; originNamespace != openshiftNamespace { namespaces = append(namespaces, openshiftNamespace) } c.imageStreamSearcher = app.ImageStreamSearcher{ Client: osclient, ImageStreamImages: osclient, Namespaces: namespaces, StopOnMatch: !c.AsSearch, } c.imageStreamByAnnotationSearcher = app.NewImageStreamByAnnotationSearcher(osclient, osclient, namespaces) c.templateSearcher = app.TemplateSearcher{ Client: osclient, TemplateConfigsNamespacer: osclient, Namespaces: namespaces, } c.templateFileSearcher = &app.TemplateFileSearcher{ Typer: c.typer, Mapper: c.mapper, ClientMapper: c.clientMapper, Namespace: originNamespace, } c.dockerSearcher = app.ImageImportSearcher{ Client: osclient.ImageStreams(originNamespace), AllowInsecure: c.InsecureRegistry, Fallback: c.dockerImageSearcher(), } }
// SetOpenShiftClient sets the passed OpenShift client in the application configuration func (c *AppConfig) SetOpenShiftClient(osclient client.Interface, OriginNamespace string, dockerclient *docker.Client) { c.OSClient = osclient c.OriginNamespace = OriginNamespace namespaces := []string{OriginNamespace} if openshiftNamespace := "openshift"; OriginNamespace != openshiftNamespace { namespaces = append(namespaces, openshiftNamespace) } c.ImageStreamSearcher = app.ImageStreamSearcher{ Client: osclient, ImageStreamImages: osclient, Namespaces: namespaces, AllowMissingTags: c.AllowMissingImageStreamTags, } c.ImageStreamByAnnotationSearcher = app.NewImageStreamByAnnotationSearcher(osclient, osclient, namespaces) c.TemplateSearcher = app.TemplateSearcher{ Client: osclient, TemplateConfigsNamespacer: osclient, Namespaces: namespaces, } c.TemplateFileSearcher = &app.TemplateFileSearcher{ Typer: c.Typer, Mapper: c.Mapper, ClientMapper: c.ClientMapper, Namespace: OriginNamespace, } // the hierarchy of docker searching is: // 1) if we have an openshift client - query docker registries via openshift, // if we're unable to query via openshift, query the docker registries directly(fallback), // if we don't find a match there and a local docker daemon exists, look in the local registry. // 2) if we don't have an openshift client - query the docker registries directly, // if we don't find a match there and a local docker daemon exists, look in the local registry. c.DockerSearcher = app.DockerClientSearcher{ Client: dockerclient, Insecure: c.InsecureRegistry, AllowMissingImages: c.AllowMissingImages, RegistrySearcher: app.ImageImportSearcher{ Client: osclient.ImageStreams(OriginNamespace), AllowInsecure: c.InsecureRegistry, Fallback: c.DockerRegistrySearcher(), }, } }
// SetOpenShiftClient sets the passed OpenShift client in the application configuration func (c *AppConfig) SetOpenShiftClient(osclient client.Interface, originNamespace string) { c.osclient = osclient c.originNamespace = originNamespace c.imageStreamSearcher = app.ImageStreamSearcher{ Client: osclient, ImageStreamImages: osclient, Namespaces: []string{originNamespace, "openshift"}, } c.imageStreamByAnnotationSearcher = app.NewImageStreamByAnnotationSearcher(osclient, osclient, []string{originNamespace, "openshift"}) c.templateSearcher = app.TemplateSearcher{ Client: osclient, TemplateConfigsNamespacer: osclient, Namespaces: []string{originNamespace, "openshift"}, } c.templateFileSearcher = &app.TemplateFileSearcher{ Typer: c.typer, Mapper: c.mapper, ClientMapper: c.clientMapper, Namespace: originNamespace, } }
func TestRunAll(t *testing.T) { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedName string expectedErr error expectInsecure sets.String expectedVolumes map[string]string checkPort string }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "source", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedVolumes: nil, expectedErr: nil, }, { name: "successful ruby app generation with labels", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "source", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", Labels: map[string]string{"label1": "value1", "label2": "value2"}, }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedVolumes: nil, expectedErr: nil, }, { name: "successful docker app generation", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeSimpleDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "docker", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, checkPort: "8080", expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby-20-centos7"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "app generation using context dir", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/sti-ruby"}), ContextDir: "2.0/test/rack-test-app", dockerSearcher: dockerSearcher, imageStreamSearcher: fakeImageStreamSearcher(), imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"sti-ruby"}, "buildConfig": {"sti-ruby"}, "deploymentConfig": {"sti-ruby"}, "service": {"sti-ruby"}, }, expectedName: "sti-ruby", expectedVolumes: nil, expectedErr: nil, }, { name: "insecure registry generation", config: &AppConfig{ Components: util.StringList([]string{"myrepo:5000/myco/example"}), SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), Strategy: "source", dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"myrepo:5000/myco/example"}}}, Image: dockerBuilderImage(), }, Insecure: true, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{}, }, templateFileSearcher: &app.TemplateFileSearcher{}, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", InsecureRegistry: true, }, expected: map[string][]string{ "imageStream": {"example", "ruby-hello-world"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, expectedVolumes: nil, expectInsecure: sets.NewString("example"), }, { name: "emptyDir volumes", config: &AppConfig{ DockerImages: util.StringList([]string{"mysql"}), dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"mysql"}, "deploymentConfig": {"mysql"}, "service": {"mysql"}, "volumeMounts": {"mysql-volume-1"}, }, expectedName: "mysql", expectedVolumes: map[string]string{ "mysql-volume-1": "EmptyDir", }, expectedErr: nil, }, { name: "Docker build", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"openshift/ruby-20-centos7"}}}, Image: dockerBuilderImage(), }, Insecure: true, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby-20-centos7"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "Docker build with no registry image", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"openshift/ruby-20-centos7"}}}, Image: dockerBuilderImage(), }, Insecure: true, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "custom name", config: &AppConfig{ DockerImages: util.StringList([]string{"mysql"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"mysql"}}}, Image: &docker.Image{ Config: &docker.Config{ ExposedPorts: map[docker.Port]struct{}{ "8080/tcp": {}, }, }, }, }, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", Name: "custom", }, expected: map[string][]string{ "imageStream": {"custom"}, "deploymentConfig": {"custom"}, "service": {"custom"}, }, expectedName: "custom", expectedErr: nil, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr res, err := test.config.RunAll() if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } imageStreams := []*imageapi.ImageStream{} got := map[string][]string{} gotVolumes := map[string]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *kapi.Service: if test.checkPort != "" { if len(tp.Spec.Ports) == 0 { t.Errorf("%s: did not get any ports in service", test.name) break } expectedPort, _ := strconv.Atoi(test.checkPort) if tp.Spec.Ports[0].Port != expectedPort { t.Errorf("%s: did not get expected port in service. Expected: %d. Got %d\n", test.name, expectedPort, tp.Spec.Ports[0].Port) } } if test.config.Labels != nil { if !mapContains(test.config.Labels, tp.Spec.Selector) { t.Errorf("%s: did not get expected service selector. Expected: %v. Got: %v", test.name, test.config.Labels, tp.Spec.Selector) } } got["service"] = append(got["service"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) imageStreams = append(imageStreams, tp) case *deployapi.DeploymentConfig: got["deploymentConfig"] = append(got["deploymentConfig"], tp.Name) if podTemplate := tp.Template.ControllerTemplate.Template; podTemplate != nil { for _, volume := range podTemplate.Spec.Volumes { if volume.VolumeSource.EmptyDir != nil { gotVolumes[volume.Name] = "EmptyDir" } else { gotVolumes[volume.Name] = "UNKNOWN" } } for _, container := range podTemplate.Spec.Containers { for _, volumeMount := range container.VolumeMounts { got["volumeMounts"] = append(got["volumeMounts"], volumeMount.Name) } } } if test.config.Labels != nil { if !mapContains(test.config.Labels, tp.Template.ControllerTemplate.Selector) { t.Errorf("%s: did not get expected deployment config rc selector. Expected: %v. Got: %v", test.name, test.config.Labels, tp.Template.ControllerTemplate.Selector) } } } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: %s resource names mismatch! Expected %v, got %v", test.name, k, exp, g) continue } } if len(test.expectedVolumes) != len(gotVolumes) { t.Errorf("%s: Volume count mismatch! Expected %d, got %d", test.name, len(test.expectedVolumes), len(gotVolumes)) continue } for k, exp := range test.expectedVolumes { g, ok := gotVolumes[k] if !ok { t.Errorf("%s: Didn't find expected volume %s", test.name, k) } if g != exp { t.Errorf("%s: Expected volume of type %s, got %s", test.name, g, exp) } } if test.expectedName != res.Name { t.Errorf("%s: Unexpected name: %s", test.name, test.expectedName) } if test.expectInsecure == nil { continue } for _, stream := range imageStreams { _, hasAnnotation := stream.Annotations[imageapi.InsecureRepositoryAnnotation] if test.expectInsecure.Has(stream.Name) && !hasAnnotation { t.Errorf("%s: Expected insecure annotation for stream: %s, but did not get one.", test.name, stream.Name) } if !test.expectInsecure.Has(stream.Name) && hasAnnotation { t.Errorf("%s: Got insecure annotation for stream: %s, and was not expecting one.", test.name, stream.Name) } } } }