appconfigmgrv2/controllers/utils.go (55 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 controllers import ( "encoding/json" "errors" "fmt" "strings" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ) // unstructuredFromProto converts a proto message into object spec. // NOTE: // We are currently using the istio proto (k8s spec) to build an unstructured object. // Eventually we should be able to use an official istio k8s client: // https://github.com/istio/istio/issues/8772 func unstructuredFromProto( gvk schema.GroupVersionKind, meta map[string]interface{}, spec proto.Message, ) (*unstructured.Unstructured, error) { jsn, err := (&jsonpb.Marshaler{}).MarshalToString(spec) if err != nil { return nil, err } var specMap map[string]interface{} if err := json.Unmarshal([]byte(jsn), &specMap); err != nil { return nil, err } u := unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": meta, "spec": specMap, }, } u.SetGroupVersionKind(gvk) return &u, nil } // unstructuredNames returns a map of NamespacedName's for a list of unstructured // objects. func unstructuredNames(list []*unstructured.Unstructured) map[types.NamespacedName]bool { names := make(map[types.NamespacedName]bool) for _, obj := range list { names[types.NamespacedName{Name: obj.GetName(), Namespace: obj.GetNamespace()}] = true } return names } // parseAllowedClient splits an allowedClient into namespace, app-label // returned in that order. func parseAllowedClient(allowedClient, defaultNamespace string) (string, string, error) { if allowedClient == "" { return "", "", errors.New("empty allowed client") } split := strings.Split(allowedClient, "/") switch n := len(split); n { case 2: return split[0], split[1], nil case 1: return defaultNamespace, allowedClient, nil default: return "", "", fmt.Errorf("expected format <namespace>/<app> or <app>, got: %s", allowedClient) } }