devfile 0.0.8.pre.alpha1-arm64-darwin-21

Sign up to get free protection for your applications and to get access to all the features.
data/ext/main.go ADDED
@@ -0,0 +1,204 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "k8s.io/apimachinery/pkg/util/yaml"
6
+ "os"
7
+ "strconv"
8
+
9
+ "k8s.io/apimachinery/pkg/runtime"
10
+ )
11
+
12
+ func main() {
13
+ args := os.Args
14
+
15
+ if len(args) <= 1 {
16
+ fmt.Fprint(os.Stderr, "Function name and devfile are required")
17
+ os.Exit(1)
18
+ }
19
+
20
+ fnName := os.Args[1]
21
+ devfile := os.Args[2]
22
+
23
+ var content string
24
+ var err error
25
+
26
+ switch fnName {
27
+ case "deployment":
28
+ content, err = getDeployment(devfile, args[3], args[4], args[5], args[6], args[7])
29
+ case "service":
30
+ content, err = getService(devfile, args[3], args[4], args[5], args[6])
31
+ case "ingress":
32
+ content, err = getIngress(devfile, args[3], args[4], args[5], args[6], args[7], args[8])
33
+ case "all":
34
+ content, err = getAll(devfile, args[3], args[4], args[5], args[6], args[7], args[8], args[9])
35
+ case "flatten":
36
+ content, err = flatten(devfile)
37
+ }
38
+
39
+ if err != nil {
40
+ fmt.Fprint(os.Stderr, err)
41
+ os.Exit(1)
42
+ }
43
+
44
+ fmt.Print(content)
45
+ }
46
+
47
+ func unmarshalKeyValuePair(data string) (map[string]string, error) {
48
+ values := map[string]string{}
49
+ err := yaml.Unmarshal([]byte(data), &values)
50
+ if err != nil {
51
+ return nil, err
52
+ }
53
+ return values, err
54
+ }
55
+
56
+ func getDeployment(devfile, name, namespace, labelsStr, annotationsStr, replicas string) (string, error) {
57
+ d, err := parseDevfile(devfile)
58
+ if err != nil {
59
+ return "", err
60
+ }
61
+ exists, err := d.hasContainerComponents()
62
+ if err != nil {
63
+ return "", err
64
+ }
65
+ if exists == false {
66
+ return "", err
67
+ }
68
+ labels, err := unmarshalKeyValuePair(labelsStr)
69
+ if err != nil {
70
+ return "", err
71
+ }
72
+ annotations, err := unmarshalKeyValuePair(annotationsStr)
73
+ if err != nil {
74
+ return "", err
75
+ }
76
+ replicasInt, err := strconv.Atoi(replicas)
77
+ if err != nil {
78
+ return "", err
79
+ }
80
+ deployment, err := d.getDeployment(name, namespace, labels, annotations, replicasInt)
81
+ if err != nil {
82
+ return "", err
83
+ }
84
+ content, err := marshalResources([]runtime.Object{deployment})
85
+ if err != nil {
86
+ return "", err
87
+ }
88
+ return content, nil
89
+ }
90
+
91
+ func getService(devfile, name, namespace, labelsStr, annotationsStr string) (string, error) {
92
+ d, err := parseDevfile(devfile)
93
+ if err != nil {
94
+ return "", err
95
+ }
96
+ exists, err := d.hasContainerComponents()
97
+ if err != nil {
98
+ return "", err
99
+ }
100
+ if exists == false {
101
+ return "", err
102
+ }
103
+ labels, err := unmarshalKeyValuePair(labelsStr)
104
+ if err != nil {
105
+ return "", err
106
+ }
107
+ annotations, err := unmarshalKeyValuePair(annotationsStr)
108
+ if err != nil {
109
+ return "", err
110
+ }
111
+ service, err := d.getService(name, namespace, labels, annotations)
112
+ if err != nil {
113
+ return "", err
114
+ }
115
+ content, err := marshalResources([]runtime.Object{service})
116
+ if err != nil {
117
+ return "", err
118
+ }
119
+ return content, nil
120
+ }
121
+
122
+ func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainTemplate, ingressClass string) (string, error) {
123
+ d, err := parseDevfile(devfile)
124
+ if err != nil {
125
+ return "", err
126
+ }
127
+ exists, err := d.hasContainerComponents()
128
+ if err != nil {
129
+ return "", err
130
+ }
131
+ if exists == false {
132
+ return "", err
133
+ }
134
+ labels, err := unmarshalKeyValuePair(labelsStr)
135
+ if err != nil {
136
+ return "", err
137
+ }
138
+ annotations, err := unmarshalKeyValuePair(annotationsStr)
139
+ if err != nil {
140
+ return "", err
141
+ }
142
+ ingress, err := d.getIngress(name, namespace, labels, annotations, domainTemplate, ingressClass)
143
+ if err != nil {
144
+ return "", err
145
+ }
146
+
147
+ if ingress == nil {
148
+ return "", nil
149
+ }
150
+
151
+ content, err := marshalResources([]runtime.Object{ingress})
152
+ if err != nil {
153
+ return "", err
154
+ }
155
+ return content, nil
156
+ }
157
+
158
+ func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainTemplate, ingressClass string) (string, error) {
159
+ d, err := parseDevfile(devfile)
160
+ if err != nil {
161
+ return "", err
162
+ }
163
+ exists, err := d.hasContainerComponents()
164
+ if err != nil {
165
+ return "", err
166
+ }
167
+ if exists == false {
168
+ return "", err
169
+ }
170
+ labels, err := unmarshalKeyValuePair(labelsStr)
171
+ if err != nil {
172
+ return "", err
173
+ }
174
+ annotations, err := unmarshalKeyValuePair(annotationsStr)
175
+ if err != nil {
176
+ return "", err
177
+ }
178
+ replicasInt, err := strconv.Atoi(replicas)
179
+ if err != nil {
180
+ return "", err
181
+ }
182
+ resources, err := d.getAll(name, namespace, labels, annotations, replicasInt, domainTemplate, ingressClass)
183
+ if err != nil {
184
+ return "", err
185
+ }
186
+ content, err := marshalResources(resources)
187
+ if err != nil {
188
+ return "", err
189
+ }
190
+ return content, nil
191
+ }
192
+
193
+ func flatten(devfile string) (string, error) {
194
+ d, err := parseDevfile(devfile)
195
+ if err != nil {
196
+ return "", err
197
+ }
198
+ flattenedDevfile := d.getFlattenedDevfileContent()
199
+ content, err := marshalDevfile(flattenedDevfile)
200
+ if err != nil {
201
+ return "", err
202
+ }
203
+ return content, err
204
+ }
data/ext/volume.go ADDED
@@ -0,0 +1,114 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "github.com/devfile/library/v2/pkg/devfile/generator"
6
+ "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
7
+ corev1 "k8s.io/api/core/v1"
8
+ "k8s.io/apimachinery/pkg/api/resource"
9
+ "strings"
10
+ )
11
+
12
+ func (d Devfile) getVolumesAndVolumeMounts(containers []corev1.Container, initContainers []corev1.Container, pvcNamePrefix string) ([]corev1.Volume, error) {
13
+ containerComponents, err := d.devfileObj.Data.GetDevfileContainerComponents(common.DevfileOptions{})
14
+ if err != nil {
15
+ return nil, err
16
+ }
17
+ volumeComponents, err := d.devfileObj.Data.GetDevfileVolumeComponents(common.DevfileOptions{})
18
+ if err != nil {
19
+ return nil, err
20
+ }
21
+
22
+ var volumes []corev1.Volume
23
+ for _, volumeComponent := range volumeComponents {
24
+ volName := volumeComponent.Name
25
+ if bool(*volumeComponent.Volume.Ephemeral) == true {
26
+ emptyDir, err := getEmptyDir(volName, volumeComponent.Volume.Size)
27
+ if err != nil {
28
+ return nil, err
29
+ }
30
+ volumes = append(volumes, emptyDir)
31
+ } else {
32
+ // TODO: figure this out; how should we pass PVC name? should the object be generated here?
33
+ pvcName := fmt.Sprintf("%s-%s", pvcNamePrefix, volName)
34
+ volumes = append(volumes, getPVC(volName, pvcName))
35
+ }
36
+ // containerNameToMountPaths is a map of the Devfile container name to their Devfile Volume Mount Paths for a given Volume Name
37
+ containerNameToMountPaths := make(map[string][]string)
38
+ for _, containerComp := range containerComponents {
39
+ for _, volumeMount := range containerComp.Container.VolumeMounts {
40
+ if volName == volumeMount.Name {
41
+ containerNameToMountPaths[containerComp.Name] = append(containerNameToMountPaths[containerComp.Name], generator.GetVolumeMountPath(volumeMount))
42
+ }
43
+ }
44
+ }
45
+
46
+ addVolumeMountToContainers(containers, initContainers, volName, containerNameToMountPaths)
47
+ }
48
+
49
+ return volumes, nil
50
+ }
51
+
52
+ // addVolumeMountToContainers adds the Volume Mounts in containerNameToMountPaths to the containers for a given pvc and volumeName
53
+ // containerNameToMountPaths is a map of a container name to an array of its Mount Paths.
54
+ // To be moved to devfile/library.
55
+ func addVolumeMountToContainers(containers []corev1.Container, initContainers []corev1.Container, volumeName string, containerNameToMountPaths map[string][]string) {
56
+
57
+ for containerName, mountPaths := range containerNameToMountPaths {
58
+ for i := range containers {
59
+ if containers[i].Name == containerName {
60
+ for _, mountPath := range mountPaths {
61
+ containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{
62
+ Name: volumeName,
63
+ MountPath: mountPath,
64
+ SubPath: "",
65
+ },
66
+ )
67
+ }
68
+ }
69
+ }
70
+ for i := range initContainers {
71
+ if strings.HasPrefix(initContainers[i].Name, containerName) {
72
+ for _, mountPath := range mountPaths {
73
+ initContainers[i].VolumeMounts = append(initContainers[i].VolumeMounts, corev1.VolumeMount{
74
+ Name: volumeName,
75
+ MountPath: mountPath,
76
+ SubPath: "",
77
+ },
78
+ )
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ // getPVC gets a pvc type volume with the given volume name and pvc name.
86
+ func getPVC(volumeName, pvcName string) corev1.Volume {
87
+
88
+ return corev1.Volume{
89
+ Name: volumeName,
90
+ VolumeSource: corev1.VolumeSource{
91
+ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
92
+ ClaimName: pvcName,
93
+ },
94
+ },
95
+ }
96
+ }
97
+
98
+ // getEmptyDir gets an emptyDir type volume with the given volume name and size.
99
+ // size should be parseable as a Kubernetes `Quantity` or an error will be returned
100
+ func getEmptyDir(volumeName string, size string) (corev1.Volume, error) {
101
+
102
+ emptyDir := &corev1.EmptyDirVolumeSource{}
103
+ qty, err := resource.ParseQuantity(size)
104
+ if err != nil {
105
+ return corev1.Volume{}, err
106
+ }
107
+ emptyDir.SizeLimit = &qty
108
+ return corev1.Volume{
109
+ Name: volumeName,
110
+ VolumeSource: corev1.VolumeSource{
111
+ EmptyDir: emptyDir,
112
+ },
113
+ }, nil
114
+ }
data/lib/devfile.rb ADDED
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ # Module that works with the Devfile standard
6
+ module Devfile
7
+ # Set of services to parse a devfile and output k8s manifests
8
+ class Parser
9
+ FILE_PATH = File.expand_path('./../bin/devfile', File.dirname(__FILE__))
10
+
11
+ class << self
12
+ def get_deployment(devfile, name, namespace, labels, annotations, replicas)
13
+ stdout, stderr, status = Open3.capture3(
14
+ "#{FILE_PATH} deployment '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{replicas}"
15
+ )
16
+
17
+ raise stderr unless status.success?
18
+
19
+ stdout
20
+ end
21
+
22
+ def get_service(devfile, name, namespace, labels, annotations)
23
+ stdout, stderr, status = Open3.capture3(
24
+ "#{FILE_PATH} service '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}'"
25
+ )
26
+
27
+ raise stderr unless status.success?
28
+
29
+ stdout
30
+ end
31
+
32
+ def get_ingress(devfile, name, namespace, labels, annotations, domain_template, ingress_class)
33
+ stdout, stderr, status = Open3.capture3(
34
+ "#{FILE_PATH} ingress '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{domain_template} #{ingress_class}"
35
+ )
36
+
37
+ raise stderr unless status.success?
38
+
39
+ stdout
40
+ end
41
+
42
+ def get_all(devfile, name, namespace, labels, annotations, replicas, domain_template, ingress_class)
43
+ stdout, stderr, status = Open3.capture3(
44
+ "#{FILE_PATH} all '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{replicas} #{domain_template} #{ingress_class}"
45
+ )
46
+
47
+ raise stderr unless status.success?
48
+
49
+ stdout
50
+ end
51
+
52
+ def flatten(devfile)
53
+ stdout, stderr, status = Open3.capture3("#{FILE_PATH} flatten '#{devfile}'")
54
+
55
+ raise stderr unless status.success?
56
+
57
+ stdout
58
+ end
59
+ end
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devfile
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8.pre.alpha1
5
+ platform: arm64-darwin-21
6
+ authors:
7
+ - GitLab
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-03-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Library used to generate kubernetes manifests from a Devfile.
14
+ email: spatnaik@gitlab.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - bin/devfile
20
+ - ext/devfile.go
21
+ - ext/go.mod
22
+ - ext/go.sum
23
+ - ext/main.go
24
+ - ext/volume.go
25
+ - lib/devfile.rb
26
+ homepage: https://gitlab.com
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ source_code_uri: https://gitlab.com/gitlab-org/remote-development/devfile-gem
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '2.7'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">"
43
+ - !ruby/object:Gem::Version
44
+ version: 1.3.1
45
+ requirements: []
46
+ rubygems_version: 3.4.8
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Parse and generate kubernetes manifests from a Devfile
50
+ test_files: []