Skip to content

Commit

Permalink
Merge pull request #3254 from chrislovecnm/file-assets
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue.

work on using files assets

Basic MVP for file assests.

- using file assest builder
- able to upload files
- using URL structs instead of strings everywhere
  • Loading branch information
Kubernetes Submit Queue authored Dec 18, 2017
2 parents 0bfb273 + 7057aaf commit dd49d69
Show file tree
Hide file tree
Showing 35 changed files with 940 additions and 385 deletions.
2 changes: 1 addition & 1 deletion cmd/kops/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
return err
}

assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets, "")
fullCluster, err := cloudup.PopulateClusterSpec(clientset, cluster, assetBuilder)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/kops/edit_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func RunEditCluster(f *util.Factory, cmd *cobra.Command, args []string, out io.W
return preservedFile(fmt.Errorf("error populating configuration: %v", err), file, out)
}

assetBuilder := assets.NewAssetBuilder(newCluster.Spec.Assets)
assetBuilder := assets.NewAssetBuilder(newCluster.Spec.Assets, "")
fullCluster, err := cloudup.PopulateClusterSpec(clientset, newCluster, assetBuilder)
if err != nil {
results = editResults{
Expand Down
2 changes: 1 addition & 1 deletion cmd/kops/edit_instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func RunEditInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string, ou
return fmt.Errorf("error populating configuration: %v", err)
}

assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets, "")
fullCluster, err := cloudup.PopulateClusterSpec(clientset, cluster, assetBuilder)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/kops/upgrade_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func (c *UpgradeClusterCmd) Run(args []string) error {
return fmt.Errorf("error populating configuration: %v", err)
}

assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets, "")
fullCluster, err := cloudup.PopulateClusterSpec(clientset, cluster, assetBuilder)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions cmd/kops/util/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/acls/gce:go_default_library",
"//pkg/acls/s3:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/simple:go_default_library",
"//pkg/client/simple/api:go_default_library",
Expand Down
2 changes: 2 additions & 0 deletions cmd/kops/util/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/client-go/rest"
gceacls "k8s.io/kops/pkg/acls/gce"
s3acls "k8s.io/kops/pkg/acls/s3"
kopsclient "k8s.io/kops/pkg/client/clientset_generated/clientset"
"k8s.io/kops/pkg/client/simple"
"k8s.io/kops/pkg/client/simple/api"
Expand All @@ -43,6 +44,7 @@ type Factory struct {

func NewFactory(options *FactoryOptions) *Factory {
gceacls.Register()
s3acls.Register()

return &Factory{
options: options,
Expand Down
2 changes: 2 additions & 0 deletions hack/.packages
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ k8s.io/kops/nodeup/pkg/model
k8s.io/kops/nodeup/pkg/model/resources
k8s.io/kops/pkg/acls
k8s.io/kops/pkg/acls/gce
k8s.io/kops/pkg/acls/s3
k8s.io/kops/pkg/apis/kops
k8s.io/kops/pkg/apis/kops/install
k8s.io/kops/pkg/apis/kops/model
Expand Down Expand Up @@ -109,6 +110,7 @@ k8s.io/kops/pkg/testutils
k8s.io/kops/pkg/util/stringorslice
k8s.io/kops/pkg/util/templater
k8s.io/kops/pkg/validation
k8s.io/kops/pkg/values
k8s.io/kops/protokube/cmd/protokube
k8s.io/kops/protokube/pkg/etcd
k8s.io/kops/protokube/pkg/gossip
Expand Down
2 changes: 1 addition & 1 deletion nodeup/pkg/model/protokube.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (t *ProtokubeBuilder) ProtokubeFlags(k8sVersion semver.Version) (*Protokube

// TODO this is dupicate code with etcd model
image := fmt.Sprintf("gcr.io/google_containers/etcd:%s", imageVersion)
assets := assets.NewAssetBuilder(t.Cluster.Spec.Assets)
assets := assets.NewAssetBuilder(t.Cluster.Spec.Assets, "")
remapped, err := assets.RemapImage(image)
if err != nil {
return nil, fmt.Errorf("unable to remap container %q: %v", image, err)
Expand Down
26 changes: 26 additions & 0 deletions pkg/acls/s3/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = ["storage.go"],
importpath = "k8s.io/kops/pkg/acls/s3",
visibility = ["//visibility:public"],
deps = [
"//pkg/acls:go_default_library",
"//pkg/apis/kops:go_default_library",
"//pkg/values:go_default_library",
"//util/pkg/vfs:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = ["storage_test.go"],
importpath = "k8s.io/kops/pkg/acls/s3",
library = ":go_default_library",
deps = [
"//pkg/apis/kops:go_default_library",
"//util/pkg/vfs:go_default_library",
],
)
91 changes: 91 additions & 0 deletions pkg/acls/s3/storage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
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 s3

import (
"fmt"
"net/url"

"strings"

"github.com/golang/glog"
"k8s.io/kops/pkg/acls"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/values"
"k8s.io/kops/util/pkg/vfs"
)

// s3PublicAclStrategy is the AclStrategy for objects that are written with public read only ACL.
// This strategy is used by custom file assets.
type s3PublicAclStrategy struct {
}

var _ acls.ACLStrategy = &s3PublicAclStrategy{}

// GetACL creates a s3PublicAclStrategy object for writing public files with assets FileRepository.
// This strategy checks if the files are inside the state store, and if the files are located inside
// the state store, this returns nil and logs a message (level 8) that it will not run.
func (s *s3PublicAclStrategy) GetACL(p vfs.Path, cluster *kops.Cluster) (vfs.ACL, error) {
if cluster.Spec.Assets == nil || cluster.Spec.Assets.FileRepository == nil {
return nil, nil
}

s3Path, ok := p.(*vfs.S3Path)
if !ok {
return nil, nil
}

fileRepository := values.StringValue(cluster.Spec.Assets.FileRepository)

u, err := url.Parse(fileRepository)
if err != nil {
return "", fmt.Errorf("unable to parse: %q", fileRepository)
}

// We are checking that the file is in s3.amazonaws.com meaning that it is in s3
// This will miss edge cases when the region url is used.
if u.Host != "s3.amazonaws.com" {
glog.V(8).Infof("path %q is not inside of a s3 bucket", u.String)
return nil, nil
}

config, err := url.Parse(cluster.Spec.ConfigStore)
if err != nil {
return "", fmt.Errorf("unable to parse: %q", fileRepository)
}

// We are checking that the path defined is not the state store, if it is
// we do NOT set the state store as public read.
if strings.Contains(u.Path, config.Path) {
glog.V(8).Infof("path %q is inside of config store %q, not setting public-read acl", u.Path, config.Path)
return nil, nil
}

if strings.TrimPrefix(u.Path, "/") == s3Path.Bucket() {
return &vfs.S3Acl{
RequestACL: values.String("public-read"),
}, nil
} else {
glog.V(8).Infof("path %q is not inside the file registry %q, not setting public-read acl", u.Path, config.Path)
}

return nil, nil
}

func Register() {
acls.RegisterPlugin("k8s.io/kops/acl/s3", &s3PublicAclStrategy{})
}
81 changes: 81 additions & 0 deletions pkg/acls/s3/storage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
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 s3

import (
"testing"

"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/values"
"k8s.io/kops/util/pkg/vfs"
)

func Test_Strategy(t *testing.T) {
context := &vfs.VFSContext{}
path, err := context.BuildVfsPath("s3://test/foo")
if err != nil {
t.Errorf("unable to create path: %v", err)
}

cluster := &kops.Cluster{
Spec: kops.ClusterSpec{
ConfigStore: "s3://my_state_store/cluster",
Assets: &kops.Assets{
FileRepository: values.String("https://s3.amazonaws.com/test"),
},
},
}

s := &s3PublicAclStrategy{}
acl, err := s.GetACL(path, cluster)

if err != nil {
t.Errorf("error getting ACL: %v", err)
}

if acl == nil {
t.Errorf("public ro ACL is nil and should not be, this test is a positive test case.")
}
}

func Test_In_StateStore(t *testing.T) {
context := &vfs.VFSContext{}
stateStore, err := context.BuildVfsPath("s3://my_state_store/cluster")
if err != nil {
t.Errorf("unable to create path: %v", err)
}

cluster := &kops.Cluster{
Spec: kops.ClusterSpec{
ConfigStore: "s3://my_state_store/cluster",
Assets: &kops.Assets{
FileRepository: values.String("https://s3.amazonaws.com/my_state_store/opps"),
},
},
}

s := &s3PublicAclStrategy{}
acl, err := s.GetACL(stateStore, cluster)

if err != nil {
t.Errorf("error getting ACL: %v", err)
}

if acl != nil {
t.Errorf("public ro ACL is set but path is in the state store, this test is a negative test case.")
}
}
14 changes: 5 additions & 9 deletions pkg/assets/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "go_default_library",
Expand All @@ -9,13 +9,9 @@ go_library(
"//pkg/apis/kops:go_default_library",
"//pkg/featureflag:go_default_library",
"//pkg/kubemanifest:go_default_library",
"//pkg/values:go_default_library",
"//util/pkg/hashing:go_default_library",
"//util/pkg/vfs:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = ["builder_test.go"],
importpath = "k8s.io/kops/pkg/assets",
library = ":go_default_library",
deps = ["//pkg/apis/kops:go_default_library"],
)
Loading

0 comments on commit dd49d69

Please sign in to comment.