Skip to content

Commit

Permalink
Setup a Build using kodo (#25)
Browse files Browse the repository at this point in the history
* Wired List commnds to OpenShift Client

* Added build command and created BuildConfig and ImageConfig

* Added test cases and minor changes

* change source url from deploymentVariables

* changed name BuildDockerFile command and messages

* PR review changes added

* updated tests and added namespace for BuildConfig

* Added more tests and logged error

Co-authored-by: Regina Scott <rescott@localhost.localdomain>
  • Loading branch information
ranakan19 and Regina Scott authored Jun 24, 2020
1 parent e2ee6a1 commit 910380d
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 1 deletion.
Binary file modified bin/kodo
Binary file not shown.
17 changes: 16 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func init() {
rcommand.PersistentFlags().Int32VarP(&deployVar.Port, "port", "p", 8000, "port at which app should run")

rcommand.MarkFlagRequired("server")
rcommand.AddCommand(buildCommand)
rcommand.PersistentFlags().StringVarP(&deployVar.Source, "source", "o", "github.com", "github repo which has docker image")
}

func main() {
Expand All @@ -63,6 +65,19 @@ var podCommand = &cobra.Command{
},
}

var buildCommand = &cobra.Command{
Use: "build",
Run: func(cm *cobra.Command, args []string) {
fmt.Println("Building image from docker file at source")
err := cmd.BuildDockerFile(envVar, deployVar)
if err == nil {
fmt.Println("BuildConfig and ImageStream Created Successfully, Build can now be Started")
} else {
log.Fatal(err)
}
},
}

var deployCommand = &cobra.Command{
Use: "deploy",
Run: func(cm *cobra.Command, args []string) {
Expand Down Expand Up @@ -97,4 +112,4 @@ var deployCommand = &cobra.Command{
}

},
}
}
111 changes: 111 additions & 0 deletions pkg/kodo/cmd/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package cmd

import (
"context"

"k8s.io/client-go/rest"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

buildv1api "github.com/openshift/api/build/v1"
imagev1api "github.com/openshift/api/image/v1"

buildv1clientapi "github.com/openshift/client-go/build/clientset/versioned/typed/build/v1"
imagev1clientapi "github.com/openshift/client-go/image/clientset/versioned/typed/image/v1"
)

func createTypeMeta(kind string, APIVersion string) metav1.TypeMeta {
return metav1.TypeMeta{
Kind: kind,
APIVersion: APIVersion,
}
}

func createObjectType(name string, namespace string) metav1.ObjectMeta {
return metav1.ObjectMeta{
Name: name,
Namespace: namespace,
}

}

func createBuildSpec(uri string) buildv1api.BuildConfigSpec {
return buildv1api.BuildConfigSpec{
CommonSpec: buildv1api.CommonSpec{
Source: buildv1api.BuildSource{
Type: buildv1api.BuildSourceType("Git"),
Git: &buildv1api.GitBuildSource{
URI: uri,
},
},
Strategy: buildv1api.BuildStrategy{
Type: buildv1api.BuildStrategyType("Docker"),
},
Output: buildv1api.BuildOutput{
To: &corev1.ObjectReference{
Kind: "ImageStreamTag",
Name: "my-ruby-image:latest",
},
},
},
}
}

func createBuildConfig(envVar *EnvironmentVariables, deployVar *DeploymentVariables) buildv1api.BuildConfig {
return buildv1api.BuildConfig{
TypeMeta: createTypeMeta("BuildConfig", "build.openshift.io/v1"),
ObjectMeta: createObjectType("my-app-docker-build", envVar.Namespace),
Spec: createBuildSpec(deployVar.Source),
}
}

func createImageStream(envVar *EnvironmentVariables) imagev1api.ImageStream {
return imagev1api.ImageStream{
TypeMeta: createTypeMeta("ImageStream", "image.openshift.io/v1"),
ObjectMeta: createObjectType("my-ruby-image", envVar.Namespace),
}
}

func newImageStreamClient(envVar *EnvironmentVariables) *imagev1clientapi.ImageV1Client {
config := rest.Config{
Host: envVar.Host,
BearerToken: envVar.Bearertoken,
TLSClientConfig: rest.TLSClientConfig{
Insecure: true,
},
}
myClientSet, _ := imagev1clientapi.NewForConfig(&config)
return myClientSet
}
func newBuildConfigClient(envVar *EnvironmentVariables) *buildv1clientapi.BuildV1Client {
config := rest.Config{
Host: envVar.Host,
BearerToken: envVar.Bearertoken,
TLSClientConfig: rest.TLSClientConfig{
Insecure: true,
},
}
myClientSet, _ := buildv1clientapi.NewForConfig(&config)
return myClientSet
}

// BuildDockerFile : creates new BuildConfig and ImageStream from Dockerfile in github repo
func BuildDockerFile(envVar *EnvironmentVariables, deployVar *DeploymentVariables) error {
buildclient := newBuildConfigClient(envVar)
buildconfig := createBuildConfig(envVar, deployVar)

imagestreamclient := newImageStreamClient(envVar)
imagestream := createImageStream(envVar)

_, imgerr := imagestreamclient.ImageStreams(envVar.Namespace).Create(context.TODO(), &imagestream, metav1.CreateOptions{})
_, builderr := buildclient.BuildConfigs(envVar.Namespace).Create(context.TODO(), &buildconfig, metav1.CreateOptions{})

if imgerr != nil {
return imgerr
}
if builderr != nil {
return builderr
}
return nil
}
118 changes: 118 additions & 0 deletions pkg/kodo/cmd/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cmd

import (
"fmt"
"testing"

cmp "github.com/google/go-cmp/cmp"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

buildv1api "github.com/openshift/api/build/v1"
imagev1api "github.com/openshift/api/image/v1"
corev1 "k8s.io/api/core/v1"
)

var envVar = EnvironmentVariables{
Namespace: "buildtest",
Host: "",
Bearertoken: "",
}

var deployVar = DeploymentVariables{
Source: "https://github.com/openshift/ruby-hello-world.git",
}

func getBuildConfig() buildv1api.BuildConfig {
return buildv1api.BuildConfig{
TypeMeta: createTypeMeta("BuildConfig", "build.openshift.io/v1"),
ObjectMeta: createObjectType("my-app-docker-build", "buildtest"),
Spec: createBuildSpec("https://github.com/openshift/ruby-hello-world.git"),
}
}

func getBuildConfigSpec() buildv1api.BuildConfigSpec {
return buildv1api.BuildConfigSpec{
CommonSpec: buildv1api.CommonSpec{
Source: buildv1api.BuildSource{
Type: buildv1api.BuildSourceType("Git"),
Git: &buildv1api.GitBuildSource{
URI: "gitUrl",
},
},
Strategy: buildv1api.BuildStrategy{
Type: buildv1api.BuildStrategyType("Docker"),
},
Output: buildv1api.BuildOutput{
To: &corev1.ObjectReference{
Kind: "ImageStreamTag",
Name: "my-ruby-image:latest",
},
},
},
}
}

func getImageStream() imagev1api.ImageStream {
return imagev1api.ImageStream{
TypeMeta: metav1.TypeMeta{
Kind: "ImageStream",
APIVersion: "image.openshift.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "my-ruby-image",
Namespace: "buildtest",
},
}
}

func TestCreateTypeMeta(t *testing.T) {
want := metav1.TypeMeta{
Kind: "testKind",
APIVersion: "testAPIVersion",
}
got := createTypeMeta("testKind", "testAPIVersion")
if diff := cmp.Diff(want, got); diff != "" {
fmt.Println(diff)
t.Fatalf("The TypeMeta didnt match")
}

}

func TestCreateObjectType(t *testing.T) {
want := metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
}
got := createObjectType("test", "test-namespace")
if diff := cmp.Diff(want, got); diff != "" {
fmt.Println(diff)
t.Fatalf("The ObjectTypes didnt match")
}
}

func TestCreateBuildSpec(t *testing.T) {
want := getBuildConfigSpec()
got := createBuildSpec("gitUrl")
if diff := cmp.Diff(want, got); diff != "" {
fmt.Println(diff)
t.Fatalf("The BuildConfigSpecs didnt match")
}
}

func TestBuildConfig(t *testing.T) {
want := getBuildConfig()
got := createBuildConfig(&envVar, &deployVar)
if diff := cmp.Diff(want, got); diff != "" {
fmt.Println(diff)
t.Fatalf("The BuildConfigs didnt match")
}
}

func TestImageStream(t *testing.T) {
want := getImageStream()
got := createImageStream(&envVar)
if diff := cmp.Diff(want, got); diff != "" {
fmt.Println(diff)
t.Fatalf("The ImageStreams didnt match")
}
}
2 changes: 2 additions & 0 deletions pkg/kodo/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import (
cv1 "k8s.io/client-go/kubernetes/typed/core/v1"
)

//DeploymentVariables - variables associated with deployment
type DeploymentVariables struct { //New struct for deployment creation variables
Image string
Replicas int32
Port int32
Source string
}

type DeploymentIdentifiers struct { //New struct to hold unique identifiers for deployment/service/route
Expand Down

0 comments on commit 910380d

Please sign in to comment.