mirror of https://github.com/kubernetes/kops.git
Support generated clientset as alternative to vfs clientset
We modelled our VFS clientset (for API objects backed by a VFS path) after the "real" clientsets, so now it is relatively easy to add a second implementation that will be backed by a real clientset. The snafu here is that we weren't really using namespaces previously. Namespaces do seem to be the primary RBAC scoping mechanism though, so we start using them with the real clientset. The namespace is currently inferred from the cluster name. We map dots to dashes, because of namespace limitations, which could yield collisions, but we'll deal with this by simply preventing users from creating conflicting cluster names - i.e. you simply won't be able to create a.b.example.com and a-b.example.com
This commit is contained in:
parent
98ae12a152
commit
e945322cab
2
Makefile
2
Makefile
|
|
@ -481,6 +481,8 @@ apimachinery:
|
|||
#cd pkg/apis/kops/v1alpha2/ && ~/k8s/bin/codecgen -d 1234 -o types.generated.go instancegroup.go cluster.go federation.go
|
||||
#cd pkg/apis/kops/v1alpha1/ && ~/k8s/bin/codecgen -d 1234 -o types.generated.go instancegroup.go cluster.go federation.go
|
||||
#cd pkg/apis/kops/ && ~/k8s/bin/codecgen -d 1234 -o types.generated.go instancegroup.go cluster.go federation.go
|
||||
${GOPATH}/bin/client-gen --input-base k8s.io/kops/pkg/apis/ --input="kops/,kops/v1alpha1,kops/v1alpha2" --clientset-path k8s.io/kops/pkg/client/clientset_generated/
|
||||
${GOPATH}/bin/client-gen --clientset-name="clientset" --input-base k8s.io/kops/pkg/apis/ --input="kops/,kops/v1alpha1,kops/v1alpha2" --clientset-path k8s.io/kops/pkg/client/clientset_generated/
|
||||
|
||||
|
||||
# -----------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@ limitations under the License.
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"bytes"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
|
@ -140,7 +139,7 @@ func RunCreate(f *util.Factory, out io.Writer, c *CreateOptions) error {
|
|||
|
||||
switch v := o.(type) {
|
||||
case *kopsapi.Federation:
|
||||
_, err = clientset.Federations().Create(v)
|
||||
_, err = clientset.FederationsFor(v).Create(v)
|
||||
if err != nil {
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("federation %q already exists", v.ObjectMeta.Name)
|
||||
|
|
@ -156,7 +155,7 @@ func RunCreate(f *util.Factory, out io.Writer, c *CreateOptions) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("error populating configuration: %v", err)
|
||||
}
|
||||
_, err = clientset.Clusters().Create(v)
|
||||
_, err = clientset.ClustersFor(v).Create(v)
|
||||
if err != nil {
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("cluster %q already exists", v.ObjectMeta.Name)
|
||||
|
|
@ -172,7 +171,12 @@ func RunCreate(f *util.Factory, out io.Writer, c *CreateOptions) error {
|
|||
if clusterName == "" {
|
||||
return fmt.Errorf("must specify %q label with cluster name to create instanceGroup", kopsapi.LabelClusterName)
|
||||
}
|
||||
_, err = clientset.InstanceGroups(clusterName).Create(v)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error querying cluster %q: %v", clusterName, err)
|
||||
}
|
||||
|
||||
_, err = clientset.InstanceGroupsFor(cluster).Create(v)
|
||||
if err != nil {
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("instanceGroup %q already exists", v.ObjectMeta.Name)
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kops"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/registry"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
"k8s.io/kops/pkg/client/simple/vfsclientset"
|
||||
"k8s.io/kops/pkg/dns"
|
||||
"k8s.io/kops/pkg/featureflag"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
|
|
@ -328,9 +328,13 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
|
|||
return err
|
||||
}
|
||||
|
||||
cluster, err := clientset.Clusters().Get(clusterName)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
if apierrors.IsNotFound(err) {
|
||||
cluster = nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cluster != nil {
|
||||
|
|
@ -338,6 +342,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
|
|||
}
|
||||
|
||||
cluster = &api.Cluster{}
|
||||
cluster.ObjectMeta.Name = clusterName
|
||||
|
||||
channel, err := api.LoadChannel(c.Channel)
|
||||
if err != nil {
|
||||
|
|
@ -354,7 +359,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
|
|||
}
|
||||
cluster.Spec.Channel = c.Channel
|
||||
|
||||
configBase, err := clientset.Clusters().(*vfsclientset.ClusterVFS).ConfigBase(clusterName)
|
||||
configBase, err := clientset.ConfigBaseFor(cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building ConfigBase for cluster: %v", err)
|
||||
}
|
||||
|
|
@ -640,10 +645,6 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
|
|||
cluster.Spec.Project = c.Project
|
||||
}
|
||||
|
||||
if clusterName != "" {
|
||||
cluster.ObjectMeta.Name = clusterName
|
||||
}
|
||||
|
||||
if c.KubernetesVersion != "" {
|
||||
cluster.Spec.KubernetesVersion = c.KubernetesVersion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ func runCreateClusterIntegrationTest(t *testing.T, srcDir string, version string
|
|||
}
|
||||
|
||||
// Compare cluster
|
||||
clusters, err := clientset.Clusters().List(metav1.ListOptions{})
|
||||
clusters, err := clientset.ListClusters(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error listing clusters: %v", err)
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ func runCreateClusterIntegrationTest(t *testing.T, srcDir string, version string
|
|||
|
||||
// Compare instance groups
|
||||
|
||||
instanceGroups, err := clientset.InstanceGroups(clusters.Items[0].ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
instanceGroups, err := clientset.InstanceGroupsFor(&clusters.Items[0]).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error listing instance groups: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
|
|
@ -111,7 +112,7 @@ func RunCreateInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string,
|
|||
return err
|
||||
}
|
||||
|
||||
existing, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Get(groupName)
|
||||
existing, err := clientset.InstanceGroupsFor(cluster).Get(groupName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -175,7 +176,7 @@ func RunCreateInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string,
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = clientset.InstanceGroups(cluster.ObjectMeta.Name).Create(group)
|
||||
_, err = clientset.InstanceGroupsFor(cluster).Create(group)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error storing InstanceGroup: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
"k8s.io/kops/pkg/instancegroups"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup"
|
||||
|
|
@ -129,7 +130,7 @@ func RunDeleteInstanceGroup(f *util.Factory, out io.Writer, options *DeleteInsta
|
|||
return err
|
||||
}
|
||||
|
||||
group, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Get(groupName)
|
||||
group, err := clientset.InstanceGroupsFor(cluster).Get(groupName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading InstanceGroup %q: %v", groupName, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func RunEditCluster(f *util.Factory, cmd *cobra.Command, args []string, out io.W
|
|||
return err
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroups(oldCluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientset.InstanceGroupsFor(oldCluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -235,7 +235,7 @@ func RunEditCluster(f *util.Factory, cmd *cobra.Command, args []string, out io.W
|
|||
}
|
||||
|
||||
// Note we perform as much validation as we can, before writing a bad config
|
||||
_, err = clientset.Clusters().Update(newCluster)
|
||||
_, err = clientset.ClustersFor(newCluster).Update(newCluster)
|
||||
if err != nil {
|
||||
return preservedFile(err, file, out)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func RunEditFederation(f *util.Factory, cmd *cobra.Command, args []string, out i
|
|||
return fmt.Errorf("name is required")
|
||||
}
|
||||
|
||||
old, err := clientset.Federations().Get(name)
|
||||
old, err := clientset.GetFederation(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading Federation %q: %v", name, err)
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ func RunEditFederation(f *util.Factory, cmd *cobra.Command, args []string, out i
|
|||
}
|
||||
|
||||
// Note we perform as much validation as we can, before writing a bad config
|
||||
_, err = clientset.Federations().Update(newFed)
|
||||
_, err = clientset.FederationsFor(newFed).Update(newFed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
|
|
@ -105,7 +105,7 @@ func RunEditInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string, ou
|
|||
return fmt.Errorf("name is required")
|
||||
}
|
||||
|
||||
oldGroup, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Get(groupName)
|
||||
oldGroup, err := clientset.InstanceGroupsFor(cluster).Get(groupName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading InstanceGroup %q: %v", groupName, err)
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ func RunEditInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string, ou
|
|||
}
|
||||
|
||||
// Note we perform as much validation as we can, before writing a bad config
|
||||
_, err = clientset.InstanceGroups(cluster.ObjectMeta.Name).Update(fullGroup)
|
||||
_, err = clientset.InstanceGroupsFor(cluster).Update(fullGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ func RunGet(context Factory, out io.Writer, options *GetOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
cluster, err := client.Clusters().Get(options.clusterName)
|
||||
cluster, err := client.GetCluster(options.clusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ func RunGet(context Factory, out io.Writer, options *GetOptions) error {
|
|||
|
||||
clusters, err := buildClusters(args, clusterList)
|
||||
|
||||
ig, err := client.InstanceGroups(options.clusterName).List(metav1.ListOptions{})
|
||||
ig, err := client.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ func RunGetClusters(context Factory, out io.Writer, options *GetClusterOptions)
|
|||
return err
|
||||
}
|
||||
|
||||
clusterList, err := client.Clusters().List(metav1.ListOptions{})
|
||||
clusterList, err := client.ListClusters(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func RunGetFederations(context Factory, out io.Writer, options *GetFederationOpt
|
|||
return err
|
||||
}
|
||||
|
||||
list, err := client.Federations().List(metav1.ListOptions{})
|
||||
list, err := client.ListFederations(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,12 @@ func RunGetInstanceGroups(options *GetInstanceGroupsOptions, args []string) erro
|
|||
return err
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroups(clusterName).List(metav1.ListOptions{})
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching cluster %q: %v", cluster, err)
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func (c *ImportClusterCmd) Run() error {
|
|||
return err
|
||||
}
|
||||
|
||||
cluster, err := clientset.Clusters().Get(clusterName)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
|
|
@ -25,8 +26,6 @@ import (
|
|||
"k8s.io/kops/cmd/kops/util"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
|
||||
"bytes"
|
||||
|
||||
kopsapi "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
|
|
@ -101,13 +100,13 @@ func RunReplace(f *util.Factory, cmd *cobra.Command, out io.Writer, c *ReplaceOp
|
|||
|
||||
switch v := o.(type) {
|
||||
case *kopsapi.Federation:
|
||||
_, err = clientset.Federations().Update(v)
|
||||
_, err = clientset.FederationsFor(v).Update(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error replacing federation: %v", err)
|
||||
}
|
||||
|
||||
case *kopsapi.Cluster:
|
||||
_, err = clientset.Clusters().Update(v)
|
||||
_, err = clientset.ClustersFor(v).Update(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error replacing cluster: %v", err)
|
||||
}
|
||||
|
|
@ -117,7 +116,11 @@ func RunReplace(f *util.Factory, cmd *cobra.Command, out io.Writer, c *ReplaceOp
|
|||
if clusterName == "" {
|
||||
return fmt.Errorf("must specify %q label with cluster name to replace instanceGroup", kopsapi.LabelClusterName)
|
||||
}
|
||||
_, err = clientset.InstanceGroups(clusterName).Update(v)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching cluster %q: %v", clusterName, err)
|
||||
}
|
||||
_, err = clientset.InstanceGroupsFor(cluster).Update(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error replacing instanceGroup: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func RunRollingUpdateCluster(f *util.Factory, out io.Writer, options *RollingUpd
|
|||
}
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientset.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ func GetCluster(factory *util.Factory, clusterName string) (*kopsapi.Cluster, er
|
|||
return nil, err
|
||||
}
|
||||
|
||||
cluster, err := clientset.Clusters().Get(clusterName)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading cluster configuration: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,12 +99,12 @@ func RunToolboxConvertImported(f *util.Factory, out io.Writer, options *ToolboxC
|
|||
return fmt.Errorf("ClusterName is required")
|
||||
}
|
||||
|
||||
cluster, err := clientset.Clusters().Get(options.ClusterName)
|
||||
cluster, err := clientset.GetCluster(options.ClusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientset.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func RunToolboxDump(f *util.Factory, out io.Writer, options *ToolboxDumpOptions)
|
|||
return fmt.Errorf("ClusterName is required")
|
||||
}
|
||||
|
||||
cluster, err := clientset.Clusters().Get(options.ClusterName)
|
||||
cluster, err := clientset.GetCluster(options.ClusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ func RunUpdateCluster(f *util.Factory, clusterName string, out io.Writer, c *Upd
|
|||
|
||||
var instanceGroups []*kops.InstanceGroup
|
||||
{
|
||||
list, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientset.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func RunUpdateFederation(factory *util.Factory, cmd *cobra.Command, args []strin
|
|||
return err
|
||||
}
|
||||
|
||||
f, err := clientset.Federations().Get(name)
|
||||
f, err := clientset.GetFederation(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading federation %q: %v", name, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (c *UpgradeClusterCmd) Run(args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
list, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientset.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -294,13 +294,13 @@ func (c *UpgradeClusterCmd) Run(args []string) error {
|
|||
}
|
||||
|
||||
// Note we perform as much validation as we can, before writing a bad config
|
||||
_, err = clientset.Clusters().Update(cluster)
|
||||
_, err = clientset.ClustersFor(cluster).Update(cluster)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, g := range instanceGroups {
|
||||
_, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Update(g)
|
||||
_, err := clientset.InstanceGroupsFor(cluster).Update(g)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing InstanceGroup %q: %v", g.ObjectMeta.Name, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,14 @@ import (
|
|||
"k8s.io/kops/pkg/client/simple/vfsclientset"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
kopsclient "k8s.io/kops/pkg/client/clientset_generated/clientset"
|
||||
|
||||
// Register our APIs
|
||||
"github.com/golang/glog"
|
||||
_ "k8s.io/kops/pkg/apis/kops/install"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FactoryOptions struct {
|
||||
|
|
@ -59,16 +65,46 @@ func (f *Factory) Clientset() (simple.Clientset, error) {
|
|||
if registryPath == "" {
|
||||
return nil, field.Required(field.NewPath("State Store"), STATE_ERROR)
|
||||
}
|
||||
basePath, err := vfs.Context.BuildVfsPath(registryPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building path for %q: %v", registryPath, err)
|
||||
}
|
||||
|
||||
if !vfs.IsClusterReadable(basePath) {
|
||||
return nil, field.Invalid(field.NewPath("State Store"), registryPath, INVALID_STATE_ERROR)
|
||||
}
|
||||
// We recognize a `k8s` scheme; this might change in future so we won't document it yet
|
||||
// In practice nobody is going to hit this accidentally, so I don't think we need a feature flag.
|
||||
if strings.HasPrefix(registryPath, "k8s://") {
|
||||
u, err := url.Parse(registryPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Invalid kops server url: %q", registryPath)
|
||||
}
|
||||
|
||||
f.clientset = vfsclientset.NewVFSClientset(basePath)
|
||||
config := &rest.Config{
|
||||
Host: u.Scheme + "://" + u.Host,
|
||||
}
|
||||
|
||||
glog.Warning("Using insecure TLS")
|
||||
config.Insecure = true
|
||||
|
||||
kopsClient, err := kopsclient.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building kops API client: %v", err)
|
||||
}
|
||||
|
||||
f.clientset = &simple.RESTClientset{
|
||||
BaseURL: &url.URL{
|
||||
Scheme: "k8s",
|
||||
Host: u.Host,
|
||||
},
|
||||
KopsClient: kopsClient.Kops(),
|
||||
}
|
||||
} else {
|
||||
basePath, err := vfs.Context.BuildVfsPath(registryPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building path for %q: %v", registryPath, err)
|
||||
}
|
||||
|
||||
if !vfs.IsClusterReadable(basePath) {
|
||||
return nil, field.Invalid(field.NewPath("State Store"), registryPath, INVALID_STATE_ERROR)
|
||||
}
|
||||
|
||||
f.clientset = vfsclientset.NewVFSClientset(basePath)
|
||||
}
|
||||
}
|
||||
|
||||
return f.clientset, nil
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func RunValidateCluster(f *util.Factory, cmd *cobra.Command, args []string, out
|
|||
return err
|
||||
}
|
||||
|
||||
list, err := clientSet.InstanceGroups(cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := clientSet.InstanceGroupsFor(cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get InstanceGroups for %q: %v", cluster.ObjectMeta.Name, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
func apply() error {
|
||||
clientset := vfsclientset.NewVFSClientset(registryBase)
|
||||
|
||||
cluster, err := clientset.Clusters().Get(clusterName)
|
||||
cluster, err := clientset.GetCluster(clusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func up() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err := clientset.Clusters().Create(cluster)
|
||||
_, err := clientset.ClustersFor(cluster).Create(cluster)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ func up() error {
|
|||
Role: api.InstanceGroupRoleMaster,
|
||||
Subnets: masterZones,
|
||||
}
|
||||
_, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Create(ig)
|
||||
_, err := clientset.InstanceGroupsFor(cluster).Create(ig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ func up() error {
|
|||
Subnets: nodeZones,
|
||||
}
|
||||
|
||||
_, err := clientset.InstanceGroups(cluster.ObjectMeta.Name).Create(ig)
|
||||
_, err := clientset.InstanceGroupsFor(cluster).Create(ig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func (o *ApplyFederationOperation) FindKubecfg() (*kubeconfig.KubeconfigBuilder,
|
|||
|
||||
// Loop through looking for a configured cluster
|
||||
for _, controller := range o.Federation.Spec.Controllers {
|
||||
cluster, err := o.KopsClient.Clusters().Get(controller)
|
||||
cluster, err := o.KopsClient.GetCluster(controller)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading cluster %q: %v", controller, err)
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ func (o *ApplyFederationOperation) Run() error {
|
|||
|
||||
var controllerKubernetesClients []kubernetes.Interface
|
||||
for _, controller := range o.Federation.Spec.Controllers {
|
||||
cluster, err := o.KopsClient.Clusters().Get(controller)
|
||||
cluster, err := o.KopsClient.GetCluster(controller)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading cluster %q: %v", controller, err)
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ func (o *ApplyFederationOperation) Run() error {
|
|||
|
||||
for _, member := range o.Federation.Spec.Members {
|
||||
glog.V(2).Infof("configuring member cluster %q", member)
|
||||
cluster, err := o.KopsClient.Clusters().Get(member)
|
||||
cluster, err := o.KopsClient.GetCluster(member)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading cluster %q: %v", member, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,24 @@ k8s.io/kops/pkg/apis/nodeup
|
|||
k8s.io/kops/pkg/apiserver
|
||||
k8s.io/kops/pkg/apiserver/cmd/server
|
||||
k8s.io/kops/pkg/apiserver/registry/cluster
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/scheme
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/v1alpha1
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/v1alpha1/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/v1alpha2
|
||||
k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/v1alpha2/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/scheme
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/internalversion
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/internalversion/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha1
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha1/fake
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha2
|
||||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha2/fake
|
||||
k8s.io/kops/pkg/client/simple
|
||||
k8s.io/kops/pkg/client/simple/vfsclientset
|
||||
k8s.io/kops/pkg/diff
|
||||
|
|
|
|||
|
|
@ -33,3 +33,7 @@ cp ${WORK_DIR}/go/bin/conversion-gen ${GOPATH}/bin/
|
|||
|
||||
GOPATH=${WORK_DIR}/go/ go install k8s.io/kubernetes/cmd/libs/go2idl/defaulter-gen
|
||||
cp ${WORK_DIR}/go/bin/defaulter-gen ${GOPATH}/bin/
|
||||
|
||||
GOPATH=${WORK_DIR}/go/ go install k8s.io/kubernetes/cmd/libs/go2idl/client-gen
|
||||
cp ${WORK_DIR}/go/bin/client-gen ${GOPATH}/bin/
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +groupName=kops
|
||||
package kops // import "k8s.io/kops/pkg/apis/kops"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Federation represents a federated set of kubernetes clusters
|
||||
type Federation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ const LabelClusterName = "kops.k8s.io/cluster"
|
|||
// Deprecated - use the new labels & taints node-role.kubernetes.io/master and node-role.kubernetes.io/node
|
||||
const TaintNoScheduleMaster15 = "dedicated=master:NoSchedule"
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// InstanceGroup represents a group of instances (either nodes or masters) with the same configuration
|
||||
type InstanceGroup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ func CreateClusterConfig(clientset simple.Clientset, cluster *api.Cluster, group
|
|||
}
|
||||
}
|
||||
|
||||
_, err := clientset.Clusters().Create(cluster)
|
||||
_, err := clientset.ClustersFor(cluster).Create(cluster)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ig := range groups {
|
||||
_, err = clientset.InstanceGroups(cluster.ObjectMeta.Name).Create(ig)
|
||||
_, err = clientset.InstanceGroupsFor(cluster).Create(ig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing updated instancegroup configuration: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
type Federation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// InstanceGroup represents a group of instances (either nodes or masters) with the same configuration
|
||||
type InstanceGroup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Federation represents a federated set of kubernetes clusters
|
||||
type Federation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// InstanceGroup represents a group of instances (either nodes or masters) with the same configuration
|
||||
type InstanceGroup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -16,8 +16,97 @@ limitations under the License.
|
|||
|
||||
package simple
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
kopsinternalversion "k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Clientset interface {
|
||||
Clusters() ClusterInterface
|
||||
InstanceGroups(cluster string) InstanceGroupInterface
|
||||
Federations() FederationInterface
|
||||
// ClustersFor returns the ClusterInterface bound to the namespace for a particular Cluster
|
||||
ClustersFor(cluster *kops.Cluster) kopsinternalversion.ClusterInterface
|
||||
|
||||
// GetCluster reads a cluster by name
|
||||
GetCluster(name string) (*kops.Cluster, error)
|
||||
|
||||
// ListClusters returns all clusters
|
||||
ListClusters(options metav1.ListOptions) (*kops.ClusterList, error)
|
||||
|
||||
// ConfigBaseFor returns the vfs path where we will read configuration information from
|
||||
ConfigBaseFor(cluster *kops.Cluster) (vfs.Path, error)
|
||||
|
||||
// InstanceGroupsFor returns the InstanceGroupInterface bounds to the namespace for a particular Cluster
|
||||
InstanceGroupsFor(cluster *kops.Cluster) kopsinternalversion.InstanceGroupInterface
|
||||
|
||||
// FederationsFor returns the FederationInterface bounds to the namespace for a particular Federation
|
||||
FederationsFor(federation *kops.Federation) kopsinternalversion.FederationInterface
|
||||
|
||||
// GetFederation reads a federation by name
|
||||
GetFederation(name string) (*kops.Federation, error)
|
||||
|
||||
// ListFederations returns all federations
|
||||
ListFederations(options metav1.ListOptions) (*kops.FederationList, error)
|
||||
}
|
||||
|
||||
// RESTClientset is an implementation of clientset that uses a "real" generated REST client
|
||||
type RESTClientset struct {
|
||||
BaseURL *url.URL
|
||||
KopsClient kopsinternalversion.KopsInterface
|
||||
}
|
||||
|
||||
func (c *RESTClientset) ClustersFor(cluster *kops.Cluster) kopsinternalversion.ClusterInterface {
|
||||
namespace := restNamespaceForClusterName(cluster.Name)
|
||||
return c.KopsClient.Clusters(namespace)
|
||||
}
|
||||
|
||||
func (c *RESTClientset) GetCluster(name string) (*kops.Cluster, error) {
|
||||
namespace := restNamespaceForClusterName(name)
|
||||
return c.KopsClient.Clusters(namespace).Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (c *RESTClientset) ConfigBaseFor(cluster *kops.Cluster) (vfs.Path, error) {
|
||||
// URL for clusters looks like https://<server>/apis/kops/v1alpha2/namespaces/<cluster>/clusters/<cluster>
|
||||
// We probably want to add a subresource for full resources
|
||||
return vfs.Context.BuildVfsPath(c.BaseURL.String())
|
||||
}
|
||||
|
||||
func (c *RESTClientset) ListClusters(options metav1.ListOptions) (*kops.ClusterList, error) {
|
||||
return c.KopsClient.Clusters(metav1.NamespaceAll).List(options)
|
||||
}
|
||||
|
||||
func (c *RESTClientset) InstanceGroupsFor(cluster *kops.Cluster) kopsinternalversion.InstanceGroupInterface {
|
||||
namespace := restNamespaceForClusterName(cluster.Name)
|
||||
return c.KopsClient.InstanceGroups(namespace)
|
||||
}
|
||||
|
||||
func (c *RESTClientset) FederationsFor(federation *kops.Federation) kopsinternalversion.FederationInterface {
|
||||
// Unsure if this should be namespaced or not - probably, so that we can RBAC it...
|
||||
panic("Federations are curently not supported by the server API")
|
||||
//namespace := restNamespaceForFederationName(federation.Name)
|
||||
//return c.KopsClient.Federations(namespace)
|
||||
}
|
||||
|
||||
func (c *RESTClientset) ListFederations(options metav1.ListOptions) (*kops.FederationList, error) {
|
||||
return c.KopsClient.Federations(metav1.NamespaceAll).List(options)
|
||||
}
|
||||
|
||||
func (c *RESTClientset) GetFederation(name string) (*kops.Federation, error) {
|
||||
namespace := restNamespaceForFederationName(name)
|
||||
return c.KopsClient.Federations(namespace).Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func restNamespaceForClusterName(clusterName string) string {
|
||||
// We are not allowed dots, so we map them to dashes
|
||||
// This can conflict, but this will simply be a limitation that we pass on to the user
|
||||
// i.e. it will not be possible to create a.b.example.com and a-b.example.com
|
||||
namespace := strings.Replace(clusterName, ".", "-", -1)
|
||||
return namespace
|
||||
}
|
||||
|
||||
func restNamespaceForFederationName(clusterName string) string {
|
||||
namespace := strings.Replace(clusterName, ".", "-", -1)
|
||||
return namespace
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package simple
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
)
|
||||
|
||||
// ClusterInterface has methods to work with Cluster resources.
|
||||
type ClusterInterface interface {
|
||||
Create(*api.Cluster) (*api.Cluster, error)
|
||||
Update(*api.Cluster) (*api.Cluster, error)
|
||||
//UpdateStatus(*api.Cluster) (*api.Cluster, error)
|
||||
//Delete(name string, options *api.DeleteOptions) error
|
||||
//DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Cluster, error)
|
||||
List(opts metav1.ListOptions) (*api.ClusterList, error)
|
||||
//Watch(opts k8sapi.ListOptions) (watch.Interface, error)
|
||||
//Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Cluster, err error)
|
||||
//ClusterExpansion
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package simple
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
)
|
||||
|
||||
// FederationInterface has methods to work with Federation resources.
|
||||
type FederationInterface interface {
|
||||
Create(*api.Federation) (*api.Federation, error)
|
||||
Update(*api.Federation) (*api.Federation, error)
|
||||
//UpdateStatus(*api.Federation) (*api.Federation, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
//DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Federation, error)
|
||||
List(opts metav1.ListOptions) (*api.FederationList, error)
|
||||
//Watch(opts k8sapi.ListOptions) (watch.Interface, error)
|
||||
//Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Federation, err error)
|
||||
//FederationExpansion
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package simple
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
)
|
||||
|
||||
// InstanceGroupInterface has methods to work with InstanceGroup resources.
|
||||
type InstanceGroupInterface interface {
|
||||
Create(*api.InstanceGroup) (*api.InstanceGroup, error)
|
||||
Update(*api.InstanceGroup) (*api.InstanceGroup, error)
|
||||
//UpdateStatus(*api.InstanceGroup) (*api.InstanceGroup, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
//DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.InstanceGroup, error)
|
||||
List(opts metav1.ListOptions) (*api.InstanceGroupList, error)
|
||||
//Watch(opts k8sapi.ListOptions) (watch.Interface, error)
|
||||
//Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.InstanceGroup, err error)
|
||||
//InstanceGroupExpansion
|
||||
}
|
||||
|
|
@ -17,6 +17,9 @@ limitations under the License.
|
|||
package vfsclientset
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
kopsinternalversion "k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
)
|
||||
|
|
@ -27,21 +30,50 @@ type VFSClientset struct {
|
|||
|
||||
var _ simple.Clientset = &VFSClientset{}
|
||||
|
||||
func (c *VFSClientset) Clusters() simple.ClusterInterface {
|
||||
func (c *VFSClientset) ClustersFor(cluster *kops.Cluster) kopsinternalversion.ClusterInterface {
|
||||
return c.clusters()
|
||||
}
|
||||
|
||||
func (c *VFSClientset) clusters() *ClusterVFS {
|
||||
return newClusterVFS(c.basePath)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) InstanceGroups(clusterName string) simple.InstanceGroupInterface {
|
||||
func (c *VFSClientset) GetCluster(name string) (*kops.Cluster, error) {
|
||||
return c.clusters().Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (c *VFSClientset) ListClusters(options metav1.ListOptions) (*kops.ClusterList, error) {
|
||||
return c.clusters().List(options)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) ConfigBaseFor(cluster *kops.Cluster) (vfs.Path, error) {
|
||||
return c.clusters().configBase(cluster.Name)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) InstanceGroupsFor(cluster *kops.Cluster) kopsinternalversion.InstanceGroupInterface {
|
||||
clusterName := cluster.Name
|
||||
return newInstanceGroupVFS(c, clusterName)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) Federations() simple.FederationInterface {
|
||||
func (c *VFSClientset) federations() kopsinternalversion.FederationInterface {
|
||||
return newFederationVFS(c)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) FederationsFor(federation *kops.Federation) kopsinternalversion.FederationInterface {
|
||||
return c.federations()
|
||||
}
|
||||
|
||||
func (c *VFSClientset) ListFederations(options metav1.ListOptions) (*kops.FederationList, error) {
|
||||
return c.federations().List(options)
|
||||
}
|
||||
|
||||
func (c *VFSClientset) GetFederation(name string) (*kops.Federation, error) {
|
||||
return c.federations().Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func NewVFSClientset(basePath vfs.Path) simple.Clientset {
|
||||
clientset := &VFSClientset{
|
||||
vfsClientset := &VFSClientset{
|
||||
basePath: basePath,
|
||||
}
|
||||
return clientset
|
||||
return vfsClientset
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@ import (
|
|||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/registry"
|
||||
"k8s.io/kops/pkg/apis/kops/v1alpha1"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
kopsinternalversion "k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
"os"
|
||||
"strings"
|
||||
|
|
@ -43,14 +45,17 @@ func newClusterVFS(basePath vfs.Path) *ClusterVFS {
|
|||
return c
|
||||
}
|
||||
|
||||
var _ simple.ClusterInterface = &ClusterVFS{}
|
||||
var _ kopsinternalversion.ClusterInterface = &ClusterVFS{}
|
||||
|
||||
func (c *ClusterVFS) Get(name string) (*api.Cluster, error) {
|
||||
func (c *ClusterVFS) Get(name string, options metav1.GetOptions) (*api.Cluster, error) {
|
||||
if options.ResourceVersion != "" {
|
||||
return nil, fmt.Errorf("ResourceVersion not supported in ClusterVFS::Get")
|
||||
}
|
||||
return c.find(name)
|
||||
}
|
||||
|
||||
// Deprecated, but we need this for now..
|
||||
func (c *ClusterVFS) ConfigBase(clusterName string) (vfs.Path, error) {
|
||||
func (c *ClusterVFS) configBase(clusterName string) (vfs.Path, error) {
|
||||
if clusterName == "" {
|
||||
return nil, fmt.Errorf("clusterName is required")
|
||||
}
|
||||
|
|
@ -180,7 +185,7 @@ func (r *ClusterVFS) find(clusterName string) (*api.Cluster, error) {
|
|||
|
||||
// TODO: Split this out into real version updates / schema changes
|
||||
if c.Spec.ConfigBase == "" {
|
||||
configBase, err := r.ConfigBase(clusterName)
|
||||
configBase, err := r.configBase(clusterName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building ConfigBase for cluster: %v", err)
|
||||
}
|
||||
|
|
@ -189,3 +194,19 @@ func (r *ClusterVFS) find(clusterName string) (*api.Cluster, error) {
|
|||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (r *ClusterVFS) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return fmt.Errorf("cluster Delete not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *ClusterVFS) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
return fmt.Errorf("cluster DeleteCollection not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *ClusterVFS) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return nil, fmt.Errorf("cluster Watch not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *ClusterVFS) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *api.Cluster, err error) {
|
||||
return nil, fmt.Errorf("cluster Patch not implemented for vfs store")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@ limitations under the License.
|
|||
package vfsclientset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/v1alpha1"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
kopsinternalversion "k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion"
|
||||
)
|
||||
|
||||
type FederationVFS struct {
|
||||
|
|
@ -42,9 +45,12 @@ func newFederationVFS(c *VFSClientset) *FederationVFS {
|
|||
return r
|
||||
}
|
||||
|
||||
var _ simple.FederationInterface = &FederationVFS{}
|
||||
var _ kopsinternalversion.FederationInterface = &FederationVFS{}
|
||||
|
||||
func (c *FederationVFS) Get(name string) (*api.Federation, error) {
|
||||
func (c *FederationVFS) Get(name string, options metav1.GetOptions) (*api.Federation, error) {
|
||||
if options.ResourceVersion != "" {
|
||||
return nil, fmt.Errorf("ResourceVersion not supported in FederationVFS::Get")
|
||||
}
|
||||
o, err := c.get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -84,3 +90,15 @@ func (c *FederationVFS) Update(g *api.Federation) (*api.Federation, error) {
|
|||
func (c *FederationVFS) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return c.delete(name, options)
|
||||
}
|
||||
|
||||
func (r *FederationVFS) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
return fmt.Errorf("FederationVFS DeleteCollection not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *FederationVFS) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return nil, fmt.Errorf("FederationVFS Watch not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *FederationVFS) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *api.Federation, err error) {
|
||||
return nil, fmt.Errorf("FederationVFS Patch not implemented for vfs store")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,17 @@ limitations under the License.
|
|||
package vfsclientset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/v1alpha1"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
kopsinternalversion "k8s.io/kops/pkg/client/clientset_generated/clientset/typed/kops/internalversion"
|
||||
)
|
||||
|
||||
type InstanceGroupVFS struct {
|
||||
|
|
@ -52,9 +55,13 @@ func newInstanceGroupVFS(c *VFSClientset, clusterName string) *InstanceGroupVFS
|
|||
return r
|
||||
}
|
||||
|
||||
var _ simple.InstanceGroupInterface = &InstanceGroupVFS{}
|
||||
var _ kopsinternalversion.InstanceGroupInterface = &InstanceGroupVFS{}
|
||||
|
||||
func (c *InstanceGroupVFS) Get(name string, options metav1.GetOptions) (*api.InstanceGroup, error) {
|
||||
if options.ResourceVersion != "" {
|
||||
return nil, fmt.Errorf("ResourceVersion not supported in InstanceGroupVFS::Get")
|
||||
}
|
||||
|
||||
func (c *InstanceGroupVFS) Get(name string) (*api.InstanceGroup, error) {
|
||||
o, err := c.get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -108,3 +115,15 @@ func (c *InstanceGroupVFS) Update(g *api.InstanceGroup) (*api.InstanceGroup, err
|
|||
func (c *InstanceGroupVFS) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return c.delete(name, options)
|
||||
}
|
||||
|
||||
func (r *InstanceGroupVFS) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
return fmt.Errorf("InstanceGroupVFS DeleteCollection not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *InstanceGroupVFS) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return nil, fmt.Errorf("InstanceGroupVFS Watch not implemented for vfs store")
|
||||
}
|
||||
|
||||
func (r *InstanceGroupVFS) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *api.InstanceGroup, err error) {
|
||||
return nil, fmt.Errorf("InstanceGroupVFS Patch not implemented for vfs store")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ func (c *DeleteInstanceGroup) DeleteInstanceGroup(group *api.InstanceGroup) erro
|
|||
}
|
||||
}
|
||||
|
||||
err = c.Clientset.InstanceGroups(c.Cluster.ObjectMeta.Name).Delete(group.ObjectMeta.Name, nil)
|
||||
err = c.Clientset.InstanceGroupsFor(c.Cluster).Delete(group.ObjectMeta.Name, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
}
|
||||
|
||||
if c.InstanceGroups == nil {
|
||||
list, err := c.Clientset.InstanceGroups(c.Cluster.ObjectMeta.Name).List(metav1.ListOptions{})
|
||||
list, err := c.Clientset.InstanceGroupsFor(c.Cluster).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -709,7 +709,7 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
}
|
||||
|
||||
for _, g := range c.InstanceGroups {
|
||||
_, err := c.Clientset.InstanceGroups(c.Cluster.ObjectMeta.Name).Update(g)
|
||||
_, err := c.Clientset.InstanceGroupsFor(c.Cluster).Update(g)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing InstanceGroup %q to registry: %v", g.ObjectMeta.Name, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import (
|
|||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/registry"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
"k8s.io/kops/pkg/client/simple/vfsclientset"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup"
|
||||
|
|
@ -77,7 +76,7 @@ func (x *ConvertKubeupCluster) Upgrade() error {
|
|||
// Build completed cluster (force errors asap)
|
||||
cluster.ObjectMeta.Name = newClusterName
|
||||
|
||||
newConfigBase, err := x.Clientset.Clusters().(*vfsclientset.ClusterVFS).ConfigBase(newClusterName)
|
||||
newConfigBase, err := x.Clientset.ConfigBaseFor(cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building ConfigBase for cluster: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import (
|
|||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/registry"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
"k8s.io/kops/pkg/client/simple/vfsclientset"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup"
|
||||
|
|
@ -72,7 +71,7 @@ func (x *ImportCluster) ImportAWSCluster() error {
|
|||
cluster.Spec.KubernetesAPIAccess = []string{"0.0.0.0/0"}
|
||||
cluster.Spec.SSHAccess = []string{"0.0.0.0/0"}
|
||||
|
||||
configBase, err := x.Clientset.Clusters().(*vfsclientset.ClusterVFS).ConfigBase(clusterName)
|
||||
configBase, err := x.Clientset.ConfigBaseFor(cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building ConfigBase for cluster: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import (
|
|||
// but allows us to configure S3 credentials, for example
|
||||
type VFSContext struct {
|
||||
s3Context *S3Context
|
||||
k8sContext *KubernetesContext
|
||||
memfsContext *MemFSContext
|
||||
// mutex guards gcsClient
|
||||
mutex sync.Mutex
|
||||
|
|
@ -44,7 +45,8 @@ type VFSContext struct {
|
|||
}
|
||||
|
||||
var Context = VFSContext{
|
||||
s3Context: NewS3Context(),
|
||||
s3Context: NewS3Context(),
|
||||
k8sContext: NewKubernetesContext(),
|
||||
}
|
||||
|
||||
// ReadLocation reads a file from a vfs URL
|
||||
|
|
@ -106,6 +108,10 @@ func (c *VFSContext) BuildVfsPath(p string) (Path, error) {
|
|||
return c.buildGCSPath(p)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(p, "k8s://") {
|
||||
return c.buildKubernetesPath(p)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown / unhandled path type: %q", p)
|
||||
}
|
||||
|
||||
|
|
@ -219,6 +225,24 @@ func (c *VFSContext) buildS3Path(p string) (*S3Path, error) {
|
|||
return s3path, nil
|
||||
}
|
||||
|
||||
func (c *VFSContext) buildKubernetesPath(p string) (*KubernetesPath, error) {
|
||||
u, err := url.Parse(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid kubernetes vfs path: %q", p)
|
||||
}
|
||||
if u.Scheme != "k8s" {
|
||||
return nil, fmt.Errorf("invalid kubernetes vfs path: %q", p)
|
||||
}
|
||||
|
||||
bucket := strings.TrimSuffix(u.Host, "/")
|
||||
if bucket == "" {
|
||||
return nil, fmt.Errorf("invalid kubernetes vfs path: %q", p)
|
||||
}
|
||||
|
||||
k8sPath := newKubernetesPath(c.k8sContext, bucket, u.Path)
|
||||
return k8sPath, nil
|
||||
}
|
||||
|
||||
func (c *VFSContext) buildMemFSPath(p string) (*MemFSPath, error) {
|
||||
if !strings.HasPrefix(p, "memfs://") {
|
||||
return nil, fmt.Errorf("memfs path not recognized: %q", p)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vfs
|
||||
|
||||
// KubernetesContext is the context for a Kubernetes VFS implementation
|
||||
type KubernetesContext struct {
|
||||
}
|
||||
|
||||
// NewKubernetesContext builds a KubernetesContext
|
||||
// This will likely take a kubernetes rest client object (or similar) once the implementation is more complete
|
||||
func NewKubernetesContext() *KubernetesContext {
|
||||
return &KubernetesContext{}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/kops/util/pkg/hashing"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// KubernetesPath is a path for a VFS backed by the kubernetes API
|
||||
// Currently all operations are no-ops
|
||||
type KubernetesPath struct {
|
||||
k8sContext *KubernetesContext
|
||||
host string
|
||||
key string
|
||||
}
|
||||
|
||||
var _ Path = &KubernetesPath{}
|
||||
var _ HasHash = &KubernetesPath{}
|
||||
|
||||
func newKubernetesPath(k8sContext *KubernetesContext, host string, key string) *KubernetesPath {
|
||||
host = strings.TrimSuffix(host, "/")
|
||||
key = strings.TrimPrefix(key, "/")
|
||||
|
||||
return &KubernetesPath{
|
||||
k8sContext: k8sContext,
|
||||
host: host,
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Path() string {
|
||||
return "k8s://" + p.host + "/" + p.key
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Host() string {
|
||||
return p.host
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Key() string {
|
||||
return p.key
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) String() string {
|
||||
return p.Path()
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Remove() error {
|
||||
return fmt.Errorf("KubernetesPath::Remove not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Join(relativePath ...string) Path {
|
||||
args := []string{p.key}
|
||||
args = append(args, relativePath...)
|
||||
joined := path.Join(args...)
|
||||
return &KubernetesPath{
|
||||
k8sContext: p.k8sContext,
|
||||
host: p.host,
|
||||
key: joined,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) WriteFile(data []byte) error {
|
||||
return fmt.Errorf("KubernetesPath::WriteFile not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) CreateFile(data []byte) error {
|
||||
return fmt.Errorf("KubernetesPath::CreateFile not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) ReadFile() ([]byte, error) {
|
||||
return nil, fmt.Errorf("KubernetesPath::ReadFile not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) ReadDir() ([]Path, error) {
|
||||
return nil, fmt.Errorf("KubernetesPath::ReadDir not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) ReadTree() ([]Path, error) {
|
||||
return nil, fmt.Errorf("KubernetesPath::ReadTree not supported")
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Base() string {
|
||||
return path.Base(p.key)
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) PreferredHash() (*hashing.Hash, error) {
|
||||
return p.Hash(hashing.HashAlgorithmMD5)
|
||||
}
|
||||
|
||||
func (p *KubernetesPath) Hash(a hashing.HashAlgorithm) (*hashing.Hash, error) {
|
||||
return nil, fmt.Errorf("KubernetesPath::Hash not supported")
|
||||
}
|
||||
|
|
@ -90,6 +90,9 @@ func IsClusterReadable(p Path) bool {
|
|||
case *S3Path, *GSPath:
|
||||
return true
|
||||
|
||||
case *KubernetesPath:
|
||||
return true
|
||||
|
||||
case *SSHPath:
|
||||
return false
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue