Beispiel #1
0
func generatePod(genericParams map[string]interface{}, containers []api.Container) (runtime.Object, error) {
	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}

	labelString, found := params["labels"]
	var labels map[string]string
	var err error
	if found && len(labelString) > 0 {
		labels, err = kubectl.ParseLabels(labelString)
		if err != nil {
			return nil, err
		}
	}
	restartPolicy := api.RestartPolicy(params["restart"])
	pod := api.Pod{
		ObjectMeta: api.ObjectMeta{
			Name:   params["name"],
			Labels: labels,
		},
		Spec: api.PodSpec{
			Containers:    containers,
			DNSPolicy:     api.DNSClusterFirst,
			RestartPolicy: restartPolicy,
		},
	}
	return &pod, nil
}
Beispiel #2
0
func (o *NewServiceAccountTokenOptions) Complete(args []string, requestedLabels string, f *clientcmd.Factory, cmd *cobra.Command) error {
	if len(args) != 1 {
		return cmdutil.UsageError(cmd, fmt.Sprintf("expected one service account name as an argument, got %q", args))
	}

	o.SAName = args[0]

	if len(requestedLabels) > 0 {
		labels, err := kubectl.ParseLabels(requestedLabels)
		if err != nil {
			return cmdutil.UsageError(cmd, err.Error())
		}
		o.Labels = labels
	}

	client, err := f.Client()
	if err != nil {
		return err
	}

	namespace, _, err := f.DefaultNamespace()
	if err != nil {
		return fmt.Errorf("could not retrieve default namespace: %v", err)
	}

	o.SAClient = client.ServiceAccounts(namespace)
	o.SecretsClient = client.Secrets(namespace)
	return nil
}
Beispiel #3
0
// Generate accepts a set of parameters and maps them into a new route
func (RouteGenerator) Generate(params map[string]string) (runtime.Object, error) {
	var (
		labels map[string]string
		err    error
	)

	labelString, found := params["labels"]
	if found && len(labelString) > 0 {
		labels, err = kubectl.ParseLabels(labelString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}

	return &api.Route{
		ObjectMeta: kapi.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.RouteSpec{
			Host: params["hostname"],
			To: kapi.ObjectReference{
				Name: params["default-name"],
			},
		},
	}, nil
}
Beispiel #4
0
// Generate accepts a set of parameters and maps them into a new route
func (RouteGenerator) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
	var (
		labels map[string]string
		err    error
	)

	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}

	labelString, found := params["labels"]
	if found && len(labelString) > 0 {
		labels, err = kubectl.ParseLabels(labelString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}

	route := &api.Route{
		ObjectMeta: kapi.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.RouteSpec{
			Host: params["hostname"],
			Path: params["path"],
			To: api.RouteTargetReference{
				Name: params["default-name"],
			},
		},
	}

	portString := params["port"]
	if len(portString) > 0 {
		var targetPort intstr.IntOrString
		if port, err := strconv.Atoi(portString); err == nil {
			targetPort = intstr.FromInt(port)
		} else {
			targetPort = intstr.FromString(portString)
		}
		route.Spec.Port = &api.RoutePort{
			TargetPort: targetPort,
		}
	}

	return route, nil
}
Beispiel #5
0
// Generate accepts a set of parameters and maps them into a new route
func (RouteGenerator) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
	var (
		labels map[string]string
		err    error
	)

	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}

	labelString, found := params["labels"]
	if found && len(labelString) > 0 {
		labels, err = kubectl.ParseLabels(labelString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}

	var portString string
	portString, found = params["port"]
	if !found || len(portString) == 0 {
		portString = strings.Split(params["ports"], ",")[0]
	}
	if len(portString) == 0 {
		return nil, fmt.Errorf("exposed service does not have any target ports specified")
	}

	return &api.Route{
		ObjectMeta: kapi.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.RouteSpec{
			Host: params["hostname"],
			To: kapi.ObjectReference{
				Name: params["default-name"],
			},
			Port: &api.RoutePort{
				TargetPort: util.NewIntOrStringFromString(portString),
			},
		},
	}, nil
}
Beispiel #6
0
func initExample(cmdNamespace string, resource string, f *cmdutil.Factory, cmd *cobra.Command) (runtime.Object, error) {
	mapper, _ := f.Object()
	version, kind, err := mapper.VersionAndKindForResource(resource)
	if err != nil {
		return nil, err
	}

	exBuilder := f.ExampleBuilder()
	obj, _, err := exBuilder.NewExample(version, kind)
	if err != nil {
		return nil, err
	}

	mapping, err := mapper.RESTMapping(kind, version)
	if err != nil {
		return nil, err
	}

	err = mapping.SetAPIVersion(obj, version)
	if err != nil {
		return nil, err
	}
	err = mapping.SetKind(obj, kind)
	if err != nil {
		return nil, err
	}
	err = mapping.SetNamespace(obj, cmdNamespace)
	if err != nil {
		return nil, err
	}

	nameFlag := cmdutil.GetFlagString(cmd, "name")
	if nameFlag != "" {
		err = mapping.SetName(obj, nameFlag)
	} else {
		err = mapping.SetName(obj, " ")
	}
	if err != nil {
		return nil, err
	}

	labelsFlag := cmdutil.GetFlagString(cmd, "labels")
	if labelsFlag != "" {
		parsedLabels, err := kubectl.ParseLabels(labelsFlag)
		if err != nil {
			return nil, err
		}

		err = mapping.SetLabels(obj, parsedLabels)
		if err != nil {
			return nil, err
		}
	}

	return obj, nil
}
Beispiel #7
0
func setAppConfigLabels(c *cobra.Command, config *newcmd.AppConfig) error {
	labelStr := kcmdutil.GetFlagString(c, "labels")
	if len(labelStr) != 0 {
		var err error
		config.Labels, err = ctl.ParseLabels(labelStr)
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #8
0
// Generate accepts a set of parameters and maps them into a new route
func (RouteGenerator) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
	var (
		labels map[string]string
		err    error
	)

	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}

	labelString, found := params["labels"]
	if found && len(labelString) > 0 {
		labels, err = kubectl.ParseLabels(labelString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}

	return &api.Route{
		ObjectMeta: kapi.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.RouteSpec{
			Host: params["hostname"],
			To: kapi.ObjectReference{
				Name: params["default-name"],
			},
		},
	}, nil
}
Beispiel #9
0
func (testServiceGenerator) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}
	labelsString, found := params["labels"]
	var labels map[string]string
	var err error
	if found && len(labelsString) > 0 {
		labels, err = kubectl.ParseLabels(labelsString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}
	portString, found := params["port"]
	if !found {
		return nil, fmt.Errorf("'port' is a required parameter.")
	}
	port, err := strconv.Atoi(portString)
	if err != nil {
		return nil, err
	}
	servicePortName, found := params["port-name"]
	if !found {
		// Leave the port unnamed.
		servicePortName = ""
	}
	service := api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.ServiceSpec{
			Ports: []api.ServicePort{
				{
					Name:     servicePortName,
					Port:     port,
					Protocol: api.Protocol(params["protocol"]),
				},
			},
		},
	}
	targetPort, found := params["target-port"]
	if !found {
		targetPort, found = params["container-port"]
	}
	if found && len(targetPort) > 0 {
		if portNum, err := strconv.Atoi(targetPort); err != nil {
			service.Spec.Ports[0].TargetPort = intstr.FromString(targetPort)
		} else {
			service.Spec.Ports[0].TargetPort = intstr.FromInt(portNum)
		}
	} else {
		service.Spec.Ports[0].TargetPort = intstr.FromInt(port)
	}
	if params["create-external-load-balancer"] == "true" {
		service.Spec.Type = api.ServiceTypeLoadBalancer
	}
	if len(params["external-ip"]) > 0 {
		service.Spec.ExternalIPs = []string{params["external-ip"]}
	}
	if len(params["type"]) != 0 {
		service.Spec.Type = api.ServiceType(params["type"])
	}
	if len(params["session-affinity"]) != 0 {
		switch api.ServiceAffinity(params["session-affinity"]) {
		case api.ServiceAffinityNone:
			service.Spec.SessionAffinity = api.ServiceAffinityNone
		case api.ServiceAffinityClientIP:
			service.Spec.SessionAffinity = api.ServiceAffinityClientIP
		default:
			return nil, fmt.Errorf("unknown session affinity: %s", params["session-affinity"])
		}
	}
	return &service, nil
}
Beispiel #10
0
// RunProject contains all the necessary functionality for the OpenShift cli process command
func RunProcess(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
	templateName, valueArgs := "", []string{}
	for _, s := range args {
		isValue := strings.Contains(s, "=")
		switch {
		case isValue:
			valueArgs = append(valueArgs, s)
		case !isValue && len(templateName) == 0:
			templateName = s
		case !isValue && len(templateName) > 0:
			return kcmdutil.UsageError(cmd, "template name must be specified only once: %s", s)
		}
	}

	filename := kcmdutil.GetFlagString(cmd, "filename")
	if len(templateName) == 0 && len(filename) == 0 {
		return kcmdutil.UsageError(cmd, "Must pass a filename or name of stored template")
	}

	if kcmdutil.GetFlagBool(cmd, "parameters") {
		for _, flag := range []string{"value", "labels", "output", "output-version", "raw", "template"} {
			if f := cmd.Flags().Lookup(flag); f != nil && f.Changed {
				return kcmdutil.UsageError(cmd, "The --parameters flag does not process the template, can't be used with --%v", flag)
			}
		}
	}

	namespace, explicit, err := f.DefaultNamespace()
	if err != nil {
		return err
	}

	mapper, typer := f.Object()

	client, _, err := f.Clients()
	if err != nil {
		return err
	}

	var (
		objects []runtime.Object
		infos   []*resource.Info
	)

	mapping, err := mapper.RESTMapping(templateapi.Kind("Template"))
	if err != nil {
		return err
	}

	// When templateName is not empty, then we fetch the template from the
	// server, otherwise we require to set the `-f` parameter.
	if len(templateName) > 0 {
		var (
			storedTemplate, rs string
			sourceNamespace    string
			ok                 bool
		)
		sourceNamespace, rs, storedTemplate, ok = parseNamespaceResourceName(templateName, namespace)
		if !ok {
			return fmt.Errorf("invalid argument %q", templateName)
		}
		if len(rs) > 0 && (rs != "template" && rs != "templates") {
			return fmt.Errorf("unable to process invalid resource %q", rs)
		}
		if len(storedTemplate) == 0 {
			return fmt.Errorf("invalid value syntax %q", templateName)
		}
		templateObj, err := client.Templates(sourceNamespace).Get(storedTemplate)
		if err != nil {
			if errors.IsNotFound(err) {
				return fmt.Errorf("template %q could not be found", storedTemplate)
			}
			return err
		}
		templateObj.CreationTimestamp = unversioned.Now()
		infos = append(infos, &resource.Info{Object: templateObj})
	} else {
		infos, err = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), kapi.Codecs.UniversalDecoder()).
			NamespaceParam(namespace).RequireNamespace().
			FilenameParam(explicit, filename).
			Do().
			Infos()
		if err != nil {
			return err
		}
	}

	outputFormat := kcmdutil.GetFlagString(cmd, "output")

	for i := range infos {
		obj, ok := infos[i].Object.(*templateapi.Template)
		if !ok {
			sourceName := filename
			if len(templateName) > 0 {
				sourceName = namespace + "/" + templateName
			}
			fmt.Fprintf(cmd.Out(), "unable to parse %q, not a valid Template but %s\n", sourceName, reflect.TypeOf(infos[i].Object))
			continue
		}

		// If 'parameters' flag is set it does not do processing but only print
		// the template parameters to console for inspection.
		// If multiple templates are passed, this will print combined output for all
		// templates.
		if kcmdutil.GetFlagBool(cmd, "parameters") {
			if len(infos) > 1 {
				fmt.Fprintf(out, "\n%s:\n", obj.Name)
			}
			if err := describe.PrintTemplateParameters(obj.Parameters, out); err != nil {
				fmt.Fprintf(cmd.Out(), "error printing parameters for %q: %v\n", obj.Name, err)
			}
			continue
		}

		if label := kcmdutil.GetFlagString(cmd, "labels"); len(label) > 0 {
			lbl, err := kubectl.ParseLabels(label)
			if err != nil {
				fmt.Fprintf(cmd.Out(), "error parsing labels: %v\n", err)
				continue
			}
			if obj.ObjectLabels == nil {
				obj.ObjectLabels = make(map[string]string)
			}
			for key, value := range lbl {
				obj.ObjectLabels[key] = value
			}
		}

		// Override the values for the current template parameters
		// when user specify the --value
		if cmd.Flag("value").Changed {
			values := kcmdutil.GetFlagStringSlice(cmd, "value")
			injectUserVars(values, out, obj)
		}
		injectUserVars(valueArgs, out, obj)

		resultObj, err := client.TemplateConfigs(namespace).Create(obj)
		if err != nil {
			fmt.Fprintf(cmd.Out(), "error processing the template %q: %v\n", obj.Name, err)
			continue
		}

		if outputFormat == "describe" {
			if s, err := (&describe.TemplateDescriber{
				MetadataAccessor: meta.NewAccessor(),
				ObjectTyper:      kapi.Scheme,
				ObjectDescriber:  nil,
			}).DescribeTemplate(resultObj); err != nil {
				fmt.Fprintf(cmd.Out(), "error describing %q: %v\n", obj.Name, err)
			} else {
				fmt.Fprintf(out, s)
			}
			continue
		}
		objects = append(objects, resultObj.Objects...)
	}

	// Do not print the processed templates when asked to only show parameters or
	// describe.
	if kcmdutil.GetFlagBool(cmd, "parameters") || outputFormat == "describe" {
		return nil
	}

	p, _, err := kubectl.GetPrinter(outputFormat, "")
	if err != nil {
		return err
	}
	gv := mapping.GroupVersionKind.GroupVersion()
	version, err := kcmdutil.OutputVersion(cmd, &gv)
	if err != nil {
		return err
	}
	p = kubectl.NewVersionedPrinter(p, kapi.Scheme, version)

	// use generic output
	if kcmdutil.GetFlagBool(cmd, "raw") {
		for i := range objects {
			p.PrintObj(objects[i], out)
		}
		return nil
	}

	return p.PrintObj(&kapi.List{
		ListMeta: unversioned.ListMeta{},
		Items:    objects,
	}, out)
}
Beispiel #11
0
// RunProject contains all the necessary functionality for the OpenShift cli process command
func RunProcess(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
	templateName, valueArgs := "", []string{}
	for _, s := range args {
		isValue := strings.Contains(s, "=")
		switch {
		case isValue:
			valueArgs = append(valueArgs, s)
		case !isValue && len(templateName) == 0:
			templateName = s
		case !isValue && len(templateName) > 0:
			return kcmdutil.UsageError(cmd, "template name must be specified only once: %s", s)
		}
	}

	keys := sets.NewString()
	duplicatedKeys := sets.NewString()

	var flagValues []string
	if cmd.Flag("value").Changed {
		flagValues = kcmdutil.GetFlagStringSlice(cmd, "value")
	}

	for _, value := range flagValues {
		key := strings.Split(value, "=")[0]
		if keys.Has(key) {
			duplicatedKeys.Insert(key)
		}
		keys.Insert(key)
	}

	for _, value := range valueArgs {
		key := strings.Split(value, "=")[0]
		if keys.Has(key) {
			duplicatedKeys.Insert(key)
		}
		keys.Insert(key)
	}

	if len(duplicatedKeys) != 0 {
		return kcmdutil.UsageError(cmd, fmt.Sprintf("The following values were provided more than once: %s", strings.Join(duplicatedKeys.List(), ", ")))
	}

	filename := kcmdutil.GetFlagString(cmd, "filename")
	if len(templateName) == 0 && len(filename) == 0 {
		return kcmdutil.UsageError(cmd, "Must pass a filename or name of stored template")
	}

	if kcmdutil.GetFlagBool(cmd, "parameters") {
		for _, flag := range []string{"value", "labels", "output", "output-version", "raw", "template"} {
			if f := cmd.Flags().Lookup(flag); f != nil && f.Changed {
				return kcmdutil.UsageError(cmd, "The --parameters flag does not process the template, can't be used with --%v", flag)
			}
		}
	}

	namespace, explicit, err := f.DefaultNamespace()
	if err != nil {
		return err
	}

	mapper, typer := f.Object(false)

	client, _, err := f.Clients()
	if err != nil {
		return err
	}

	var (
		objects []runtime.Object
		infos   []*resource.Info
	)

	mapping, err := mapper.RESTMapping(templateapi.Kind("Template"))
	if err != nil {
		return err
	}

	// When templateName is not empty, then we fetch the template from the
	// server, otherwise we require to set the `-f` parameter.
	if len(templateName) > 0 {
		var (
			storedTemplate, rs string
			sourceNamespace    string
			ok                 bool
		)
		sourceNamespace, rs, storedTemplate, ok = parseNamespaceResourceName(templateName, namespace)
		if !ok {
			return fmt.Errorf("invalid argument %q", templateName)
		}
		if len(rs) > 0 && (rs != "template" && rs != "templates") {
			return fmt.Errorf("unable to process invalid resource %q", rs)
		}
		if len(storedTemplate) == 0 {
			return fmt.Errorf("invalid value syntax %q", templateName)
		}
		templateObj, err := client.Templates(sourceNamespace).Get(storedTemplate)
		if err != nil {
			if errors.IsNotFound(err) {
				return fmt.Errorf("template %q could not be found", storedTemplate)
			}
			return err
		}
		templateObj.CreationTimestamp = unversioned.Now()
		infos = append(infos, &resource.Info{Object: templateObj})
	} else {
		infos, err = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), kapi.Codecs.UniversalDecoder()).
			NamespaceParam(namespace).RequireNamespace().
			FilenameParam(explicit, false, filename).
			Do().
			Infos()
		if err != nil {
			return err
		}
	}

	outputFormat := kcmdutil.GetFlagString(cmd, "output")

	if len(infos) > 1 {
		// in order to run validation on the input given to us by a user, we only support the processing
		// of one template in a list. For instance, we want to be able to fail when a user does not give
		// a parameter that the template wants or when they give a parameter the template doesn't need,
		// as this may indicate that they have mis-used `oc process`. This is much less complicated when
		// we process at most one template.
		fmt.Fprintf(out, "%d input templates found, but only the first will be processed", len(infos))
	}

	obj, ok := infos[0].Object.(*templateapi.Template)
	if !ok {
		sourceName := filename
		if len(templateName) > 0 {
			sourceName = namespace + "/" + templateName
		}
		return fmt.Errorf("unable to parse %q, not a valid Template but %s\n", sourceName, reflect.TypeOf(infos[0].Object))
	}

	// If 'parameters' flag is set it does not do processing but only print
	// the template parameters to console for inspection.
	if kcmdutil.GetFlagBool(cmd, "parameters") {
		return describe.PrintTemplateParameters(obj.Parameters, out)
	}

	if label := kcmdutil.GetFlagString(cmd, "labels"); len(label) > 0 {
		lbl, err := kubectl.ParseLabels(label)
		if err != nil {
			return fmt.Errorf("error parsing labels: %v\n", err)
		}
		if obj.ObjectLabels == nil {
			obj.ObjectLabels = make(map[string]string)
		}
		for key, value := range lbl {
			obj.ObjectLabels[key] = value
		}
	}

	// Override the values for the current template parameters
	// when user specify the --value
	if cmd.Flag("value").Changed {
		values := kcmdutil.GetFlagStringSlice(cmd, "value")
		if errs := injectUserVars(values, obj); errs != nil {
			return kerrors.NewAggregate(errs)
		}
	}

	if errs := injectUserVars(valueArgs, obj); errs != nil {
		return kerrors.NewAggregate(errs)
	}

	resultObj, err := client.TemplateConfigs(namespace).Create(obj)
	if err != nil {
		return fmt.Errorf("error processing the template %q: %v\n", obj.Name, err)
	}

	if outputFormat == "describe" {
		if s, err := (&describe.TemplateDescriber{
			MetadataAccessor: meta.NewAccessor(),
			ObjectTyper:      kapi.Scheme,
			ObjectDescriber:  nil,
		}).DescribeTemplate(resultObj); err != nil {
			return fmt.Errorf("error describing %q: %v\n", obj.Name, err)
		} else {
			_, err := fmt.Fprintf(out, s)
			return err
		}
	}
	objects = append(objects, resultObj.Objects...)

	// Do not print the processed templates when asked to only show parameters or
	// describe.
	if kcmdutil.GetFlagBool(cmd, "parameters") || outputFormat == "describe" {
		return nil
	}

	p, _, err := kubectl.GetPrinter(outputFormat, "")
	if err != nil {
		return err
	}
	gv := mapping.GroupVersionKind.GroupVersion()
	version, err := kcmdutil.OutputVersion(cmd, &gv)
	if err != nil {
		return err
	}
	p = kubectl.NewVersionedPrinter(p, kapi.Scheme, version)

	// use generic output
	if kcmdutil.GetFlagBool(cmd, "raw") {
		for i := range objects {
			p.PrintObj(objects[i], out)
		}
		return nil
	}

	return p.PrintObj(&kapi.List{
		ListMeta: unversioned.ListMeta{},
		Items:    objects,
	}, out)
}