builder/kubebuilder-build/utils/acmsplit/main.go (137 lines of code) (raw):
// Copyright 2019 Google LLC
//
// 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 2019 Google LLC. This software is provided as-is,
// without warranty or representation for any use or purpose.
//
package main
import (
"bufio"
"bytes"
b64 "encoding/base64"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"k8s.io/api/admissionregistration/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
//metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes/scheme"
//"sigs.k8s.io/controller-runtime/pkg/webhook"
// "k8s.io/client-go/pkg/api"
// _ "k8s.io/client-go/pkg/api/install"
// _ "k8s.io/client-go/pkg/apis/extensions/install"
// _ "k8s.io/client-go/pkg/apis/rbac/install"
// //...
// // "k8s.io/client-go/pkg/api/v1"
// "k8s.io/client-go/pkg/apis/rbac/v1beta1"
// make sure to import all client-go/pkg/api(s) you need to cover with your code
)
// createConfigMapWithYAML creates a ConfigMap with the YAML of the webhook, to be able to generate
// at install time with the key information and caBundle
func createConfigMapWithYAML(b []byte) ([]byte, error) {
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, groupVersionKind, err := decode(b, nil, nil)
if err != nil {
return nil, errors.New("Invalid Object")
}
name := ""
namespace := ""
if groupVersionKind.Kind == "MutatingWebhookConfiguration" {
name = obj.(*v1beta1.MutatingWebhookConfiguration).Name
namespace = obj.(*v1beta1.MutatingWebhookConfiguration).Namespace
}
if groupVersionKind.Kind == "ValidatingWebhookConfiguration" {
name = obj.(*v1beta1.ValidatingWebhookConfiguration).Name
namespace = obj.(*v1beta1.ValidatingWebhookConfiguration).Namespace
}
if len(namespace) > 0 {
namespace = "namespace: " + namespace + "\n"
}
//fmt.Println(string(b))
sEnc := b64.StdEncoding.EncodeToString(b)
b = append([]byte("---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n" +
" name: " + name + "\n" + namespace +
"data:\n" +
" webhook.yaml: " + sEnc + "\n"))
return b, nil
}
// SplitYAMLDocuments reads the YAML bytes per-document, unmarshals the TypeMeta information from each document
// and returns a map between the GroupVersionKind of the document and the document bytes
func SplitYAMLDocuments(yamlBytes []byte) ([]byte, []byte, error) {
gvkListCluster := make([]byte, 0)
gvkListOther := make([]byte, 0)
errs := []error{}
buf := bytes.NewBuffer(yamlBytes)
reader := utilyaml.NewYAMLReader(bufio.NewReader(buf))
for {
typeMetaInfo := runtime.TypeMeta{}
typeObjectInfo := corev1.ObjectReference{}
// Read one YAML document at a time, until io.EOF is returned
b, err := reader.Read()
if err == io.EOF {
break
} else if err != nil {
return nil, nil, err
}
if len(b) == 0 {
break
}
// Deserialize the TypeMeta information of this byte slice
if err := yaml.Unmarshal(b, &typeMetaInfo); err != nil {
return nil, nil, err
}
if err := yaml.Unmarshal(b, &typeObjectInfo); err != nil {
return nil, nil, err
}
// Require TypeMeta information to be present
if len(typeMetaInfo.APIVersion) == 0 || len(typeMetaInfo.Kind) == 0 {
errs = append(errs, errors.New("invalid configuration: kind and apiVersion is mandatory information that needs to be specified in all YAML documents"))
continue
}
fmt.Println("kind", typeMetaInfo.Kind, len(b))
// Save the mapping between the gvk and the bytes that object consists of
switch typeMetaInfo.Kind {
case "Namespace":
case "ConstraintTemplate", "Constraint":
fallthrough
case "ClusterRole":
fallthrough
case "ClusterRoleBinding":
fallthrough
case "CustomResourceDefinition":
b = append([]byte("---\n"), b...)
gvkListCluster = append(gvkListCluster, b...)
case "MutatingWebhookConfiguration":
fallthrough
case "ValidatingWebhookConfiguration":
configMapBytes, err := createConfigMapWithYAML(b)
if err != nil {
return nil, nil, err
}
gvkListOther = append(gvkListOther, configMapBytes...)
default:
b = append([]byte("---\n"), b...)
gvkListOther = append(gvkListOther, b...)
}
}
return gvkListCluster, gvkListOther, nil
}
//TODO - This could use a shared utitlity
func generateOSSHeader() []byte {
return []byte(
`# Copyright 2019 Google LLC
#
# 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 2019 Google LLC. This software is provided as-is,
# without warranty or representation for any use or purpose.#
#`)
}
// Utility to split yaml files for Anthos Config Management to separate cluster commands from Other
func main() {
readFrom := flag.String("read-from", "./config/generated/all.yaml", "a string")
splitToDir := flag.String("split-to-dir", "./config/generated/", "a string")
flag.Parse()
yamlFile, err := ioutil.ReadFile(*readFrom)
if err != nil {
log.Println(fmt.Sprintf("Error while decoding YAML object. Err was: %s", err))
}
// parseK8sYaml(yamlFile)
gvkCluster, gvkOther, err := SplitYAMLDocuments(yamlFile)
if err != nil {
log.Println(err, "errors-gvkmap")
}
gvkCluster = append(generateOSSHeader(), gvkCluster...)
gvkOther = append(generateOSSHeader(), gvkOther...)
fmt.Println("Total - Len", len(gvkCluster)+len(gvkOther))
ioutil.WriteFile(*splitToDir+"all-cluster.yaml", gvkCluster, 0644)
ioutil.WriteFile(*splitToDir+"all-other.yaml", gvkOther, 0644)
}