Trying to write a microservice to manage imagestreams on my Openshift cluster. I read the oc
client code to work out how to read my kubeconfig
and create the Client
.
I can make requests with the Kubernetes Client
to get the Kubernetes objects, e.g. pods, but any requests I make with the Openshift Client
returns back an empty list.
I'm new to Go as well, so I'm sure I'm doing something wrong. Here's what I have so far:
package main
import (
"fmt"
"log"
"github.com/spf13/pflag"
kapi "k8s.io/kubernetes/pkg/api"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
)
func main() {
flags := pflag.FlagSet{}
factory := clientcmd.New(&flags)
osclient, kclient, err := factory.Clients()
if err != nil {
log.Fatalln("Error:", err)
}
config, _ := factory.ClientConfig()
fmt.Println("KClient config", config)
config, _ = factory.OpenShiftClientConfig.ClientConfig()
fmt.Println("OSClient config", config)
// Empty list!
projects, err := osclient.Projects().List(kapi.ListOptions{})
if err != nil {
log.Println("Error:", err)
} else {
fmt.Println("Projects", projects, len(projects.Items))
}
// Also empty list
buildconfigs, err := osclient.BuildConfigs("my-project").List(kapi.ListOptions{})
if err != nil {
log.Println("Error:", err)
} else {
fmt.Println("Buildconfigs", buildconfigs, len(buildconfigs.Items))
}
// Works!
pods, err := kclient.Pods("my-project").List(kapi.ListOptions{})
if err != nil {
log.Println("Error:", err)
} else {
fmt.Println("Pods", len(pods.Items))
for _, pod := range pods.Items {
fmt.Println(pod.ObjectMeta.Name)
}
}
// Permission error, as expected
namespaces, err := kclient.Namespaces().List(kapi.ListOptions{})
if err != nil {
log.Println("Error:", err)
} else {
fmt.Println("Namespaces", namespaces, len(namespaces.Items))
}
}
You were ever so close and the issue was a tiny one: you needed to include the following additional import:
import _ "github.com/openshift/origin/pkg/api/install"
I'm not fully clear what the import actually does, but evidently it causes necessary additional functionality to be linked into the binary, without which the OpenShift client doesn't work (returns empty lists).
All of the OpenShift command line tools include that import, and as of writing many include some/all of the following as well:
import (
_ "github.com/openshift/origin/pkg/api/install"
_ "k8s.io/kubernetes/pkg/api/install"
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
_ "k8s.io/kubernetes/pkg/apis/batch/install"
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
)
Finally, here's a full code example which works for me (updated against origin v3.6.0-alpha):
package main
import (
"fmt"
_ "github.com/openshift/origin/pkg/api/install"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
factory := clientcmd.New(pflag.CommandLine)
pflag.Parse()
oc, kc, err := factory.Clients()
if err != nil {
panic(err)
}
namespace, _, err := factory.DefaultNamespace()
if err != nil {
panic(err)
}
pods, err := kc.Core().Pods(namespace).List(v1.ListOptions{})
if err != nil {
panic(err)
}
for _, pod := range pods.Items {
fmt.Printf("Pod: %s
", pod.Name)
}
buildconfigs, err := oc.BuildConfigs(namespace).List(v1.ListOptions{})
if err != nil {
panic(err)
}
for _, buildconfig := range buildconfigs.Items {
fmt.Printf("BuildConfig: %s
", buildconfig.Name)
}
}
To run this example, you will currently need to vendor OpenShift and its dependencies. One very hacky way to do this is as follows:
rm -rf vendor
mkdir -p vendor/github.com/openshift/origin
ln -s $GOPATH/src/github.com/openshift/origin/vendor/* vendor
ln -s $GOPATH/src/github.com/openshift/origin/vendor/github.com/* vendor/github.com
ln -s $GOPATH/src/github.com/openshift/origin/vendor/github.com/openshift/* vendor/github.com/openshift
ln -s $GOPATH/src/github.com/openshift/origin/pkg vendor/github.com/openshift/origin
Finally, it is intended to make a proper standalone Go client for OpenShift - the backlog card for this is at https://trello.com/c/PTDrY0GF/794-13-client-provide-go-client-similar-to-kubernetes.
When the go client code returns an empty list and no error, that means that there no resources of that type present. What do you get using the same kubeconfig file and running oc get projects
and oc get bc
?