Skip to content

*: simplify Watch API by using dynamic resource client#34

Merged
hongchaodeng merged 2 commits intooperator-framework:masterfrom
hasbro17:haseeb/use-dynamic-client-for-watch
Feb 22, 2018
Merged

*: simplify Watch API by using dynamic resource client#34
hongchaodeng merged 2 commits intooperator-framework:masterfrom
hasbro17:haseeb/use-dynamic-client-for-watch

Conversation

@hasbro17
Copy link
Copy Markdown
Contributor

This PR simplifies the Watch() API by removing the rest client argument. Instead the user now passes in the apiVersion and Kind which can be used to create a dynamic resource client which is used to setup the informer for that resource.

@hasbro17
Copy link
Copy Markdown
Contributor Author

Testing out the Informer+dynamic-client Watch implementation separately. Will ping here once it works.

Comment thread pkg/util/k8sutil/k8sutil.go Outdated
"k8s.io/client-go/rest"
)

// MustNewKubeClientAndConfig returns the in-cluster config and kubernetes client
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better put these func into k8sutil/client.go

)

// init initializes the restMapper and clientPool needed to create a resource client dynamically
func init() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not put any side effect into util/ package.
Probably have another package called pkg/k8sclient/

Comment thread pkg/sdk/api.go Outdated
// obj is an instance of the resource type, e.g. &Pod{}.
// resourcePluralName is the plural name of the resource, e.g. “pods”.
// resourceClient is the rest client for the resource, e.g. `kubeclient.CoreV1().RESTClient()`.
// apiVersion is the APIVersion of the resource, e.g "v1" for pods, or "cache.example.com/v1alpha1" for memcached custom resource
Copy link
Copy Markdown
Contributor

@hongchaodeng hongchaodeng Feb 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g "v1" for pods, or "cache.example.com/v1alpha1" for memcached custom resource

This is understatement of the specification of kube API.
I would suggest to mention at least 3 things:

  • reference upstream kube API doc: https://kubernetes.io/docs/reference/
  • describe that apiVersion would be of format "groupName/version" except "core" group. List some examples.
  • underscore that "core" group would be only "v1". List some examples.

Comment thread pkg/sdk/api.go Outdated
// resourcePluralName is the plural name of the resource, e.g. “pods”.
// resourceClient is the rest client for the resource, e.g. `kubeclient.CoreV1().RESTClient()`.
// apiVersion is the APIVersion of the resource, e.g "v1" for pods, or "cache.example.com/v1alpha1" for memcached custom resource
// kind is the Kind of the resource, e.g "Pod" for pods, or "Memcached" for memcached custom resource
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give a reference where user can find the kind.
This would be a good reference: https://kubernetes.io/docs/reference/

@hongchaodeng
Copy link
Copy Markdown
Contributor

This closes #16

@hasbro17 hasbro17 changed the title *: simplify Watch API by using dynamic resource client [WIP]*: simplify Watch API by using dynamic resource client Feb 22, 2018
@hasbro17
Copy link
Copy Markdown
Contributor Author

  • Fixed the informer's Run() to be blocking and not shutdown the queue.
  • Moved all resource client utils to pkg/k8sclient/client.go
  • Removed objType from the Watch API since with using the resource client the type will always be *unstructured.Unstructured.

I've tested this implementation of informer+dynamic-client separately and verified that it works in watching Pod, EtcdCluster, VaultService etc as long as the Group,Version and Kind is correct.

@hongchaodeng PTAL.

@hasbro17 hasbro17 changed the title [WIP]*: simplify Watch API by using dynamic resource client *: simplify Watch API by using dynamic resource client Feb 22, 2018
Comment thread pkg/sdk/api.go Outdated
// obj is an instance of the resource type, e.g. &Pod{}.
// resourcePluralName is the plural name of the resource, e.g. “pods”.
// resourceClient is the rest client for the resource, e.g. `kubeclient.CoreV1().RESTClient()`.
// apiVersion is the APIVersion of the resource, e.g "v1" for pods, or "cache.example.com/v1alpha1" for memcached custom resource
Copy link
Copy Markdown
Contributor

@hongchaodeng hongchaodeng Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This previous comment wasn't addressed: #34 (comment)

Paste again:

This is understatement of the specification of kube API.
I would suggest to mention at least 3 things:

  • reference upstream kube API doc: https://kubernetes.io/docs/reference/
  • describe that apiVersion would be of format "groupName/version" except "core" group. List some examples.
  • underscore that "core" group would be only "v1". List some examples.

Comment thread pkg/sdk/api.go Outdated
// resourcePluralName is the plural name of the resource, e.g. “pods”.
// resourceClient is the rest client for the resource, e.g. `kubeclient.CoreV1().RESTClient()`.
// apiVersion is the APIVersion of the resource, e.g "v1" for pods, or "cache.example.com/v1alpha1" for memcached custom resource
// kind is the Kind of the resource, e.g "Pod" for pods, or "Memcached" for memcached custom resource
Copy link
Copy Markdown
Contributor

@hongchaodeng hongchaodeng Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous comment wasn't addressed: #34 (comment)

Paste again:

Give a reference where user can find the kind.
This would be a good reference: https://kubernetes.io/docs/reference/

Comment thread pkg/k8sclient/client.go Outdated
return resource, nil
}

// MustNewKubeClientAndConfig returns the in-cluster config and kubernetes client
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MustNewKubeClientAndConfig -> mustNewKubeClientAndConfig

Comment thread pkg/k8sclient/client.go Outdated
return kubernetes.NewForConfigOrDie(cfg), cfg
}

// inClusterConfig returns the in-cluster config accessible to a pod
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to a pod -> inside a pod

Comment thread pkg/sdk/informer/informer.go Outdated

if !cache.WaitForCacheSync(ctx.Done(), i.sharedIndexInformer.HasSynced) {
return errors.New("Timed out waiting for caches to sync")
logrus.Error("Timed out waiting for caches to sync")
Copy link
Copy Markdown
Contributor

@hongchaodeng hongchaodeng Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would slip the error down.
If we can't handle the error here, just panic initially.

Comment thread pkg/k8sclient/client.go
}
resource := &metav1.APIResource{
Name: mapping.Resource,
Namespaced: mapping.Scope == meta.RESTScopeNamespace,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just curious when will an APIResource not be in a Namespace?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's not common but if you watch cluster-wide resources like StorageClass or ClusterRole then those are non-namespaced.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Thanks for the clarification!

@hasbro17
Copy link
Copy Markdown
Contributor Author

Fixed. PTAL and double check the Watch() API comment.

Comment thread pkg/sdk/api.go
// resourceClient is the rest client for the resource, e.g. `kubeclient.CoreV1().RESTClient()`.
// apiVersion for a resource is of the format "Group/Version" except for the "Core" group whose APIVersion is just "v1". For e.g:
// - Deployments have Group "apps" and Version "v1beta2" giving the APIVersion "apps/v1beta2"
// - Pods have Group "Core" and Version "v1" giving the APIVersion "v1"
Copy link
Copy Markdown
Contributor

@fanminshi fanminshi Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an example on what's the APIVersion for Custom Resource? I am guessing that is what most user will be using SDK.Watch for.

Comment thread pkg/sdk/api.go Outdated
// kind is the Kind of the resource, e.g "Pod" for pods
// Consult the API reference for the Group, Version and Kind of a resource: https://kubernetes.io/docs/reference/
// namespace is the Namespace to watch for the resource
// opts provide more options for doing the watch.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have opts yet right? maybe remove it and add later?

@fanminshi
Copy link
Copy Markdown
Contributor

some suggestions around sdk.Watch()'s comment. Then sdk.Watch() interface lgtm.

@hasbro17
Copy link
Copy Markdown
Contributor Author

Added the APIVersion example comment for Memcached CR.

@hongchaodeng
Copy link
Copy Markdown
Contributor

LGTM

@fanminshi
Copy link
Copy Markdown
Contributor

lgtm

@hongchaodeng hongchaodeng merged commit 1663ab7 into operator-framework:master Feb 22, 2018
@hongchaodeng hongchaodeng deleted the haseeb/use-dynamic-client-for-watch branch February 22, 2018 20:50
@fanminshi fanminshi mentioned this pull request Feb 22, 2018
21 tasks
ryantking added a commit to ryantking/operator-sdk that referenced this pull request Apr 12, 2022
Currently, scorecard's XUnit output does not conform to any XUnit
schema. This makes the scorecard XUnit output conform with the XUnit
schema defined by the Jenkins XUnit plugin.

This is sample output from running scorecard against the sample Go v3
Memcached operator:

```xml
<testsuites name="scorecard">
  <testsuite name="olm-bundle-validation-test" tests="1" skipped="0" failures="0" errors="0">
    <properties>
      <property name="spec.image" value="quay.io/operator-framework/scorecard-test:v1.19.0"></property>
      <property name="spec.entrypoint" value="scorecard-test olm-bundle-validation"></property>
      <property name="labels.test" value="olm-bundle-validation-test"></property>
    </properties>
    <testcase name="olm-bundle-validation" time="0001-01-01T00:00:00Z">
      <system-out>time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found manifests directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found metadata directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Getting mediaType info from manifests directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found annotations file&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Could not find optional dependencies file&operator-framework#34; name=bundle-test&#xA;</system-out>
    </testcase>
  </testsuite>
  <!-- Some suites omitted for readability -->
</testsuites>
```

The full output can be recreated by installing the `operator-sdk` tool
built from this commit and running scorecard against the sample Go v3
memcached operator:

```
cd /path/to/operator-sdk
make install
operator-sdk scorecard testdata/go/v3/memcached-operator
```

The XUnit XSD schema can be found here:
https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd

The tool used to validate the output against the schema can be found
here: https://www.freeformatter.com/xml-validator-xsd.html

Signed-off-by: Ryan King <ryking@redhat.com>
ryantking added a commit to ryantking/operator-sdk that referenced this pull request Apr 12, 2022
Currently, scorecard's XUnit output does not conform to any XUnit
schema. This makes the scorecard XUnit output conform with the XUnit
schema defined by the Jenkins XUnit plugin.

This is sample output from running scorecard against the sample Go v3
Memcached operator:

```xml
<testsuites name="scorecard">
  <testsuite name="olm-bundle-validation-test" tests="1" skipped="0" failures="0" errors="0">
    <properties>
      <property name="spec.image" value="quay.io/operator-framework/scorecard-test:v1.19.0"></property>
      <property name="spec.entrypoint" value="scorecard-test olm-bundle-validation"></property>
      <property name="labels.test" value="olm-bundle-validation-test"></property>
    </properties>
    <testcase name="olm-bundle-validation" time="0001-01-01T00:00:00Z">
      <system-out>time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found manifests directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found metadata directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Getting mediaType info from manifests directory&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Found annotations file&operator-framework#34; name=bundle-test&#xA;time=&operator-framework#34;2022-04-12T19:21:52Z&operator-framework#34; level=debug msg=&operator-framework#34;Could not find optional dependencies file&operator-framework#34; name=bundle-test&#xA;</system-out>
    </testcase>
  </testsuite>
  <!-- Some suites omitted for readability -->
</testsuites>
```

The full output can be recreated by installing the `operator-sdk` tool
built from this commit and running scorecard against the sample Go v3
memcached operator:

```
cd /path/to/operator-sdk
make install
operator-sdk scorecard testdata/go/v3/memcached-operator
```

The XUnit XSD schema can be found here:
https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd

The tool used to validate the output against the schema can be found
here: https://www.freeformatter.com/xml-validator-xsd.html

Signed-off-by: Ryan King <ryking@redhat.com>
jmrodri pushed a commit that referenced this pull request Apr 13, 2022
Currently, scorecard's XUnit output does not conform to any XUnit
schema. This makes the scorecard XUnit output conform with the XUnit
schema defined by the Jenkins XUnit plugin.

This is sample output from running scorecard against the sample Go v3
Memcached operator:

```xml
<testsuites name="scorecard">
  <testsuite name="olm-bundle-validation-test" tests="1" skipped="0" failures="0" errors="0">
    <properties>
      <property name="spec.image" value="quay.io/operator-framework/scorecard-test:v1.19.0"></property>
      <property name="spec.entrypoint" value="scorecard-test olm-bundle-validation"></property>
      <property name="labels.test" value="olm-bundle-validation-test"></property>
    </properties>
    <testcase name="olm-bundle-validation" time="0001-01-01T00:00:00Z">
      <system-out>time=&#34;2022-04-12T19:21:52Z&#34; level=debug msg=&#34;Found manifests directory&#34; name=bundle-test&#xA;time=&#34;2022-04-12T19:21:52Z&#34; level=debug msg=&#34;Found metadata directory&#34; name=bundle-test&#xA;time=&#34;2022-04-12T19:21:52Z&#34; level=debug msg=&#34;Getting mediaType info from manifests directory&#34; name=bundle-test&#xA;time=&#34;2022-04-12T19:21:52Z&#34; level=debug msg=&#34;Found annotations file&#34; name=bundle-test&#xA;time=&#34;2022-04-12T19:21:52Z&#34; level=debug msg=&#34;Could not find optional dependencies file&#34; name=bundle-test&#xA;</system-out>
    </testcase>
  </testsuite>
  <!-- Some suites omitted for readability -->
</testsuites>
```

The full output can be recreated by installing the `operator-sdk` tool
built from this commit and running scorecard against the sample Go v3
memcached operator:

```
cd /path/to/operator-sdk
make install
operator-sdk scorecard testdata/go/v3/memcached-operator
```

The XUnit XSD schema can be found here:
https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd

The tool used to validate the output against the schema can be found
here: https://www.freeformatter.com/xml-validator-xsd.html

Signed-off-by: Ryan King <ryking@redhat.com>
m1kola pushed a commit to m1kola/operator-sdk that referenced this pull request Jun 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants