Example #1
0
func autoConvert_v1_Template_To_api_Template(in *Template, out *template_api.Template, s conversion.Scope) error {
	if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
		return err
	}
	if err := api_v1.Convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
		return err
	}
	out.Message = in.Message
	if in.Objects != nil {
		in, out := &in.Objects, &out.Objects
		*out = make([]runtime.Object, len(*in))
		for i := range *in {
			if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Objects = nil
	}
	if in.Parameters != nil {
		in, out := &in.Parameters, &out.Parameters
		*out = make([]template_api.Parameter, len(*in))
		for i := range *in {
			if err := Convert_v1_Parameter_To_api_Parameter(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Parameters = nil
	}
	out.ObjectLabels = in.ObjectLabels
	return nil
}
Example #2
0
// AddParameter adds new custom parameter to the Template. It overrides
// the existing parameter, if already defined.
func AddParameter(t *api.Template, param api.Parameter) {
	if existing := GetParameterByName(t, param.Name); existing != nil {
		*existing = param
	} else {
		t.Parameters = append(t.Parameters, param)
	}
}
Example #3
0
// Process transforms Template object into List object. It generates
// Parameter values using the defined set of generators first, and then it
// substitutes all Parameter expression occurrences with their corresponding
// values (currently in the containers' Environment variables only).
func (p *Processor) Process(template *api.Template) field.ErrorList {
	templateErrors := field.ErrorList{}

	if fieldError := p.GenerateParameterValues(template); fieldError != nil {
		return append(templateErrors, fieldError)
	}

	// Place parameters into a map for efficient lookup
	paramMap := make(map[string]api.Parameter)
	for _, param := range template.Parameters {
		paramMap[param.Name] = param
	}

	// Perform parameter substitution on the template's user message. This can be used to
	// instruct a user on next steps for the template.
	template.Message = p.EvaluateParameterSubstitution(paramMap, template.Message)

	itemPath := field.NewPath("item")
	for i, item := range template.Objects {
		idxPath := itemPath.Index(i)
		if obj, ok := item.(*runtime.Unknown); ok {
			// TODO: use runtime.DecodeList when it returns ValidationErrorList
			decodedObj, err := runtime.Decode(runtime.UnstructuredJSONScheme, obj.Raw)
			if err != nil {
				templateErrors = append(templateErrors, field.Invalid(idxPath.Child("objects"), obj, fmt.Sprintf("unable to handle object: %v", err)))
				continue
			}
			item = decodedObj
		}

		newItem, err := p.SubstituteParameters(paramMap, item)
		if err != nil {
			templateErrors = append(templateErrors, field.Invalid(idxPath.Child("parameters"), template.Parameters, err.Error()))
		}
		// If an object definition's metadata includes a namespace field, the field will be stripped out of
		// the definition during template instantiation.  This is necessary because all objects created during
		// instantiation are placed into the target namespace, so it would be invalid for the object to declare
		//a different namespace.
		stripNamespace(newItem)
		if err := util.AddObjectLabels(newItem, template.ObjectLabels); err != nil {
			templateErrors = append(templateErrors, field.Invalid(idxPath.Child("labels"),
				template.ObjectLabels, fmt.Sprintf("label could not be applied: %v", err)))
		}
		template.Objects[i] = newItem
	}

	return templateErrors
}
Example #4
0
func processTemplate(tmpl *tapi.Template, domain string, apiserver string) {
	generators := map[string]generator.Generator{
		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))),
	}
	p := template.NewProcessor(generators)

	tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{
		Name:  "DOMAIN",
		Value: domain,
	}, tapi.Parameter{
		Name:  "APISERVER",
		Value: apiserver,
	})

	errorList := p.Process(tmpl)
	for _, errInfo := range errorList {
		util.Errorf("Processing template field %s got error %s\n", errInfo.Field, errInfo.Detail)
	}
}
Example #5
0
func processTemplate(tmpl *tapi.Template, ns string, domain string, apiserver string) {
	generators := map[string]generator.Generator{
		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))),
	}
	p := template.NewProcessor(generators)

	ip, port, err := net.SplitHostPort(apiserver)
	if err != nil && !strings.Contains(err.Error(), "missing port in address") {
		util.Fatalf("%s", err)
	}

	namespaceIdx := -1
	for i, param := range tmpl.Parameters {
		if param.Name == "NAMESPACE" {
			namespaceIdx = i
		}
	}
	if namespaceIdx >= 0 {
		tmpl.Parameters[namespaceIdx].Value = ns
	}
	tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{
		Name:  "DOMAIN",
		Value: ns + "." + domain,
	}, tapi.Parameter{
		Name:  "APISERVER",
		Value: ip,
	}, tapi.Parameter{
		Name:  "OAUTH_AUTHORIZE_PORT",
		Value: port,
	})

	errorList := p.Process(tmpl)
	for _, errInfo := range errorList {
		util.Errorf("Processing template field %s got error %s\n", errInfo.Field, errInfo.Detail)
	}
}
Example #6
0
func createTemplate(jsonData []byte, templateName string, ns string, domain string, apiserver string, c *k8sclient.Client) {
	var v1tmpl tapiv1.Template
	err := json.Unmarshal(jsonData, &v1tmpl)
	if err != nil {
		util.Fatalf("Cannot get %s template to deploy. error: %v\ntemplate: %s", templateName, err, string(jsonData))
	}
	var tmpl tapi.Template

	err = api.Scheme.Convert(&v1tmpl, &tmpl)
	if err != nil {
		util.Fatalf("Cannot convert %s template to deploy: %v", templateName, err)
	}

	generators := map[string]generator.Generator{
		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))),
	}
	p := template.NewProcessor(generators)

	tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{
		Name:  "DOMAIN",
		Value: domain,
	}, tapi.Parameter{
		Name:  "APISERVER",
		Value: apiserver,
	})

	p.Process(&tmpl)

	objectCount := len(tmpl.Objects)

	if objectCount == 0 {
		// can't be a template so lets try just process it directly
		var v1List v1.List
		err = json.Unmarshal(jsonData, &v1List)
		if err != nil {
			util.Fatalf("Cannot unmarshal List %s to deploy. error: %v\ntemplate: %s", templateName, err, string(jsonData))
		}
		if len(v1List.Items) == 0 {
			// lets check if its an RC / ReplicaSet or something
			_, groupVersionKind, err := api.Codecs.UniversalDeserializer().Decode(jsonData, nil, nil)
			if err != nil {
				printResult(templateName, Failure, err)
			} else {
				kind := groupVersionKind.Kind
				util.Infof("Processing resource of kind: %s version: %s\n", kind, groupVersionKind.Version)
				if len(kind) <= 0 {
					printResult(templateName, Failure, fmt.Errorf("Could not find kind from json %s", string(jsonData)))
				} else {
					processResource(c, jsonData, ns, kind)
				}
			}
		} else {
			var kubeList api.List
			err = api.Scheme.Convert(&v1List, &kubeList)
			if err != nil {
				util.Fatalf("Cannot convert %s List to deploy: %v", templateName, err)
			}

			util.Infof("Converted json to list with %d items with json %s\n", len(kubeList.Items), string(jsonData))

			util.Infof("Creating "+templateName+" list resources from %d objects\n", len(kubeList.Items))
			for _, o := range kubeList.Items {
				err = processItem(c, &o, ns)
			}
		}

	} else {
		util.Infof("Creating "+templateName+" template resources from %d objects\n", objectCount)
		for _, o := range tmpl.Objects {
			err = processItem(c, &o, ns)
		}
	}

	if err != nil {
		printResult(templateName, Failure, err)
	} else {
		printResult(templateName, Success, nil)
	}
}
Example #7
0
func TestEvaluateLabels(t *testing.T) {
	testCases := map[string]struct {
		Input  string
		Output string
		Labels map[string]string
	}{
		"no labels": {
			Input: `{
				"kind":"Template", "apiVersion":"v1",
				"objects": [
					{
						"kind": "Service", "apiVersion": "v1",
						"metadata": {"labels": {"key1": "v1", "key2": "v2"}	}
					}
				]
			}`,
			Output: `{
				"kind":"Template","apiVersion":"v1","metadata":{"creationTimestamp":null},
				"objects":[
					{
						"apiVersion":"v1","kind":"Service","metadata":{
						"labels":{"key1":"v1","key2":"v2"}}
					}
				]
			}`,
		},
		"one different label": {
			Input: `{
				"kind":"Template", "apiVersion":"v1",
				"objects": [
					{
						"kind": "Service", "apiVersion": "v1",
						"metadata": {"labels": {"key1": "v1", "key2": "v2"}	}
					}
				]
			}`,
			Output: `{
				"kind":"Template","apiVersion":"v1","metadata":{"creationTimestamp":null},
				"objects":[
					{
						"apiVersion":"v1","kind":"Service","metadata":{
						"labels":{"key1":"v1","key2":"v2","key3":"v3"}}
					}
				],
				"labels":{"key3":"v3"}
			}`,
			Labels: map[string]string{"key3": "v3"},
		},
		"when the root object has labels and metadata": {
			Input: `{
				"kind":"Template", "apiVersion":"v1",
				"objects": [
					{
						"kind": "Service", "apiVersion": "v1",
						"metadata": {},
						"labels": {
							"key1": "v1",
							"key2": "v2"
						}
					}
				]
			}`,
			Output: `{
				"kind":"Template","apiVersion":"v1","metadata":{"creationTimestamp":null},
				"objects":[
					{
						"apiVersion":"v1","kind":"Service",
						"labels":{"key1":"v1","key2":"v2"},
						"metadata":{"labels":{"key3":"v3"}}
					}
				],
				"labels":{"key3":"v3"}
			}`,
			Labels: map[string]string{"key3": "v3"},
		},
		"overwrites label": {
			Input: `{
				"kind":"Template", "apiVersion":"v1",
				"objects": [
					{
						"kind": "Service", "apiVersion": "v1",
						"metadata": {"labels": {"key1": "v1", "key2": "v2"}	}
					}
				]
			}`,
			Output: `{
				"kind":"Template","apiVersion":"v1","metadata":{"creationTimestamp":null},
				"objects":[
					{
						"apiVersion":"v1","kind":"Service","metadata":{
						"labels":{"key1":"v1","key2":"v3"}}
					}
				],
				"labels":{"key2":"v3"}
			}`,
			Labels: map[string]string{"key2": "v3"},
		},
	}

	for k, testCase := range testCases {
		var template api.Template
		if err := runtime.DecodeInto(kapi.Codecs.UniversalDecoder(), []byte(testCase.Input), &template); err != nil {
			t.Errorf("%s: unexpected error: %v", k, err)
			continue
		}

		generators := map[string]generator.Generator{
			"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(1337))),
		}
		processor := NewProcessor(generators)

		template.ObjectLabels = testCase.Labels

		// Transform the template config into the result config
		errs := processor.Process(&template)
		if len(errs) > 0 {
			t.Errorf("%s: unexpected error: %v", k, errs)
			continue
		}
		result, err := runtime.Encode(kapi.Codecs.LegacyCodec(v1.SchemeGroupVersion), &template)
		if err != nil {
			t.Errorf("%s: unexpected error: %v", k, err)
			continue
		}
		expect := testCase.Output
		expect = trailingWhitespace.ReplaceAllString(expect, "")
		stringResult := strings.TrimSpace(string(result))
		if expect != stringResult {
			t.Errorf("%s: unexpected output: %s", k, diff.StringDiff(expect, stringResult))
			continue
		}
	}
}
Example #8
0
func NewCmdDeploy(f *cmdutil.Factory) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "deploy",
		Short: "Deploy fabric8 to your Kubernetes or OpenShift environment",
		Long:  `deploy fabric8 to your Kubernetes or OpenShift environment`,
		PreRun: func(cmd *cobra.Command, args []string) {
			showBanner()
		},
		Run: func(cmd *cobra.Command, args []string) {
			c, cfg := client.NewClient(f)
			ns, _, _ := f.DefaultNamespace()
			util.Info("Deploying fabric8 to your ")
			util.Success(string(util.TypeOfMaster(c)))
			util.Info(" installation at ")
			util.Success(cfg.Host)
			util.Info(" in namespace ")
			util.Successf("%s\n\n", ns)

			if confirmAction(cmd.Flags()) {
				v := cmd.Flags().Lookup("version").Value.String()

				typeOfMaster := util.TypeOfMaster(c)
				v = f8Version(v, typeOfMaster)

				versioniPaaS := cmd.Flags().Lookup(versioniPaaSFlag).Value.String()
				versioniPaaS = versionForUrl(versioniPaaS, iPaaSMetadataUrl)

				util.Warnf("\nStarting deployment of %s...\n\n", v)

				if typeOfMaster == util.Kubernetes {
					uri := fmt.Sprintf(baseConsoleKubernetesUrl, v)
					filenames := []string{uri}

					createCmd := cobra.Command{}
					createCmd.Flags().StringSlice("filename", filenames, "")
					err := kcmd.RunCreate(f, &createCmd, ioutil.Discard)
					if err != nil {
						printResult("fabric8 console", Failure, err)
					} else {
						printResult("fabric8 console", Success, nil)
					}
				} else {
					oc, _ := client.NewOpenShiftClient(cfg)

					r, err := verifyRestrictedSecurityContextConstraints(c, f)
					printResult("SecurityContextConstraints restricted", r, err)
					r, err = deployFabric8SecurityContextConstraints(c, f, ns)
					printResult("SecurityContextConstraints fabric8", r, err)

					printAddClusterRoleToUser(oc, f, "cluster-admin", "system:serviceaccount:"+ns+":fabric8")
					printAddClusterRoleToUser(oc, f, "cluster-admin", "system:serviceaccount:"+ns+":jenkins")
					printAddClusterRoleToUser(oc, f, "cluster-reader", "system:serviceaccount:"+ns+":metrics")

					printAddServiceAccount(c, f, "metrics")
					printAddServiceAccount(c, f, "router")

					if cmd.Flags().Lookup(templatesFlag).Value.String() == "true" {
						uri := fmt.Sprintf(baseConsoleUrl, v)
						resp, err := http.Get(uri)
						if err != nil {
							util.Fatalf("Cannot get fabric8 template to deploy: %v", err)
						}
						defer resp.Body.Close()
						jsonData, err := ioutil.ReadAll(resp.Body)
						if err != nil {
							util.Fatalf("Cannot get fabric8 template to deploy: %v", err)
						}
						var v1tmpl tapiv1.Template
						err = json.Unmarshal(jsonData, &v1tmpl)
						if err != nil {
							util.Fatalf("Cannot get fabric8 template to deploy: %v", err)
						}
						var tmpl tapi.Template

						err = api.Scheme.Convert(&v1tmpl, &tmpl)
						if err != nil {
							util.Fatalf("Cannot get fabric8 template to deploy: %v", err)
						}

						generators := map[string]generator.Generator{
							"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))),
						}
						p := template.NewProcessor(generators)

						tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{
							Name:  "DOMAIN",
							Value: cmd.Flags().Lookup("domain").Value.String(),
						})

						p.Process(&tmpl)

						for _, o := range tmpl.Objects {
							switch o := o.(type) {
							case *runtime.Unstructured:
								var b []byte
								b, err = json.Marshal(o.Object)
								if err != nil {
									break
								}
								req := c.Post().Body(b)
								if o.Kind != "OAuthClient" {
									req.Namespace(ns).Resource(strings.ToLower(o.TypeMeta.Kind + "s"))
								} else {
									req.AbsPath("oapi", "v1", strings.ToLower(o.TypeMeta.Kind+"s"))
								}
								res := req.Do()
								if res.Error() != nil {
									err = res.Error()
									break
								}
								var statusCode int
								res.StatusCode(&statusCode)
								if statusCode != http.StatusCreated {
									err = fmt.Errorf("Failed to create %s: %d", o.TypeMeta.Kind, statusCode)
									break
								}
							}
						}

						if err != nil {
							printResult("fabric8 console", Failure, err)
						} else {
							printResult("fabric8 console", Success, nil)
						}
					} else {
						printError("Ignoring the deploy of the fabric8 console", nil)
					}

					if cmd.Flags().Lookup(templatesFlag).Value.String() == "true" {
						printError("Install DevOps templates", installTemplates(oc, f, v, templatesDistroUrl))
						printError("Install iPaaS templates", installTemplates(oc, f, versioniPaaS, iPaaSTemplatesDistroUrl))
					} else {
						printError("Ignoring the deploy of templates", nil)
					}

					domain := cmd.Flags().Lookup(domainFlag).Value.String()

					printError("Create routes", createRoutesForDomain(ns, domain, c, oc, f))
				}
			}
		},
	}
	cmd.PersistentFlags().StringP("domain", "d", defaultDomain(), "The domain name to append to the service name to access web applications")
	cmd.PersistentFlags().StringP(versioniPaaSFlag, "", "latest", "The version to use for the Fabric8 iPaaS templates")
	cmd.PersistentFlags().Bool(templatesFlag, true, "Should the standard Fabric8 templates be installed?")
	cmd.PersistentFlags().Bool(consoleFlag, true, "Should the Fabric8 console be deployed?")
	return cmd
}