Unverified Commit 52f89335 authored by Bryan Liles's avatar Bryan Liles Committed by GitHub
Browse files

Merge pull request #466 from bryanl/reorganize-layout

Reorganize layout
parents 7d0b21b5 570e935c
project_name: ks
builds:
- main: .
- main: ./cmd/ks/main.go
binary: ks
ldflags: -X main.version={{.Version}}
goos:
......
......@@ -66,26 +66,7 @@ before_install:
export GO_LDFLAGS='-linkmode external -extldflags=-static'
fi
install:
- go build -i -ldflags "$GO_LDFLAGS" .
- |
if [ "$DO_INTEGRATION_TEST" = 1 ]; then
if ! which minikube; then
wget -O minikube \
https://storage.googleapis.com/minikube/releases/v0.21.0/minikube-$(go env GOOS)-$(go env GOARCH)
install -m 755 minikube $GOPATH/bin/minikube
fi
if ! which kubectl; then
wget https://storage.googleapis.com/kubernetes-release/release/$INT_KVERS/bin/$(go env GOOS)/$(go env GOARCH)/kubectl
install -m 755 kubectl $GOPATH/bin/kubectl
fi
mkdir -p $HOME/.kube
touch $HOME/.kube/config
sudo -E $GOPATH/bin/minikube start --vm-driver=none \
--extra-config apiserver.Authorization.Mode=RBAC \
--kubernetes-version $INT_KVERS
go get github.com/onsi/ginkgo/ginkgo
fi
- go build -i -ldflags "$GO_LDFLAGS" ./cmd/ks
script:
- make VERSION="$VERSION" EXTRA_GO_FLAGS="$EXTRA_GO_FLAGS_TEST" test
- make vet
......
......@@ -40,13 +40,13 @@ INTEGRATION_TEST_FIXTURES = ./fixtures
all: ks docs
ks:
$(GO) build -o $(KS_BIN) $(GO_FLAGS) .
$(GO) build -o $(KS_BIN) $(GO_FLAGS) ./cmd/ks
docs:
$(DOC_GEN_FILE)
install:
$(GO) build -o $(GOPATH)/bin/ks $(GO_FLAGS) .
$(GO) build -o $(GOPATH)/bin/ks $(GO_FLAGS) ./cmd/ks
test: gotest docstest
......
......@@ -20,7 +20,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/ksonnet/ksonnet/cmd"
"github.com/ksonnet/ksonnet/pkg/clicmd"
"github.com/ksonnet/ksonnet/pkg/kubecfg"
)
......@@ -29,10 +29,10 @@ var version = "(dev build)"
var apimachineryVersion = ""
func main() {
cmd.Version = version
cmd.APImachineryVersion = apimachineryVersion
clicmd.Version = version
clicmd.APImachineryVersion = apimachineryVersion
if err := cmd.RootCmd.Execute(); err != nil {
if err := clicmd.RootCmd.Execute(); err != nil {
// PersistentPreRunE may not have been run for early
// errors, like invalid command line flags.
logFmt := &log.TextFormatter{
......
......@@ -17,16 +17,16 @@ package main
import (
"log"
"os"
"os"
"github.com/ksonnet/ksonnet/pkg/clicmd"
"github.com/spf13/cobra/doc"
"github.com/ksonnet/ksonnet/cmd"
)
func main() {
outputDir := os.Args[1]
cmd := cmd.RootCmd
cmd := clicmd.RootCmd
// Remove auto-generated timestamps
cmd.DisableAutoGenTag = true
......
......@@ -127,7 +127,7 @@ func (e *e2e) buildKs() {
"build",
"-o",
e.ksBin(),
`github.com/ksonnet/ksonnet`,
`github.com/ksonnet/ksonnet/cmd/ks`,
}
cmd := exec.Command("go", args...)
......
// Copyright 2018 The kubecfg 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.
// +build integration
package integration
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/api/core/v1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func cmData(cm *v1.ConfigMap) map[string]string {
return cm.Data
}
var _ = Describe("apply", func() {
var c corev1.CoreV1Interface
var host string
var ns string
const cmName = "testcm"
BeforeEach(func() {
config := clusterConfigOrDie()
host = config.Host
c = corev1.NewForConfigOrDie(config)
ns = createNsOrDie(c, "apply")
})
AfterEach(func() {
deleteNsOrDie(c, ns)
})
Describe("A simple apply", func() {
var cm *v1.ConfigMap
JustBeforeEach(func() {
err := runKsonnetWith([]string{"apply", "default", "-v"}, host, ns)
Expect(err).NotTo(HaveOccurred())
})
Context("With no existing state", func() {
It("should produce expected object", func() {
Expect(c.Services(ns).Get("guestbook-ui", metav1.GetOptions{})).
NotTo(BeNil())
})
})
Context("With existing object", func() {
BeforeEach(func() {
cm = &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: cmName},
Data: map[string]string{"foo": "bar"},
}
_, err := c.ConfigMaps(ns).Create(cm)
Expect(err).To(Not(HaveOccurred()))
})
It("should succeed", func() {
Expect(c.Services(ns).Get("guestbook-ui", metav1.GetOptions{})).
NotTo(BeNil())
})
})
})
Describe("An apply with mixed namespaces", func() {
var ns2 string
BeforeEach(func() {
ns2 = createNsOrDie(c, "apply")
})
AfterEach(func() {
deleteNsOrDie(c, ns2)
})
JustBeforeEach(func() {
err := runKsonnetWith([]string{"apply", "default", "-v", "-n", ns2}, host, ns)
Expect(err).NotTo(HaveOccurred())
})
It("should create objects in the correct namespaces", func() {
Expect(c.Services(ns2).Get("guestbook-ui", metav1.GetOptions{})).
NotTo(BeNil())
})
})
})
// Copyright 2018 The kubecfg 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.
// +build integration
package integration
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/api/core/v1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func objNames(list *v1.ConfigMapList) []string {
ret := make([]string, 0, len(list.Items))
for _, obj := range list.Items {
ret = append(ret, obj.GetName())
}
return ret
}
var _ = Describe("delete", func() {
var c corev1.CoreV1Interface
var ns string
var host string
BeforeEach(func() {
config := clusterConfigOrDie()
c = corev1.NewForConfigOrDie(config)
host = config.Host
ns = createNsOrDie(c, "delete")
})
AfterEach(func() {
deleteNsOrDie(c, ns)
})
Describe("Simple delete", func() {
JustBeforeEach(func() {
err := runKsonnetWith([]string{"delete", "default", "-v"}, host, ns)
Expect(err).NotTo(HaveOccurred())
})
Context("With no existing state", func() {
It("should succeed", func() {
Expect(c.ConfigMaps(ns).List(metav1.ListOptions{})).
To(WithTransform(objNames, BeEmpty()))
})
})
Context("With existing objects", func() {
BeforeEach(func() {
objs := []runtime.Object{
&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
},
&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "bar"},
},
}
toCreate := []*v1.ConfigMap{}
for _, cm := range objs {
toCreate = append(toCreate, cm.(*v1.ConfigMap))
}
for _, cm := range toCreate {
_, err := c.ConfigMaps(ns).Create(cm)
Expect(err).To(Not(HaveOccurred()))
}
})
It("should only delete objects in the targeted env", func() {
Expect(c.ConfigMaps(ns).List(metav1.ListOptions{})).
NotTo(WithTransform(objNames, BeEmpty()))
})
})
})
})
apiVersion: "0.1"
gitVersion:
commitSha: 9d78d6bb445d530d5b927656d2293d4f12654608
refSpec: master
kind: ksonnet.io/registry
libraries:
apache:
path: apache
version: test-reg
efk:
path: efk
version: test-reg
mariadb:
path: mariadb
version: test-reg
memcached:
path: memcached
version: test-reg
mongodb:
path: mongodb
version: test-reg
mysql:
path: mysql
version: test-reg
nginx:
path: nginx
version: test-reg
node:
path: node
version: test-reg
postgres:
path: postgres
version: test-reg
redis:
path: redis
version: test-reg
tomcat:
path: tomcat
version: test-reg
local k = import "k.libsonnet";
local service = k.core.v1.service;
local servicePort = k.core.v1.service.mixin.spec.portsType;
local targetPort = 80;
local labels = {app: "guestbook-ui"};
local appService = service
.new(
"guestbook-ui",
labels,
servicePort.new(80, targetPort))
.withType("LoadBalancer");
k.core.v1.list.new([appService])
{
global: {
// User-defined global parameters; accessible to all component and environments, Ex:
// replicas: 4,
},
components: {
// Component-level parameters, defined initially from 'ks prototype use ...'
// Each object below should correspond to a component in the components/ directory
},
}
local components = std.extVar("__ksonnet/components");
components + {
// Insert user-specified overrides here.
}
local base = import "base.libsonnet";
local k = import "k.libsonnet";
base + {
// Insert user-specified overrides here. For example if a component is named "nginx-deployment", you might have something like:
// "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"})
}
local params = import "../../components/params.libsonnet";
params + {
components +: {
// Insert component parameter overrides here. Ex:
// guestbook +: {
// name: "guestbook-dev",
// replicas: params.global.replicas,
// },
},
}
local k8s = import "k8s.libsonnet";
local apps = k8s.apps;
local core = k8s.core;
local extensions = k8s.extensions;
local hidden = {
mapContainers(f):: {
local podContainers = super.spec.template.spec.containers,
spec+: {
template+: {
spec+: {
// IMPORTANT: This overwrites the 'containers' field
// for this deployment.
containers: std.map(f, podContainers),
},
},
},
},
mapContainersWithName(names, f) ::
local nameSet =
if std.type(names) == "array"
then std.set(names)
else std.set([names]);
local inNameSet(name) = std.length(std.setInter(nameSet, std.set([name]))) > 0;
self.mapContainers(
function(c)
if std.objectHas(c, "name") && inNameSet(c.name)
then f(c)
else c
),
};
k8s + {
apps:: apps + {
v1beta1:: apps.v1beta1 + {
local v1beta1 = apps.v1beta1,
daemonSet:: v1beta1.daemonSet + {
mapContainers(f):: hidden.mapContainers(f),
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
},
deployment:: v1beta1.deployment + {
mapContainers(f):: hidden.mapContainers(f),
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
},
},
},
core:: core + {
v1:: core.v1 + {
list:: {
new(items)::
{apiVersion: "v1"} +
{kind: "List"} +
self.items(items),
items(items):: if std.type(items) == "array" then {items+: items} else {items+: [items]},
},
},
},
extensions:: extensions + {
v1beta1:: extensions.v1beta1 + {
local v1beta1 = extensions.v1beta1,
daemonSet:: v1beta1.daemonSet + {
mapContainers(f):: hidden.mapContainers(f),
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
},
deployment:: v1beta1.deployment + {
mapContainers(f):: hidden.mapContainers(f),
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
},
},
},
}
This diff is collapsed.
// Copyright 2018 The kubecfg 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.
// +build integration
package integration
import (
"flag"
"fmt"
"io"
"os"
"os/exec"
"path"
"testing"
"github.com/ksonnet/ksonnet/metadata/app"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
// For client auth plugins
_ "k8s.io/client-go/plugin/pkg/client/auth"
)
var kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
var ksonnetBin = flag.String("ksonnet-bin", "ks", "path to ksonnet executable under test")
var ksonnetData = flag.String("fixtures", "integration/fixtures", "path to ksonnet test data")
func init() {
registrationManager, err := registered.NewAPIRegistrationManager("")
if err != nil {
panic(err.Error())
}
if missingVersions := registrationManager.ValidateEnvRequestedVersions(); len(missingVersions) != 0 {
panic(fmt.Sprintf("KUBE_API_VERSIONS contains versions that are not installed: %q.", missingVersions))
}
}
func clusterConfigOrDie() *rest.Config {
var config *rest.Config
var err error
if *kubeconfig != "" {
config, err = clientcmd.BuildConfigFromFlags("", *kubeconfig)
} else {
config, err = rest.InClusterConfig()
}
if err != nil {
panic(err.Error())
}
return config
}
func createNsOrDie(c corev1.CoreV1Interface, ns string) string {
result, err := c.Namespaces().Create(
&v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
GenerateName: ns,
},
})
if err != nil {
panic(err.Error())
}
name := result.GetName()
fmt.Fprintf(GinkgoWriter, "Created namespace %s\n", name)
return name
}
func deleteNsOrDie(c corev1.CoreV1Interface, ns string) {
err := c.Namespaces().Delete(ns, &metav1.DeleteOptions{})
if err != nil {
panic(err.Error())
}
}
func containsString(haystack []string, needle string) bool {
for _, s := range haystack {
if s == needle {
return true
}
}
return false
}
func runKsonnetWith(flags []string, host, ns string) error {
spec := app.Spec{
Version: "0.0.1",
APIVersion: "0.1.0",
Environments: app.EnvironmentSpecs{
"default": &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: ns,
Server: host,
},
KubernetesVersion: "v1.7.0",
},
},
}