Esempio n. 1
0
func newEtcd(ns runtime.NegotiatedSerializer, storageGroupVersionString, memoryGroupVersionString string, etcdConfig etcdstorage.EtcdConfig) (etcdStorage storage.Interface, err error) {
	if storageGroupVersionString == "" {
		return etcdStorage, fmt.Errorf("storageVersion is required to create a etcd storage")
	}
	storageVersion, err := unversioned.ParseGroupVersion(storageGroupVersionString)
	if err != nil {
		return nil, fmt.Errorf("couldn't understand storage version %v: %v", storageGroupVersionString, err)
	}
	memoryVersion, err := unversioned.ParseGroupVersion(memoryGroupVersionString)
	if err != nil {
		return nil, fmt.Errorf("couldn't understand memory version %v: %v", memoryGroupVersionString, err)
	}

	var storageConfig etcdstorage.EtcdStorageConfig
	storageConfig.Config = etcdConfig
	s, ok := ns.SerializerForMediaType("application/json", nil)
	if !ok {
		return nil, fmt.Errorf("unable to find serializer for JSON")
	}
	glog.Infof("constructing etcd storage interface.\n  sv: %v\n  mv: %v\n", storageVersion, memoryVersion)
	encoder := ns.EncoderForVersion(s, storageVersion)
	decoder := ns.DecoderToVersion(s, memoryVersion)
	if memoryVersion.Group != storageVersion.Group {
		// Allow this codec to translate between groups.
		if err = versioning.EnableCrossGroupEncoding(encoder, memoryVersion.Group, storageVersion.Group); err != nil {
			return nil, fmt.Errorf("error setting up encoder for %v: %v", storageGroupVersionString, err)
		}
		if err = versioning.EnableCrossGroupDecoding(decoder, storageVersion.Group, memoryVersion.Group); err != nil {
			return nil, fmt.Errorf("error setting up decoder for %v: %v", storageGroupVersionString, err)
		}
	}
	storageConfig.Codec = runtime.NewCodec(encoder, decoder)
	return storageConfig.NewStorage()
}
Esempio n. 2
0
// dest must be a map of group to groupVersion.
func mergeGroupVersionIntoMap(gvList string, dest map[string]unversioned.GroupVersion) error {
	for _, gvString := range strings.Split(gvList, ",") {
		if gvString == "" {
			continue
		}
		// We accept two formats. "group/version" OR
		// "group=group/version". The latter is used when types
		// move between groups.
		if !strings.Contains(gvString, "=") {
			gv, err := unversioned.ParseGroupVersion(gvString)
			if err != nil {
				return err
			}
			dest[gv.Group] = gv

		} else {
			parts := strings.SplitN(gvString, "=", 2)
			gv, err := unversioned.ParseGroupVersion(parts[1])
			if err != nil {
				return err
			}
			dest[parts[0]] = gv
		}
	}

	return nil
}
Esempio n. 3
0
// rawExtensionToEmbeddedObject does the conversion you would expect from the name, using the information
// given in conversion.Scope. It's placed in all schemes as a ConversionFunc to enable plugins;
// see the comment for RawExtension.
func (self *Scheme) rawExtensionToEmbeddedObject(in *RawExtension, out *EmbeddedObject, s conversion.Scope) error {
	if len(in.RawJSON) == 0 || (len(in.RawJSON) == 4 && string(in.RawJSON) == "null") {
		out.Object = nil
		return nil
	}
	// Figure out the type and kind of the output object.
	inGroupVersionString, outGroupVersionString, scheme := self.fromScope(s)
	dataKind, err := scheme.raw.DataKind(in.RawJSON)
	if err != nil {
		return err
	}
	inVersion, err := unversioned.ParseGroupVersion(inGroupVersionString)
	if err != nil {
		return err
	}
	outVersion, err := unversioned.ParseGroupVersion(outGroupVersionString)
	if err != nil {
		return err
	}

	// We have to make this object ourselves because we don't store the version field for
	// plugin objects.
	inObj, err := scheme.New(inVersion.WithKind(dataKind.Kind))
	if err != nil {
		return err
	}

	err = DecodeInto(scheme, in.RawJSON, inObj)
	if err != nil {
		return err
	}

	// Make the desired internal version, and do the conversion.
	outObj, err := scheme.New(outVersion.WithKind(dataKind.Kind))
	if err != nil {
		return err
	}
	err = scheme.Convert(inObj, outObj)
	if err != nil {
		return err
	}
	// Last step, clear the Kind field; that should always be blank in memory.
	err = s.Convert(
		&emptyPlugin{PluginBase: PluginBase{Kind: ""}},
		outObj,
		conversion.SourceToDest|conversion.IgnoreMissingFields|conversion.AllowDifferentFieldTypeNames,
	)
	if err != nil {
		return err
	}
	out.Object = outObj
	return nil
}
Esempio n. 4
0
// ClientConfigForVersion returns the correct config for a server
func (c *ClientCache) ClientConfigForVersion(version string) (*client.Config, error) {
	if c.defaultConfig == nil {
		config, err := c.loader.ClientConfig()
		if err != nil {
			return nil, err
		}
		c.defaultConfig = config
		if c.matchVersion {
			if err := client.MatchesServerVersion(c.defaultClient, config); err != nil {
				return nil, err
			}
		}
	}
	if config, ok := c.configs[version]; ok {
		return config, nil
	}
	// TODO: have a better config copy method
	config := *c.defaultConfig

	// TODO these fall out when we finish the refactor
	var preferredGV *unversioned.GroupVersion
	if len(version) > 0 {
		gv, err := unversioned.ParseGroupVersion(version)
		if err != nil {
			return nil, err
		}
		preferredGV = &gv
	}
	registeredGVs := []unversioned.GroupVersion{}
	for _, gvString := range registered.RegisteredVersions {
		gv, err := unversioned.ParseGroupVersion(gvString)
		if err != nil {
			return nil, err
		}
		registeredGVs = append(registeredGVs, gv)
	}

	negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registeredGVs)
	if err != nil {
		return nil, err
	}
	config.GroupVersion = negotiatedVersion
	client.SetKubernetesDefaults(&config)
	c.configs[version] = &config

	// `version` does not necessarily equal `config.Version`.  However, we know that we call this method again with
	// `config.Version`, we should get the the config we've just built.
	configCopy := config
	c.configs[config.GroupVersion.String()] = &configCopy

	return &config, nil
}
Esempio n. 5
0
func AddHPAScaleRefEdges(g osgraph.Graph) {
	for _, node := range g.NodesByKind(kubegraph.HorizontalPodAutoscalerNodeKind) {
		hpaNode := node.(*kubegraph.HorizontalPodAutoscalerNode)

		syntheticMeta := kapi.ObjectMeta{
			Name:      hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Name,
			Namespace: hpaNode.HorizontalPodAutoscaler.Namespace,
		}

		var groupVersionResource unversioned.GroupVersionResource
		resource := strings.ToLower(hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Kind)
		if groupVersion, err := unversioned.ParseGroupVersion(hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.APIVersion); err == nil {
			groupVersionResource = groupVersion.WithResource(resource)
		} else {
			groupVersionResource = unversioned.GroupVersionResource{Resource: resource}
		}

		groupVersionResource, err := registered.RESTMapper().ResourceFor(groupVersionResource)
		if err != nil {
			continue
		}

		var syntheticNode graph.Node
		switch groupVersionResource.GroupResource() {
		case kapi.Resource("replicationcontrollers"):
			syntheticNode = kubegraph.FindOrCreateSyntheticReplicationControllerNode(g, &kapi.ReplicationController{ObjectMeta: syntheticMeta})
		case deployapi.Resource("deploymentconfigs"):
			syntheticNode = deploygraph.FindOrCreateSyntheticDeploymentConfigNode(g, &deployapi.DeploymentConfig{ObjectMeta: syntheticMeta})
		default:
			continue
		}

		g.AddEdge(hpaNode, syntheticNode, ScalingEdgeKind)
	}
}
Esempio n. 6
0
// DecodeList alters the list in place, attempting to decode any objects found in
// the list that have the runtime.Unknown type. Any errors that occur are returned
// after the entire list is processed. Decoders are tried in order.
func DecodeList(objects []Object, decoders ...ObjectDecoder) []error {
	errs := []error(nil)
	for i, obj := range objects {
		switch t := obj.(type) {
		case *Unknown:
			for _, decoder := range decoders {
				gv, err := unversioned.ParseGroupVersion(t.APIVersion)
				if err != nil {
					errs = append(errs, err)
					break
				}

				if !decoder.Recognizes(gv.WithKind(t.Kind)) {
					continue
				}
				obj, err := Decode(decoder, t.RawJSON)
				if err != nil {
					errs = append(errs, err)
					break
				}
				objects[i] = obj
				break
			}
		}
	}
	return errs
}
Esempio n. 7
0
func (g TestGroup) GroupVersion() *unversioned.GroupVersion {
	gv, err := unversioned.ParseGroupVersion(g.GroupVersionUnderTest)
	if err != nil {
		panic(err)
	}
	return &gv
}
Esempio n. 8
0
// Convert_runtime_RawExtension_To_runtime_Object well, this is the reason why there was runtime.Embedded.  The `out` here is hopeless.
// The caller doesn't know the type ahead of time and that means this method can't communicate the return value.  This sucks really badly.
// I'm going to set the `in.Object` field can have callers to this function do magic to pull it back out.  I'm also going to bitch about it.
func Convert_runtime_RawExtension_To_runtime_Object(in *runtime.RawExtension, out runtime.Object, s conversion.Scope) error {
	if in == nil || len(in.Raw) == 0 || in.Object != nil {
		return nil
	}

	// the scheme knows all available group versions, so its possible to build the decoder properly, but it would require some refactoring

	srcVersion, err := unversioned.ParseGroupVersion(s.Meta().SrcVersion)
	if err != nil {
		return err
	}
	decodedObject, err := runtime.Decode(kapi.Codecs.UniversalDecoder(srcVersion), in.Raw)
	if err != nil {
		return err
	}

	internalObject, err := kapi.Scheme.ConvertToVersion(decodedObject, s.Meta().DestVersion)
	if err != nil {
		return err
	}

	in.Object = internalObject

	return nil
}
Esempio n. 9
0
// The docker metadata must be cast to a version
func Convert_api_Image_To_v1beta3_Image(in *newer.Image, out *Image, s conversion.Scope) error {
	if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
		return err
	}

	out.DockerImageReference = in.DockerImageReference
	out.DockerImageManifest = in.DockerImageManifest
	out.DockerImageManifestMediaType = in.DockerImageManifestMediaType
	out.DockerImageConfig = in.DockerImageConfig

	gvString := in.DockerImageMetadataVersion
	if len(gvString) == 0 {
		gvString = "1.0"
	}
	if !strings.Contains(gvString, "/") {
		gvString = "/" + gvString
	}

	version, err := unversioned.ParseGroupVersion(gvString)
	if err != nil {
		return err
	}
	data, err := runtime.Encode(api.Codecs.LegacyCodec(version), &in.DockerImageMetadata, version)
	if err != nil {
		return err
	}
	out.DockerImageMetadata.Raw = data
	out.DockerImageMetadataVersion = version.Version

	return nil
}
Esempio n. 10
0
// serverAPIVersions fetches the server versions available from the groupless API at the given prefix
func serverAPIVersions(c *kclient.Client, grouplessPrefix string) ([]unversioned.GroupVersion, error) {
	// Get versions doc
	body, err := c.Get().AbsPath(grouplessPrefix).Do().Raw()
	if err != nil {
		return []unversioned.GroupVersion{}, err
	}

	// Unmarshal
	var v unversioned.APIVersions
	err = json.Unmarshal(body, &v)
	if err != nil {
		return []unversioned.GroupVersion{}, fmt.Errorf("got '%s': %v", string(body), err)
	}

	// Convert to GroupVersion structs
	serverAPIVersions := []unversioned.GroupVersion{}
	for _, version := range v.Versions {
		gv, err := unversioned.ParseGroupVersion(version)
		if err != nil {
			return []unversioned.GroupVersion{}, err
		}
		serverAPIVersions = append(serverAPIVersions, gv)
	}
	return serverAPIVersions, nil
}
Esempio n. 11
0
// ConvertToVersion attempts to convert an input object to its matching Kind in another
// version within this scheme. Will return an error if the provided version does not
// contain the inKind (or a mapping by name defined with AddKnownTypeWithName). Will also
// return an error if the conversion does not result in a valid Object being
// returned. The serializer handles loading/serializing nested objects.
func (s *Scheme) ConvertToVersion(in Object, outVersion string) (Object, error) {
	gv, err := unversioned.ParseGroupVersion(outVersion)
	if err != nil {
		return nil, err
	}
	switch in.(type) {
	case *Unknown, *Unstructured, *UnstructuredList:
		old := in.GetObjectKind().GroupVersionKind()
		defer in.GetObjectKind().SetGroupVersionKind(old)
		setTargetVersion(in, s, gv)
		return in, nil
	}
	t := reflect.TypeOf(in)
	if t.Kind() != reflect.Ptr {
		return nil, fmt.Errorf("only pointer types may be converted: %v", t)
	}

	t = t.Elem()
	if t.Kind() != reflect.Struct {
		return nil, fmt.Errorf("only pointers to struct types may be converted: %v", t)
	}

	var kind unversioned.GroupVersionKind
	if unversionedKind, ok := s.unversionedTypes[t]; ok {
		kind = unversionedKind
	} else {
		kinds, ok := s.typeToGVK[t]
		if !ok || len(kinds) == 0 {
			return nil, fmt.Errorf("%v is not a registered type and cannot be converted into version %q", t, outVersion)
		}
		for _, kind := range kinds {
			if gv.Version == kind.Version && gv.Group == kind.Group {
				setTargetKind(in, kind)
				return in, nil
			}
		}

		kind = kinds[0]
	}

	outKind := gv.WithKind(kind.Kind)

	inKind, err := s.ObjectKind(in)
	if err != nil {
		return nil, err
	}

	out, err := s.New(outKind)
	if err != nil {
		return nil, err
	}

	flags, meta := s.generateConvertMeta(inKind.GroupVersion(), gv, in)
	if err := s.converter.Convert(in, out, flags, meta); err != nil {
		return nil, err
	}

	setTargetVersion(out, s, gv)
	return out, nil
}
Esempio n. 12
0
func setExtensionsDefaults(config *Config) error {
	// if experimental group is not registered, return an error
	g, err := latest.Group("extensions")
	if err != nil {
		return err
	}
	config.Prefix = "apis/"
	if config.UserAgent == "" {
		config.UserAgent = DefaultKubernetesUserAgent()
	}
	// TODO: Unconditionally set the config.Version, until we fix the config.
	//if config.Version == "" {
	gv, err := unversioned.ParseGroupVersion(g.GroupVersion)
	if err != nil {
		return err
	}
	config.GroupVersion = &gv
	//}

	versionInterfaces, err := g.InterfacesFor(config.GroupVersion.String())
	if err != nil {
		return fmt.Errorf("Extensions API group/version '%v' is not recognized (valid values: %s)",
			config.GroupVersion, strings.Join(latest.GroupOrDie("extensions").Versions, ", "))
	}
	config.Codec = versionInterfaces.Codec
	if config.QPS == 0 {
		config.QPS = 5
	}
	if config.Burst == 0 {
		config.Burst = 10
	}
	return nil
}
Esempio n. 13
0
// InfoForObject creates an Info object for the given Object. An error is returned
// if the object cannot be introspected. Name and namespace will be set into Info
// if the mapping's MetadataAccessor can retrieve them.
func (m *Mapper) InfoForObject(obj runtime.Object) (*Info, error) {
	gvString, kind, err := m.ObjectVersionAndKind(obj)
	if err != nil {
		return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err)
	}
	gv, err := unversioned.ParseGroupVersion(gvString)
	if err != nil {
		return nil, fmt.Errorf("unable to parse group/version from %q: %v", gvString, err)
	}
	mapping, err := m.RESTMapping(unversioned.GroupKind{Group: gv.Group, Kind: kind}, gv.Version)
	if err != nil {
		return nil, fmt.Errorf("unable to recognize %q: %v", kind, err)
	}
	client, err := m.ClientForMapping(mapping)
	if err != nil {
		return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
	}
	name, _ := mapping.MetadataAccessor.Name(obj)
	namespace, _ := mapping.MetadataAccessor.Namespace(obj)
	resourceVersion, _ := mapping.MetadataAccessor.ResourceVersion(obj)
	return &Info{
		Mapping:   mapping,
		Client:    client,
		Namespace: namespace,
		Name:      name,

		Object:          obj,
		ResourceVersion: resourceVersion,
	}, nil
}
Esempio n. 14
0
func TestDirectCodec(t *testing.T) {
	s := GetDirectCodecTestScheme()
	cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
	serializer, _ := cf.SerializerForFileExtension("json")
	df := DirectCodecFactory{cf}
	ignoredGV, err := unversioned.ParseGroupVersion("ignored group/ignored version")
	if err != nil {
		t.Fatal(err)
	}
	directEncoder := df.EncoderForVersion(serializer, ignoredGV)
	directDecoder := df.DecoderToVersion(serializer, ignoredGV)
	out, err := runtime.Encode(directEncoder, &ExternalTestType1{})
	if err != nil {
		t.Fatal(err)
	}
	if string(out) != `{"myVersionKey":"v1","myKindKey":"ExternalTestType1"}`+"\n" {
		t.Fatal(string(out))
	}
	a, _, err := directDecoder.Decode(out, nil, nil)
	e := &ExternalTestType1{
		MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{
			APIVersion: "v1",
			ObjectKind: "ExternalTestType1",
		},
	}
	if !semantic.DeepEqual(e, a) {
		t.Fatalf("expect %v, got %v", e, a)
	}
}
Esempio n. 15
0
func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
	version, kind, err := runtime.UnstructuredJSONScheme.DataVersionAndKind(data)
	if err != nil {
		return err
	}
	gv, err := unversioned.ParseGroupVersion(version)
	if err != nil {
		return fmt.Errorf("unable to parse group/version from %q: %v", version, err)
	}
	if ok := registered.IsRegisteredAPIGroupVersion(gv); !ok {
		return fmt.Errorf("API version %q isn't supported, only supports API versions %q", version, registered.RegisteredGroupVersions)
	}
	resource, _ := meta.KindToResource(kind, false)
	gvk, err := c.mapper.KindFor(resource)
	if err != nil {
		return fmt.Errorf("could not find api group for %s: %v", kind, err)
	}
	if gvk.Group == "extensions" {
		if c.c.ExtensionsClient == nil {
			return errors.New("unable to validate: no experimental client")
		}
		return getSchemaAndValidate(c.c.ExtensionsClient.RESTClient, data, "apis/", version, c.cacheDir)
	}
	return getSchemaAndValidate(c.c.RESTClient, data, "api", version, c.cacheDir)
}
Esempio n. 16
0
// FindAllCanonicalResources returns all resource names that map directly to their kind (Kind -> Resource -> Kind)
// and are not subresources. This is the closest mapping possible from the client side to resources that can be
// listed and updated. Note that this may return some virtual resources (like imagestreamtags) that can be otherwise
// represented.
// TODO: add a field to APIResources for "virtual" (or that points to the canonical resource).
// TODO: fallback to the scheme when discovery is not possible.
func FindAllCanonicalResources(d discovery.DiscoveryInterface, m meta.RESTMapper) ([]unversioned.GroupResource, error) {
	set := make(map[unversioned.GroupResource]struct{})
	all, err := d.ServerResources()
	if err != nil {
		return nil, err
	}
	for apiVersion, v := range all {
		gv, err := unversioned.ParseGroupVersion(apiVersion)
		if err != nil {
			continue
		}
		for _, r := range v.APIResources {
			// ignore subresources
			if strings.Contains(r.Name, "/") {
				continue
			}
			// because discovery info doesn't tell us whether the object is virtual or not, perform a lookup
			// by the kind for resource (which should be the canonical resource) and then verify that the reverse
			// lookup (KindsFor) does not error.
			if mapping, err := m.RESTMapping(unversioned.GroupKind{Group: gv.Group, Kind: r.Kind}, gv.Version); err == nil {
				if _, err := m.KindsFor(mapping.GroupVersionKind.GroupVersion().WithResource(mapping.Resource)); err == nil {
					set[unversioned.GroupResource{Group: mapping.GroupVersionKind.Group, Resource: mapping.Resource}] = struct{}{}
				}
			}
		}
	}
	var groupResources []unversioned.GroupResource
	for k := range set {
		groupResources = append(groupResources, k)
	}
	sort.Sort(groupResourcesByName(groupResources))
	return groupResources, nil
}
Esempio n. 17
0
func (o *AppJSONOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string) error {
	version, _ := cmd.Flags().GetString("output-version")
	for _, v := range strings.Split(version, ",") {
		gv, err := unversioned.ParseGroupVersion(v)
		if err != nil {
			return fmt.Errorf("provided output-version %q is not valid: %v", v, err)
		}
		o.OutputVersions = append(o.OutputVersions, gv)
	}
	o.OutputVersions = append(o.OutputVersions, registered.EnabledVersions()...)

	o.Action.Bulk.Mapper = clientcmd.ResourceMapper(f)
	o.Action.Bulk.Op = configcmd.Create
	mapper, _ := f.Object(false)
	o.PrintObject = cmdutil.VersionedPrintObject(f.PrintObject, cmd, mapper, o.Action.Out)

	o.Generator, _ = cmd.Flags().GetString("generator")

	ns, _, err := f.DefaultNamespace()
	if err != nil {
		return err
	}
	o.Namespace = ns

	o.Client, _, err = f.Clients()
	return err
}
Esempio n. 18
0
func NewDefaultRESTMapper(group string, groupVersionStrings []string, interfacesFunc meta.VersionInterfacesFunc,
	importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {

	mapper := meta.NewDefaultRESTMapper(group, groupVersionStrings, interfacesFunc)
	// enumerate all supported versions, get the kinds, and register with the mapper how to address
	// our resources.
	for _, gvString := range groupVersionStrings {
		gv, err := unversioned.ParseGroupVersion(gvString)
		// TODO stop panicing when the types are fixed
		if err != nil {
			panic(err)
		}
		if gv.Group != group {
			panic(fmt.Sprintf("%q does not match the expect %q", gv.Group, group))
		}

		for kind, oType := range Scheme.KnownTypes(gv.String()) {
			// TODO: Remove import path prefix check.
			// We check the import path prefix because we currently stuff both "api" and "extensions" objects
			// into the same group within Scheme since Scheme has no notion of groups yet.
			if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
				continue
			}
			scope := meta.RESTScopeNamespace
			if rootScoped.Has(kind) {
				scope = meta.RESTScopeRoot
			}
			mapper.Add(scope, kind, gv.String(), false)
		}
	}
	return mapper
}
Esempio n. 19
0
func IsThirdPartyObject(rawData []byte, gvk *unversioned.GroupVersionKind) (isThirdParty bool, gvkOut *unversioned.GroupVersionKind, err error) {
	var gv unversioned.GroupVersion
	if gvk == nil {
		data, err := yaml.ToJSON(rawData)
		if err != nil {
			return false, nil, err
		}
		metadata := unversioned.TypeMeta{}
		if err = json.Unmarshal(data, &metadata); err != nil {
			return false, nil, err
		}
		gv, err = unversioned.ParseGroupVersion(metadata.APIVersion)
		if err != nil {
			return false, nil, err
		}
		gvkOut = &unversioned.GroupVersionKind{
			Group:   gv.Group,
			Version: gv.Version,
			Kind:    metadata.Kind,
		}
	} else {
		gv = gvk.GroupVersion()
		gvkOut = gvk
	}
	return registered.IsThirdPartyAPIGroupVersion(gv), gvkOut, nil
}
Esempio n. 20
0
func init() {
	kubeTestAPI := os.Getenv("KUBE_TEST_API")
	if len(kubeTestAPI) != 0 {
		testGroupVersions := strings.Split(kubeTestAPI, ",")
		for _, gvString := range testGroupVersions {
			groupVersion, err := unversioned.ParseGroupVersion(gvString)
			if err != nil {
				panic(fmt.Sprintf("Error parsing groupversion %v: %v", gvString, err))
			}

			Groups[groupVersion.Group] = TestGroup{
				externalGroupVersion: groupVersion,
				internalGroupVersion: unversioned.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal},
			}
		}
	}

	if _, ok := Groups[api.GroupName]; !ok {
		Groups[api.GroupName] = TestGroup{
			externalGroupVersion: unversioned.GroupVersion{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version},
			internalGroupVersion: api.SchemeGroupVersion,
		}
	}
	if _, ok := Groups[extensions.GroupName]; !ok {
		Groups[extensions.GroupName] = TestGroup{
			externalGroupVersion: unversioned.GroupVersion{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version},
			internalGroupVersion: extensions.SchemeGroupVersion,
		}
	}

	Default = Groups[api.GroupName]
	Extensions = Groups[extensions.GroupName]
}
Esempio n. 21
0
func (s *Scheme) DecodeToVersionedObject(data []byte) (interface{}, string, string, error) {
	version, kind, err := s.DataVersionAndKind(data)
	if err != nil {
		return nil, "", "", err
	}

	gv, err := unversioned.ParseGroupVersion(version)
	if err != nil {
		return nil, "", "", err
	}

	internalGV, exists := s.InternalVersions[gv.Group]
	if !exists {
		return nil, "", "", fmt.Errorf("no internalVersion specified for %v", gv)
	}

	if len(gv.Version) == 0 && len(internalGV.Version) != 0 {
		return nil, "", "", fmt.Errorf("version not set in '%s'", string(data))
	}
	if kind == "" {
		return nil, "", "", fmt.Errorf("kind not set in '%s'", string(data))
	}
	obj, err := s.NewObject(version, kind)
	if err != nil {
		return nil, "", "", err
	}

	if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
		return nil, "", "", err
	}
	return obj, version, kind, nil
}
func NewShortcutExpander(discoveryClient discovery.DiscoveryInterface, delegate meta.RESTMapper) ShortcutExpander {
	defaultMapper := ShortcutExpander{RESTMapper: delegate}

	// this assumes that legacy kube versions and legacy origin versions are the same, probably fair
	apiResources, err := discoveryClient.ServerResources()
	if err != nil {
		return defaultMapper
	}

	availableResources := []unversioned.GroupVersionResource{}
	for groupVersionString, resourceList := range apiResources {
		currVersion, err := unversioned.ParseGroupVersion(groupVersionString)
		if err != nil {
			return defaultMapper
		}

		for _, resource := range resourceList.APIResources {
			availableResources = append(availableResources, currVersion.WithResource(resource.Name))
		}
	}

	availableAll := []string{}
	for _, requestedResource := range userResources {
		for _, availableResource := range availableResources {
			if requestedResource == availableResource.Resource {
				availableAll = append(availableAll, requestedResource)
				break
			}
		}
	}

	return ShortcutExpander{All: availableAll, RESTMapper: delegate}
}
Esempio n. 23
0
func (t *thirdPartyResourceDataDecoder) populateFromObject(mapObj map[string]interface{}, data []byte) (runtime.Object, *unversioned.GroupVersionKind, error) {
	typeMeta := unversioned.TypeMeta{}
	if err := json.Unmarshal(data, &typeMeta); err != nil {
		return nil, nil, err
	}

	gv, err := unversioned.ParseGroupVersion(typeMeta.APIVersion)
	if err != nil {
		return nil, nil, err
	}
	gvk := gv.WithKind(typeMeta.Kind)

	isList := strings.HasSuffix(typeMeta.Kind, "List")
	switch {
	case !isList && (len(t.kind) == 0 || typeMeta.Kind == t.kind):
		result := &extensions.ThirdPartyResourceData{}
		if err := t.populateResource(result, mapObj, data); err != nil {
			return nil, nil, err
		}
		return result, &gvk, nil
	case isList && (len(t.kind) == 0 || typeMeta.Kind == t.kind+"List"):
		list := &extensions.ThirdPartyResourceDataList{}
		if err := t.populateListResource(list, mapObj); err != nil {
			return nil, nil, err
		}
		return list, &gvk, nil
	default:
		return nil, nil, fmt.Errorf("unexpected kind: %s, expected %s", typeMeta.Kind, t.kind)
	}
}
Esempio n. 24
0
func (u *Unstructured) GroupVersionKind() *unversioned.GroupVersionKind {
	gv, err := unversioned.ParseGroupVersion(u.GetAPIVersion())
	if err != nil {
		return nil
	}
	gvk := gv.WithKind(u.GetKind())
	return &gvk
}
Esempio n. 25
0
func (u *UnstructuredList) GroupVersionKind() unversioned.GroupVersionKind {
	gv, err := unversioned.ParseGroupVersion(u.GetAPIVersion())
	if err != nil {
		return unversioned.GroupVersionKind{}
	}
	gvk := gv.WithKind(u.GetKind())
	return gvk
}
Esempio n. 26
0
// convertItemsForDisplayFromDefaultCommand returns a new list that contains parallel elements that have been converted to the most preferred external version
// TODO: move this function into the core factory PrintObjects method
// TODO: print-objects should have preferred output versions
func convertItemsForDisplayFromDefaultCommand(cmd *cobra.Command, objs []runtime.Object) ([]runtime.Object, error) {
	requested := kcmdutil.GetFlagString(cmd, "output-version")
	version, err := unversioned.ParseGroupVersion(requested)
	if err != nil {
		return nil, err
	}
	return convertItemsForDisplay(objs, version)
}
Esempio n. 27
0
func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (runtime.Object, string, meta.RESTMapper, *meta.RESTMapping, error) {
	err := kubectl.ValidateParams(names, params)
	if err != nil {
		return nil, "", nil, nil, err
	}

	obj, err := generator.Generate(params)
	if err != nil {
		return nil, "", nil, nil, err
	}

	mapper, typer := f.Object()
	gvString, kind, err := typer.ObjectVersionAndKind(obj)
	if err != nil {
		return nil, "", nil, nil, err
	}
	gv, err := unversioned.ParseGroupVersion(gvString)
	if err != nil {
		return nil, "", nil, nil, err
	}
	gvk := gv.WithKind(kind)

	if len(overrides) > 0 {
		obj, err = cmdutil.Merge(obj, overrides, kind)
		if err != nil {
			return nil, "", nil, nil, err
		}
	}

	mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
	if err != nil {
		return nil, "", nil, nil, err
	}
	client, err := f.RESTClient(mapping)
	if err != nil {
		return nil, "", nil, nil, err
	}

	// TODO: extract this flag to a central location, when such a location exists.
	if !cmdutil.GetFlagBool(cmd, "dry-run") {
		resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()}
		info, err := resourceMapper.InfoForObject(obj)
		if err != nil {
			return nil, "", nil, nil, err
		}

		if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info); err != nil {
			return nil, "", nil, nil, err
		}

		obj, err = resource.NewHelper(client, mapping).Create(namespace, false, info.Object)
		if err != nil {
			return nil, "", nil, nil, err
		}
	}
	return obj, kind, mapper, mapping, err
}
Esempio n. 28
0
func (obj objectAccessor) SetAPIVersion(version string) {
	gvk := obj.GetObjectKind().GroupVersionKind()
	gv, err := unversioned.ParseGroupVersion(version)
	if err != nil {
		gv = unversioned.GroupVersion{Version: version}
	}
	gvk.Group, gvk.Version = gv.Group, gv.Version
	obj.GetObjectKind().SetGroupVersionKind(gvk)
}
Esempio n. 29
0
// RunExplain executes the appropriate steps to print a model's documentation
func RunExplain(f *cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, args []string) error {
	if len(args) == 0 {
		fmt.Fprint(cmdErr, "You must specify the type of resource to explain. ", valid_resources)
		return cmdutil.UsageError(cmd, "Required resource not specified.")
	}
	if len(args) > 1 {
		return cmdutil.UsageError(cmd, "We accept only this format: explain RESOURCE")
	}

	recursive := cmdutil.GetFlagBool(cmd, "recursive")
	apiVersionString := cmdutil.GetFlagString(cmd, "api-version")
	apiVersion := unversioned.GroupVersion{}

	mapper, _ := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
	// TODO: After we figured out the new syntax to separate group and resource, allow
	// the users to use it in explain (kubectl explain <group><syntax><resource>).
	// Refer to issue #16039 for why we do this. Refer to PR #15808 that used "/" syntax.
	inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper)
	if err != nil {
		return err
	}

	// TODO: We should deduce the group for a resource by discovering the supported resources at server.
	fullySpecifiedGVR, groupResource := unversioned.ParseResourceArg(inModel)
	gvk := unversioned.GroupVersionKind{}
	if fullySpecifiedGVR != nil {
		gvk, _ = mapper.KindFor(*fullySpecifiedGVR)
	}
	if gvk.Empty() {
		gvk, err = mapper.KindFor(groupResource.WithVersion(""))
		if err != nil {
			return err
		}
	}

	if len(apiVersionString) == 0 {
		groupMeta, err := registered.Group(gvk.Group)
		if err != nil {
			return err
		}
		apiVersion = groupMeta.GroupVersion

	} else {
		apiVersion, err = unversioned.ParseGroupVersion(apiVersionString)
		if err != nil {
			return nil
		}
	}

	schema, err := f.SwaggerSchema(apiVersion.WithKind(gvk.Kind))
	if err != nil {
		return err
	}

	return kubectl.PrintModelDescription(inModel, fieldsPath, out, schema, recursive)
}
Esempio n. 30
0
// Recognizes returns true if the scheme is able to handle the provided version and kind
// of an object.
func (s *Scheme) Recognizes(gvString, kind string) bool {
	gv, err := unversioned.ParseGroupVersion(gvString)
	if err != nil {
		return false
	}
	gvk := gv.WithKind(kind)

	_, exists := s.gvkToType[gvk]
	return exists
}