blob: f78134f1d04867f1df1a0ba729f8060584bdc656 [file] [log] [blame]
giolekva07f6be92020-04-16 21:09:30 +04001package main
2
3import (
giolekva88d6e352020-04-30 13:32:38 +04004 "errors"
giolekva07f6be92020-04-16 21:09:30 +04005 "flag"
6 "fmt"
giolekvafb52e0d2020-04-23 22:52:13 +04007 "io"
giolekva07f6be92020-04-16 21:09:30 +04008 "io/ioutil"
9 "log"
10 "net/http"
giolekvafb52e0d2020-04-23 22:52:13 +040011
giolekvafb52e0d2020-04-23 22:52:13 +040012 "k8s.io/client-go/kubernetes"
13 corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
14 "k8s.io/client-go/rest"
15 "k8s.io/client-go/tools/clientcmd"
giolekvac76b21b2020-04-18 19:28:43 +040016
17 "github.com/giolekva/pcloud/controller/schema"
18
19 "github.com/golang/glog"
20 "github.com/itaysk/regogo"
giolekva07f6be92020-04-16 21:09:30 +040021)
22
giolekvafb52e0d2020-04-23 22:52:13 +040023var kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file.")
24
giolekva07f6be92020-04-16 21:09:30 +040025var port = flag.Int("port", 123, "Port to listen on.")
giolekvafb52e0d2020-04-23 22:52:13 +040026var dgraphGqlAddress = flag.String("graphql_address", "", "GraphQL server address.")
27var dgraphSchemaAddress = flag.String("dgraph_admin_address", "", "Dgraph server admin address.")
giolekva07f6be92020-04-16 21:09:30 +040028
giolekvac76b21b2020-04-18 19:28:43 +040029const imgJson = `{ objectPath: \"%s\"}`
giolekvafb52e0d2020-04-23 22:52:13 +040030const insertQuery = `mutation { add%s(input: [%s]) { %s { id } } }`
giolekvac76b21b2020-04-18 19:28:43 +040031const getQuery = `{ "query": "{ get%s(id: \"%s\") { id objectPath } } " }`
32
giolekvac76b21b2020-04-18 19:28:43 +040033type MinioWebhook struct {
giolekva8fe32df2020-05-12 13:31:46 +040034 gql schema.GraphQLClient
giolekvafb52e0d2020-04-23 22:52:13 +040035}
36
giolekva88d6e352020-04-30 13:32:38 +040037type query struct {
38 query string
39 operation string
40 variables string
41}
42
43func extractQuery(r *http.Request) (*query, error) {
44 if r.Method == "GET" {
45 if err := r.ParseForm(); err != nil {
46 return nil, err
47 }
48 q, ok := r.Form["query"]
49 if !ok || len(q) != 1 {
50 return nil, errors.New("Exactly one query must be provided")
51 }
52 return &query{query: q[0]}, nil
53 } else {
54 body, err := ioutil.ReadAll(r.Body)
55 if err != nil {
56 return nil, err
57 }
58 q, err := regogo.Get(string(body), "input.query")
59 if err != nil {
60 return nil, err
61 }
62 return &query{query: q.String()}, nil
63 }
64}
65
giolekvafb52e0d2020-04-23 22:52:13 +040066func (m *MinioWebhook) graphqlHandler(w http.ResponseWriter, r *http.Request) {
67 glog.Infof("New GraphQL query received: %s", r.Method)
giolekva88d6e352020-04-30 13:32:38 +040068 q, err := extractQuery(r)
giolekvafb52e0d2020-04-23 22:52:13 +040069 if err != nil {
giolekva88d6e352020-04-30 13:32:38 +040070 glog.Error(err.Error())
71 http.Error(w, "Could not extract query", http.StatusBadRequest)
giolekvafb52e0d2020-04-23 22:52:13 +040072 }
giolekva88d6e352020-04-30 13:32:38 +040073 resp, err := m.gql.RunQuery(q.query)
giolekvafb52e0d2020-04-23 22:52:13 +040074 if err != nil {
75 glog.Error(err)
76 http.Error(w, err.Error(), http.StatusInternalServerError)
77 return
78 }
79 io.WriteString(w, resp)
80 w.Header().Set("Content-Type", "application/json")
81}
82
83func getKubeConfig() (*rest.Config, error) {
84 if *kubeconfig != "" {
85 return clientcmd.BuildConfigFromFlags("", *kubeconfig)
86 } else {
87 return rest.InClusterConfig()
88 }
giolekva07f6be92020-04-16 21:09:30 +040089}
90
91func main() {
92 flag.Parse()
giolekvac76b21b2020-04-18 19:28:43 +040093
giolekvafb52e0d2020-04-23 22:52:13 +040094 gqlClient, err := schema.NewDgraphClient(
95 *dgraphGqlAddress, *dgraphSchemaAddress)
96 if err != nil {
97 panic(err)
98 }
giolekva26a8b5f2020-05-01 20:01:13 +040099 err = gqlClient.SetSchema(`
100enum EventState {
101 NEW
102 PROCESSING
103 DONE
104}
giolekvafb52e0d2020-04-23 22:52:13 +0400105
giolekva26a8b5f2020-05-01 20:01:13 +0400106type Foo { bar: Int }`)
107 if err != nil {
108 panic(err)
109 }
110 err = gqlClient.AddSchema(`
111 type Image {
112 id: ID!
113 objectPath: String! @search(by: [exact])
114 }
giolekvafb52e0d2020-04-23 22:52:13 +0400115
giolekva26a8b5f2020-05-01 20:01:13 +0400116 type ImageSegment {
117 id: ID!
118 upperLeftX: Float!
119 upperLeftY: Float!
120 lowerRightX: Float!
121 lowerRightY: Float!
122 sourceImage: Image! @hasInverse(field: segments)
123 }
124
125 extend type Image {
126 segments: [ImageSegment] @hasInverse(field: sourceImage)
127 }`)
128 if err != nil {
129 panic(err)
130 }
giolekva8fe32df2020-05-12 13:31:46 +0400131 mw := MinioWebhook{gqlClient}
giolekvafb52e0d2020-04-23 22:52:13 +0400132 http.HandleFunc("/graphql", mw.graphqlHandler)
giolekva07f6be92020-04-16 21:09:30 +0400133 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
134}