1// Copyright 2017 Google LLC. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package gnostic_extension_v1
16
17import (
18	"io/ioutil"
19	"log"
20	"os"
21
22	"github.com/golang/protobuf/proto"
23	"github.com/golang/protobuf/ptypes"
24)
25
26type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error)
27
28// Main implements the main program of an extension handler.
29func Main(handler extensionHandler) {
30	// unpack the request
31	data, err := ioutil.ReadAll(os.Stdin)
32	if err != nil {
33		log.Println("File error:", err.Error())
34		os.Exit(1)
35	}
36	if len(data) == 0 {
37		log.Println("No input data.")
38		os.Exit(1)
39	}
40	request := &ExtensionHandlerRequest{}
41	err = proto.Unmarshal(data, request)
42	if err != nil {
43		log.Println("Input error:", err.Error())
44		os.Exit(1)
45	}
46	// call the handler
47	handled, output, err := handler(request.Wrapper.ExtensionName, request.Wrapper.Yaml)
48	// respond with the output of the handler
49	response := &ExtensionHandlerResponse{
50		Handled: false, // default assumption
51		Errors:  make([]string, 0),
52	}
53	if err != nil {
54		response.Errors = append(response.Errors, err.Error())
55	} else if handled {
56		response.Handled = true
57		response.Value, err = ptypes.MarshalAny(output)
58		if err != nil {
59			response.Errors = append(response.Errors, err.Error())
60		}
61	}
62	responseBytes, _ := proto.Marshal(response)
63	os.Stdout.Write(responseBytes)
64}
65