Ejemplo n.º 1
0
func DefaultTemplate() *templateapi.Template {
	ret := &templateapi.Template{}
	ret.Name = DefaultTemplateName

	ns := "${" + ProjectNameParam + "}"

	templateContents := []runtime.Object{}

	project := &projectapi.Project{}
	project.Name = ns
	project.Annotations = map[string]string{
		projectapi.ProjectDescription: "${" + ProjectDescriptionParam + "}",
		projectapi.ProjectDisplayName: "${" + ProjectDisplayNameParam + "}",
		projectapi.ProjectRequester:   "${" + ProjectRequesterParam + "}",
	}
	templateContents = append(templateContents, project)

	serviceAccountRoleBindings := bootstrappolicy.GetBootstrapServiceAccountProjectRoleBindings(ns)
	for i := range serviceAccountRoleBindings {
		templateContents = append(templateContents, &serviceAccountRoleBindings[i])
	}

	binding := &authorizationapi.RoleBinding{}
	binding.Name = bootstrappolicy.AdminRoleName
	binding.Namespace = ns
	binding.Subjects = []kapi.ObjectReference{{Kind: authorizationapi.UserKind, Name: "${" + ProjectAdminUserParam + "}"}}
	binding.RoleRef.Name = bootstrappolicy.AdminRoleName
	templateContents = append(templateContents, binding)

	if err := templateapi.AddObjectsToTemplate(ret, templateContents, latest.Version); err != nil {
		// this should never happen because we're tightly controlling what goes in.
		panic(err)
	}

	for _, parameterName := range parameters {
		parameter := templateapi.Parameter{}
		parameter.Name = parameterName
		ret.Parameters = append(ret.Parameters, parameter)
	}

	return ret
}
Ejemplo n.º 2
0
func TestTemplate(t *testing.T) {
	_, path, err := testserver.StartTestMasterAPI()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	for _, version := range []unversioned.GroupVersion{v1.SchemeGroupVersion} {
		config, err := testutil.GetClusterAdminClientConfig(path)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		config.GroupVersion = &version
		c, err := client.New(config)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		template := &templateapi.Template{
			Parameters: []templateapi.Parameter{
				{
					Name:  "NAME",
					Value: "test",
				},
			},
		}

		templateObjects := []runtime.Object{
			&v1.Service{
				ObjectMeta: v1.ObjectMeta{
					Name:      "${NAME}-tester",
					Namespace: "somevalue",
				},
				Spec: v1.ServiceSpec{
					ClusterIP:       "1.2.3.4",
					SessionAffinity: "some-bad-${VALUE}",
				},
			},
		}
		templateapi.AddObjectsToTemplate(template, templateObjects, v1.SchemeGroupVersion)

		obj, err := c.TemplateConfigs("default").Create(template)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if len(obj.Objects) != 1 {
			t.Fatalf("unexpected object: %#v", obj)
		}
		if err := runtime.DecodeList(obj.Objects, runtime.UnstructuredJSONScheme); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		svc := obj.Objects[0].(*runtime.Unstructured).Object
		spec := svc["spec"].(map[string]interface{})
		meta := svc["metadata"].(map[string]interface{})
		// keep existing values
		if spec["clusterIP"] != "1.2.3.4" {
			t.Fatalf("unexpected object: %#v", svc)
		}
		// replace a value
		if meta["name"] != "test-tester" {
			t.Fatalf("unexpected object: %#v", svc)
		}
		// clear namespace
		if meta["namespace"] != "" {
			t.Fatalf("unexpected object: %#v", svc)
		}
		// preserve values exactly
		if spec["sessionAffinity"] != "some-bad-${VALUE}" {
			t.Fatalf("unexpected object: %#v", svc)
		}
	}
}
Ejemplo n.º 3
0
func TestNewRESTTemplateLabels(t *testing.T) {
	testLabels := map[string]string{
		"label1": "value1",
		"label2": "value2",
	}
	storage := NewREST()

	// because of encoding changes, we to round-trip ourselves
	templateToCreate := &template.Template{
		ObjectMeta: kapi.ObjectMeta{
			Name: "test",
		},
		ObjectLabels: testLabels,
	}
	templateObjects := []runtime.Object{
		&kapi.Service{
			ObjectMeta: kapi.ObjectMeta{
				Name: "test-service",
			},
			Spec: kapi.ServiceSpec{
				Ports: []kapi.ServicePort{
					{
						Port:     80,
						Protocol: kapi.ProtocolTCP,
					},
				},
				SessionAffinity: kapi.ServiceAffinityNone,
			},
		},
	}
	template.AddObjectsToTemplate(templateToCreate, templateObjects, registered.GroupOrDie(kapi.GroupName).GroupVersions[0])
	originalBytes, err := runtime.Encode(kapi.Codecs.LegacyCodec(registered.GroupOrDie(kapi.GroupName).GroupVersions[0]), templateToCreate)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	objToCreate, err := runtime.Decode(kapi.Codecs.UniversalDecoder(), originalBytes)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	templateToCreate = objToCreate.(*template.Template)

	obj, err := storage.Create(nil, templateToCreate)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	bytes, err := runtime.Encode(kapi.Codecs.LegacyCodec(registered.GroupOrDie(kapi.GroupName).GroupVersions[0]), obj)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	obj, err = runtime.Decode(kapi.Codecs.UniversalDecoder(), bytes)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	config := obj.(*template.Template)
	if err := utilerrors.NewAggregate(runtime.DecodeList(config.Objects, kapi.Codecs.UniversalDecoder())); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	svc, ok := config.Objects[0].(*kapi.Service)
	if !ok {
		t.Fatalf("Unexpected object in config: %#v", config.Objects[0])
	}
	for k, v := range testLabels {
		value, ok := svc.Labels[k]
		if !ok {
			t.Fatalf("Missing output label: %s", k)
		}
		if value != v {
			t.Fatalf("Unexpected label value: %s", value)
		}
	}
}
Ejemplo n.º 4
0
func TestProjectRequestError(t *testing.T) {
	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)

	const (
		ns                = "testns"
		templateNamespace = "default"
		templateName      = "project-request-template"
	)
	masterConfig, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("error creating config: %v", err)
	}

	masterConfig.ProjectConfig.ProjectRequestTemplate = templateNamespace + "/" + templateName

	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)
	}
	openshiftClient, err := testutil.GetClusterAdminClient(kubeConfigFile)
	if err != nil {
		t.Fatalf("error getting openshift client: %v", err)
	}

	// Create custom template
	template := delegated.DefaultTemplate()
	template.Name = templateName

	additionalObjects := []runtime.Object{
		// Append an object that will succeed
		&kapi.ConfigMap{ObjectMeta: kapi.ObjectMeta{Name: "configmapname"}},
		// Append a custom object that will fail validation
		&kapi.ConfigMap{},
		// Append another object that should never be created, since we short circuit
		&kapi.ConfigMap{ObjectMeta: kapi.ObjectMeta{Name: "configmapname2"}},
	}
	if err := templateapi.AddObjectsToTemplate(template, additionalObjects, kapiv1.SchemeGroupVersion); err != nil {
		t.Fatal(err)
	}
	if _, err := openshiftClient.Templates(templateNamespace).Create(template); err != nil {
		t.Fatal(err)
	}

	// Watch the project, rolebindings, and configmaps
	nswatch, err := kubeClient.Namespaces().Watch(kapi.ListOptions{FieldSelector: fields.OneTermEqualSelector("metadata.name", ns)})
	if err != nil {
		t.Fatal(err)
	}
	policywatch, err := openshiftClient.PolicyBindings(ns).Watch(kapi.ListOptions{})
	if err != nil {
		t.Fatal(err)
	}
	cmwatch, err := kubeClient.ConfigMaps(ns).Watch(kapi.ListOptions{})
	if err != nil {
		t.Fatal(err)
	}

	// Create project request
	_, err = openshiftClient.ProjectRequests().Create(&projectapi.ProjectRequest{ObjectMeta: kapi.ObjectMeta{Name: ns}})
	if err == nil || err.Error() != `Internal error occurred: ConfigMap "" is invalid: metadata.name: Required value: name or generateName is required` {
		t.Fatalf("Expected internal error creating project, got %v", err)
	}

	pairCreationDeletion := func(w watch.Interface) (int, int, []watch.Event) {
		added := 0
		deleted := 0
		events := []watch.Event{}
		for {
			select {
			case e := <-w.ResultChan():
				events = append(events, e)
				switch e.Type {
				case watch.Added:
					added++
				case watch.Deleted:
					deleted++
				}
			case <-time.After(10 * time.Second):
				return added, deleted, events
			}

			if added == deleted && added > 0 {
				return added, deleted, events
			}
		}
	}

	if added, deleted, events := pairCreationDeletion(nswatch); added != deleted || added != 1 {
		for _, e := range events {
			t.Logf("%s %#v", e.Type, e.Object)
		}
		t.Errorf("expected 1 namespace to be added and deleted, got %d added / %d deleted", added, deleted)
	}
	if added, deleted, events := pairCreationDeletion(policywatch); added != deleted || added != 1 {
		for _, e := range events {
			t.Logf("%s %#v", e.Type, e.Object)
		}
		t.Errorf("expected 1 policybinding to be added and deleted, got %d added / %d deleted", added, deleted)
	}
	if added, deleted, events := pairCreationDeletion(cmwatch); added != deleted || added != 1 {
		for _, e := range events {
			t.Logf("%s %#v", e.Type, e.Object)
		}
		t.Errorf("expected 1 configmap to be added and deleted, got %d added / %d deleted", added, deleted)
	}

	// Verify project is deleted
	if nsObj, err := kubeClient.Namespaces().Get(ns); !kapierrors.IsNotFound(err) {
		t.Errorf("Expected namespace to be gone, got %#v, %#v", nsObj, err)
	}
}