Home Explore Blog CI



kubernetes

3rd chunk of `content/en/blog/_posts/2018-01-00-Introducing-Client-Go-Version-6.md`
3ffce35e7b786b46d7447b5055ea3d3c9e02650bcad6bd830000000100001114
Often objects in one namespace or only with certain labels are to be processed in a controller. Informers [now allow](https://github.com/kubernetes/kubernetes/pull/54660) you to tweak the ListOptions used to query the API server to list and watch objects. Uninitialized objects (for consumption by [initializers](/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-initializers)) can be made visible by setting IncludeUnitialized to true. All this can be done using the new NewFilteredSharedInformerFactory constructor for shared informers:  

```

import “k8s.io/client-go/informers”
...  
sharedInformers := informers.NewFilteredSharedInformerFactory(  
 client,  
 30\*time.Minute,   
 “some-namespace”,  
 func(opt \*metav1.ListOptions) {  
  opt.LabelSelector = “foo=bar”  
 },  
)  
 ```



Note that the corresponding lister will only know about the objects matching the namespace and the given ListOptions. Note that the same restrictions apply for a List or Watch call on a client.  

This [production code example](https://github.com/jetstack/cert-manager/blob/b978faa28c9f0fb0414b5d7293fab7bde65bde76/cmd/controller/app/controller.go#L123) of a cert-manager demonstrates how namespace informers can be used in real code.



## Polymorphic scale client
Historically, only types in the extensions API group would work with autogenerated Scale clients. Furthermore, different API groups use different Scale types for their /scale subresources. To remedy these issues, k8s.io/client-go/scale provides a [polymorphic scale client](https://github.com/kubernetes/client-go/tree/master/scale) to scale different resources in different API groups in a coherent way:  


```

import (


apimeta "k8s.io/apimachinery/pkg/api/meta"

 discocache "k8s.io/client-go/discovery/cached"  
 "k8s.io/client-go/discovery"

"k8s.io/client-go/dynamic"

“k8s.io/client-go/scale”  
)

...

cachedDiscovery := discocache.NewMemCacheClient(client.Discovery())  
restMapper := discovery.NewDeferredDiscoveryRESTMapper(

cachedDiscovery,

apimeta.InterfacesForUnstructured,

)  
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(

client.Discovery(),

)  
scaleClient, err := scale.NewForConfig(

client, restMapper,

dynamic.LegacyAPIPathResolverFunc,

scaleKindResolver,

)
scale, err := scaleClient.Scales("default").Get(groupResource, "foo")

 ```



The returned scale object is generic and is exposed as the autoscaling/v1.Scale object. It is backed by an internal Scale type, with conversions defined to and from all the special Scale types in the API groups supporting scaling. We planto [extend this to CustomResources in 1.10](https://github.com/kubernetes/kubernetes/pull/55168).  

If you’re implementing support for the scale subresource, we recommend that you expose the autoscaling/v1.Scale object.



## Type-safe DeepCopy
Deeply copying an object formerly required a call to Scheme.Copy(Object) with the notable disadvantage of losing type safety. A typical piece of code from client-go version 5 required type casting:  


```

newObj, err := runtime.NewScheme().Copy(node)


if err != nil {

    return fmt.Errorf("failed to copy node %v: %s”, node, err)

}


newNode, ok := newObj.(\*v1.Node)

if !ok {

    return fmt.Errorf("failed to type-assert node %v", newObj)


}

 ```



Thanks to [k8s.io/code-generator](https://github.com/kubernetes/code-generator), Copy has now been replaced by a type-safe DeepCopy method living on each object, allowing you to simplify code significantly both in terms of volume and API error surface:  

newNode := node.DeepCopy()  

No error handling is necessary: this call never fails. If and only if the node is nil does DeepCopy() return nil.  

To copy runtime.Objects there is an additional DeepCopyObject() method in the runtime.Object interface.  

With the old method gone for good, clients need to update their copy invocations accordingly.  


## Code generation and CustomResources
Using client-go’s dynamic client to access CustomResources is discouraged and superseded by type-safe code using the generators in [k8s.io/code-generator](https://github.com/kubernetes/code-generator). Check out the [Deep Dive on the Open Shift blog](https://blog.openshift.com/kubernetes-deep-dive-code-generation-customresources/) to learn about using code generation with client-go.  

Title: Polymorphic Scale Client, Type-Safe DeepCopy, and Code Generation with CustomResources
Summary
This section discusses a polymorphic scale client in client-go to scale different resources in different API groups in a coherent way. It recommends exposing the autoscaling/v1.Scale object when implementing support for the scale subresource. It also introduces type-safe DeepCopy methods on each object, replacing the need for Scheme.Copy(Object) and type casting. Finally, it discourages using client-go's dynamic client to access CustomResources, recommending type-safe code using generators in k8s.io/code-generator instead.